From: nishi Date: Sat, 27 Apr 2024 01:03:39 +0000 (+0000) Subject: define-func works X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=579902ccabafc10aea6b01dcd16ff6e39222c56c;p=serenade.git define-func works git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@61 0f02c867-ac3d-714e-8a88-971ba1f6efcf --- diff --git a/Serenade/interpreter.c b/Serenade/interpreter.c index 642f91e..a8adff3 100644 --- a/Serenade/interpreter.c +++ b/Serenade/interpreter.c @@ -162,14 +162,14 @@ void sn_interpreter_free(struct sn_interpreter* sn) { free(sn); } -void sn_set_variable(struct sn_interpreter* sn, const char* name, struct sn_generic* gen) { +struct sn_interpreter_kv* 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->variables[i]->value = gen; replaced = true; - break; + return sn->variables[i]; } } if(!replaced) { @@ -186,17 +186,18 @@ void sn_set_variable(struct sn_interpreter* sn, const char* name, struct sn_gene sn->variables[i]->handler = NULL; if(gen->type == SN_TYPE_FUNCTION) sn->variables[i]->handler = gen->handler; sn->variables[i + 1] = NULL; + return sn->variables[i]; } } -void sn_set_handler(struct sn_interpreter* sn, const char* name, struct sn_generic* (*handler)(struct sn_interpreter* sn, int, struct sn_generic**)) { +struct sn_interpreter_kv* 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->variables[i]->handler = handler; replaced = true; - break; + return sn->variables[i]; } } if(!replaced) { @@ -212,6 +213,7 @@ void sn_set_handler(struct sn_interpreter* sn, const char* name, struct sn_gener sn->variables[i]->value = NULL; sn->variables[i]->handler = handler; sn->variables[i + 1] = NULL; + return sn->variables[i]; } } @@ -222,6 +224,7 @@ int sn_eval(struct sn_interpreter* sn, char* data, unsigned long long len) { int i; for(i = 0; gens[i] != NULL; i++) { if(r == 0) { + sn->local_variables = NULL; if(sn_run(sn, gens[i]) != 0) { r = 1; } diff --git a/Serenade/interpreter.h b/Serenade/interpreter.h index c23a8f6..fc7c73c 100644 --- a/Serenade/interpreter.h +++ b/Serenade/interpreter.h @@ -35,19 +35,21 @@ struct sn_interpreter { struct sn_interpreter_kv** variables; + struct sn_interpreter_kv** local_variables; struct sn_generic*** generics; }; struct sn_interpreter_kv { char* key; struct sn_generic* value; + void* argvalue; 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**)); +struct sn_interpreter_kv* sn_set_variable(struct sn_interpreter* sn, const char* name, struct sn_generic* gen); +struct sn_interpreter_kv* sn_set_handler(struct sn_interpreter* sn, const char* name, struct sn_generic* (*handler)(struct sn_interpreter* sn, int, struct sn_generic**)); int sn_eval(struct sn_interpreter* sn, char* data, unsigned long long len); void sn_stdlib_init(struct sn_interpreter* sn); void sn_ffi_init(struct sn_interpreter* sn); diff --git a/Serenade/parser.h b/Serenade/parser.h index f00b6d8..373542c 100644 --- a/Serenade/parser.h +++ b/Serenade/parser.h @@ -49,6 +49,7 @@ struct sn_generic { char* name; struct sn_tree* tree; bool used; + void* argvalue; struct sn_generic* (*handler)(struct sn_interpreter* sn, int, struct sn_generic**); }; diff --git a/Serenade/run.c b/Serenade/run.c index 18f52c4..9a0530d 100644 --- a/Serenade/run.c +++ b/Serenade/run.c @@ -39,6 +39,19 @@ #include #include +struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen); + +struct sn_generic* run_code(struct sn_interpreter* sn, int argc, struct sn_generic** args){ + struct sn_generic* r = malloc(sizeof(struct sn_generic)); + r->type = SN_TYPE_VOID; + struct sn_generic** gens = (struct sn_generic**)args[0]->argvalue; + int i; + for(i = 0; gens[i] != NULL; i++){ + _sn_run(sn, gens[i]); + } + return r; +} + struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) { if(gen->type == SN_TYPE_TREE) { struct sn_generic* op = gen->tree->args[0]; @@ -59,6 +72,14 @@ struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) { r->string = sn_strdup(SERENADE_VERSION); r->string_length = strlen(r->string); return r; + }else if(strcmp(op->name, "define-func") == 0){ + char* name = malloc(gen->tree->args[1]->string_length + 1); + memcpy(name, gen->tree->args[1]->string, gen->tree->args[1]->string_length); + name[gen->tree->args[1]->string_length] = 0; + struct sn_interpreter_kv* kv = sn_set_handler(sn, name, run_code); + kv->argvalue = gen->tree->args + 1; + free(name); + return r; } bool called = false; int j; @@ -82,6 +103,7 @@ struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) { if(sn->variables[j]->value != NULL) { args[0] = sn->variables[j]->value; } + args[0]->argvalue = sn->variables[j]->argvalue; op_result = sn->variables[j]->handler(sn, argc, args); } else { struct sn_generic* build = malloc(sizeof(struct sn_generic)); diff --git a/Serenade/util.c b/Serenade/util.c index 78a8e53..a9ff8ba 100644 --- a/Serenade/util.c +++ b/Serenade/util.c @@ -59,8 +59,9 @@ void sn_print_to(FILE* f, struct sn_generic* gen) { } else if(gen->type == SN_TYPE_FUNCTION) { fprintf(f, "name == NULL ? "(anonymous)" : gen->name); if(gen->name == NULL) { - fprintf(f, ":%x>", gen->handler); + fprintf(f, ":%x", gen->handler); } + fprintf(f, ">"); } else if(gen->type == SN_TYPE_PTR) { fprintf(f, "", gen->ptr); }