From: nishi Date: Tue, 23 Apr 2024 14:03:25 +0000 (+0000) Subject: can do math now X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=d78babb6052db53d1907647a8c3f455a91438603;p=serenade.git can do math now git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@22 0f02c867-ac3d-714e-8a88-971ba1f6efcf --- diff --git a/Serenade/interpreter.c b/Serenade/interpreter.c index c1b94b0..9c042d5 100644 --- a/Serenade/interpreter.c +++ b/Serenade/interpreter.c @@ -33,12 +33,58 @@ #include "util.h" #include +#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; + gen->type = SN_TYPE_DOUBLE; + gen->number = 0; + if(strcmp(gens[0]->name, "*") == 0) gen->number = 1; + int i; + for(i = 1; i < args; i++) { + if(gens[i]->type == SN_TYPE_DOUBLE) { + if(strcmp(gens[0]->name, "*") == 0) { + gen->number *= gens[i]->number; + } else if(strcmp(gens[0]->name, "+") == 0) { + gen->number += gens[i]->number; + } else if(strcmp(gens[0]->name, "-") == 0) { + if(i == 1) { + gen->number += gens[i]->number; + } else { + gen->number -= gens[i]->number; + } + } else if(strcmp(gens[0]->name, "/") == 0) { + if(i == 1) { + gen->number += gens[i]->number; + } else { + gen->number /= gens[i]->number; + } + } + } + } + return gen; +} + +struct sn_generic* print_handler(struct sn_interpreter* sn, int args, struct sn_generic** gens) { + struct sn_generic* gen = malloc(sizeof(struct sn_generic)); + int i; + for(i = 1; i < args; i++) { + if(i > 1) printf(" "); + fflush(stdout); + if(gens[i]->type == SN_TYPE_DOUBLE) { + printf("%f", gens[i]->number); + } else if(gens[i]->type == SN_TYPE_STRING) { + fwrite(gens[i]->string, 1, gens[i]->string_length, stdout); + } else if(gens[i]->type == SN_TYPE_VOID) { + printf(""); + } + fflush(stdout); + } + printf("\n"); + gen->type = SN_TYPE_FUNCTION; + gen->name = sn_strdup("print"); return gen; } @@ -51,6 +97,7 @@ struct sn_interpreter* sn_create_interpreter(void) { sn_set_handler(sn, "-", math_handler); sn_set_handler(sn, "*", math_handler); sn_set_handler(sn, "/", math_handler); + sn_set_handler(sn, "print", print_handler); return sn; } diff --git a/Serenade/run.c b/Serenade/run.c index d9dd72a..2830510 100644 --- a/Serenade/run.c +++ b/Serenade/run.c @@ -44,12 +44,12 @@ struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) { op = _sn_run(sn, op); } int j; - for(j = 1; gen->tree->args[j]; j++) + for(j = 0; gen->tree->args[j]; j++) ; - struct sn_generic** args = malloc(sizeof(struct sn_generic*) * (j - 1)); - int argc = j - 1; - for(j = 1; gen->tree->args[j]; j++) { - args[j - 1] = _sn_run(sn, gen->tree->args[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)); @@ -60,6 +60,26 @@ struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) { free(args); return NULL; } else { + for(j = 0; sn->variables[j] != NULL; j++) { + if(strcmp(sn->variables[j]->key, op->name) == 0) { + struct sn_generic* op_result = NULL; + if(sn->variables[j]->handler != NULL) { + op_result = sn->variables[j]->handler(sn, argc, args); + } else { + struct sn_generic* build = malloc(sizeof(struct sn_generic)); + build->tree = malloc(sizeof(struct sn_tree)); + build->tree->args = args; + build->tree->args[0] = sn->variables[j]->value; + op_result = _sn_run(sn, build); + free(build->tree); + } + if(op_result != NULL) { + free(r); + r = op_result; + } + break; + } + } } free(args); return r;