]> Nishi Git Mirror - serenade.git/commitdiff
cond works
authornishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Sun, 5 May 2024 16:17:27 +0000 (16:17 +0000)
committernishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Sun, 5 May 2024 16:17:27 +0000 (16:17 +0000)
git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@109 0f02c867-ac3d-714e-8a88-971ba1f6efcf

Serenade/interpreter.c
Serenade/run.c
Serenade/util.c

index 8908887fac6c592d1df1819c59b23f4573fd4498..60faa41d4bee178c5df79f25f8d66bdb3836d6a8 100644 (file)
@@ -71,6 +71,29 @@ struct sn_generic* math_handler(struct sn_interpreter* sn, int args, struct sn_g
        return gen;
 }
 
+struct sn_generic* cond_handler(struct sn_interpreter* sn, int args, struct sn_generic** gens) {
+       struct sn_generic* gen = malloc(sizeof(struct sn_generic));
+       gen->type = SN_TYPE_DOUBLE;
+       gen->number = 0;
+       int i;
+       if(args != 3 || !(gens[1]->type == SN_TYPE_DOUBLE && gens[2]->type == SN_TYPE_DOUBLE)) {
+               gen->number = -1;
+       } else {
+               double a = gens[1]->number;
+               double b = gens[2]->number;
+               if(strcmp(gens[0]->name, "<") == 0) {
+                       gen->number = a < b ? 1 : 0;
+               } else if(strcmp(gens[0]->name, ">") == 0) {
+                       gen->number = a > b ? 1 : 0;
+               } else if(strcmp(gens[0]->name, ">=") == 0) {
+                       gen->number = a >= b ? 1 : 0;
+               } else if(strcmp(gens[0]->name, ">=") == 0) {
+                       gen->number = a <= b ? 1 : 0;
+               }
+       }
+       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;
@@ -151,6 +174,10 @@ void sn_stdlib_init(struct sn_interpreter* sn) {
        sn_set_handler(sn, "-", math_handler);
        sn_set_handler(sn, "*", math_handler);
        sn_set_handler(sn, "/", math_handler);
+       sn_set_handler(sn, "<=", cond_handler);
+       sn_set_handler(sn, ">=", cond_handler);
+       sn_set_handler(sn, "<", cond_handler);
+       sn_set_handler(sn, ">", cond_handler);
        sn_set_handler(sn, "print", print_handler);
        sn_set_handler(sn, "eval", eval_handler);
        sn_set_handler(sn, "define-variable", defvar_handler);
@@ -199,8 +226,10 @@ do_again:
                int j;
        do_again2:
                for(j = 0; sn->generics[i][j] != NULL; j++) {
-                       if(sn->generics[i][j] != (void*)1) sn_generic_free(sn, sn->generics[i][j]);
-                       goto do_again2;
+                       if(sn->generics[i][j] != (void*)1 && sn->generics[i][j] != (void*)2) {
+                               sn_generic_free(sn, sn->generics[i][j]);
+                               goto do_again2;
+                       }
                }
                free(sn->generics[i]);
        }
@@ -306,6 +335,7 @@ int sn_eval(struct sn_interpreter* sn, char* data, unsigned long long len) {
                                }
                        }
                }
+               if(r == 1) return r;
                int j;
                struct sn_generic*** oldgens = sn->generics;
                for(j = 0; oldgens[j] != NULL; j++)
index fc27efb045caf4fb1ac8fd711ab2abe0381824d9..670a508a48fed939ce25e01be67b5a52a7e83089 100644 (file)
@@ -104,7 +104,47 @@ struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) {
                                free(name);
                                return r;
                        } else if(strcmp(op->name, "loop") == 0) {
+                               int i;
+                               for(i = 0; gen->tree->args[i] != NULL; i++)
+                                       ;
+                               if(i < 2) {
+                                       fprintf(stderr, "Insufficient arguments\n");
+                                       free(r);
+                                       return NULL;
+                               }
+                       do_loop:;
+                               struct sn_interpreter_kv** old_kv = sn->local_variables;
+                               sn->local_variables = malloc(sizeof(struct sn_interpreter_kv*));
+                               sn->local_variables[0] = NULL;
+
+                               struct sn_generic* cond = _sn_run(sn, gen->tree->args[1]);
+                               if(cond == NULL) {
+                                       free(r);
+                                       return NULL;
+                               }
+
+                               free(sn->local_variables);
+                               sn->local_variables = old_kv;
+
                                r->type = SN_TYPE_VOID;
+
+                               if(cond->type != SN_TYPE_DOUBLE) {
+                                       fprintf(stderr, "Cannot use non-number (Type %d) for loop condition\n", r->type);
+                                       free(r);
+                                       return NULL;
+                               } else if(cond->number != 0) {
+                                       old_kv = sn->local_variables;
+                                       sn->local_variables = malloc(sizeof(struct sn_interpreter_kv*));
+                                       sn->local_variables[0] = NULL;
+
+                                       for(i = 2; gen->tree->args[i] != NULL; i++) {
+                                               _sn_run(sn, gen->tree->args[i]);
+                                       }
+
+                                       free(sn->local_variables);
+                                       sn->local_variables = old_kv;
+                                       goto do_loop;
+                               }
                                return r;
                        }
                        bool called = false;
@@ -115,6 +155,11 @@ struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) {
                        int argc = j;
                        for(j = 0; gen->tree->args[j]; j++) {
                                args[j] = _sn_run(sn, gen->tree->args[j]);
+                               if(args[j] == NULL) {
+                                       free(args);
+                                       free(r);
+                                       return NULL;
+                               }
                        }
                        if(0) {
                                free(r);
index a9ff8baa457b9ef34b88dc6bf36f8c0ec17f0d18..55693dee3e1277d9ff74f45e11816dc3a9190753 100644 (file)
@@ -62,6 +62,8 @@ void sn_print_to(FILE* f, struct sn_generic* gen) {
                        fprintf(f, ":%x", gen->handler);
                }
                fprintf(f, ">");
+       } else if(gen->type == SN_TYPE_VARIABLE) {
+               fprintf(f, "<variable %s>", gen->name == NULL ? "(unnamed)" : gen->name);
        } else if(gen->type == SN_TYPE_PTR) {
                fprintf(f, "<pointer %x>", gen->ptr);
        }