From: nishi Date: Wed, 24 Apr 2024 01:53:33 +0000 (+0000) Subject: variable works X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=516d6b30e1a502f191c92be604738f28486ae88d;p=serenade.git variable works git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@28 0f02c867-ac3d-714e-8a88-971ba1f6efcf --- diff --git a/Serenade/interpreter.c b/Serenade/interpreter.c index 2d3f5a4..1d5879f 100644 --- a/Serenade/interpreter.c +++ b/Serenade/interpreter.c @@ -80,6 +80,7 @@ struct sn_generic* print_handler(struct sn_interpreter* sn, int args, struct sn_ fwrite(gens[i]->string, 1, gens[i]->string_length, stdout); } else if(gens[i]->type == SN_TYPE_VOID) { printf(""); + } else if(gens[i]->type == SN_TYPE_FUNCTION) { } fflush(stdout); } @@ -89,6 +90,26 @@ struct sn_generic* print_handler(struct sn_interpreter* sn, int args, struct sn_ return gen; } +struct sn_generic* defvar_handler(struct sn_interpreter* sn, int args, struct sn_generic** gens) { + struct sn_generic* gen = malloc(sizeof(struct sn_generic)); + int i; + if(args > 1) { + for(i = 1; i < args; i += 2) { + if(gens[i + 1] == NULL) break; + if(gens[i]->type == SN_TYPE_STRING) { + char* str = malloc(gens[i]->string_length + 1); + gens[i + 1]->used = true; + memcpy(str, gens[i]->string, gens[i]->string_length); + str[gens[i]->string_length] = 0; + sn_set_variable(sn, str, gens[i + 1]); + free(str); + } + } + } + gen->type = SN_TYPE_VOID; + return gen; +} + struct sn_generic* eval_handler(struct sn_interpreter* sn, int args, struct sn_generic** gens) { int i; int result = 0; @@ -116,6 +137,7 @@ struct sn_interpreter* sn_create_interpreter(void) { sn_set_handler(sn, "/", math_handler); sn_set_handler(sn, "print", print_handler); sn_set_handler(sn, "eval", eval_handler); + sn_set_handler(sn, "define-var", defvar_handler); return sn; } @@ -136,7 +158,6 @@ void sn_set_variable(struct sn_interpreter* sn, const char* name, struct sn_gene bool replaced = false; for(i = 0; sn->variables[i] != NULL; i++) { if(strcmp(sn->variables[i]->key, name) == 0) { - sn_generic_free(sn->variables[i]->value); sn->variables[i]->value = gen; replaced = true; break; @@ -163,7 +184,6 @@ void sn_set_handler(struct sn_interpreter* sn, const char* name, struct sn_gener bool replaced = false; for(i = 0; sn->variables[i] != NULL; i++) { if(strcmp(sn->variables[i]->key, name) == 0) { - sn_generic_free(sn->variables[i]->value); sn->variables[i]->handler = handler; replaced = true; break; @@ -195,9 +215,9 @@ int sn_eval(struct sn_interpreter* sn, char* data, unsigned long long len) { if(sn_run(sn, gens[i]) != 0) { r = 1; } - sn_generic_free(gens[i]); } } + for(i = 0; gens[i] != NULL; i++) sn_generic_free(gens[i]); free(gens); } return r; diff --git a/Serenade/parser.c b/Serenade/parser.c index fe92f98..c17ed1f 100644 --- a/Serenade/parser.c +++ b/Serenade/parser.c @@ -49,6 +49,22 @@ struct sn_generic { }; */ +struct sn_generic* sn_generic_dup(struct sn_generic* g) { + if(g == NULL) return NULL; + struct sn_generic* r = malloc(sizeof(struct sn_generic)); + r->type = g->type; + if(r->type == SN_TYPE_STRING) { + r->string = malloc(g->string_length); + r->string_length = g->string_length; + memcpy(r->string, g->string, r->string_length); + } else if(r->type == SN_TYPE_DOUBLE) { + r->number = g->number; + } else if(r->type == SN_TYPE_FUNCTION) { + r->name = sn_strdup(g->name); + } + return r; +} + void push_stack_generic(struct sn_generic* gen, struct sn_generic* pushthis) { if(gen->type == SN_TYPE_TREE) { struct sn_generic** old_gen = gen->tree->args; @@ -73,7 +89,7 @@ void push_stack(struct sn_generic* gen, char* buf, int mode) { if(mode == SN_TYPE_STRING) { newgen->string = sn_strdup(buf); newgen->string_length = strlen(buf); - } else if(mode == SN_TYPE_FUNCTION) { + } else if(mode == SN_TYPE_FUNCTION || mode == SN_TYPE_VARIABLE) { newgen->name = sn_strdup(buf); } else if(mode == SN_TYPE_DOUBLE) { newgen->number = atof(buf); @@ -108,6 +124,7 @@ struct sn_generic* sn_expr_parse(char* data, unsigned long long size) { gn_stack[br]->tree = malloc(sizeof(struct sn_tree)); gn_stack[br]->tree->args = malloc(sizeof(struct sn_generic*)); gn_stack[br]->tree->args[0] = NULL; + gn_stack[br]->used = false; index_stack[br] = 0; br++; } else if(c == ')') { @@ -144,8 +161,10 @@ struct sn_generic* sn_expr_parse(char* data, unsigned long long size) { if(argbufmode == SN_TYPE_VOID) { if(c == '.' || (c >= '0' && c <= '9')) { argbufmode = SN_TYPE_DOUBLE; - } else { + } else if(index_stack[br - 1] == 0) { argbufmode = SN_TYPE_FUNCTION; + } else { + argbufmode = SN_TYPE_VARIABLE; } } } @@ -213,6 +232,8 @@ void sn_generic_free(struct sn_generic* g) { free(g->string); } else if(g->type == SN_TYPE_TREE) { sn_tree_free(g->tree); + } else if(g->type == SN_TYPE_FUNCTION || g->type == SN_TYPE_VARIABLE) { + free(g->name); } free(g); } diff --git a/Serenade/parser.h b/Serenade/parser.h index 030e18d..a6a245b 100644 --- a/Serenade/parser.h +++ b/Serenade/parser.h @@ -31,7 +31,9 @@ #ifndef __SERENADE_PARSER_H__ #define __SERENADE_PARSER_H__ -enum types { SN_TYPE_DOUBLE = 0, SN_TYPE_STRING, SN_TYPE_TREE, SN_TYPE_PTR, SN_TYPE_FUNCTION, SN_TYPE_VOID }; +#include + +enum types { SN_TYPE_DOUBLE = 0, SN_TYPE_STRING, SN_TYPE_TREE, SN_TYPE_PTR, SN_TYPE_FUNCTION, SN_TYPE_VOID, SN_TYPE_VARIABLE }; struct sn_generic { int type; @@ -41,6 +43,7 @@ struct sn_generic { void* ptr; char* name; struct sn_tree* tree; + bool used; }; struct sn_tree { @@ -49,6 +52,7 @@ struct sn_tree { struct sn_generic** sn_parse(char* data, unsigned long long size); void sn_generic_free(struct sn_generic* g); +struct sn_generic* sn_generic_dup(struct sn_generic* g); void sn_tree_free(struct sn_tree* t); #endif diff --git a/Serenade/run.c b/Serenade/run.c index 3eae2a7..44f7d95 100644 --- a/Serenade/run.c +++ b/Serenade/run.c @@ -44,25 +44,24 @@ struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) { if(op->type == SN_TYPE_TREE) { op = _sn_run(sn, op); } - int j; - for(j = 0; gen->tree->args[j]; j++) - ; - struct sn_generic** args = malloc(sizeof(struct sn_generic*) * (j)); - int argc = j; - for(j = 0; gen->tree->args[j]; j++) { - args[j] = _sn_run(sn, gen->tree->args[j]); - } struct sn_generic* r = malloc(sizeof(struct sn_generic)); r->type = SN_TYPE_VOID; if(op->type != SN_TYPE_FUNCTION) { fprintf(stderr, "Cannot call non-function (Type %d)\n", op->type); - free(args); free(r); return NULL; } else { bool called = false; + int j; + for(j = 0; gen->tree->args[j]; j++) + ; + struct sn_generic** args = malloc(sizeof(struct sn_generic*) * (j)); + int argc = j; + for(j = 0; gen->tree->args[j]; j++) { + args[j] = _sn_run(sn, gen->tree->args[j]); + } for(j = 0; sn->variables[j] != NULL; j++) { if(strcmp(sn->variables[j]->key, op->name) == 0) { called = true; @@ -90,8 +89,23 @@ struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) { free(r); return NULL; } + free(args); + } + return r; + } else if(gen->type == SN_TYPE_VARIABLE) { + struct sn_generic* r = malloc(sizeof(struct sn_generic)); + r->type = SN_TYPE_VOID; + int i; + for(i = 0; sn->variables[i] != NULL; i++) { + if(strcmp(sn->variables[i]->key, gen->name) == 0) { + free(r); + struct sn_generic* var = sn->variables[i]->value; + if(var != NULL) { + return sn->variables[i]->value; + } + break; + } } - free(args); return r; } else { return gen;