From 29db17c07422f86b0c8056aca1eb6cc1aad779a3 Mon Sep 17 00:00:00 2001 From: NunoSempere Date: Tue, 2 May 2023 02:53:49 -0400 Subject: [PATCH] step: spend a bit obsessing over memory leaks. --- mumble | Bin 112148 -> 112668 bytes src/mumble.c | 421 +++++++++++++++++++++++++++++---------------------- 2 files changed, 237 insertions(+), 184 deletions(-) diff --git a/mumble b/mumble index 1b6dbf9757dbe5480b617ff46d6af9b3aedd7ae9..7997110a3c5ee4289ba86566c41376ecc5263509 100755 GIT binary patch delta 30633 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 z%0D3LO12&i7YRdLu`Dx%VX0WBk`qM_(%IFq#HUS#EPpzl4*7Yzc{H)!#(^KMw-><# z*V`hl=})q-aim9^PUs+3*Nt4r;~$X1dOor93W2q}DZ;M8;}6-Eaj?233u=Lg=FHp2 zx^M#A;f3!wSX~>7k(-QWX8lKFa6E0RYY*0DJV~3lK9VP$&O^yxbU_=wZuY`7w@@6H;cQqbj`>==KpgWp(^>U+*p7%|_7lhylEAVjkjMC%U?SY4&+5TS zCc?l?WX~s(N7|NfHhm&IhumZFlSx1Aa?`gak%wBtFu~4am!<&QrwOo@M*8HgMmZy* zab80Pt(fmL_$31WuB`nu(m`tyihiBgfoWuz0she@=#99LfoWPOhd6oQH-ZD`flH3Z zdQB%y?3z4pk74E0dT{`lnf3QnZc6}Loei69^svy|FcM!MJm5{;O~)fVZ{_=fi{eX7+eK84C~K84F0$h@Tr-4aHlp0{MX% zSsZ@`qz}9#S+)>bJH>Y5$0qjKLMZrBW?4u=T&{RoLzY|M(P$Bg zbTY*mbx9pgyXM8QR~Erj(H{%oxq8MTlBzkzv5yy#T@FSMbTSvSXcKA53Kx^kq?BD; z4EgqEsY@W=8|=^$GDJJjnw?$+PyInli3em6vlRN^>Sk>)FJ4S6@xl9W&($iH!>MUn zN+LC%*6iR?@}V{=hE2^OC&?(*+(ah9J^6YQ6!JCZnhOo3MTv%%SgT^6{AggXU982_KL?re@_oylHX z0gn>rSlJ5bUj_?bNpiK@j;#L@*jW2=CF!W;JL0DAU~NU1=553iv1#3z*0HyiPhe5__~W$3JB;Cenl*d>w}HZFc*0vQ%qfFIow0 zimim>WqTDgFqFCGLjxV`Y8z<9+UJw_W4ZaHRMQshWF6N)bMQHJ4Ox$yTx&=(Q|myZ z?s;e|{Ea`)LkGgqWIY^KSHa2kJhTsDNJdv($#D$dIFb#Fp@f<%6 z01R^${+%?A?;&#&2Ck#lmL?WAG55%nyXL9U>7%p~D0gg4qa2Q$S z0LQ-}hFb!t0LRx6!@UarGhLjxf3!nlVpFs@w+)x3I zk0XX#PN+aF?ufXEkpio2qj;@h%cw&>)-RO^D$E3o5|z2E_1G2^HXY zHR5>0@fXc?Z(*pJ%PkP(Hcfs72^}Xc zpuud!HIJ|YXAsXpTvdzbA+D^&^AVTT;)RHdIX;g5ix3xad>HX!#D!LD(oJ59M6Q*9 zk|56Jcn><{BF^OaUBt@}r*XUq@p8oR9B)9p0&#RL&O>bEcs1&;A$H?qzK0 zu?P)TA+C9d6_|}UA8{4OQxUI5T*>iR#07}UI39s`4dP;s2O>5jF5oal(S5OFrgtr4$BoXK$n;thz?I1WKf5yx|EK>P;c=vw?1Vk5^Ms58WF9Gjew z*ocIV6B^>T5!XDx3Ox1$ya{m?$M+C#MqJ79Z-}=bF5~z*;;o2_Ilh8;8{#64ze2nn zaUo(;=mjK-kjUi*XAr-GIGf|+h~Gt=$?;*tI}oRFya(}nh~qha7xDXuqdDG$cqd{b z#~TpuLhJ_E^gMJm61$Pm)dtv)xaM!H01tQ&aTUirU@_uKj(NaCh|4(U@eU&{=6E^A zFF{CnXn+cj{b@u5@%1~p_+lUIOcK0A&(&sqqxJd5(YaG?9x{9 z;MnKe$e{WISMAQiymSTfbFKVbFF)UqpG9d9t_%7a;LH_K& z@c(={y@#9D@bjLT-8oF!I_;Ktx0ywj0M1=2^xU;?Xsn(qxI6~UGTmNrd>;I)&#r`@%qMV>3JWJzV7I_r1sFJv9FPn+j X`hS!~A7%%RlCJRo*s?oENwfb06X`Oz delta 30176 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 diff --git a/src/mumble.c b/src/mumble.c index c51d2f8..26562fc 100644 --- a/src/mumble.c +++ b/src/mumble.c @@ -7,7 +7,9 @@ #include "mpc/mpc.h" #define VERBOSE 0 #define LISPVAL_ASSERT(cond, err) \ - if (!(cond)) { return lispval_err(err); } + if (!(cond)) { \ + return lispval_err(err); \ + } // Types typedef struct lispval { @@ -24,7 +26,7 @@ enum { LISPVAL_ERR, LISPVAL_SYM, LISPVAL_SEXPR, - LISPVAL_QEXPR, + LISPVAL_QEXPR, }; enum { @@ -36,6 +38,7 @@ enum { // Constructors lispval* lispval_num(double x) { + printf("\nAllocated num"); lispval* v = malloc(sizeof(lispval)); v->type = LISPVAL_NUM; v->count = 0; @@ -45,6 +48,7 @@ lispval* lispval_num(double x) lispval* lispval_err(char* message) { + printf("\nAllocated err"); lispval* v = malloc(sizeof(lispval)); v->type = LISPVAL_ERR; v->count = 0; @@ -55,6 +59,7 @@ lispval* lispval_err(char* message) lispval* lispval_sym(char* symbol) { + printf("\nAllocated sym"); lispval* v = malloc(sizeof(lispval)); v->type = LISPVAL_SYM; v->count = 0; @@ -65,6 +70,7 @@ lispval* lispval_sym(char* symbol) lispval* lispval_sexpr(void) { + printf("\nAllocated sexpr"); lispval* v = malloc(sizeof(lispval)); v->type = LISPVAL_SEXPR; v->count = 0; @@ -74,6 +80,7 @@ lispval* lispval_sexpr(void) lispval* lispval_qexpr(void) { + printf("\nAllocated qexpr"); lispval* v = malloc(sizeof(lispval)); v->type = LISPVAL_QEXPR; v->count = 0; @@ -84,24 +91,51 @@ lispval* lispval_qexpr(void) // Destructor void delete_lispval(lispval* v) { + // printf("\n1"); switch (v->type) { case LISPVAL_NUM: + printf("\nFreed num"); + // free(v); + // v = NULL; + // printf("\n2"); break; case LISPVAL_ERR: - free(v->err); + printf("\nFreed err"); + // printf("\n3"); + if (v->err != NULL) + free(v->err); + v->err = NULL; break; case LISPVAL_SYM: - free(v->sym); + printf("\nFreed sym"); + // printf("\n4"); + if (v->sym != NULL) + free(v->sym); + v->sym = NULL; break; case LISPVAL_SEXPR: + // printf("\n5"); case LISPVAL_QEXPR: + printf("\nFreed s/qexpr"); + // printf("\n6"); for (int i = 0; i < v->count; i++) { - delete_lispval(v->cell[i]); + if (v->cell[i] != NULL) + delete_lispval(v->cell[i]); + v->cell[i] = NULL; } - free(v->cell); + // printf("\n8"); + if (v->cell != NULL) + free(v->cell); + v->cell = NULL; + + // printf("\n9"); break; } - free(v); + if (v != NULL) + free(v); + // printf("\n10"); + v = NULL; + // printf("\n11"); } // Read ast into a lispval object @@ -122,35 +156,36 @@ lispval* read_lispval_num(mpc_ast_t* t) lispval* read_lispval(mpc_ast_t* t) { - // Non-ignorable children - // Relevant for the edge-case of considering the case where you - // only have one top level item. - int c = 0; - int c_index = -1; - for(int i=0; ichildren_num; i++){ - mpc_ast_t* child = t->children[i]; - if( ( strcmp(child->tag, "regex") != 0 ) || (strcmp(child->contents, "") != 0 ) || child->children_num != 0 ){ - c++; - c_index = i; - } - } - if(VERBOSE) printf("\nNon ignorable children: %i", c); + // Non-ignorable children + // Relevant for the edge-case of considering the case where you + // only have one top level item. + int c = 0; + int c_index = -1; + for (int i = 0; i < t->children_num; i++) { + mpc_ast_t* child = t->children[i]; + if ((strcmp(child->tag, "regex") != 0) || (strcmp(child->contents, "") != 0) || child->children_num != 0) { + c++; + c_index = i; + } + } + if (VERBOSE) + printf("\nNon ignorable children: %i", c); 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) && (c==1)) { - return read_lispval(t->children[c_index]); + } else if ((strcmp(t->tag, ">") == 0) && (c == 1)) { + return read_lispval(t->children[c_index]); } else if ((strcmp(t->tag, ">") == 0) || strstr(t->tag, "sexpr") || strstr(t->tag, "qexpr")) { lispval* x; - if((strcmp(t->tag, ">") == 0) || strstr(t->tag, "sexpr")){ - x = lispval_sexpr(); - } else if(strstr(t->tag, "qexpr")){ - x = lispval_qexpr(); - } else { - return lispval_err("Error: Unreachable code state reached."); - } + if ((strcmp(t->tag, ">") == 0) || strstr(t->tag, "sexpr")) { + x = lispval_sexpr(); + } else if (strstr(t->tag, "qexpr")) { + x = lispval_qexpr(); + } else { + return lispval_err("Error: Unreachable code state reached."); + } for (int i = 0; i < (t->children_num); i++) { if (strcmp(t->children[i]->contents, "(") == 0) { @@ -159,18 +194,16 @@ lispval* read_lispval(mpc_ast_t* t) continue; } else if (strcmp(t->children[i]->contents, "{") == 0) { continue; - } - else if (strcmp(t->children[i]->contents, "}") == 0) { + } else if (strcmp(t->children[i]->contents, "}") == 0) { continue; - } - else if (strcmp(t->children[i]->tag, "regex") == 0) { + } else if (strcmp(t->children[i]->tag, "regex") == 0) { continue; } else { - x = lispval_append_child(x, read_lispval(t->children[i])); - } + x = lispval_append_child(x, read_lispval(t->children[i])); + } } return x; - } else { + } else { lispval* err = lispval_err("Unknown AST type."); return err; } @@ -212,6 +245,7 @@ void print_lispval_tree(lispval* v, int indent_level) printf("%s", v->sym); } free(indent); + indent = NULL; } void print_lispval_parenthesis(lispval* v) @@ -264,57 +298,58 @@ void print_ast(mpc_ast_t* ast, int indent_level) print_ast(child_i, indent_level + 2); } free(indent); + indent = NULL; } // Lispval helpers lispval* clone_lispval(lispval* old) { - lispval* new; - // print_lispval_tree(old, 0); - // printf("\nCloning lispval of type %d\n", old->type); - switch(old->type){ + lispval* new; + // print_lispval_tree(old, 0); + // printf("\nCloning lispval of type %d\n", old->type); + switch (old->type) { case LISPVAL_NUM: - // printf("\n1"); - // printf("\nnum: %f", old->num); - // print_lispval_tree(old, 0); - new = lispval_num(old->num); - // printf("\nAssigned new"); - // printf("\n count: %i", old->count); + // printf("\n1"); + // printf("\nnum: %f", old->num); + // print_lispval_tree(old, 0); + new = lispval_num(old->num); + // printf("\nAssigned new"); + // printf("\n count: %i", old->count); break; case LISPVAL_ERR: - // printf("2"); + // printf("2"); new = lispval_err(old->err); break; case LISPVAL_SYM: - // printf("3"); + // printf("3"); new = lispval_sym(old->sym); break; case LISPVAL_SEXPR: - // printf("4"); - new = lispval_sexpr(); - break; - case LISPVAL_QEXPR: - // printf("\n5"); - new = lispval_qexpr(); + // printf("4"); + new = lispval_sexpr(); break; - default: - return lispval_err("Error: Cloning element of unknown type."); - } - - // printf("\n6"); - if(old->count > 0 && (old->type == LISPVAL_QEXPR || old->type == LISPVAL_SEXPR) ){ - for (int i = 0; i < old->count; i++) { - lispval* temp_child = old->cell[i]; - lispval* child = clone_lispval(temp_child); - lispval_append_child(new, child); - } - } + case LISPVAL_QEXPR: + // printf("\n5"); + new = lispval_qexpr(); + break; + default: + return lispval_err("Error: Cloning element of unknown type."); + } + + // printf("\n6"); + if (old->count > 0 && (old->type == LISPVAL_QEXPR || old->type == LISPVAL_SEXPR)) { + for (int i = 0; i < old->count; i++) { + lispval* temp_child = old->cell[i]; + lispval* child = clone_lispval(temp_child); + lispval_append_child(new, child); + } + } return new; } lispval* pop_lispval(lispval* v, int i) { - LISPVAL_ASSERT(v->type == LISPVAL_QEXPR || v->type == LISPVAL_SEXPR, "Error: function pop passed too many arguments"); + LISPVAL_ASSERT(v->type == LISPVAL_QEXPR || v->type == LISPVAL_SEXPR, "Error: function pop passed too many arguments"); lispval* r = v->cell[i]; /* Shift memory after the item at "i" over the top */ memmove(&v->cell[i], &v->cell[i + 1], @@ -330,7 +365,7 @@ lispval* pop_lispval(lispval* v, int i) lispval* take_lispval(lispval* v, int i) { // Unneeded. - LISPVAL_ASSERT(v->type == LISPVAL_QEXPR || v->type == LISPVAL_SEXPR, "Error: function take_lispval passed too many arguments"); + LISPVAL_ASSERT(v->type == LISPVAL_QEXPR || v->type == LISPVAL_SEXPR, "Error: function take_lispval passed too many arguments"); lispval* x = pop_lispval(v, i); delete_lispval(v); return x; @@ -338,102 +373,108 @@ lispval* take_lispval(lispval* v, int i) // Operations // Ops for q-expressions -lispval* builtin_head(lispval* v){ - // printf("Entering builtin_head with v->count = %d and v->cell[0]->type = %d\n", v->count, v->cell[0]->type); - // head { 1 2 3 } - // But actually, that gets processd into head ({ 1 2 3 }), hence the v->cell[0]->cell[0]; - LISPVAL_ASSERT(v->count == 1, "Error: function head passed too many arguments"); - LISPVAL_ASSERT(v->cell[0]->type == LISPVAL_QEXPR, "Error: Argument passed to head is not a q-expr, i.e., a bracketed list."); - LISPVAL_ASSERT(v->cell[0]->count != 0, "Error: Argument passed to head is {}"); - // printf("Passed assertions, v->cell[0]->count = %d\n", v->cell[0]->count); - // print_lispval_parenthesis(v); - // print_lispval_parenthesis(v->cell[0]); - lispval* result = clone_lispval(v->cell[0]->cell[0]); - // printf("Cloned lispval, result->type = %d\n", result->type); - // lispval* result = pop_lispval(v->cell[0], 0); - // ^ also possible - // A bit unclear. Pop seems like it would depend on the size of the array. clone depends on the sie of head. - // either way the original array will soon be deleted, so I could have used pop - // but I wanted to write & use clone instead. - return result; - // Returns something that should be freed later: yes. - // Returns something that doesn't share pointers with the input: yes. +lispval* builtin_head(lispval* v) +{ + // printf("Entering builtin_head with v->count = %d and v->cell[0]->type = %d\n", v->count, v->cell[0]->type); + // head { 1 2 3 } + // But actually, that gets processd into head ({ 1 2 3 }), hence the v->cell[0]->cell[0]; + LISPVAL_ASSERT(v->count == 1, "Error: function head passed too many arguments"); + LISPVAL_ASSERT(v->cell[0]->type == LISPVAL_QEXPR, "Error: Argument passed to head is not a q-expr, i.e., a bracketed list."); + LISPVAL_ASSERT(v->cell[0]->count != 0, "Error: Argument passed to head is {}"); + // printf("Passed assertions, v->cell[0]->count = %d\n", v->cell[0]->count); + // print_lispval_parenthesis(v); + // print_lispval_parenthesis(v->cell[0]); + lispval* result = clone_lispval(v->cell[0]->cell[0]); + // printf("Cloned lispval, result->type = %d\n", result->type); + // lispval* result = pop_lispval(v->cell[0], 0); + // ^ also possible + // A bit unclear. Pop seems like it would depend on the size of the array. clone depends on the sie of head. + // either way the original array will soon be deleted, so I could have used pop + // but I wanted to write & use clone instead. + return result; + // Returns something that should be freed later: yes. + // Returns something that doesn't share pointers with the input: yes. } lispval* builtin_tail(lispval* v) { - // tail { 1 2 3 } - LISPVAL_ASSERT(v->count ==1, "Error: function tail passed too many arguments"); - - lispval* old = v->cell[0]; - LISPVAL_ASSERT(old->type == LISPVAL_QEXPR, "Error: Argument passed to tail is not a q-expr, i.e., a bracketed list."); - LISPVAL_ASSERT(old->count != 0, "Error: Argument passed to tail is {}"); - - // lispval* head = pop_lispval(v->cell[0], 0); - // print_lispval_parenthesis(v); - // print_lispval_parenthesis(old); - lispval* new = lispval_qexpr(); - if(old->count == 1){ - return new; - } else if (old->count > 1 && old->type == LISPVAL_QEXPR) { - for(int i=1; i<(old->count); i++){ - // lispval_append_child(new, clone_lispval(old->cell[i])); - lispval_append_child(new, old->cell[i]); - } - return clone_lispval(new); - } else { - return lispval_err("Error: Unreachable point reached in tail function"); - } - - // Returns something that should be freed later: yes. - // Returns something that doesn't share pointers with the input: yes. + // tail { 1 2 3 } + LISPVAL_ASSERT(v->count == 1, "Error: function tail passed too many arguments"); + + lispval* old = v->cell[0]; + LISPVAL_ASSERT(old->type == LISPVAL_QEXPR, "Error: Argument passed to tail is not a q-expr, i.e., a bracketed list."); + LISPVAL_ASSERT(old->count != 0, "Error: Argument passed to tail is {}"); + + // lispval* head = pop_lispval(v->cell[0], 0); + // print_lispval_parenthesis(v); + // print_lispval_parenthesis(old); + lispval* new = lispval_qexpr(); + if (old->count == 1) { + return new; + } else if (old->count > 1 && old->type == LISPVAL_QEXPR) { + for (int i = 1; i < (old->count); i++) { + // lispval_append_child(new, clone_lispval(old->cell[i])); + lispval_append_child(new, old->cell[i]); + } + return clone_lispval(new); + } else { + return lispval_err("Error: Unreachable point reached in tail function"); + } + + // Returns something that should be freed later: yes. + // Returns something that doesn't share pointers with the input: yes. } -lispval* builtin_list(lispval* v){ - // list ( 1 2 3 ) - LISPVAL_ASSERT(v->count ==1, "Error: function list passed too many arguments"); - lispval* old = v->cell[0]; - LISPVAL_ASSERT(old->type == LISPVAL_SEXPR, "Error: Argument passed to list is not an s-expr, i.e., a list with parenthesis."); - lispval* new = clone_lispval(old); - new->type=LISPVAL_QEXPR; - return new; - // Returns something that should be freed later: yes. - // Returns something that is independent of the input: yes. +lispval* builtin_list(lispval* v) +{ + // list ( 1 2 3 ) + LISPVAL_ASSERT(v->count == 1, "Error: function list passed too many arguments"); + lispval* old = v->cell[0]; + LISPVAL_ASSERT(old->type == LISPVAL_SEXPR, "Error: Argument passed to list is not an s-expr, i.e., a list with parenthesis."); + lispval* new = clone_lispval(old); + new->type = LISPVAL_QEXPR; + return new; + // Returns something that should be freed later: yes. + // Returns something that is independent of the input: yes. } lispval* evaluate_lispval(lispval* l); -lispval* builtin_eval(lispval* v){ - // eval { + 1 2 3 } - // not sure how this will end up working, but we'll see - LISPVAL_ASSERT(v->count ==1, "Error: function eval passed too many arguments"); - lispval* old = v->cell[0]; - LISPVAL_ASSERT(old->type == LISPVAL_QEXPR, "Error: Argument passed to eval is not a q-expr, i.e., a bracketed list."); - lispval* new = clone_lispval(old); - new->type=LISPVAL_SEXPR; - return evaluate_lispval(new); - // Returns something that should be freed later: probably. - // Returns something that is independent of the input: depends on the output of evaluate_lispval. +lispval* builtin_eval(lispval* v) +{ + // eval { + 1 2 3 } + // not sure how this will end up working, but we'll see + LISPVAL_ASSERT(v->count == 1, "Error: function eval passed too many arguments"); + lispval* old = v->cell[0]; + LISPVAL_ASSERT(old->type == LISPVAL_QEXPR, "Error: Argument passed to eval is not a q-expr, i.e., a bracketed list."); + lispval* temp = clone_lispval(old); + temp->type = LISPVAL_SEXPR; + lispval* answer = evaluate_lispval(temp); + delete_lispval(temp); + return answer; + // Returns something that should be freed later: probably. + // Returns something that is independent of the input: depends on the output of evaluate_lispval. } -lispval* builtin_join(lispval* l){ - // return lispval_err("Error: Join not ready yet."); - // join { {1 2} {3 4} } - print_lispval_parenthesis(l); - LISPVAL_ASSERT(l->count ==1, "Error: function join passed too many arguments"); - lispval* old = l->cell[0]; - LISPVAL_ASSERT(old->type == LISPVAL_QEXPR, "Error: function join not passed q-expression"); - lispval* result = lispval_qexpr(); - for(int i=0; icount; i++){ - lispval* temp = old->cell[i]; - LISPVAL_ASSERT(temp->type == LISPVAL_QEXPR, "Error: function join not passed a q expression with other q-expressions"); +lispval* builtin_join(lispval* l) +{ + // return lispval_err("Error: Join not ready yet."); + // join { {1 2} {3 4} } + print_lispval_parenthesis(l); + LISPVAL_ASSERT(l->count == 1, "Error: function join passed too many arguments"); + lispval* old = l->cell[0]; + LISPVAL_ASSERT(old->type == LISPVAL_QEXPR, "Error: function join not passed q-expression"); + lispval* result = lispval_qexpr(); + for (int i = 0; i < old->count; i++) { + lispval* temp = old->cell[i]; + LISPVAL_ASSERT(temp->type == LISPVAL_QEXPR, "Error: function join not passed a q expression with other q-expressions"); - for(int j=0; jcount; j++){ - lispval_append_child(result, temp->cell[j]); - } - } - return result; - // Returns something that should be freed later: yes. - // Returns something that is independent of the input: yes. + for (int j = 0; j < temp->count; j++) { + lispval_append_child(result, temp->cell[j]); + } + } + return result; + // Returns something that should be freed later: yes. + // Returns something that is independent of the input: yes. } // Simple math ops @@ -455,10 +496,10 @@ lispval* builtin_math_ops(char* op, lispval* v) return lispval_err("Error: Non minus unary operation"); } } else if (v->count >= 2) { - lispval* x = clone_lispval(v->cell[0]);// pop_lispval(v, 0); - - for(int i=1;icount; i++){ - lispval* y = v->cell[i]; + lispval* x = clone_lispval(v->cell[0]); // pop_lispval(v, 0); + + for (int i = 1; i < v->count; i++) { + lispval* y = v->cell[i]; if (strcmp(op, "+") == 0) { x->num += y->num; } @@ -477,36 +518,43 @@ lispval* builtin_math_ops(char* op, lispval* v) } x->num /= y->num; } - } + } return x; } else { return lispval_err("Error: Incorrect number of args. Perhaps a lispval->count was wrongly initialized?"); } - // Returns something that should be freed later: yes. - // Returns something that is independent of the input: yes. + // Returns something that should be freed later: yes. + // Returns something that is independent of the input: yes. } // Aggregate both math and operations over lists lispval* builtin_functions(char* func, lispval* v) { - if (strcmp("list", func) == 0) { return builtin_list(v); } - else if (strcmp("head", func) == 0) { return builtin_head(v); } - else if (strcmp("tail", func) == 0) { return builtin_tail(v); } - else if (strcmp("join", func) == 0) { return builtin_join(v); } - else if (strcmp("eval", func) == 0) { return builtin_eval(v); } - else if (strstr("+-/*", func)) { return builtin_math_ops(func, v); - } else { - return lispval_err("Unknown function"); - } - // Returns something that should be freed later: depends on eval - // Returns something that is independent of the input: depends on eval + if (strcmp("list", func) == 0) { + return builtin_list(v); + } else if (strcmp("head", func) == 0) { + return builtin_head(v); + } else if (strcmp("tail", func) == 0) { + return builtin_tail(v); + } else if (strcmp("join", func) == 0) { + return builtin_join(v); + } else if (strcmp("eval", func) == 0) { + return builtin_eval(v); + } else if (strstr("+-/*", func)) { + return builtin_math_ops(func, v); + } else { + return lispval_err("Unknown function"); + } + // Returns something that should be freed later: depends on eval + // Returns something that is independent of the input: depends on eval } // Evaluate the lispval lispval* evaluate_lispval(lispval* l) { - // Check if this is an s-expression - if(l->type != LISPVAL_SEXPR) return l; + // Check if this is an s-expression + if (l->type != LISPVAL_SEXPR) + return l; // Evaluate the children if needed for (int i = 0; i < l->count; i++) { if (l->cell[i]->type == LISPVAL_SEXPR) { @@ -522,16 +570,20 @@ lispval* evaluate_lispval(lispval* l) // Check if the first element is an operation. if (l->count >= 2 && ((l->cell[0])->type == LISPVAL_SYM)) { - // lispval* op = pop_lispval(l, 0); - lispval* operation = clone_lispval(l->cell[0]); - lispval* operands = lispval_sexpr(); - for(int i=1; icount; i++){ - lispval_append_child(operands, l->cell[i]); - } - lispval* result = builtin_functions(operation->sym, operands); + lispval* temp = clone_lispval(l->cell[0]); + lispval* operation = pop_lispval(l, 0); + lispval* operands = temp; + // lispval* operation = clone_lispval(l->cell[0]); + // lispval* operands = lispval_sexpr(); + // for (int i = 1; i < l->count; i++) { + // lispval_append_child(operands, l->cell[i]); + // } + lispval* answer = builtin_functions(operation->sym, l); delete_lispval(operation); delete_lispval(operands); - return result; + // delete_lispval(operation); + // delete_lispval(operands); // < wrong! they still remain in the list. + return answer; } return l; } @@ -540,7 +592,7 @@ int main(int argc, char** argv) { // Info puts("Mumble version 0.0.2\n"); - puts("Press Ctrl+C/Ctrl+D to exit\n"); + puts("Press Ctrl+C to exit\n"); /* Create Some Parsers */ mpc_parser_t* Number = mpc_new("number"); @@ -595,14 +647,14 @@ int main(int argc, char** argv) printf("\nParenthesis printing: "); print_lispval_parenthesis(l); } - lispval* result = evaluate_lispval(l); + lispval* answer = evaluate_lispval(l); { printf("\n\nResult: "); - print_lispval_parenthesis(result); + print_lispval_parenthesis(answer); printf("\n"); } delete_lispval(l); - delete_lispval(result); + delete_lispval(answer); } else { /* Otherwise Print the Error */ mpc_err_print(result.error); @@ -613,6 +665,7 @@ int main(int argc, char** argv) } puts(""); free(input); + input = NULL; } /* Undefine and Delete our Parsers */