From: nishi Date: Tue, 23 Apr 2024 13:38:26 +0000 (+0000) Subject: interpreter X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=a86519acf25c179de642d1091dc3f8409dd901e6;p=serenade.git interpreter git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@21 0f02c867-ac3d-714e-8a88-971ba1f6efcf --- diff --git a/Serenade/interpreter.c b/Serenade/interpreter.c index 5edad85..c1b94b0 100644 --- a/Serenade/interpreter.c +++ b/Serenade/interpreter.c @@ -30,11 +30,92 @@ #include "interpreter.h" +#include "util.h" + +#include #include +#include + +struct sn_generic* math_handler(struct sn_interpreter* sn, int args, struct sn_generic** gens) { + struct sn_generic* gen = malloc(sizeof(struct sn_generic)); + gen->type = SN_TYPE_VOID; + return gen; +} struct sn_interpreter* sn_create_interpreter(void) { struct sn_interpreter* sn = malloc(sizeof(struct sn_interpreter)); + sn->variables = malloc(sizeof(struct sn_interpreter_kv*)); + sn->variables[0] = NULL; + + sn_set_handler(sn, "+", math_handler); + sn_set_handler(sn, "-", math_handler); + sn_set_handler(sn, "*", math_handler); + sn_set_handler(sn, "/", math_handler); + return sn; } -void sn_interpreter_free(struct sn_interpreter* sn) { free(sn); } +void sn_interpreter_free(struct sn_interpreter* sn) { + int i; + for(i = 0; sn->variables[i] != NULL; i++) { + free(sn->variables[i]->key); + if(sn->variables[i]->value != NULL) sn_generic_free(sn->variables[i]->value); + free(sn->variables[i]); + } + free(sn->variables); + free(sn); +} + +void sn_set_variable(struct sn_interpreter* sn, const char* name, struct sn_generic* gen) { + int i; + 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; + } + } + if(!replaced) { + struct sn_interpreter_kv** oldvariables = sn->variables; + for(i = 0; oldvariables[i] != NULL; i++) + ; + sn->variables = malloc(sizeof(struct sn_interpreter_kv*) * (i + 2)); + for(i = 0; oldvariables[i] != NULL; i++) { + sn->variables[i] = oldvariables[i]; + } + sn->variables[i] = malloc(sizeof(struct sn_generic)); + sn->variables[i]->key = sn_strdup(name); + sn->variables[i]->value = gen; + sn->variables[i]->handler = NULL; + sn->variables[i + 1] = NULL; + } +} + +void sn_set_handler(struct sn_interpreter* sn, const char* name, struct sn_generic* (*handler)(struct sn_interpreter* sn, int, struct sn_generic**)) { + int i; + 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; + } + } + if(!replaced) { + struct sn_interpreter_kv** oldvariables = sn->variables; + for(i = 0; oldvariables[i] != NULL; i++) + ; + sn->variables = malloc(sizeof(struct sn_interpreter_kv*) * (i + 2)); + for(i = 0; oldvariables[i] != NULL; i++) { + sn->variables[i] = oldvariables[i]; + } + sn->variables[i] = malloc(sizeof(struct sn_generic)); + sn->variables[i]->key = sn_strdup(name); + sn->variables[i]->value = NULL; + sn->variables[i]->handler = handler; + sn->variables[i + 1] = NULL; + } +} diff --git a/Serenade/interpreter.h b/Serenade/interpreter.h index f528359..689ed25 100644 --- a/Serenade/interpreter.h +++ b/Serenade/interpreter.h @@ -33,9 +33,19 @@ #include "parser.h" -struct sn_interpreter {}; +struct sn_interpreter { + struct sn_interpreter_kv** variables; +}; + +struct sn_interpreter_kv { + char* key; + struct sn_generic* value; + struct sn_generic* (*handler)(struct sn_interpreter* sn, int, struct sn_generic**); +}; struct sn_interpreter* sn_create_interpreter(void); void sn_interpreter_free(struct sn_interpreter* sn); +void sn_set_variable(struct sn_interpreter* sn, const char* name, struct sn_generic* gen); +void sn_set_handler(struct sn_interpreter* sn, const char* name, struct sn_generic* (*handler)(struct sn_interpreter* sn, int, struct sn_generic**)); #endif diff --git a/Serenade/parser.c b/Serenade/parser.c index 6a89783..1e6a7f2 100644 --- a/Serenade/parser.c +++ b/Serenade/parser.c @@ -29,6 +29,7 @@ /* --- END LICENSE --- */ #include "parser.h" + #include "../config.h" #include "util.h" diff --git a/Serenade/run.c b/Serenade/run.c index 07a47fe..d9dd72a 100644 --- a/Serenade/run.c +++ b/Serenade/run.c @@ -29,6 +29,7 @@ /* --- END LICENSE --- */ #include "run.h" + #include "util.h" #include