diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2018-02-12 11:23:17 -0500 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2018-02-12 11:23:17 -0500 |
commit | 5d85baa270b046eedf472d4cb851fe17fb608fc5 (patch) | |
tree | 346fe38604047b1d25157af0966a1561961a3b4c /parser.c | |
parent | 1d092d70a3c941920da6fb25899bac0aec5cf6bf (diff) |
indent fixes, nested conditionals
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 183 |
1 files changed, 131 insertions, 52 deletions
@@ -7,6 +7,7 @@ #include <ctype.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> #define MAX_VARS 48 @@ -24,9 +25,10 @@ void iinit(interpreter *interp) interp->vnames = (char **)malloc(MAX_VARS * sizeof(char *)); interp->stack = (stack_t *)malloc(MAX_STACK * sizeof(stack_t)); interp->stidx = 0; - interp->lines = (char **)calloc(MAX_LINES, sizeof(char *)); + interp->lines = (variable ***)malloc(MAX_LINES * sizeof(variable **)); interp->lnidx = 0; interp->indent = 0; + interp->sindent = 0; for (unsigned int i = 0; i < MAX_VARS; i++) { interp->vars[i].used = 0; @@ -38,6 +40,30 @@ void iinit(interpreter *interp) iload_core(interp); } +void iend(interpreter *it) +{ + for (unsigned int i = 0; i < MAX_VARS; i++) { + if (it->vars[i].used == 1) { + char *s = it->vars[i].svalue; + if (s != 0 && s != str_undef && s != str_func) + free(s); + free(it->vnames[i]); + } + } + for (unsigned int i = 0; i < MAX_LINES; i++) + free(it->lines[i]); + free(it->vars); + free(it->vnames); + free(it->stack); + free(it->lines); +} + +void iskip(interpreter *it) +{ + if (!(it->sindent & SKIP)) + it->sindent = it->indent | SKIP; +} + variable *interpreter_get_variable(interpreter *interp, const char *name) { for (uint32_t i = 0; i < MAX_VARS; i++) { @@ -66,7 +92,7 @@ char *interpreter_get_name(interpreter *interp, variable *v) return str_undef; } -void inew_string(interpreter *interp, const char *name, char *value) +variable *inew_string(interpreter *interp, const char *name, char *value) { variable *v = interpreter_get_variable(interp, name); if (v != 0) { @@ -74,9 +100,10 @@ void inew_string(interpreter *interp, const char *name, char *value) INT(v) = 0; v->svalue = strclone(value); } + return v; } -void inew_integer(interpreter *interp, const char *name, int32_t value) +variable *inew_integer(interpreter *interp, const char *name, int32_t value) { variable *v = interpreter_get_variable(interp, name); if (v != 0) { @@ -84,9 +111,10 @@ void inew_integer(interpreter *interp, const char *name, int32_t value) INT(v) = value; isetstr(v); } + return v; } -void inew_float(interpreter *interp, const char *name, float value) +variable *inew_float(interpreter *interp, const char *name, float value) { variable *v = interpreter_get_variable(interp, name); if (v != 0) { @@ -94,6 +122,7 @@ void inew_float(interpreter *interp, const char *name, float value) FLOAT(v) = value; fsetstr(v); } + return v; } void inew_cfunc(interpreter *interp, const char *name, func_t func) @@ -116,12 +145,8 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next) if (!eot(line[end + 1])) return 0; // TODO string breakdown - variable *v = (variable *)malloc(sizeof(variable)); - v->used = 0; - v->valtype = STRING; - v->svalue = strnclone(line + 1, end - 1); *next = end + 1; - return v; + return vmake(0, STRING, strnclone(line + 1, end - 1)); } end++; } @@ -131,7 +156,8 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next) if (eot(line[end])) return 0; *next = end + 1; - return idoexpr(interp, line + 1); + return vmake(0, EXPR, strnclone(line + 1, end)); + //return idoexpr(interp, line + 1); } else if (isalpha(line[0])) { // variable/func uint32_t end = 1; for (; isalnum(line[end]); end++); @@ -141,7 +167,9 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next) strncpy(name, line, end); name[end] = '\0'; *next = end; - return interpreter_get_variable(interp, name); + variable *v = interpreter_get_variable(interp, name); + free(name); + return v; } else if (isdigit(line[0])) { // number uint32_t end = 1; uint8_t dec = 0; @@ -157,17 +185,11 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next) } } } - variable *v = (variable *)malloc(sizeof(variable)); - v->used = 0; + variable *v; if (dec) { - v->valtype = FLOAT; - FLOAT(v) = strtof(line, 0); - fsetstr(v); - } else { - v->valtype = INTEGER; - INT(v) = atoi(line); - isetstr(v); - } + v = vmakef(strtof(line, 0)); + } else + v = vmake(0, INTEGER, (void *)atoi(line)); *next = end; return v; } @@ -176,39 +198,34 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next) int idoline(interpreter *interp, const char *line) { - variable *ops[8]; - uint32_t ooffset, offset, next; + uint32_t ooffset = 0, offset = 0, next; + int fret = 0; if (line[0] == '\0') return 0; - - interp->lines[interp->lnidx] = strclone(line); -loop: - ooffset = 0; - offset = 0; skipblank(line, eol, &offset); + if (line[offset] == '#') + return 0; - if (line[offset] == '#') { - goto norun; - } else if (interp->indent > 0) { - if (!strcmp(line + offset, "end")) - interp->indent--; - goto norun; - } + interp->lines[interp->lnidx] = (variable **)calloc(8, sizeof(variable *)); + variable **ops = interp->lines[interp->lnidx]; // step 1 - convert to tokens while (!eol(line[offset])) { if (offset > 0 && line[offset] == '>') { offset++; skipblank(line, eol, &offset); - interp->ret = make_var(interp, line + offset, &next); + variable *r = make_var(interp, line + offset, &next); + ops[ooffset] = (void *)-1; + ops[ooffset + 1] = r; offset += next; skipblank(line, eol, &offset); continue; } ops[ooffset] = make_var(interp, line + offset, &next); if (ops[ooffset] == 0) { - return -4; + fret = -4; + goto fail; } else { ooffset++; offset += next; @@ -217,14 +234,61 @@ loop: } // step 2 - execute - if (ooffset == 0) - return -1; + if (ooffset == 0) { + fret = -1; + goto fail; + } + + if (ops[0]->valtype != FUNC) { + fret = -2; + goto fail; + } - if (ops[0]->valtype != FUNC) - return -2; + if (ops[0]->fromc && ops[0]->value == 0) { + fret = -3; + goto fail; + } - if (ops[0]->fromc && ops[0]->value == 0) - return -3; + if (ops[ooffset] != (void *)-1) + ops[ooffset] = 0; + +loop: + for (uint8_t i = 0; i < IUP_COUNT; i++) { + if (interp->lines[interp->lnidx][0]->value + == (uint32_t)indent_up[i]) { + interp->indent++; + goto cont; + } + } + for (uint8_t i = 0; i < IDOWN_COUNT; i++) { + if (interp->lines[interp->lnidx][0]->value + == (uint32_t)indent_down[i]) { + if (--interp->indent < 0) { + fret = -6; + goto fail; + } + if (interp->indent < (interp->sindent & ~(SKIP))) + interp->sindent &= ~(SKIP); + else + goto cont; + break; + } + } + +cont: + if (interp->indent > 0 && interp->sindent & SKIP) + goto norun; + + ops = (variable **)malloc(8 * sizeof(variable *)); + memcpy(ops, interp->lines[interp->lnidx], 8 * sizeof(variable *)); + uint32_t oldLnidx = interp->lnidx; + + // eval expressions + ooffset = 1; + for (; ops[ooffset] != 0 && ops[ooffset] != (void *)-1; ooffset++) { + if (ops[ooffset]->valtype == EXPR) + ops[ooffset] = idoexpr(interp, ops[ooffset]->svalue); + } if (ops[0]->fromc) { for (uint32_t i = ooffset; --i > 0;) @@ -237,7 +301,7 @@ loop: } else { char an[6]; for (uint32_t i = 1; i < ooffset; i++) { - snprintf(an, 6, "arg%d", i - 1); + snprintf(an, 6, "arg%d", (int)(i - 1)); switch (ops[i]->valtype) { case STRING: inew_string(interp, an, ops[i]->svalue); @@ -255,26 +319,35 @@ loop: ipush(interp, (void *)(interp->lnidx)); interp->lnidx = ops[0]->value; + interp->indent++; } + if (ops[ooffset] == (void *)-1) + interp->ret = ops[ooffset + 1]; + if ((int32_t)interp->stidx < 0) { interp->stidx = 0; return -5; } - for (uint32_t i = 0; i < ooffset; i++) { - if (!ops[i]->used) + for (uint32_t i = 1; i < ooffset; i++) { + if (ops[i] != interp->lines[oldLnidx][i]) { + free(ops[i]->svalue); free(ops[i]); + } } - + free(ops); norun: interp->lnidx++; - if (interp->lines[interp->lnidx] != 0) { - line = interp->lines[interp->lnidx]; + if (interp->lines[interp->lnidx] != 0) goto loop; - } return 0; + +fail: + free(interp->lines[interp->lnidx]); + interp->lines[interp->lnidx] = 0; + return fret; } variable *idoexpr(interpreter *interp, const char *line) @@ -359,10 +432,16 @@ variable *idoexpr(interpreter *interp, const char *line) } for (uint32_t i = 0; i < ooffset; i += 2) { - if (!((variable *)ops[i])->used) + if (!((variable *)ops[i])->used) { + char *s = ((variable *)ops[i])->svalue; + if (s != 0 && s != str_undef) + free(s); free(ops[i]); + } } - + + result->used = 0; + result->svalue = 0; if (result->valtype == INTEGER) isetstr(result); else |