diff --git a/makefile b/makefile index d31bfd0..37e6df7 100644 --- a/makefile +++ b/makefile @@ -6,8 +6,9 @@ # make uninstall ## C compiler -CC=tcc # much faster compilation than gcc -COMPILER_FLAGS=-g3 -Wall -Wextra -Wconversion -Wdouble-promotion -Wno-unused-parameter -Wno-unused-function -Wno-sign-conversion -fsanitize=undefined -fsanitize-trap +CC=gcc # much faster compilation than gcc +COMPILER_FLAGS=#-g3 -Wall -Wextra -Wconversion -Wdouble-promotion -Wno-unused-parameter -Wno-unused-function -Wno-sign-conversion -fsanitize=undefined +# exclude: -fsanitize-trap, because I'm using an old version of gcc and couldn't bother getting a new one. ## ^ from ## diff --git a/mumble b/mumble index 7e0ed09..ba990f4 100755 Binary files a/mumble and b/mumble differ diff --git a/src/mumble.c b/src/mumble.c index 607f3f2..bb63db8 100644 --- a/src/mumble.c +++ b/src/mumble.c @@ -8,27 +8,153 @@ #define VERBOSE 1 // Types -typedef struct { +typedef struct lispval { int type; long num; - int err; + char* err; + char* sym; + int count; + struct lispval** cell; // list of lisval* } lispval; enum { LISPVAL_NUM, LISPVAL_ERR, LISPVAL_SYM, LISPVAL_SEXPR }; enum { LISPERR_DIV_ZERO, LISPERR_BAD_OP, LISPERR_BAD_NUM }; -lispval lispval_num(long x){ - lispval v; - v.type = LISPVAL_NUM; - v.num = x; +// Constructors +lispval* lispval_num(long x){ + lispval* v = malloc(sizeof(lispval)); + v->type = LISPVAL_NUM; + v->num = x; return v; } -lispval lispval_err(int i){ - lispval v; - v.type = LISPVAL_ERR; - v.err = i; +lispval* lispval_err(char* message){ + lispval* v = malloc(sizeof(lispval)); + v->type = LISPVAL_ERR; + v->err = malloc(strlen(message)+1); + strcpy(v->err, message); return v; } +lispval* lispval_sym(char* symbol){ + lispval* v = malloc(sizeof(lispval)); + v->type = LISPVAL_SYM; + v->sym = malloc(strlen(symbol)+1); + strcpy(v->sym, symbol); + return v; +} +lispval* lispval_sexpr(void){ + lispval* v = malloc(sizeof(lispval)); + v->type = LISPVAL_SEXPR; + v->count = 0; + v->cell = NULL; + return v; +} + +// Delete +void delete_lispval(lispval* v){ + switch(v->type){ + case LISPVAL_NUM: break; + case LISPVAL_ERR: free(v->err); break; + case LISPVAL_SYM: free(v->sym); break; + case LISPVAL_SEXPR: + for(int i=0; i< v->count; i++){ + delete_lispval(v->cell[i]); + } + free(v->cell); + break; + } + free(v); +} + +// Read ast into a lispval object +lispval* lispval_append_child(lispval* parent, lispval* child){ + parent->count = parent->count + 1; + parent->cell = realloc(parent->cell, sizeof(lispval) * parent->count); + parent->cell[parent->count -1] = child; + return parent; +} +lispval* read_lispval_num(mpc_ast_t* t){ + errno = 0; + long x = strtol(t->contents, NULL, 10); + return errno != ERANGE ? lispval_num(x) : lispval_err("Error: Invalid number."); +} +lispval* read_lispval(mpc_ast_t* t){ + if(strstr(t->tag, "number")){ + return read_lispval_num(t); + }else if(strstr(t->tag, "symbol")){ + return lispval_sym(t->contents); + } else if((strcmp(t->tag, ">") == 0) || strstr(t->tag, "sexpr")){ + lispval* x = lispval_sexpr(); + for(int i=0; i<(t->children_num); i++){ + if (strcmp(t->children[i]->contents, "(") == 0) { continue; } + if (strcmp(t->children[i]->contents, ")") == 0) { continue; } + if (strcmp(t->children[i]->tag, "regex") == 0) { continue; } + x = lispval_append_child(x, read_lispval(t->children[i])); + } + return x; + }else{ + lispval* err = lispval_err("Unknown ast type."); + return err; + } +} + +// Print +void print_lispval_tree(lispval* v, int indent_level) +{ + char* indent = malloc(sizeof(char)*(indent_level+1)); // ""; + for(int i=0; itype){ + case LISPVAL_NUM: + printf("\n%sNumber: %li", indent, v->num); + break; + case LISPVAL_ERR: + printf("\n%sError: %s", indent, v->err); + break; + case LISPVAL_SYM: + printf("\n%sSymbol: %s", indent, v->sym); + break; + case LISPVAL_SEXPR: + printf("\n%sSExpr, with %d children:", indent, v->count); + for(int i=0; icount; i++){ + print_lispval_tree(v->cell[i], indent_level + 2); + } + break; + default: + printf("Error: unknown lispval type\n"); + printf("%s", v->sym); + } + free(indent); +} + +void print_lispval_parenthesis(lispval* v) +{ + switch(v->type){ + case LISPVAL_NUM: + printf("%li ", v->num); + break; + case LISPVAL_ERR: + printf("[Error: %s] ", v->err); + break; + case LISPVAL_SYM: + printf("%s ", v->sym); + break; + case LISPVAL_SEXPR: + printf("( "); + for(int i=0; icount; i++){ + print_lispval_parenthesis(v->cell[i]); + } + printf(") "); + break; + default: + printf("Error: unknown lispval type\n"); + printf("%s", v->sym); + } +} + +/* void print_lispval(lispval l){ switch(l.type){ case LISPVAL_NUM: @@ -53,7 +179,7 @@ void print_lispval(lispval l){ printf("\nUnknown lispval type"); } } - +*/ // Utils int is_ignorable(mpc_ast_t* t){ int is_regex = !strcmp(t->tag, "regex"); @@ -61,24 +187,27 @@ int is_ignorable(mpc_ast_t* t){ return is_regex || is_parenthesis; } -void print_ast(mpc_ast_t* ast, int num_tabs) +void print_ast(mpc_ast_t* ast, int indent_level) { - char tabs[100] = ""; - for(int i=0; itag); - printf("\n%sContents: %s", tabs, strcmp(ast->contents, "") ? ast->contents : "None"); - printf("\n%sNumber of children: %i", tabs, ast->children_num); + indent[indent_level] = '\0'; + printf("\n%sTag: %s", indent, ast->tag); + printf("\n%sContents: %s", indent, strcmp(ast->contents, "") ? ast->contents : "None"); + printf("\n%sNumber of children: %i", indent, ast->children_num); /* Print the children */ for (int i = 0; i < ast->children_num; i++) { mpc_ast_t* child_i = ast->children[i]; - printf("\n%sChild #%d", tabs, i); - print_ast(child_i, 1); + printf("\n%sChild #%d", indent, i); + print_ast(child_i, indent_level + 2); } + free(indent); } // Operations +/* lispval evaluate_unary_operation(char* op, lispval x) { if(x.type == LISPVAL_ERR) return x; @@ -169,7 +298,7 @@ lispval evaluate_ast(mpc_ast_t* t) return x; } - +*/ // Main int main(int argc, char** argv) { @@ -216,9 +345,13 @@ int main(int argc, char** argv) if(VERBOSE) print_ast(ast, 0); // Evaluate the AST - if(VERBOSE) printf("\n\nEvaluating the AST"); - lispval result = evaluate_ast(ast); - print_lispval(result); + // if(VERBOSE) printf("\n\nEvaluating the AST"); + // lispval result = evaluate_ast(ast); + lispval* l = read_lispval(ast); + if(VERBOSE) printf("\n\nTree printing: "); print_lispval_tree(l, 0); + if(VERBOSE) printf("\nParenthesis printing: \n"); print_lispval_parenthesis(l); + delete_lispval(l); + } else { /* Otherwise Print the Error */ mpc_err_print(result.error); @@ -232,7 +365,7 @@ int main(int argc, char** argv) } /* Undefine and Delete our Parsers */ - mpc_cleanup(4, Number, Symbol, Sexpr, Expr, Mumble); + mpc_cleanup(5, Number, Symbol, Sexpr, Expr, Mumble); return 0; }