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;
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);
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]);
}
}
}
}
+ if(r == 1) return r;
int j;
struct sn_generic*** oldgens = sn->generics;
for(j = 0; oldgens[j] != NULL; j++)
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;
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);