#include #include #include #include #include #include "stack.h" #include "parser.h" #include "eval.h" static unsigned int jumpdist; static char *readexpr(char *expr){ char *out = malloc(strlen(expr+1)); char *c = expr; stack *s = push(NULL, *c); int i; for (i = 0; s->len != 0; i++){ out[i] = *c; c++; if (*c == '(') s = push(s, '('); else if (*c == ')' && peek(s) == '(') pop(s); } cleanstack(s); out[i] = ')'; out[i+1] = 0; out = realloc(out, strlen(out)); jumpdist = i+1; return out; } static char *readval(char *expr){ char *out = strdup(expr); char *gap = strchr(out, ' '); if (gap == NULL) gap = strchr(out, ')'); jumpdist = (gap - out)+1; *gap = 0; out = realloc(out, strlen(out)); return out; } static luckyval *readargs(char *expr){ luckyval *head = malloc(sizeof(luckyval)); if (*expr != ')' && expr[0] != 0){ if (expr[0] == '(' ){ // nested function char *subexpr = readexpr(expr); expr += jumpdist + 1; head->tree = parse(subexpr); head->type = LUCKYTREE; free(subexpr); } else if (strchr(expr, '.') != NULL){ // float char *val = readval(expr); expr += jumpdist; head->f = atof(val); head->type = LUCKYFLOAT; free(val); } else if (isdigit(expr[0])){ // int char *val = readval(expr); expr += jumpdist; head->i = atoi(val); head->type = LUCKYINT; free(val); } else { // var name char *val = readval(expr); expr += jumpdist; head->var = strdup(val); head->type = LUCKYVAR; } } else return NULL; head->nextelement = readargs(expr); return head; } luckytree *parse(char *expr){ char *c = expr; stack *s = push(NULL, *c); while (*c != 0){ c++; if (*c == '(') s = push(s, '('); else if (*c == ')' && peek(s) == '(') pop(s); } if (s->len != 0){ printf("%s\n", expr); for (int i = 0; i < (c - expr) - 1; i++) printf(" "); printf("^\n"); printf("bracket mismatch!\n"); exit(1); } cleanstack(s); luckytree *tree = malloc(sizeof(luckytree)); int funcnamelen; if (strchr(expr+1, ' ') == NULL) funcnamelen = (strchr(expr+1, ')') - expr) - 1; else funcnamelen = (strchr(expr+1, ' ') - expr) - 1; tree->function = malloc(funcnamelen + 1); memcpy(tree->function, expr + 1, funcnamelen); tree->function[funcnamelen] = 0; expr += funcnamelen + 2; tree->arguments = readargs(expr); return tree; }