]> Nishi Git Mirror - serenade.git/commitdiff
define-func works
authornishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Sat, 27 Apr 2024 01:03:39 +0000 (01:03 +0000)
committernishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Sat, 27 Apr 2024 01:03:39 +0000 (01:03 +0000)
git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@61 0f02c867-ac3d-714e-8a88-971ba1f6efcf

Serenade/interpreter.c
Serenade/interpreter.h
Serenade/parser.h
Serenade/run.c
Serenade/util.c

index 642f91e55abab2bab09834e43b15793e6606b1d1..a8adff36e6a03e1e36e268f269e75e3b14b592b8 100644 (file)
@@ -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;
                                }
index c23a8f61eb93f130c4338b08f5833d9e74c71bc6..fc7c73c354799f6c9bda972e3a02ec6a9042c25d 100644 (file)
 
 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);
index f00b6d8513261347cb139f92ff4ac9c113e41029..373542c650df89e454ed91fa8095e8a6bee5fc34 100644 (file)
@@ -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**);
 };
 
index 18f52c4e40a82ef4ea61ea85119e759fe32ed6b3..9a0530d941174de43a9f14fbf85405037f507825 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+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));
index 78a8e5302a701fded87141039eee8b2ef5d3ca1f..a9ff8baa457b9ef34b88dc6bf36f8c0ec17f0d18 100644 (file)
@@ -59,8 +59,9 @@ void sn_print_to(FILE* f, struct sn_generic* gen) {
        } else if(gen->type == SN_TYPE_FUNCTION) {
                fprintf(f, "<function %s", gen->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, "<pointer %x>", gen->ptr);
        }