Browse Source

Sol Part 24: Harry Kwanzuhannamas!

master
Graham Northup 7 years ago
parent
commit
4df3383ccc
  1. 1
      .gitignore
  2. 2
      astprint.c
  3. 3
      build.sh
  4. 361
      builtins.c
  5. 1
      dummypow.c
  6. 175
      object.c
  7. 6
      runtime.c
  8. 111
      sol.h
  9. 366
      state.c
  10. 51
      test.sol

1
.gitignore

@ -1,2 +1,3 @@
sol
*.o
stdout

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('\t');
for(i = 0; i < lev; i++) { putchar('|'); putchar(' '); }
va_start(vl, fmt);
vprintf(fmt, vl);
va_end(vl);

3
build.sh

@ -10,5 +10,4 @@ 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
gcc -g *.o -o sol -lm -ldl

361
builtins.c

@ -3,11 +3,14 @@
#include <stdio.h>
#include <math.h>
#include <stdint.h>
#include <dlfcn.h>
#include "ast.h"
#include "dsl/dsl.h"
// XXX hardcoded buffer sizes
#define STDIO_CHUNK_SIZE 4096
static char *_itoa(int i) {
int n = 33;
char *s = malloc(n);
@ -34,6 +37,20 @@ sol_object_t *sol_f_default_cmp(sol_state_t *state, sol_object_t *args) {
return res;
}
sol_object_t *sol_f_default_tostring(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0);
char s[64];
snprintf(s, 64, "<%s object at %p>", obj->ops->tname, obj);
sol_obj_free(obj);
return sol_new_string(state, s);
}
sol_object_t *sol_f_default_repr(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *res = obj->ops->tostring(state, args);
sol_obj_free(obj);
return res;
}
sol_object_t *sol_f_no_op(sol_state_t *state, sol_object_t *args) {
if(state) return sol_incref(state->None);
return NULL;
@ -94,33 +111,38 @@ sol_object_t *sol_f_error(sol_state_t *state, sol_object_t *args) {
return res;
}
static char *sol_TypeNames[] = {"singlet", "integer", "float", "string", "list", "map", "mapcell", "function", "cfunction", "cdata"};
sol_object_t *sol_f_type(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0);
sol_object_t *res = sol_new_string(state, sol_TypeNames[obj->type]);
sol_object_t *res = sol_new_string(state, obj->ops->tname);
sol_obj_free(obj);
return res;
}
static dsl_seq *seen=NULL;
void ob_print(sol_object_t *obj) {
sol_object_t *cur;
int test_seen(sol_object_t *obj) {
dsl_seq_iter *iter;
int i;
if(seen) {
iter = dsl_new_seq_iter(seen);
while(!dsl_seq_iter_is_invalid(iter)) {
if(dsl_seq_iter_at(iter) == obj) {
printf("... (%p)", obj);
return;
return 1;
}
dsl_seq_iter_next(iter);
}
dsl_free_seq_iter(iter);
dsl_seq_insert(seen, dsl_seq_len(seen), obj);
}
return 0;
}
void ob_print(sol_object_t *obj) {
sol_object_t *cur;
dsl_seq_iter *iter;
int i;
if(test_seen(obj)) {
return;
}
switch(obj->type) {
case SOL_SINGLET:
printf("%s", obj->str);
@ -223,25 +245,25 @@ sol_object_t *sol_f_prepr(sol_state_t *state, sol_object_t *args) {
}
printf("\n");
dsl_free_seq(seen);
seen = NULL;
return sol_incref(state->None);
}
sol_object_t *sol_f_print(sol_state_t *state, sol_object_t *args) {
int i, sz = sol_list_len(state, args);
sol_object_t *obj;
sol_object_t *obj, *str;
seen = dsl_seq_new_array(NULL, NULL);
for(i=0; i<sz; i++) {
obj = sol_list_get_index(state, args, i);
if(sol_is_string(obj)) {
printf("%s", obj->str);
} else {
ob_print(obj);
}
printf(" ");
str = sol_cast_string(state, obj);
sol_printf(state, "%s", str->str);
sol_printf(state, " ");
sol_obj_free(obj);
sol_obj_free(str);
}
printf("\n");
sol_printf(state, "\n");
dsl_free_seq(seen);
seen = NULL;
return sol_incref(state->None);
}
@ -455,6 +477,12 @@ sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) {
return res;
}
sol_object_t *sol_f_singlet_tostring(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *res = sol_new_string(state, obj->str);
sol_obj_free(obj);
return res;
}
sol_object_t *sol_f_int_add(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
sol_object_t *res = sol_new_int(state, a->ival + b->ival);
@ -664,12 +692,9 @@ sol_object_t *sol_f_float_tostring(sol_state_t *state, sol_object_t *args) {
sol_object_t *sol_f_str_add(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_string(state, sol_list_get_index(state, args, 1));
int n = strlen(a->str) + strlen(b->str) + 1;
char *s = malloc(n);
sol_object_t *res = sol_new_string(state, strncat(strncpy(s, a->str, n), b->str, n));
sol_object_t *res = sol_string_concat(state, a, b);
sol_obj_free(a);
sol_obj_free(b);
free(s);
if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
return res;
}
@ -738,6 +763,15 @@ sol_object_t *sol_f_str_tostring(sol_state_t *state, sol_object_t *args) {
return sol_list_get_index(state, args, 0);
}
sol_object_t *sol_f_str_repr(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *cur = sol_new_string(state, "\""), *next = sol_string_concat(state, cur, obj);
sol_obj_free(cur);
cur = next;
next = sol_string_concat_cstr(state, cur, "\"");
sol_obj_free(cur);
return next;
}
sol_object_t *sol_f_list_add(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ls;
if(!sol_is_list(b)) {
@ -774,9 +808,11 @@ sol_object_t *sol_f_list_mul(sol_state_t *state, sol_object_t *args) {
sol_object_t *sol_f_list_index(sol_state_t *state, sol_object_t *args) {
sol_object_t *ls = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ival;
sol_object_t *res;
sol_object_t *res, *funcs;
if(sol_is_string(b)) {
res = sol_map_get(state, state->ListFuncs, b);
funcs = sol_get_methods_name(state, "list");
res = sol_map_get(state, funcs, b);
sol_obj_free(funcs);
} else {
ival = sol_cast_int(state, b);
res = sol_list_get_index(state, ls, ival->ival);
@ -809,7 +845,32 @@ sol_object_t *sol_f_list_iter(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_list_tostring(sol_state_t *state, sol_object_t *args) {
return sol_new_string(state, "<List>");
sol_object_t *cur = sol_new_string(state, "["), *next, *str, *obj = sol_list_get_index(state, args, 0), *item;
dsl_seq_iter *iter = dsl_new_seq_iter(obj->seq);
char s[64];
while(!dsl_seq_iter_is_invalid(iter)) {
item = AS_OBJ(dsl_seq_iter_at(iter));
if(test_seen(item)) {
snprintf(s, 64, "... (%p)", item);
next = sol_string_concat_cstr(state, cur, s);
} else {
str = sol_cast_repr(state, item);
next = sol_string_concat(state, cur, str);
sol_obj_free(str);
}
sol_obj_free(cur);
cur = next;
if(!dsl_seq_iter_at_end(iter)) {
next = sol_string_concat_cstr(state, cur, ", ");
sol_obj_free(cur);
cur = next;
}
dsl_seq_iter_next(iter);
}
next = sol_string_concat_cstr(state, cur, "]");
sol_obj_free(cur);
dsl_free_seq_iter(iter);
return next;
}
sol_object_t *sol_f_list_copy(sol_state_t *state, sol_object_t *args) {
@ -986,7 +1047,62 @@ sol_object_t *sol_f_map_iter(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_map_tostring(sol_state_t *state, sol_object_t *args) {
return sol_new_string(state, "<Map>");
sol_object_t *cur = sol_new_string(state, "{"), *next, *str, *obj = sol_list_get_index(state, args, 0), *item;
dsl_seq_iter *iter = dsl_new_seq_iter(obj->seq);
char s[64];
while(!dsl_seq_iter_is_invalid(iter)) {
item = AS_OBJ(dsl_seq_iter_at(iter));
if(test_seen(item)) {
snprintf(s, 64, "... (%p)", item);
next = sol_string_concat_cstr(state, cur, s);
} else {
str = sol_cast_repr(state, item);
next = sol_string_concat(state, cur, str);
sol_obj_free(str);
}
sol_obj_free(cur);
cur = next;
if(!dsl_seq_iter_at_end(iter)) {
next = sol_string_concat_cstr(state, cur, ", ");
sol_obj_free(cur);
cur = next;
}
dsl_seq_iter_next(iter);
}
next = sol_string_concat_cstr(state, cur, "}");
sol_obj_free(cur);
dsl_free_seq_iter(iter);
sol_obj_free(obj);
return next;
}
sol_object_t *sol_f_mcell_tostring(sol_state_t *state, sol_object_t *args) {
sol_object_t *mcell = sol_list_get_index(state, args, 0), *cur = sol_new_string(state, "["), *next, *str;
char s[64];
if(test_seen(mcell->key)) {
snprintf(s, 64, "... (%p)", mcell->key);
next = sol_string_concat_cstr(state, cur, s);
} else {
str = sol_cast_repr(state, mcell->key);
next = sol_string_concat(state, cur, str);
sol_obj_free(str);
}
sol_obj_free(cur);
cur = next;
next = sol_string_concat_cstr(state, cur, "] = ");
sol_obj_free(cur);
cur = next;
if(test_seen(mcell->val)) {
snprintf(s, 64, "... (%p)", mcell->val);
next = sol_string_concat_cstr(state, cur, s);
} else {
str = sol_cast_repr(state, mcell->val);
next = sol_string_concat(state, cur, str);
sol_obj_free(str);
}
sol_obj_free(cur);
sol_obj_free(mcell);
return next;
}
sol_object_t *sol_f_func_index(sol_state_t *state, sol_object_t *args) {
@ -1047,7 +1163,11 @@ sol_object_t *sol_f_func_setindex(sol_state_t *state, sol_object_t *args) {
sol_object_t *sol_f_func_tostring(sol_state_t *state, sol_object_t *args) {
sol_object_t *func = sol_list_get_index(state, args, 0), *ret;
char *s = malloc(256 * sizeof(char));
snprintf(s, 256, "<Function %s>", func->fname);
if(func->fname) {
snprintf(s, 256, "<Function %s>", func->fname);
} else {
snprintf(s, 256, "<Function>");
}
ret = sol_new_string(state, s);
free(s);
sol_obj_free(func);
@ -1578,8 +1698,10 @@ sol_object_t *sol_f_astnode_tostring(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_buffer_index(sol_state_t *state, sol_object_t *args) {
sol_object_t *key = sol_list_get_index(state, args, 1), *res = sol_map_get(state, state->BufferFuncs, key);
sol_object_t *key = sol_list_get_index(state, args, 1), *funcs = sol_get_methods_name(state, "buffer");
sol_object_t *res = sol_map_get(state, funcs, key);
sol_obj_free(key);
sol_obj_free(funcs);
return res;
}
@ -1872,4 +1994,191 @@ sol_object_t *sol_f_buffer_fromaddress(sol_state_t *state, sol_object_t *args) {
sol_obj_free(iaddr);
sol_obj_free(isz);
return buf;
}
sol_object_t *sol_f_dylib_index(sol_state_t *state, sol_object_t *args) {
sol_object_t *dylib = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *skey = sol_cast_string(state, key);
void *handle = dlsym(dylib->dlhandle, skey->str);
sol_obj_free(dylib);
sol_obj_free(key);
sol_obj_free(skey);
if(handle) {
return sol_new_dysym(state, handle, NULL, BUF_NONE);
} else {
return sol_incref(state->None);
}
}
sol_object_t *sol_f_dylib_tostring(sol_state_t *state, sol_object_t *args) {
return sol_new_string(state, "<DyLib>");
}
sol_object_t *sol_f_dysym_call(sol_state_t *state, sol_object_t *args) {
//TODO
return sol_incref(state->None);
}
sol_object_t *sol_f_dysym_index(sol_state_t *state, sol_object_t *args) {
//TODO
return sol_incref(state->None);
}
sol_object_t *sol_f_dysym_setindex(sol_state_t *state, sol_object_t *args) {
//TODO
return sol_incref(state->None);
}
sol_object_t *sol_f_dysym_tostring(sol_state_t *state, sol_object_t *args) {
return sol_new_string(state, "<DySym>");
}
sol_object_t *sol_f_stream_blsh(sol_state_t *state, sol_object_t *args) {
return sol_f_stream_write(state, args);
}
sol_object_t *sol_f_stream_brsh(sol_state_t *state, sol_object_t *args) {
return sol_f_stream_read(state, args);
}
sol_object_t *sol_f_stream_index(sol_state_t *state, sol_object_t *args) {
sol_object_t *key = sol_list_get_index(state, args, 1), *funcs = sol_get_methods_name(state, "stream");
sol_object_t *res = sol_map_get(state, funcs, key);
sol_obj_free(key);
sol_obj_free(funcs);
return res;
}
sol_object_t *sol_f_stream_tostring(sol_state_t *state, sol_object_t *args) {
return sol_new_string(state, "<Stream>");
}
sol_object_t *sol_f_stream_write(sol_state_t *state, sol_object_t *args) {
sol_object_t *stream = sol_list_get_index(state, args, 0), *obj = sol_list_get_index(state, args, 1), *str = sol_cast_string(state, obj);
size_t sz = sol_stream_printf(state, stream, "%s", str->str);
sol_obj_free(obj);
sol_obj_free(str);
sol_obj_free(stream);
return sol_new_int(state, sz);
}
sol_object_t *sol_f_stream_read(sol_state_t *state, sol_object_t *args) {
sol_object_t *stream = sol_list_get_index(state, args, 0), *amt = sol_list_get_index(state, args, 1), *iamt, *res;
char *s=NULL, *p;
size_t count=0, max=0, pos, end;
if(sol_is_string(amt)) {
if(sol_string_eq(state, amt, "ALL")) {
pos = sol_stream_ftell(state, stream);
sol_stream_fseek(state, stream, 0, SEEK_END);
end = sol_stream_ftell(state, stream);
sol_stream_fseek(state, stream, pos, SEEK_SET);
//printf("IO: Reading %ld bytes starting at %ld\n", end-pos, pos);
s = malloc((end-pos+1)*sizeof(char));
if(sol_stream_fread(state, stream, s, sizeof(char), end-pos)<(end-pos)) {
free(s);
sol_obj_free(stream);
sol_obj_free(amt);
return sol_set_error_string(state, "IO read error");
}
s[end-pos]='\0';
} else if(sol_string_eq(state, amt, "LINE")) {
s = malloc(STDIO_CHUNK_SIZE*sizeof(char));
sol_stream_fgets(state, stream, s, STDIO_CHUNK_SIZE);
}
} else {
iamt = sol_cast_int(state, amt);
s = malloc((iamt->ival + 1)*sizeof(char));
count = sol_stream_fread(state, stream, s, sizeof(char), iamt->ival);
s[iamt->ival]='\0';
sol_obj_free(iamt);
}
if(s) {
//printf("IO: Read result: %s\n", s);
res = sol_new_string(state, s);
free(s);
} else {
//printf("IO: No read result!\n");
res = sol_incref(state->None);
}
sol_obj_free(amt);
sol_obj_free(stream);
return res;
}
sol_object_t *sol_f_stream_seek(sol_state_t *state, sol_object_t *args) {
sol_object_t *stream = sol_list_get_index(state, args, 0), *offset = sol_list_get_index(state, args, 1), *whence = sol_list_get_index(state, args, 2);
sol_object_t *ioffset = sol_cast_int(state, offset), *iwhence = sol_cast_int(state, whence);
sol_object_t *res = sol_new_int(state, sol_stream_fseek(state, stream, ioffset->ival, iwhence->ival));
sol_obj_free(stream);
sol_obj_free(offset);
sol_obj_free(whence);
sol_obj_free(ioffset);
sol_obj_free(iwhence);
return res;
}
sol_object_t *sol_f_stream_tell(sol_state_t *state, sol_object_t *args) {
sol_object_t *stream = sol_list_get_index(state, args, 0), *res = sol_new_int(state, sol_stream_ftell(state, stream));
sol_obj_free(stream);
return res;
}
sol_object_t *sol_f_stream_flush(sol_state_t *state, sol_object_t *args) {
sol_object_t *stream = sol_list_get_index(state, args, 0), *res = sol_new_int(state, sol_stream_fflush(state, stream));
sol_obj_free(stream);
return res;
}
static char *sol_FileModes[]={
NULL,
"r",
"w",
"r+",
NULL,
NULL,
"a",
"a+",
NULL,
NULL,
"w",
"w+",
NULL,
NULL,
NULL,
NULL,
NULL,
"rb",
"wb",
"r+b",
NULL,
NULL,
"ab",
"a+b",
NULL,
NULL,
"wb",
"w+b",
NULL,
NULL,
NULL,
NULL
};
sol_object_t *sol_f_stream_open(sol_state_t *state, sol_object_t *args) {
sol_object_t *fn = sol_list_get_index(state, args, 0), *mode = sol_list_get_index(state, args, 1);
sol_object_t *sfn = sol_cast_string(state, fn), *imode = sol_cast_int(state, mode);
sol_modes_t m = imode->ival;
char *smode = sol_FileModes[m];
FILE *f;
sol_obj_free(mode);
sol_obj_free(imode);
if(!smode) {
sol_obj_free(fn);
sol_obj_free(sfn);
return sol_set_error_string(state, "Bad file open mode");
}
f = fopen(sfn->str, smode);
sol_obj_free(sfn);
sol_obj_free(fn);
if(!f) return sol_set_error_string(state, "File open failed");
return sol_new_stream(state, f, m);
}

1
dummypow.c

@ -1 +0,0 @@
double pow(double a, double b) { return 0.0; }

175
object.c

@ -4,6 +4,8 @@
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <dlfcn.h>
#include <stdarg.h>
sol_object_t *sol_cast_int(sol_state_t *state, sol_object_t *obj) {
sol_object_t *res, *ls;
@ -12,7 +14,6 @@ sol_object_t *sol_cast_int(sol_state_t *state, sol_object_t *obj) {
sol_list_insert(state, ls, 0, obj);
res = obj->ops->toint(state, ls);
sol_obj_free(ls);
sol_obj_free(obj);
return res;
}
@ -23,7 +24,6 @@ sol_object_t *sol_cast_float(sol_state_t *state, sol_object_t *obj) {
sol_list_insert(state, ls, 0, obj);
res = obj->ops->tofloat(state, ls);
sol_obj_free(ls);
sol_obj_free(obj);
return res;
}
@ -34,7 +34,14 @@ sol_object_t *sol_cast_string(sol_state_t *state, sol_object_t *obj) {
sol_list_insert(state, ls, 0, obj);
res = obj->ops->tostring(state, ls);
sol_obj_free(ls);
sol_obj_free(obj);
return res;
}
sol_object_t *sol_cast_repr(sol_state_t *state, sol_object_t *obj) {
sol_object_t *res, *ls = sol_new_list(state);
sol_list_insert(state, ls, 0, obj);
res = obj->ops->repr(state, ls);
sol_obj_free(ls);
return res;
}
@ -45,7 +52,7 @@ sol_object_t *sol_new_singlet(sol_state_t *state, const char *name) {
if(res) {
res->type = SOL_SINGLET;
res->refcnt = 0;
res->ops = &(state->NullOps);
res->ops = &(state->SingletOps);
res->str = strdup(name);
}
return sol_incref(res);
@ -139,6 +146,24 @@ int sol_string_cmp(sol_state_t *state, sol_object_t *str, const char *s) {
return strcmp(str->str, s);
}
sol_object_t *sol_string_concat(sol_state_t *state, sol_object_t *a, sol_object_t *b) {
sol_object_t *res, *sa = sol_cast_string(state, a), *sb = sol_cast_string(state, b);
int n = strlen(sa->str) + strlen(sb->str) + 1;
char *s = malloc(n);
res = sol_new_string(state, strncat(strncpy(s, a->str, n), b->str, n));
sol_obj_free(sa);
sol_obj_free(sb);
free(s);
return res;
}
sol_object_t *sol_string_concat_cstr(sol_state_t *state, sol_object_t *a, char *s) {
sol_object_t *b = sol_new_string(state, s);
sol_object_t *res = sol_string_concat(state, a, b);
sol_obj_free(b);
return res;
}
sol_object_t *sol_f_str_free(sol_state_t *state, sol_object_t *obj) {
free(obj->str);
return obj;
@ -288,6 +313,7 @@ sol_object_t *sol_new_map(sol_state_t *state) {
map->type = SOL_MAP;
map->ops = &(state->MapOps);
map->seq = dsl_seq_new_array(NULL, &(state->obfuncs));
sol_init_object(state, map);
return map;
}
@ -305,8 +331,14 @@ int sol_map_len(sol_state_t *state, sol_object_t *map) {
}
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), *cmp, *icmp, *res = NULL;
dsl_seq_iter *iter = dsl_new_seq_iter(map->seq);
sol_object_t *list, *cmp, *icmp, *res = NULL;
dsl_seq_iter *iter;
if(!sol_is_map(map)) {
printf("WARNING: Attempt to index non-map as map\n");
return sol_incref(state->None);
}
list = sol_new_list(state);
iter = dsl_new_seq_iter(map->seq);
if(sol_has_error(state)) {
dsl_free_seq_iter(iter);
sol_obj_free(list);
@ -406,6 +438,19 @@ void sol_map_merge_existing(sol_state_t *state, sol_object_t *dest, sol_object_t
dsl_free_seq_iter(iter);
}
void sol_map_invert(sol_state_t *state, sol_object_t *map) {
dsl_seq *pairs = dsl_seq_copy(map->seq);
dsl_seq_iter *iter = dsl_new_seq_iter(pairs);
sol_object_t *mcell;
while(!dsl_seq_iter_is_invalid(iter)) {
mcell = dsl_seq_iter_at(iter);
sol_map_set(state, map, mcell->val, mcell->key);
dsl_seq_iter_next(iter);
}
dsl_free_seq_iter(iter);
dsl_free_seq(pairs);
}
sol_object_t *sol_f_map_free(sol_state_t *state, sol_object_t *map) {
dsl_free_seq(map->seq);
return map;
@ -443,6 +488,7 @@ sol_object_t *sol_new_cfunc(sol_state_t *state, sol_cfunc_t cfunc) {
res->type = SOL_CFUNCTION;
res->ops = &(state->CFuncOps);
res->cfunc = cfunc;
sol_init_object(state, res);
return res;
}
@ -451,6 +497,7 @@ sol_object_t *sol_new_cdata(sol_state_t *state, void *cdata, sol_ops_t *ops) {
res->type = SOL_CDATA;
res->ops = ops;
res->cdata = cdata;
sol_init_object(state, res);
return res;
}
@ -463,6 +510,7 @@ sol_object_t *sol_new_buffer(sol_state_t *state, void *buffer, ssize_t sz, sol_o
res->own = own;
res->freef = freef;
res->movef = movef;
sol_init_object(state, res);
return res;
}
@ -478,3 +526,118 @@ sol_object_t *sol_f_buffer_free(sol_state_t *state, sol_object_t *buf) {
}
return buf;
}
sol_object_t *sol_new_dylib(sol_state_t *state, void *handle) {
sol_object_t *res = sol_alloc_object(state);
res->type = SOL_DYLIB;
res->ops = &(state->DyLibOps);
res->dlhandle = handle;
sol_init_object(state, res);
return res;
}
sol_object_t *sol_f_dylib_free(sol_state_t *state, sol_object_t *dylib) {
dlclose(dylib->dlhandle);
return dylib;
}
sol_object_t *sol_new_dysym(sol_state_t *state, void *sym, dsl_seq *argtp, sol_buftype_t rettp) {
sol_object_t *res = sol_alloc_object(state);
res->type = SOL_DYSYM;
res->ops = &(state->DySymOps);
res->dlsym = sym;
if(argtp) {
res->argtp = dsl_seq_copy(argtp);
} else {
res->argtp = dsl_seq_new_array(NULL, &(state->obfuncs));
}
res->rettp = rettp;
sol_init_object(state, res);
return res;
}
sol_object_t *sol_new_stream(sol_state_t *state, FILE *stream, sol_modes_t modes) {
sol_object_t *res = sol_alloc_object(state);
res->type = SOL_STREAM;
res->ops = &(state->StreamOps);
res->stream = stream;
res->modes = modes;
sol_init_object(state, res);
return res;
}
size_t sol_stream_printf(sol_state_t *state, sol_object_t *stream, const char *fmt, ...) {
va_list va;
size_t res;
if(!(stream->modes & MODE_WRITE)) {
sol_obj_free(sol_set_error_string(state, "Write to non-writable stream"));
return 0;
}
va_start(va, fmt);
res = vfprintf(stream->stream, fmt, va);
va_end(va);
return res;
}
size_t sol_stream_scanf(sol_state_t *state, sol_object_t *stream, const char *fmt, ...) {
va_list va;
size_t res;
if(!(stream->modes & MODE_READ)) {
sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
return 0;
}
va_start(va, fmt);
res = vfscanf(stream->stream, fmt, va);
va_end(va);
return res;
}
size_t sol_stream_fread(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz, size_t memb) {
if(!(stream->modes & MODE_READ)) {
sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
return 0;
}
return fread(buffer, sz, memb, stream->stream);
}
size_t sol_stream_fwrite(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz, size_t memb) {
if(!(stream->modes & MODE_WRITE)) {
sol_obj_free(sol_set_error_string(state, "Write to non-writable stream"));
return 0;
}
return fwrite(buffer, sz, memb, stream->stream);
}
char *sol_stream_fgets(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz) {
if(!(stream->modes & MODE_READ)) {
sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
return NULL;
}
return fgets(buffer, sz, stream->stream);
}
int sol_stream_feof(sol_state_t *state, sol_object_t *stream) {
return feof(stream->stream);
}
int sol_stream_ferror(sol_state_t *state, sol_object_t *stream) {
return ferror(stream->stream);
}
int sol_stream_fseek(sol_state_t *state, sol_object_t *stream, long offset, int whence) {
return fseek(stream->stream, offset, whence);
}
long sol_stream_ftell(sol_state_t *state, sol_object_t *stream) {
return ftell(stream->stream);
}
int sol_stream_fflush(sol_state_t *state, sol_object_t *stream) {
return fflush(stream->stream);
}
sol_object_t *sol_f_stream_free(sol_state_t *state, sol_object_t *stream) {
//printf("IO: Closing open file\n");
fclose(stream->stream);
return stream;
}

6
runtime.c

@ -252,7 +252,7 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
break;
case OP_BOR:
res = left->ops->bor(state, list); printf("BINOP\n"); ob_print(list); printf("\n");
res = left->ops->bor(state, list);
break;
case OP_BXOR:
@ -535,6 +535,10 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
case ST_BREAK:
state->sflag = SF_BREAKING;
break;
default:
printf("WARNING: Unhandled statement\n");
break;
}
}

111
sol.h

@ -5,6 +5,7 @@
#define NULL ((void *) 0)
#endif
#include <stdio.h>
#include "dsl/dsl.h"
// Forward declarations:
@ -16,7 +17,10 @@ typedef struct sol_tag_state_t sol_state_t;
typedef sol_object_t *(*sol_cfunc_t)(sol_state_t *, sol_object_t *);
typedef void (*sol_printfunc_t)(sol_object_t *);
typedef struct {
char *tname;
sol_cfunc_t add;
sol_cfunc_t sub;
sol_cfunc_t mul;
@ -38,6 +42,7 @@ typedef struct {
sol_cfunc_t toint;
sol_cfunc_t tofloat;
sol_cfunc_t tostring;
sol_cfunc_t repr;
sol_cfunc_t init;
sol_cfunc_t free;
} sol_ops_t;
@ -55,6 +60,9 @@ typedef enum {
SOL_STMT,
SOL_EXPR,
SOL_BUFFER,
SOL_DYLIB,
SOL_DYSYM,
SOL_STREAM,
SOL_CDATA
} sol_objtype_t;
@ -86,6 +94,14 @@ typedef enum {
OWN_CALLF
} sol_owntype_t;
typedef enum {
MODE_READ = 1,
MODE_WRITE = 2,
MODE_APPEND = 4,
MODE_TRUNCATE = 8,
MODE_BINARY = 16
} sol_modes_t;
typedef void (*sol_freefunc_t)(void *, size_t);
typedef void *(*sol_movefunc_t)(void *, size_t);
@ -118,6 +134,16 @@ typedef struct sol_tag_object_t {
sol_freefunc_t freef;
sol_movefunc_t movef;
};
void *dlhandle;
struct {
void *dlsym;
dsl_seq *argtp;
sol_buftype_t rettp;
};
struct {
FILE *stream;
sol_modes_t modes;
};
void *cdata;
};
} sol_object_t;
@ -133,6 +159,7 @@ typedef struct sol_tag_state_t {
sol_object_t *OutOfMemory;
sol_object_t *StopIteration;
sol_ops_t NullOps;
sol_ops_t SingletOps;
sol_ops_t IntOps;
sol_ops_t FloatOps;
sol_ops_t StringOps;
@ -143,8 +170,11 @@ typedef struct sol_tag_state_t {
sol_ops_t CFuncOps;
sol_ops_t ASTNodeOps;
sol_ops_t BufferOps;
sol_object_t *ListFuncs;
sol_object_t *BufferFuncs;
sol_ops_t DyLibOps;
sol_ops_t DySymOps;
sol_ops_t StreamOps;
sol_object_t *modules;
sol_object_t *methods;
dsl_object_funcs obfuncs;
} sol_state_t;
@ -168,6 +198,19 @@ sol_object_t *sol_set_error(sol_state_t *, sol_object_t *);
sol_object_t *sol_set_error_string(sol_state_t *, const char *);
void sol_clear_error(sol_state_t *);
void sol_register_module(sol_state_t *, sol_object_t *, sol_object_t *);
void sol_register_module_name(sol_state_t *, char *, sol_object_t *);
sol_object_t *sol_get_module(sol_state_t *, sol_object_t *);
sol_object_t *sol_get_module_name(sol_state_t *, char *);
void sol_register_methods(sol_state_t *, sol_object_t *, sol_object_t *);
void sol_register_methods_name(sol_state_t *, char *, sol_object_t *);
sol_object_t *sol_get_methods(sol_state_t *, sol_object_t *);
sol_object_t *sol_get_methods_name(sol_state_t *, char *);
sol_object_t *sol_get_stdin(sol_state_t *);
sol_object_t *sol_get_stdout(sol_state_t *);
sol_object_t *sol_get_stderr(sol_state_t *);
void sol_ops_init(sol_ops_t *);
// builtins.c
@ -175,6 +218,8 @@ void sol_ops_init(sol_ops_t *);
sol_object_t *sol_f_not_impl(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_no_op(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_default_cmp(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_default_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_default_repr(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_toint(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_tofloat(sol_state_t *, sol_object_t *);
@ -203,6 +248,8 @@ sol_object_t *sol_f_iter_str(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_iter_list(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_iter_map(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_singlet_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_int_add(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_int_sub(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_int_mul(sol_state_t *, sol_object_t *);
@ -239,6 +286,7 @@ 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 *);
sol_object_t *sol_f_str_repr(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_add(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_mul(sol_state_t *, sol_object_t *);
@ -263,6 +311,8 @@ sol_object_t *sol_f_map_len(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_map_iter(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_map_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_mcell_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_func_call(sol_state_t *, sol_object_t *); // Defined in ast.c
sol_object_t *sol_f_func_index(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_func_setindex(sol_state_t *, sol_object_t *);
@ -278,17 +328,42 @@ 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_new(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 *);
sol_object_t *sol_f_dylib_index(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_dylib_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_dylib_open(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_dysym_call(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_dysym_index(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_dysym_setindex(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_dysym_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_dysym_get(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_dysym_set(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_blsh(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_brsh(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_index(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_write(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_read(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_seek(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_tell(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_flush(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_open(sol_state_t *, sol_object_t *);
// object.c
@ -326,6 +401,8 @@ 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_string_concat(sol_state_t *, sol_object_t *, sol_object_t *);
sol_object_t *sol_string_concat_cstr(sol_state_t *, sol_object_t *, char *);
sol_object_t *sol_new_list(sol_state_t *);
sol_object_t *sol_list_from_seq(sol_state_t *, dsl_seq *);
@ -353,6 +430,7 @@ void sol_map_set_existing(sol_state_t *, sol_object_t *, sol_object_t *, sol_obj
sol_object_t *sol_map_copy(sol_state_t *, sol_object_t *);
void sol_map_merge(sol_state_t *, sol_object_t *, sol_object_t *);
void sol_map_merge_existing(sol_state_t *, sol_object_t *, sol_object_t *);
void sol_map_invert(sol_state_t *, sol_object_t *);
// Defined in ast.h
// sol_object_t *sol_new_func(sol_state_t *, identlist_node *, stmt_node *, char *);
@ -364,14 +442,39 @@ 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_new_dylib(sol_state_t *, void *);
sol_object_t *sol_new_dysym(sol_state_t *, void *, dsl_seq *, sol_buftype_t);
sol_object_t *sol_new_stream(sol_state_t *, FILE *, sol_modes_t);
size_t sol_stream_printf(sol_state_t *, sol_object_t *, const char *, ...);
size_t sol_stream_scanf(sol_state_t *, sol_object_t *, const char *, ...);
size_t sol_stream_fread(sol_state_t *, sol_object_t *, char *, size_t, size_t);
size_t sol_stream_fwrite(sol_state_t *, sol_object_t *, char *, size_t, size_t);
char *sol_stream_fgets(sol_state_t *, sol_object_t *, char *, size_t);
#define sol_printf(state, ...) sol_stream_printf(state, sol_get_stdout(state), __VA_ARGS__)
#define sol_scanf(state, ...) sol_stream_scanf(state, sol_get_stdin(state, __VA_ARGS__)
#define sol_fread(state, ...) sol_stream_fread(state, sol_get_stdin(state), __VA_ARGS__)
#define sol_fwrite(state, ...) sol_stream_fwrite(state, sol_get_stdout(state), __VA_ARGS__)
int sol_stream_feof(sol_state_t *, sol_object_t *);
int sol_stream_ferror(sol_state_t *, sol_object_t *);
#define sol_stream_ready(state, stream) (!(sol_stream_feof((state), (stream)) || sol_stream_ferror((state), (stream))))
int sol_stream_fseek(sol_state_t *, sol_object_t *, long, int);
long sol_stream_ftell(sol_state_t *, sol_object_t *);
int sol_stream_fflush(sol_state_t *, sol_object_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_cast_repr(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_map_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_mcell_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_dylib_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_stream_free(sol_state_t *, sol_object_t *);
int sol_validate_list(sol_state_t *, sol_object_t *);
int sol_validate_map(sol_state_t *, sol_object_t *);

366
state.c

@ -1,8 +1,10 @@
#include <stdint.h>
#include <stdio.h>
#include "ast.h"
int sol_state_init(sol_state_t *state) {
sol_object_t *globals, *debug, *iter, *ast, *buffer, *btype, *bsize;
sol_object_t *globals, *mod, *meths;
sol_object_t *btype, *bsize, *bobj;
state->None = NULL;
state->OutOfMemory = NULL;
@ -22,7 +24,8 @@ int sol_state_init(sol_state_t *state) {
//Initialize all of the builtin operations
//(these ones are technically already pointed to by None/OOM)
sol_ops_init(&(state->NullOps));
state->SingletOps = state->NullOps;
state->IntOps = state->NullOps;
state->FloatOps = state->NullOps;
state->StringOps = state->NullOps;
@ -33,7 +36,14 @@ int sol_state_init(sol_state_t *state) {
state->CFuncOps = state->NullOps;
state->ASTNodeOps = state->NullOps;
state->BufferOps = state->NullOps;
state->DyLibOps = state->NullOps;
state->DySymOps = state->NullOps;
state->StreamOps = state->NullOps;
state->SingletOps.tname = "singlet";
state->SingletOps.tostring = sol_f_singlet_tostring;
state->IntOps.tname = "int";
state->IntOps.add = sol_f_int_add;
state->IntOps.sub = sol_f_int_sub;
state->IntOps.mul = sol_f_int_mul;
@ -49,7 +59,8 @@ int sol_state_init(sol_state_t *state) {
state->IntOps.toint = sol_f_int_toint;
state->IntOps.tofloat = sol_f_int_tofloat;
state->IntOps.tostring = sol_f_int_tostring;
state->FloatOps.tname = "float";
state->FloatOps.add = sol_f_float_add;
state->FloatOps.sub = sol_f_float_sub;
state->FloatOps.mul = sol_f_float_mul;
@ -58,7 +69,8 @@ int sol_state_init(sol_state_t *state) {
state->FloatOps.toint = sol_f_float_toint;
state->FloatOps.tofloat = sol_f_float_tofloat;
state->FloatOps.tostring = sol_f_float_tostring;
state->StringOps.tname = "string";
state->StringOps.add = sol_f_str_add;
state->StringOps.mul = sol_f_str_mul;
state->StringOps.cmp = sol_f_str_cmp;
@ -68,8 +80,10 @@ int sol_state_init(sol_state_t *state) {
state->StringOps.toint = sol_f_str_toint;
state->StringOps.tofloat = sol_f_str_tofloat;
state->StringOps.tostring = sol_f_str_tostring;
state->StringOps.repr = sol_f_str_repr;
state->StringOps.free = sol_f_str_free;
state->ListOps.tname = "list";
state->ListOps.add = sol_f_list_add;
state->ListOps.mul = sol_f_list_mul;
state->ListOps.call = sol_f_not_impl;
@ -79,7 +93,8 @@ int sol_state_init(sol_state_t *state) {
state->ListOps.iter = sol_f_list_iter;
state->ListOps.tostring = sol_f_list_tostring;
state->ListOps.free = sol_f_list_free;
state->MapOps.tname = "map";
state->MapOps.add = sol_f_map_add;
state->MapOps.call = sol_f_map_call;
state->MapOps.index = sol_f_map_index;
@ -88,27 +103,50 @@ int sol_state_init(sol_state_t *state) {
state->MapOps.iter = sol_f_map_iter;
state->MapOps.tostring = sol_f_map_tostring;
state->MapOps.free = sol_f_map_free;
state->MCellOps = state->MapOps;
state->MCellOps.tname = "mcell";
state->MCellOps.tostring = sol_f_mcell_tostring;
state->MCellOps.free = sol_f_mcell_free;
state->FuncOps.tname = "function";
state->FuncOps.call = sol_f_func_call;
state->FuncOps.index = sol_f_func_index;
state->FuncOps.setindex = sol_f_func_setindex;
state->FuncOps.tostring = sol_f_func_tostring;
state->CFuncOps.tname = "cfunction";
state->CFuncOps.call = sol_f_cfunc_call;
state->CFuncOps.tostring = sol_f_cfunc_tostring;
state->ASTNodeOps.tname = "astnode";
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.tname = "buffer";
state->BufferOps.index = sol_f_buffer_index;
state->BufferOps.tostring = sol_f_buffer_tostring;
state->BufferOps.free = sol_f_buffer_free;
state->DyLibOps.tname = "dylib";
state->DyLibOps.index = sol_f_dylib_index;
state->DyLibOps.free = sol_f_dylib_free;
state->DyLibOps.tostring = sol_f_dylib_tostring;
state->DySymOps.tname = "dysym";
state->DySymOps.call = sol_f_dysym_call;
state->DySymOps.index = sol_f_dysym_index;
state->DySymOps.setindex = sol_f_dysym_setindex;
state->DySymOps.tostring = sol_f_dysym_tostring;
state->StreamOps.tname = "stream";
state->StreamOps.blsh = sol_f_stream_blsh;
state->StreamOps.brsh = sol_f_stream_brsh;
state->StreamOps.index = sol_f_stream_index;
state->StreamOps.free = sol_f_stream_free;
state->StreamOps.tostring = sol_f_stream_tostring;
state->obfuncs.copy = (dsl_copier) sol_obj_acquire;
state->obfuncs.destr = (dsl_destructor) sol_obj_free;
@ -116,14 +154,11 @@ int sol_state_init(sol_state_t *state) {
state->scopes = sol_new_list(state);
if(sol_has_error(state)) goto cleanup;
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);
state->modules = sol_new_map(state);
state->methods = sol_new_map(state);
if(sol_has_error(state)) goto cleanup;
sol_list_insert(state, state->scopes, 0, globals);
sol_obj_free(globals);
if(sol_has_error(state)) goto cleanup;
// I'm going to buffer all of these together because I can.
sol_map_set_name(state, globals, "OutOfMemory", state->OutOfMemory);
@ -143,65 +178,71 @@ int sol_state_init(sol_state_t *state) {
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));
sol_map_set_name(state, debug, "closure", sol_new_cfunc(state, sol_f_debug_closure));
sol_map_set_name(state, debug, "globals", sol_new_cfunc(state, sol_f_debug_globals));
sol_map_set_name(state, debug, "locals", sol_new_cfunc(state, sol_f_debug_locals));
sol_map_set_name(state, debug, "scopes", sol_new_cfunc(state, sol_f_debug_scopes));
sol_map_set_name(state, globals, "debug", debug);
sol_obj_free(debug);
sol_map_set_name(state, iter, "str", sol_new_cfunc(state, sol_f_iter_str));
sol_map_set_name(state, iter, "list", sol_new_cfunc(state, sol_f_iter_list));
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));
sol_map_set_name(state, ast, "OP_BAND", sol_new_int(state, OP_BAND));
sol_map_set_name(state, ast, "OP_BOR", sol_new_int(state, OP_BOR));
sol_map_set_name(state, ast, "OP_BXOR", sol_new_int(state, OP_BXOR));
sol_map_set_name(state, ast, "OP_LAND", sol_new_int(state, OP_LAND));
sol_map_set_name(state, ast, "OP_LOR", sol_new_int(state, OP_LOR));
sol_map_set_name(state, ast, "OP_EQUAL", sol_new_int(state, OP_EQUAL));
sol_map_set_name(state, ast, "OP_LESS", sol_new_int(state, OP_LESS));
sol_map_set_name(state, ast, "OP_GREATER", sol_new_int(state, OP_GREATER));
sol_map_set_name(state, ast, "OP_LESSEQ", sol_new_int(state, OP_LESSEQ));
sol_map_set_name(state, ast, "OP_GREATEREQ", sol_new_int(state, OP_GREATEREQ));
sol_map_set_name(state, ast, "OP_LSHIFT", sol_new_int(state, OP_LSHIFT));
sol_map_set_name(state, ast, "OP_RSHIFT", sol_new_int(state, OP_RSHIFT));
sol_map_set_name(state, ast, "OP_NEG", sol_new_int(state, OP_NEG));
sol_map_set_name(state, ast, "OP_BNOT", sol_new_int(state, OP_BNOT));
sol_map_set_name(state, ast, "OP_LNOT", sol_new_int(state, OP_LNOT));
sol_map_set_name(state, ast, "OP_LEN", sol_new_int(state, OP_LEN));
sol_map_set_name(state, globals, "ast", ast);
mod = sol_new_map(state);
sol_map_set_name(state, mod, "getref", sol_new_cfunc(state, sol_f_debug_getref));
sol_map_set_name(state, mod, "setref", sol_new_cfunc(state, sol_f_debug_setref));
sol_map_set_name(state, mod, "closure", sol_new_cfunc(state, sol_f_debug_closure));
sol_map_set_name(state, mod, "globals", sol_new_cfunc(state, sol_f_debug_globals));
sol_map_set_name(state, mod, "locals", sol_new_cfunc(state, sol_f_debug_locals));
sol_map_set_name(state, mod, "scopes", sol_new_cfunc(state, sol_f_debug_scopes));
sol_register_module_name(state, "debug", mod);
sol_obj_free(mod);
mod = sol_new_map(state);
sol_map_set_name(state, mod, "str", sol_new_cfunc(state, sol_f_iter_str));
sol_map_set_name(state, mod, "list", sol_new_cfunc(state, sol_f_iter_list));
sol_map_set_name(state, mod, "map", sol_new_cfunc(state, sol_f_iter_map));
sol_register_module_name(state, "iter", mod);
sol_obj_free(mod);
mod = sol_new_map(state);
sol_map_set_name(state, mod, "ST_EXPR", sol_new_int(state, ST_EXPR));
sol_map_set_name(state, mod, "ST_IFELSE", sol_new_int(state, ST_IFELSE));
sol_map_set_name(state, mod, "ST_LOOP", sol_new_int(state, ST_LOOP));
sol_map_set_name(state, mod, "ST_ITER", sol_new_int(state, ST_ITER));
sol_map_set_name(state, mod, "ST_LIST", sol_new_int(state, ST_LIST));
sol_map_set_name(state, mod, "ST_RET", sol_new_int(state, ST_RET));
sol_map_set_name(state, mod, "ST_CONT", sol_new_int(state, ST_CONT));
sol_map_set_name(state, mod, "ST_BREAK", sol_new_int(state, ST_BREAK));
sol_map_set_name(state, mod, "EX_LIT", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "EX_LISTGEN", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "EX_MAPGEN", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "EX_BINOP", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "EX_UNOP", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "EX_INDEX", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "EX_SETINDEX", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "EX_ASSIGN", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "EX_REF", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "EX_CALL", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "EX_FUNCDECL", sol_new_int(state, EX_LIT));
sol_map_set_name(state, mod, "OP_ADD", sol_new_int(state, OP_ADD));
sol_map_set_name(state, mod, "OP_SUB", sol_new_int(state, OP_SUB));
sol_map_set_name(state, mod, "OP_MUL", sol_new_int(state, OP_MUL));
sol_map_set_name(state, mod, "OP_DIV", sol_new_int(state, OP_DIV));
sol_map_set_name(state, mod, "OP_MOD", sol_new_int(state, OP_MOD));
sol_map_set_name(state, mod, "OP_POW", sol_new_int(state, OP_POW));
sol_map_set_name(state, mod, "OP_BAND", sol_new_int(state, OP_BAND));
sol_map_set_name(state, mod, "OP_BOR", sol_new_int(state, OP_BOR));
sol_map_set_name(state, mod, "OP_BXOR", sol_new_int(state, OP_BXOR));
sol_map_set_name(state, mod, "OP_LAND", sol_new_int(state, OP_LAND));
sol_map_set_name(state, mod, "OP_LOR", sol_new_int(state, OP_LOR));
sol_map_set_name(state, mod, "OP_EQUAL", sol_new_int(state, OP_EQUAL));
sol_map_set_name(state, mod, "OP_LESS", sol_new_int(state, OP_LESS));
sol_map_set_name(state, mod, "OP_GREATER", sol_new_int(state, OP_GREATER));
sol_map_set_name(state, mod, "OP_LESSEQ", sol_new_int(state, OP_LESSEQ));
sol_map_set_name(state, mod, "OP_GREATEREQ", sol_new_int(state, OP_GREATEREQ));
sol_map_set_name(state, mod, "OP_LSHIFT", sol_new_int(state, OP_LSHIFT));
sol_map_set_name(state, mod, "OP_RSHIFT", sol_new_int(state, OP_RSHIFT));
sol_map_set_name(state, mod, "OP_NEG", sol_new_int(state, OP_NEG));
sol_map_set_name(state, mod, "OP_BNOT", sol_new_int(state, OP_BNOT));
sol_map_set_name(state, mod, "OP_LNOT", sol_new_int(state, OP_LNOT));
sol_map_set_name(state, mod, "OP_LEN", sol_new_int(state, OP_LEN));
so