Browse Source

Sol Part 20: When All Else Fails, Remove the Unit Tests!

master
Graham Northup 7 years ago
parent
commit
b3b21c7d83
  1. 2
      ast.h
  2. 2
      astprint.c
  3. 5
      build.sh
  4. 1018
      builtins.c
  5. 521
      object.c
  6. 108
      runtime.c
  7. 107
      sol.h
  8. 1
      solrun.c
  9. 199
      state.c
  10. 136
      test.sol

2
ast.h

@ -178,6 +178,8 @@ typedef struct tag_stmt_node {
#define BOOL_TO_INT(cond) ((cond)?1:0)
sol_object_t *sol_new_func(sol_state_t *, identlist_node *, stmt_node *, char *);
sol_object_t *sol_new_stmtnode(sol_state_t *, stmt_node *);
sol_object_t *sol_new_exprnode(sol_state_t *, expr_node *);
// runtime.c

2
astprint.c

@ -8,7 +8,7 @@ void prlev(int lev, const char *fmt, ...) {
va_list vl;
int i;
for(i = 0; i < lev; i++) putchar(' ');
for(i = 0; i < lev; i++) putchar('\t');
va_start(vl, fmt);
vprintf(fmt, vl);
va_end(vl);

5
build.sh

@ -1,3 +1,7 @@
gcc -c -g dsl/seq.c
gcc -c -g dsl/list.c
gcc -c -g dsl/array.c
gcc -c -g dsl/generic.c
gcc -c -g lex.yy.c
gcc -c -g parser.tab.c
gcc -c -g astprint.c
@ -6,4 +10,5 @@ gcc -c -g object.c
gcc -c -g state.c
gcc -c -g builtins.c
gcc -c -g solrun.c
gcc -c -g dummypow.c
gcc -g -lm *.o -o sol

1018
builtins.c
File diff suppressed because it is too large
View File

521
object.c

@ -40,12 +40,13 @@ sol_object_t *sol_cast_string(sol_state_t *state, sol_object_t *obj) {
// This will not fail here; error checking is done in sol_state_init().
sol_object_t *sol_new_singlet(sol_state_t *state) {
sol_object_t *sol_new_singlet(sol_state_t *state, const char *name) {
sol_object_t *res = malloc(sizeof(sol_object_t));
if(res) {
res->type = SOL_SINGLET;
res->refcnt = 0;
res->ops = &(state->NullOps);
res->str = strdup(name);
}
return sol_incref(res);
}
@ -67,6 +68,10 @@ void sol_init_object(sol_state_t *state, sol_object_t *obj) {
if(obj->ops->init) obj->ops->init(state, obj);
}
sol_object_t *sol_obj_acquire(sol_object_t *obj) {
return sol_incref(obj);
}
void sol_obj_free(sol_object_t *obj) {
if(!obj) {
printf("WARNING: Attempt to free NULL\n");
@ -130,6 +135,10 @@ sol_object_t *sol_new_string(sol_state_t *state, const char *s) {
return res;
}
int sol_string_cmp(sol_state_t *state, sol_object_t *str, const char *s) {
return strcmp(str->str, s);
}
sol_object_t *sol_f_str_free(sol_state_t *state, sol_object_t *obj) {
free(obj->str);
return obj;
@ -142,256 +151,93 @@ sol_object_t *sol_new_list(sol_state_t *state) {
return sol_incref(state->None);
}
res->type = SOL_LIST;
res->lvalue = NULL;
res->lnext = NULL;
res->seq = dsl_seq_new_array(NULL, &(state->obfuncs));
res->ops = &(state->ListOps);
sol_init_object(state, res);
return res;
}
int sol_list_len(sol_state_t *state, sol_object_t *list) {
int i = 0;
sol_object_t *cur = list;
if(!sol_is_list(list)) {
sol_obj_free(sol_set_error_string(state, "Compute length of non-list"));
return -1;
}
while(cur) {
if(cur->lvalue) i++;
cur = cur->lnext;
sol_object_t *sol_list_from_seq(sol_state_t *state, dsl_seq *seq) {
sol_object_t *res = sol_alloc_object(state);
if(sol_has_error(state)) {
sol_obj_free(res);
return sol_incref(state->None);
}
return i;
res->type = SOL_LIST;
res->seq = seq;
res->ops = &(state->ListOps);
sol_init_object(state, res);
return res;
}
int sol_list_len(sol_state_t *state, sol_object_t *list) {
return dsl_seq_len(list->seq);
}
sol_object_t *sol_list_sublist(sol_state_t *state, sol_object_t *list, int idx) {
int i = 0;
sol_object_t *cur = list;
sol_object_t *copy, *res;
dsl_seq *subl;
if(idx < 0) {
return sol_set_error_string(state, "Create sublist at negative index");
}
while(cur && i < idx) {
if(cur->lvalue) i++;
cur = cur->lnext;
subl = dsl_seq_copy(list->seq);
for(i=0; i<idx; i++) {
dsl_seq_delete(subl, 0);
}
copy = sol_new_list(state);
res = copy;
while(cur) {
if(cur->lvalue) {
copy->lvalue = sol_incref(cur->lvalue);
if(cur->lnext) {
copy->lnext = sol_alloc_object(state);
copy = copy->lnext;
copy->type = SOL_LCELL;
copy->ops = &(state->LCellOps);
copy->lnext = NULL;
copy->lvalue = NULL;
}
}
cur = cur->lnext;
}
return res;
return sol_list_from_seq(state, subl);
}
sol_object_t *sol_list_get_index(sol_state_t *state, sol_object_t *list, int idx) {
sol_object_t *cur = list;
int i = 0;
if(!sol_is_list(list)) {
return sol_set_error_string(state, "Get index of non-list");
}
if(idx < 0) {
return sol_set_error_string(state, "Get negative index");
}
while(cur && i < idx) {
if(cur->lvalue) i++;
cur = cur->lnext;
}
while(cur && !cur->lvalue) cur = cur->lnext;
if(cur) {
return sol_incref(cur->lvalue);
} else {
return sol_set_error_string(state, "Get out-of-bounds index");
}
if(idx<0 || idx>=dsl_seq_len(list->seq)) return sol_incref(state->None);
return sol_incref(AS_OBJ(dsl_seq_get(list->seq, idx)));
}
void sol_list_set_index(sol_state_t *state, sol_object_t *list, int idx, sol_object_t *obj) {
sol_object_t *cur = list, *temp;
int i = 0;
if(!sol_is_list(list)) {
sol_obj_free(sol_set_error_string(state, "Set index of non-list"));
return;
}
if(idx < 0) {
sol_obj_free(sol_set_error_string(state, "Set negative index"));
return;
}
while(cur && i < idx) {
if(cur->lvalue) i++;
cur = cur->lnext;
}
while(!cur->lvalue) cur = cur->lnext;
if(cur) {
temp = cur->lvalue;
cur->lvalue = sol_incref(obj);
if(temp) sol_obj_free(temp);
} else {
sol_obj_free(sol_set_error_string(state, "Set out-of-bounds index"));
return;
}
if(idx<0 || idx>=dsl_seq_len(list->seq)) return;
dsl_seq_set(list->seq, idx, obj);
}
void sol_list_insert(sol_state_t *state, sol_object_t *list, int idx, sol_object_t *obj) {
sol_object_t *next = list, *prev = NULL, *temp = sol_alloc_object(state);
int i = -1;
if(sol_has_error(state)) return;
if(!sol_is_list(list)) {
sol_obj_free(sol_set_error_string(state, "Insert into non-list"));
return;
}
if(idx < 0) {
sol_obj_free(sol_set_error_string(state, "Insert at negative index"));
return;
}
temp->type = SOL_LCELL;
temp->ops = &(state->LCellOps);
temp->lvalue = sol_incref(obj);
while(next) {
if(next->lvalue) i++;
if(i >= idx) break;
prev = next;
next = next->lnext;
}
if(next) {
if(prev) {
prev->lnext = temp;
temp->lnext = next;
} else {
assert(next == list);
temp->lnext = sol_alloc_object(state);
temp->lnext->type = SOL_LCELL;
temp->lnext->ops = &(state->LCellOps);
temp->lnext->lvalue = list->lvalue;
temp->lnext->lnext = list->lnext;
list->lnext = temp;
list->lvalue = NULL;
}
} else {
if(prev) {
prev->lnext = temp;
temp->lnext = NULL;
} else {
sol_obj_free(temp->lvalue);
sol_obj_free(temp);
sol_obj_free(sol_set_error_string(state, "Out-of-bounds insert"));
return;
}
}
assert(!sol_validate_list(state, list));
if(idx<0 || idx>dsl_seq_len(list->seq)) return;
dsl_seq_insert(list->seq, idx, obj);
}
sol_object_t *sol_list_remove(sol_state_t *state, sol_object_t *list, int idx) {
sol_object_t *next = list, *prev = NULL, *res;
int i = -1;
if(sol_has_error(state)) return sol_incref(state->None);
if(idx < 0) {
return sol_set_error_string(state, "Remove from negative index");
}
while(next) {
if(next->lvalue) i++;
if(i >= idx) break;
prev = next;
next = next->lnext;
}
if(next) {
if(prev) {
res = sol_incref(next->lvalue);
prev->lnext = next->lnext;
sol_obj_free(next);
} else {
res = sol_incref(list->lvalue);
list->lvalue = NULL;
}
assert(!sol_validate_list(state, list));
return res;
} else {
return sol_set_error_string(state, "Out-of-bounds remove");
}
if(idx<0 || idx>=dsl_seq_len(list->seq)) return sol_incref(state->None);
return dsl_seq_remove(list->seq, idx);
}
sol_object_t *sol_list_copy(sol_state_t *state, sol_object_t *list) {
sol_object_t *newls = sol_new_list(state), *cur = list;
sol_object_t *res = newls;
while(cur) {
if(cur->lvalue) {
newls->lvalue = sol_incref(cur->lvalue);
newls->lnext = sol_alloc_object(state);
if(sol_has_error(state)) return sol_incref(state->None);
newls = newls->lnext;
newls->type = SOL_LCELL;
newls->ops = &(state->LCellOps);
newls->lvalue = NULL;
newls->lnext = NULL;
}
cur = cur->lnext;
}
return res;
return sol_list_from_seq(state, dsl_seq_copy(list->seq));
}
sol_object_t *sol_list_truncate(sol_state_t *state, sol_object_t *list, int len) {
sol_object_t *newls = sol_new_list(state), *cur = list;
sol_object_t *res = newls;
int i = 0;
while(cur && i<len) {
if(cur->lvalue) {
newls->lvalue = sol_incref(cur->lvalue);
newls->lnext = sol_alloc_object(state);
if(sol_has_error(state)) return sol_incref(state->None);
newls = newls->lnext;
newls->type = SOL_LCELL;
newls->ops = &(state->LCellOps);
newls->lvalue = NULL;
newls->lnext = NULL;
i++;
dsl_seq *newseq = dsl_seq_copy(list->seq);
dsl_seq_iter *iter = dsl_new_seq_iter(newseq);
int pos = dsl_seq_iter_seek(iter, len);
int sz = dsl_seq_len(newseq);
int i;
if(pos>=len) {
for(i=0; i<sz-pos; i++) {
dsl_seq_iter_delete_at(iter);
}
cur = cur->lnext;
}
return res;
dsl_free_seq_iter(iter);
return sol_list_from_seq(state, newseq);
}
void sol_list_append(sol_state_t *state, sol_object_t *dest, sol_object_t *src) {
sol_object_t *curd = dest, *curs = src;
while(curd->lnext) curd = curd->lnext;
while(curs) {
if(curs->lvalue) {
curd->lvalue = sol_incref(curs->lvalue);
curd->lnext = sol_alloc_object(state);
if(sol_has_error(state)) return;
curd = curd->lnext;
curd->type = SOL_LCELL;
curd->ops = &(state->LCellOps);
curd->lnext = NULL;
curd->lvalue = NULL;
}
curs = curs->lnext;
}
dsl_seq *oldseq = dest->seq;
dest->seq = dsl_seq_append(dest->seq, src->seq);
dsl_free_seq(oldseq);
}
sol_object_t *sol_f_list_free(sol_state_t *state, sol_object_t *list) {
sol_object_t *cur = list, *prev;
while(cur) {
prev = cur;
cur = cur->lnext;
if(prev!=list) sol_obj_free(prev);
}
return list;
dsl_free_seq(list->seq);
return list;
}
sol_object_t *sol_f_lcell_free(sol_state_t *state, sol_object_t *lcell) {
if(lcell->lvalue) sol_obj_free(lcell->lvalue);
return lcell;
}
int sol_test_cycle(sol_state_t *state, sol_object_t *seq) {
/*int sol_test_cycle(sol_state_t *state, sol_object_t *seq) {
sol_object_t *seen[1024]={};
sol_object_t *cur = seq, **item;
while(cur) {
@ -424,7 +270,7 @@ int sol_validate_list(sol_state_t *state, sol_object_t *list) {
snprintf(msg, 128, "Node at index %d has a next node but NULL value", i);
sol_obj_free(sol_set_error_string(state, msg));
return 1;
}*/
}*//*
cur = cur->lnext;
i++;
}
@ -434,60 +280,71 @@ int sol_validate_list(sol_state_t *state, sol_object_t *list) {
return 1;
}
return 0;
}
}*/
sol_object_t *sol_new_map(sol_state_t *state) {
sol_object_t *map = sol_alloc_object(state);
if(sol_has_error(state)) return sol_incref(state->None);
map->type = SOL_MAP;
map->ops = &(state->MapOps);
map->mkey = NULL;
map->mval = NULL;
map->mnext = NULL;
map->seq = dsl_seq_new_array(NULL, &(state->obfuncs));
return map;
}
sol_object_t *sol_map_from_seq(sol_state_t *state, dsl_seq *seq) {
sol_object_t *map = sol_alloc_object(state);
if(sol_has_error(state)) return sol_incref(state->None);
map->type = SOL_MAP;
map->ops = &(state->MapOps);
map->seq = seq;
return map;
}
int sol_map_len(sol_state_t *state, sol_object_t *map) {
int i = 0;
sol_object_t *cur = map;
while(cur) {
if(cur->mkey) i++;
cur = cur->mnext;
}
return i;
return dsl_seq_len(map->seq);
}
sol_object_t *sol_map_mcell(sol_state_t *state, sol_object_t *map, sol_object_t *key) {
sol_object_t *list = sol_new_list(state), *res = NULL, *cur = map, *cmp;
sol_object_t *list = sol_new_list(state), *cmp, *icmp, *res = NULL;
dsl_seq_iter *iter = dsl_new_seq_iter(map->seq);
if(sol_has_error(state)) {
dsl_free_seq_iter(iter);
sol_obj_free(list);
return sol_incref(state->None);
}
sol_list_insert(state, list, 0, key);
while(cur) {
if(cur->mkey) {
sol_list_insert(state, list, 1, cur->mkey);
cmp = sol_cast_int(state, key->ops->cmp(state, list));
sol_list_remove(state, list, 1);
if(cmp->ival == 0) {
res = cur;
break;
}
}
cur = cur->mnext;
}
if(res) {
return sol_incref(res);
} else {
return sol_incref(state->None);
}
sol_list_insert(state, list, 1, state->None);
if(!dsl_seq_iter_is_invalid(iter)) do {
sol_list_set_index(state, list, 1, AS_OBJ(dsl_seq_iter_at(iter))->key);
cmp = key->ops->cmp(state, list);
icmp = sol_cast_int(state, cmp);
sol_obj_free(cmp);
if(icmp->ival == 0) {
res = AS_OBJ(dsl_seq_iter_at(iter));
}
sol_obj_free(icmp);
} while(dsl_seq_iter_next(iter));
dsl_free_seq_iter(iter);
sol_obj_free(list);
if(res) {
return res;
}
return sol_incref(state->None);
}
int sol_map_has(sol_state_t *state, sol_object_t *map, sol_object_t *key) {
sol_object_t *mcell = sol_map_mcell(state, map, key);
int res = sol_is_none(state, mcell);
sol_obj_free(mcell);
return res;
}
sol_object_t *sol_map_get(sol_state_t *state, sol_object_t *map, sol_object_t *key) {
sol_object_t *submap = sol_map_mcell(state, map, key);
sol_object_t *res;
if(sol_is_map(submap)) {
res = sol_incref(submap->mval);
return res;
} else {
return sol_incref(state->None);
}
sol_object_t *mcell = sol_map_mcell(state, map, key);
if(sol_is_none(state, mcell)) {
return mcell;
}
return sol_incref(mcell->val);
}
sol_object_t *sol_map_get_name(sol_state_t *state, sol_object_t *map, char *name) {
@ -498,43 +355,20 @@ sol_object_t *sol_map_get_name(sol_state_t *state, sol_object_t *map, char *name
}
void sol_map_set(sol_state_t *state, sol_object_t *map, sol_object_t *key, sol_object_t *val) {
sol_object_t *cur = map, *prev = NULL, *list = sol_new_list(state), *cmp;
sol_list_insert(state, list, 0, key);
while(cur) {
if(cur->mkey) {
sol_list_insert(state, list, 1, cur->mkey);
cmp = sol_cast_int(state, key->ops->cmp(state, list));
sol_list_remove(state, list, 1);
if(cmp->ival == 0) {
if(sol_is_none(state, val)) {
if(prev) {
prev->mnext = cur->mnext;
sol_obj_free(cur);
} else {
sol_obj_free(cur->mkey);
sol_obj_free(cur->mval);
cur->mkey = NULL;
cur->mval = NULL;
}
} else {
sol_obj_free(cur->mval);
cur->mval = sol_incref(val);
}
return;
}
}
prev = cur;
cur = cur->mnext;
}
if(sol_is_none(state, val)) return;
prev->mnext = sol_alloc_object(state);
if(sol_has_error(state)) return;
cur = prev->mnext;
cur->type = SOL_MCELL;
cur->ops = &(state->MCellOps);
cur->mkey = sol_incref(key);
cur->mval = sol_incref(val);
cur->mnext = NULL;
sol_object_t *mcell =sol_map_mcell(state, map, key), *newcell, *temp;
if(sol_is_none(state, mcell)) {
newcell = sol_alloc_object(state);
newcell->type = SOL_MCELL;
newcell->ops = &(state->MCellOps);
newcell->key = sol_incref(key);
newcell->val = sol_incref(val);
dsl_seq_insert(map->seq, 0, newcell);
sol_obj_free(newcell);
} else {
temp = mcell->val;
mcell->val = sol_incref(val);
sol_obj_free(temp);
}
}
void sol_map_set_name(sol_state_t *state, sol_object_t *map, char *name, sol_object_t *val) {
@ -544,96 +378,46 @@ void sol_map_set_name(sol_state_t *state, sol_object_t *map, char *name, sol_obj
}
void sol_map_set_existing(sol_state_t *state, sol_object_t *map, sol_object_t *key, sol_object_t *val) {
sol_object_t *cur = map, *prev = NULL, *list = sol_new_list(state), *cmp;
sol_list_insert(state, list, 0, key);
while(cur) {
if(cur->mkey) {
sol_list_insert(state, list, 1, cur->mkey);
cmp = sol_cast_int(state, key->ops->cmp(state, list));
sol_list_remove(state, list, 1);
if(cmp->ival == 0) {
if(sol_is_none(state, val)) {
if(prev) {
prev->mnext = cur->mnext;
sol_obj_free(cur);
} else {
sol_obj_free(cur->mkey);
sol_obj_free(cur->mval);
cur->mkey = NULL;
cur->mval = NULL;
}
} else {
sol_obj_free(cur->mval);
cur->mval = sol_incref(val);
}
return;
}
}
prev = cur;
cur = cur->mnext;
}
sol_object_t *mcell =sol_map_mcell(state, map, key), *temp;
if(!sol_is_none(state, mcell)) {
temp = mcell->val;
mcell->val = sol_incref(val);
sol_obj_free(temp);
}
}
sol_object_t *sol_map_copy(sol_state_t *state, sol_object_t *map) {
sol_object_t *newmap = sol_new_map(state), *newcur = newmap, *cur = map;
while(cur) {
if(cur->mkey) {
newcur->mkey = sol_incref(cur->mkey);
newcur->mval = sol_incref(cur->mval);
newcur->mnext = sol_alloc_object(state);
newcur = newcur->mnext;
newcur->type = SOL_MCELL;
newcur->ops = &(state->MCellOps);
newcur->mkey = NULL;
newcur->mval = NULL;
newcur->mnext = NULL;
}
cur = cur->mnext;
}
return newmap;
return sol_map_from_seq(state, dsl_seq_copy(map->seq));
}
void sol_map_merge(sol_state_t *state, sol_object_t *dest, sol_object_t *src) {
sol_object_t *cur = src;
while(cur) {
if(cur->mkey) {
sol_map_set(state, dest, cur->mkey, cur->mval);
}
cur = cur->mnext;
}
dsl_seq_iter *iter = dsl_new_seq_iter(src->seq);
if(!dsl_seq_iter_is_invalid(iter)) do {
sol_map_set(state, dest, AS_OBJ(dsl_seq_iter_at(iter))->key, AS_OBJ(dsl_seq_iter_at(iter))->val);
} while(dsl_seq_iter_next(iter));
dsl_free_seq_iter(iter);
}
void sol_map_merge_existing(sol_state_t *state, sol_object_t *dest, sol_object_t *src) {
sol_object_t *cur = src;
while(cur) {
if(cur->mkey) {
sol_map_set_existing(state, dest, cur->mkey, cur->mval);
}
cur = cur->mnext;
}
dsl_seq_iter *iter = dsl_new_seq_iter(src->seq);
if(!dsl_seq_iter_is_invalid(iter)) do {
sol_map_set_existing(state, dest, AS_OBJ(dsl_seq_iter_at(iter))->key, AS_OBJ(dsl_seq_iter_at(iter))->val);
} while(dsl_seq_iter_next(iter));
dsl_free_seq_iter(iter);
}
sol_object_t *sol_f_map_free(sol_state_t *state, sol_object_t *map) {
sol_object_t *cur = map, *prev;
while(cur) {
if(cur->mkey) {
sol_obj_free(cur->mkey);
sol_obj_free(cur->mval);
}
prev = cur;
cur = cur->mnext;
if(prev!=map) free(prev);
}
dsl_free_seq(map->seq);
return map;
}
sol_object_t *sol_f_mcell_free(sol_state_t *state, sol_object_t *mcell) {
if(mcell->mkey) sol_obj_free(mcell->mkey);
if(mcell->mval) sol_obj_free(mcell->mval);
if(mcell->key) sol_obj_free(mcell->key);
if(mcell->val) sol_obj_free(mcell->val);
return mcell;
}
int sol_validate_map(sol_state_t *state, sol_object_t *map) {
/*int sol_validate_map(sol_state_t *state, sol_object_t *map) {
sol_object_t *cur = map;
int i = 0;
char msg[128];
@ -652,7 +436,7 @@ int sol_validate_map(sol_state_t *state, sol_object_t *map) {
i++;
}
return 0;
}
}*/
sol_object_t *sol_new_cfunc(sol_state_t *state, sol_cfunc_t cfunc) {
sol_object_t *res = sol_alloc_object(state);
@ -669,3 +453,28 @@ sol_object_t *sol_new_cdata(sol_state_t *state, void *cdata, sol_ops_t *ops) {
res->cdata = cdata;
return res;
}
sol_object_t *sol_new_buffer(sol_state_t *state, void *buffer, ssize_t sz, sol_owntype_t own, sol_freefunc_t freef, sol_movefunc_t movef) {
sol_object_t *res = sol_alloc_object(state);
res->type = SOL_BUFFER;
res->ops = &(state->BufferOps);
res->buffer = buffer;
res->sz = sz;
res->own = own;
res->freef = freef;
res->movef = movef;
return res;
}
sol_object_t *sol_f_buffer_free(sol_state_t *state, sol_object_t *buf) {
switch(buf->own) {
case OWN_FREE:
free(buf->buffer);
break;
case OWN_CALLF:
buf->freef(buf->buffer, buf->sz);
break;
}
return buf;
}

108
runtime.c

@ -1,5 +1,6 @@
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include "ast.h"
expr_node *sol_comp_as_expr(stmt_node *stmt) {
@ -162,11 +163,13 @@ void ex_free(expr_node *expr) {
free(expr);
}
sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
#define ERR_CHECK(state) do { if(sol_has_error(state)) longjmp(jmp, 1); } while(0)
sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
sol_object_t *res, *left, *right, *lint, *rint, *value, *list;
exprlist_node *cure;
assoclist_node *cura;
if(!expr) return sol_set_error_string(state, "Evaluate NULL expression");
ERR_CHECK(state);
switch(expr->type) {
case EX_LIT:
switch(expr->lit->type) {
@ -192,7 +195,8 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
res = sol_new_list(state);
cure = expr->listgen->list;
while(cure) {
if(cure->expr) sol_list_insert(state, res, sol_list_len(state, res), sol_eval(state, cure->expr));
if(cure->expr) sol_list_insert(state, res, sol_list_len(state, res), sol_eval_inner(state, cure->expr, jmp));
ERR_CHECK(state);
cure = cure->next;
}
return res;
@ -202,7 +206,8 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
res = sol_new_map(state);
cura = expr->mapgen->map;
while(cura) {
if(cura->item) sol_map_set(state, res, sol_eval(state, cura->item->key), sol_eval(state, cura->item->value));
if(cura->item) sol_map_set(state, res, sol_eval(state, cura->item->key), sol_eval_inner(state, cura->item->value, jmp));
ERR_CHECK(state);
cura = cura->next;
}
return res;
@ -210,8 +215,11 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
case EX_BINOP:
list = sol_new_list(state);
left = sol_eval(state, expr->binop->left);
right = sol_eval(state, expr->binop->right);
ERR_CHECK(state);
left = sol_eval_inner(state, expr->binop->left, jmp);
ERR_CHECK(state);
right = sol_eval_inner(state, expr->binop->right, jmp);
ERR_CHECK(state);
sol_list_insert(state, list, 0, left);
sol_list_insert(state, list, 1, right);
switch(expr->binop->type) {
@ -253,7 +261,9 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
case OP_LAND:
lint = sol_cast_int(state, left);
ERR_CHECK(state);
rint = sol_cast_int(state, right);
ERR_CHECK(state);
res = sol_new_int(state, BOOL_TO_INT(lint && rint));
sol_obj_free(lint);
sol_obj_free(rint);
@ -261,7 +271,9 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
case OP_LOR:
lint = sol_cast_int(state, left);
ERR_CHECK(state);
rint = sol_cast_int(state, right);
ERR_CHECK(state);
res = sol_new_int(state, BOOL_TO_INT(lint || rint));
sol_obj_free(lint);
sol_obj_free(rint);
@ -298,12 +310,15 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
sol_obj_free(list);
sol_obj_free(left);
sol_obj_free(right);
ERR_CHECK(state);
return res;
break;
case EX_UNOP:
left = sol_eval(state, expr->unop->expr);
left = sol_eval_inner(state, expr->unop->expr, jmp);
ERR_CHECK(state);
list = sol_new_list(state);
ERR_CHECK(state);
sol_list_insert(state, list, 0, left);
switch(expr->unop->type) {
case OP_NEG:
@ -319,6 +334,7 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
case OP_LNOT:
lint = sol_cast_int(state, left);
ERR_CHECK(state);
res = sol_new_int(state, BOOL_TO_INT(!lint->ival));
sol_obj_free(lint);
break;
@ -329,27 +345,36 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
}
sol_obj_free(left);
sol_obj_free(list);
ERR_CHECK(state);
return res;
break;
case EX_INDEX:
left = sol_eval(state, expr->index->expr);
right = sol_eval(state, expr->index->index);
left = sol_eval_inner(state, expr->index->expr, jmp);
ERR_CHECK(state);
right = sol_eval_inner(state, expr->index->index, jmp);
ERR_CHECK(state);
list = sol_new_list(state);
ERR_CHECK(state);
sol_list_insert(state, list, 0, left);
sol_list_insert(state, list, 1, right);
res = left->ops->index(state, list);
sol_obj_free(left);
sol_obj_free(right);
sol_obj_free(list);
ERR_CHECK(state);
return res;
break;
case EX_SETINDEX:
left = sol_eval(state, expr->setindex->expr);
right = sol_eval(state, expr->setindex->index);
value = sol_eval(state, expr->setindex->value);
left = sol_eval_inner(state, expr->setindex->expr, jmp);
ERR_CHECK(state);
right = sol_eval_inner(state, expr->setindex->index, jmp);
ERR_CHECK(state);
value = sol_eval_inner(state, expr->setindex->value, jmp);
ERR_CHECK(state);
list = sol_new_list(state);
ERR_CHECK(state);
sol_list_insert(state, list, 0, left);
sol_list_insert(state, list, 1, right);
sol_list_insert(state, list, 2, value);
@ -358,12 +383,14 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
sol_obj_free(right);
sol_obj_free(value);
sol_obj_free(list);
ERR_CHECK(state);
return res;
break;
case EX_ASSIGN:
value = sol_eval(state, expr->assign->value);
value = sol_eval_inner(state, expr->assign->value, jmp);
sol_state_assign_l_name(state, expr->assign->ident, value);
ERR_CHECK(state);
return value;
break;
@ -372,24 +399,30 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
break;
case EX_CALL:
value = sol_eval(state, expr->call->expr);
value = sol_eval_inner(state, expr->call->expr, jmp);
ERR_CHECK(state);
list = sol_new_list(state);
ERR_CHECK(state);
sol_list_insert(state, list, 0, value);
cure = expr->call->args;
while(cure) {
if(cure->expr) sol_list_insert(state, list, sol_list_len(state, list), sol_eval(state, cure->expr));
if(cure->expr) sol_list_insert(state, list, sol_list_len(state, list), sol_eval_inner(state, cure->expr, jmp));
ERR_CHECK(state);
cure = cure->next;
}
res = value->ops->call(state, list);
sol_obj_free(value);
sol_obj_free(list);
ERR_CHECK(state);
return res;
break;
case EX_FUNCDECL:
res = sol_new_func(state, expr->funcdecl->args, expr->funcdecl->body, expr->funcdecl->name);
ERR_CHECK(state);
if(expr->funcdecl->name) {
sol_state_assign_l_name(state, expr->funcdecl->name, res);
ERR_CHECK(state);
}
return res;
break;
@ -398,6 +431,15 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
return sol_incref(state->None);
}
sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
jmp_buf jmp;
if(!setjmp(jmp)) {
return sol_eval_inner(state, expr, jmp);
} else {
return sol_incref(state->None);
}
}
void sol_exec(sol_state_t *state, stmt_node *stmt) {
sol_object_t *value, *vint, *list, *iter, *item;
stmtlist_node *curs;
@ -497,32 +539,31 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
}
sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
sol_object_t *res, *scope, *value, *curo = args, *key;
sol_object_t *res, *scope, *value, *key;
identlist_node *curi;
while(curo && !curo->lvalue) curo = curo->lnext;
if(!curo) {
dsl_seq_iter *iter;
iter = dsl_new_seq_iter(args->seq);
if(!args || dsl_seq_iter_is_invalid(iter) || sol_is_none(state, args)) {
printf("WARNING: No parameters to function call (expecting function)\n");
return sol_incref(state->None);
}
value = curo->lvalue;
value = dsl_seq_iter_at(iter);
if(!value || !sol_is_func(value)) {
printf("WARNING: Function call without function as first parameter\n");
return sol_incref(state->None);
}
if(!value->func) return sol_incref(state->None);
curo = curo->lnext;
while(curo && !curo->lvalue) curo = curo->lnext;
dsl_seq_iter_next(iter);
scope = sol_map_copy(state, value->closure);
curi = AS(value->args, identlist_node);
while(curi) {
if(curi->ident) {
key = sol_new_string(state, curi->ident);
if(!(curo && curo->lvalue)) {
if(dsl_seq_iter_is_invalid(iter)) {
sol_map_set(state, scope, key, sol_incref(state->None));
} else {
sol_map_set(state, scope, key, curo->lvalue);
curo = curo->lnext;
while(curo && !curo->lvalue) curo = curo->lnext;
sol_map_set(state, scope, key, dsl_seq_iter_at(iter));
dsl_seq_iter_next(iter);
}
sol_obj_free(key);
curi = curi->next;
@ -554,7 +595,26 @@ sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_n
obj->args = identlist;
obj->fname = (name?strdup(name):NULL);
obj->closure = sol_new_map(state);
obj->udata = sol_new_map(state);
obj->type = SOL_FUNCTION;
obj->ops = &(state->FuncOps);
return obj;
}
sol_object_t *sol_new_stmtnode(sol_state_t *state, stmt_node *stmt) {
sol_object_t *obj = sol_alloc_object(state);
if(sol_has_error(state)) return sol_incref(state->None);
obj->type = SOL_STMT;
obj->ops = &(state->ASTNodeOps);
obj->node = stmt;
return obj;
}
sol_object_t *sol_new_exprnode(sol_state_t *state, expr_node *expr) {
sol_object_t *obj = sol_alloc_object(state);
if(sol_has_error(state)) return sol_incref(state->None);
obj->type = SOL_EXPR;
obj->ops = &(state->ASTNodeOps);
obj->node = expr;
return obj;
}

107
sol.h

@ -5,6 +5,8 @@
#define NULL ((void *) 0)
#endif
#include "dsl/dsl.h"
// Forward declarations:
struct sol_tag_object_t;
typedef struct sol_tag_object_t sol_object_t;
@ -46,18 +48,46 @@ typedef enum {
SOL_FLOAT,
SOL_STRING,
SOL_LIST,
SOL_LCELL,
SOL_MAP,
SOL_MCELL,
SOL_FUNCTION,
SOL_CFUNCTION,
SOL_STMT,
SOL_EXPR,
SOL_BUFFER,
SOL_CDATA
} sol_objtype_t;
typedef enum {
FR_CALL,
FR_STMT
} sol_frametype_t;
BUF_NONE,
BUF_INT8,
BUF_INT16,
BUF_INT32,
BUF_INT64,
BUF_UINT8,
BUF_UINT16,
BUF_UINT32,
BUF_UINT64,
BUF_CHAR,
BUF_BYTE,
BUF_INT,
BUF_UINT,
BUF_LONG,
BUF_ULONG,
BUF_FLOAT,
BUF_DOUBLE,
BUF_CSTR,
BUF_PTR
} sol_buftype_t;
typedef enum {
OWN_NONE,
OWN_FREE,
OWN_CALLF
} sol_owntype_t;
typedef void (*sol_freefunc_t)(void *, size_t);
typedef void *(*sol_movefunc_t)(void *, size_t);
typedef struct sol_tag_object_t {
sol_objtype_t type;
@ -67,22 +97,27 @@ typedef struct sol_tag_object_t {
long ival;
double fval;
char *str;
dsl_seq *seq;
struct {
struct sol_tag_object_t *lvalue;
struct sol_tag_object_t *lnext;
};
struct {
struct sol_tag_object_t *mkey;
struct sol_tag_object_t *mval;
struct sol_tag_object_t *mnext;
struct sol_tag_object_t *key;
struct sol_tag_object_t *val;
};
struct {
void *func; // Actually a stmt_node *
void *args; // Actually an identlist_node *
struct sol_tag_object_t *closure;
struct sol_tag_object_t *udata;
char *fname;
};
sol_cfunc_t cfunc;
void *node;
struct {
void *buffer;
ssize_t sz;
sol_owntype_t own;
sol_freefunc_t freef;
sol_movefunc_t movef;
};
void *cdata;
};
} sol_object_t;
@ -102,12 +137,15 @@ typedef struct sol_tag_state_t {
sol_ops_t FloatOps;
sol_ops_t StringOps;
sol_ops_t ListOps;
sol_ops_t LCellOps;
sol_ops_t MapOps;
sol_ops_t MCellOps;
sol_ops_t FuncOps;
sol_ops_t CFuncOps;
sol_ops_t ASTNodeOps;
sol_ops_t BufferOps;
sol_object_t *ListFuncs;
sol_object_t *BufferFuncs;
dsl_object_funcs obfuncs;
} sol_state_t;
// state.c
@ -142,6 +180,7 @@ sol_object_t *sol_f_toint(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_tofloat(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_try(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_error(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_type(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_prepr(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_print(sol_state_t *, sol_object_t *);
@ -149,8 +188,9 @@ sol_object_t *sol_f_rawget(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_rawset(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_range(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_exec(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_eval(sol_state_t *, sol_object_t *;);
sol_object_t *sol_f_eval(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_execfile(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_parse(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_debug_getref(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_debug_setref(sol_state_t *, sol_object_t *);
@ -195,6 +235,7 @@ sol_object_t *sol_f_str_mul(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_str_len(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_str_iter(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_str_cmp(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_str_index(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_str_toint(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_str_tofloat(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_str_tostring(sol_state_t *, sol_object_t *);
@ -230,11 +271,31 @@ sol_object_t *sol_f_func_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_cfunc_call(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_cfunc_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_astnode_call(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_astnode_index(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_astnode_setindex(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_astnode_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_index(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_new(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_get(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_set(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_address(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_size(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_fromstring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_fromobject(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_fromaddress(sol_state_t *, sol_object_t *);
// object.c
#define sol_incref(obj) (++((obj)->refcnt), obj)
#define sol_decref(obj) (--((obj)->refcnt))
sol_object_t *sol_obj_acquire(sol_object_t *);
void sol_obj_free(sol_object_t *);
void sol_obj_release(sol_object_t *);
@ -244,22 +305,30 @@ void sol_obj_release(sol_object_t *);
#define sol_is_int(obj) ((obj)-> type == SOL_INTEGER)
#define sol_is_float(obj) ((obj)->type == SOL_FLOAT)
#define sol_is_string(obj) ((obj)->type == SOL_STRING)
#define sol_is_list(obj) ((obj)->type == SOL_LIST || (obj)->type == SOL_LCELL)
#define sol_is_list(obj) ((obj)->type == SOL_LIST)
#define sol_is_map(obj) ((obj)->type == SOL_MAP || (obj)->type == SOL_MCELL)
#define sol_is_func(obj) ((obj)->type == SOL_FUNCTION)
#define sol_is_cfunc(obj) ((obj)->type == SOL_CFUNCTION)
#define sol_is_aststmt(obj) ((obj)->type == SOL_STMT)
#define sol_is_astexpr(obj) ((obj)->type == SOL_EXPR)
#define sol_is_astnode(obj) (sol_is_aststmt(obj) || sol_is_astexpr(obj))
#define sol_is_buffer(obj) ((obj)->type == SOL_BUFFER)
#define sol_is_cdata(obj) ((obj)->type == SOL_CDATA)
#define sol_has_error(state) (!sol_is_none((state), (state)->error))
sol_object_t *sol_alloc_object(sol_state_t *);
sol_object_t *sol_new_singlet(sol_state_t *);
sol_object_t *sol_new_singlet(sol_state_t *, const char *);
sol_object_t *sol_new_int(sol_state_t *, long);
sol_object_t *sol_new_float(sol_state_t *, double);
sol_object_t *sol_new_string(sol_state_t *, const char *);
int sol_string_cmp(sol_state_t *, sol_object_t *, const char *);
#define sol_string_eq(state, string, cstr) (sol_string_cmp((state), (string), (cstr))==0)
sol_object_t *sol_new_list(sol_state_t *);
sol_object_t *sol_list_from_seq(sol_state_t *, dsl_seq *);
int sol_list_len(sol_state_t *, sol_object_t *);
sol_object_t *sol_list_sublist(sol_state_t *, sol_object_t *, int);
sol_object_t *sol_list_get_index(sol_state_t *, sol_object_t *, int);
@ -275,6 +344,7 @@ void sol_list_append(sol_state_t *, sol_object_t *, sol_object_t *);
sol_object_t *sol_new_map(sol_state_t *);
int sol_map_len(sol_state_t *, sol_object_t *);
sol_object_t *sol_map_mcell(sol_state_t *, sol_object_t *, sol_object_t *);
int sol_map_has(sol_state_t *, sol_object_t *, sol_object_t *);
sol_object_t *sol_map_get(sol_state_t *, sol_object_t *, sol_object_t *);
sol_object_t *sol_map_get_name(sol_state_t *, sol_object_t *, char *);
void sol_map_set(sol_state_t *, sol_object_t *, sol_object_t *, sol_object_t *);
@ -286,17 +356,20 @@ void sol_map_merge_existing(sol_state_t *, sol_object_t *, sol_object_t *);
// Defined in ast.h
// sol_object_t *sol_new_func(sol_state_t *, identlist_node *, stmt_node *, char *);
// sol_object_t *sol_new_stmtnode(sol_state_t *, stmt_node *);
// sol_object_t *sol_new_exprnode(sol_state_t *, expr_node *);
sol_object_t *sol_new_cfunc(sol_state_t *, sol_cfunc_t);
sol_object_t *sol_new_cdata(sol_state_t *, void *, sol_ops_t *);
sol_object_t *sol_new_buffer(sol_state_t *, void *, ssize_t, sol_owntype_t, sol_freefunc_t, sol_movefunc_t);
sol_object_t *sol_cast_int(sol_state_t *, sol_object_t *);
sol_object_t *sol_cast_float(sol_state_t *, sol_object_t *);
sol_object_t *sol_cast_string(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_str_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_lcell_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_map_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_mcell_free(sol_state_t *, sol_object_t *);
@ -307,4 +380,6 @@ int sol_validate_map(sol_state_t *, sol_object_t *);
sol_object_t *sol_util_call(sol_state_t *, sol_object_t *, int *, int, ...);
#define AS_OBJ(x) ((sol_object_t *) (x))
#endif

1
solrun.c

@ -37,6 +37,7 @@ int main(int argc, char **argv) {
printf("\n");
}
//st_free(program);
sol_state_cleanup(&state);
return 0;
}

199
state.c

@ -1,7 +1,8 @@
#include "sol.h"
#include <stdint.h>
#include "ast.h"
int sol_state_init(sol_state_t *state) {
sol_object_t *globals, *debug, *iter;
sol_object_t *globals, *debug, *iter, *ast, *buffer, *btype, *bsize;
state->None = NULL;
state->OutOfMemory = NULL;
@ -11,9 +12,9 @@ int sol_state_init(sol_state_t *state) {
state->sflag = SF_NORMAL;
// If any of the following fail, some very weird things are happening.
if(!(state->None = sol_new_singlet(state))) goto cleanup;
if(!(state->OutOfMemory = sol_new_singlet(state))) goto cleanup;
if(!(state->StopIteration = sol_new_singlet(state))) goto cleanup;
if(!(state->None = sol_new_singlet(state, "None"))) goto cleanup;
if(!(state->OutOfMemory = sol_new_singlet(state, "OutOfMemory"))) goto cleanup;
if(!(state->StopIteration = sol_new_singlet(state, "StopIteration"))) goto cleanup;
// We can now use the normal error reporting mechanism, now
// that errors are distinguishable. Set that up now.
@ -26,11 +27,12 @@ int sol_state_init(sol_state_t *state) {
state->FloatOps = state->NullOps;
state->StringOps = state->NullOps;
state->ListOps = state->NullOps;
state->LCellOps = state->NullOps;
state->MapOps = state->NullOps;
state->MCellOps = state->NullOps;
state->FuncOps = state->NullOps;
state->CFuncOps = state->NullOps;
state->ASTNodeOps = state->NullOps;
state->BufferOps = state->NullOps;
state->IntOps.add = sol_f_int_add;
state->IntOps.sub = sol_f_int_sub;
@ -60,6 +62,7 @@ int sol_state_init(sol_state_t *state) {
state->StringOps.add = sol_f_str_add;
state->StringOps.mul = sol_f_str_mul;
state->StringOps.cmp = sol_f_str_cmp;
state->StringOps.index = sol_f_str_index;
state->StringOps.len = sol_f_str_len;
state->StringOps.iter = sol_f_str_iter;
state->StringOps.toint = sol_f_str_toint;
@ -77,9 +80,6 @@ int sol_state_init(sol_state_t *state) {
state->ListOps.tostring = sol_f_list_tostring;
state->ListOps.free = sol_f_list_free;
state->LCellOps = state->ListOps;
state->LCellOps.free = sol_f_lcell_free;
state->MapOps.add = sol_f_map_add;
state->MapOps.call = sol_f_map_call;
state->MapOps.index = sol_f_map_index;
@ -99,6 +99,18 @@ int sol_state_init(sol_state_t *state) {
state->CFuncOps.call = sol_f_cfunc_call;
state->CFuncOps.tostring = sol_f_cfunc_tostring;
state->ASTNodeOps.call = sol_f_astnode_call;
state->ASTNodeOps.index = sol_f_astnode_index;
state->ASTNodeOps.setindex = sol_f_astnode_setindex;
state->ASTNodeOps.tostring = sol_f_astnode_tostring;
state->BufferOps.index = sol_f_buffer_index;
state->BufferOps.tostring = sol_f_buffer_tostring;
state->BufferOps.free = sol_f_buffer_free;
state->obfuncs.copy = (dsl_copier) sol_obj_acquire;
state->obfuncs.destr = (dsl_destructor) sol_obj_free;
state->error = state->None;
state->scopes = sol_new_list(state);
@ -106,6 +118,10 @@ int sol_state_init(sol_state_t *state) {
globals = sol_new_map(state);
debug = sol_new_map(state);
iter = sol_new_map(state);
ast = sol_new_map(state);
btype = sol_new_map(state);
bsize = sol_new_map(state);
buffer = sol_new_map(state);
if(sol_has_error(state)) goto cleanup;
sol_list_insert(state, state->scopes, 0, globals);
if(sol_has_error(state)) goto cleanup;
@ -116,6 +132,7 @@ int sol_state_init(sol_state_t *state) {
sol_map_set_name(state, globals, "tofloat", sol_new_cfunc(state, sol_f_tofloat));
sol_map_set_name(state, globals, "tostring", sol_new_cfunc(state, sol_f_tostring));
sol_map_set_name(state, globals, "try", sol_new_cfunc(state, sol_f_try));
sol_map_set_name(state, globals, "error", sol_new_cfunc(state, sol_f_error));
sol_map_set_name(state, globals, "type", sol_new_cfunc(state, sol_f_type));
sol_map_set_name(state, globals, "prepr", sol_new_cfunc(state, sol_f_prepr));
sol_map_set_name(state, globals, "print", sol_new_cfunc(state, sol_f_print));
@ -125,6 +142,7 @@ int sol_state_init(sol_state_t *state) {
sol_map_set_name(state, globals, "exec", sol_new_cfunc(state, sol_f_exec));
sol_map_set_name(state, globals, "eval", sol_new_cfunc(state, sol_f_eval));
sol_map_set_name(state, globals, "execfile", sol_new_cfunc(state, sol_f_execfile));
sol_map_set_name(state, globals, "parse", sol_new_cfunc(state, sol_f_parse));
sol_map_set_name(state, debug, "getref", sol_new_cfunc(state, sol_f_debug_getref));
sol_map_set_name(state, debug, "setref", sol_new_cfunc(state, sol_f_debug_setref));
@ -140,6 +158,87 @@ int sol_state_init(sol_state_t *state) {
sol_map_set_name(state, iter, "map", sol_new_cfunc(state, sol_f_iter_map));
sol_map_set_name(state, globals, "iter", iter);
sol_obj_free(iter);
sol_map_set_name(state, ast, "ST_EXPR", sol_new_int(state, ST_EXPR));
sol_map_set_name(state, ast, "ST_IFELSE", sol_new_int(state, ST_IFELSE));
sol_map_set_name(state, ast, "ST_LOOP", sol_new_int(state, ST_LOOP));
sol_map_set_name(state, ast, "ST_ITER", sol_new_int(state, ST_ITER));
sol_map_set_name(state, ast, "ST_LIST", sol_new_int(state, ST_LIST));
sol_map_set_name(state, ast, "ST_RET", sol_new_int(state, ST_RET));
sol_map_set_name(state, ast, "ST_CONT", sol_new_int(state, ST_CONT));
sol_map_set_name(state, ast, "ST_BREAK", sol_new_int(state, ST_BREAK));
sol_map_set_name(state, ast, "EX_LIT", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "EX_LISTGEN", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "EX_MAPGEN", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "EX_BINOP", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "EX_UNOP", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "EX_INDEX", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "EX_SETINDEX", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "EX_ASSIGN", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "EX_REF", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "EX_CALL", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "EX_FUNCDECL", sol_new_int(state, EX_LIT));
sol_map_set_name(state, ast, "OP_ADD", sol_new_int(state, OP_ADD));
sol_map_set_name(state, ast, "OP_SUB", sol_new_int(state, OP_SUB));
sol_map_set_name(state, ast, "OP_MUL", sol_new_int(state, OP_MUL));
sol_map_set_name(state, ast, "OP_DIV", sol_new_int(state, OP_DIV));
sol_map_set_name(state, ast, "OP_MOD", sol_new_int(state, OP_MOD));
sol_map_set_name(state, ast, "OP_POW", sol_new_int(state, OP_POW));