]> Nishi Git Mirror - serenade.git/commitdiff
variable works
authornishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Wed, 24 Apr 2024 01:53:33 +0000 (01:53 +0000)
committernishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Wed, 24 Apr 2024 01:53:33 +0000 (01:53 +0000)
git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@28 0f02c867-ac3d-714e-8a88-971ba1f6efcf

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

index 2d3f5a42dfe020596ee260ea83b1c4dda53b010e..1d5879f9e3b9cc23d15c85558610cc2dd20afaef 100644 (file)
@@ -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("<void>");
+               } 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;
index fe92f98b8d372eee6d43dc143e255a97658afcb8..c17ed1f5b9794a61e3524891888d4b75667a2ac9 100644 (file)
@@ -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);
 }
index 030e18dc6f1400c77974bec75a3cfb0c5fe1c14f..a6a245bf050d877c47c17770e11e3e9f3c80c6e1 100644 (file)
@@ -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 <stdbool.h>
+
+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
index 3eae2a7c2e770b307371c6418f6e0cb2a6b9a78a..44f7d9560324d3e03e417cb644c10304d18a38a6 100644 (file)
@@ -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;