From 4df3383cccd3410d91e9b06d890249433cae573f Mon Sep 17 00:00:00 2001 From: Graham Northup Date: Wed, 3 Dec 2014 19:23:59 -0500 Subject: [PATCH] Sol Part 24: Harry Kwanzuhannamas! --- .gitignore | 1 + astprint.c | 2 +- build.sh | 3 +- builtins.c | 361 ++++++++++++++++++++++++++++++++++++++++++++++++---- dummypow.c | 1 - object.c | 175 ++++++++++++++++++++++++- runtime.c | 6 +- sol.h | 111 +++++++++++++++- state.c | 366 +++++++++++++++++++++++++++++++++++++++-------------- test.sol | 51 ++++++++ 10 files changed, 938 insertions(+), 139 deletions(-) delete mode 100644 dummypow.c diff --git a/.gitignore b/.gitignore index dbcc543..0e82342 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ sol *.o +stdout diff --git a/astprint.c b/astprint.c index 7229876..56fc36b 100644 --- a/astprint.c +++ b/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); diff --git a/build.sh b/build.sh index 552fb58..7cc45d9 100755 --- a/build.sh +++ b/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 diff --git a/builtins.c b/builtins.c index be95f9c..f01c42b 100644 --- a/builtins.c +++ b/builtins.c @@ -3,11 +3,14 @@ #include #include #include +#include #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; istr); - } 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, ""); + 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, ""); + 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, "", func->fname); + if(func->fname) { + snprintf(s, 256, "", func->fname); + } else { + snprintf(s, 256, ""); + } 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, ""); +} + +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, ""); +} + +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, ""); +} + +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); } \ No newline at end of file diff --git a/dummypow.c b/dummypow.c deleted file mode 100644 index 079cc36..0000000 --- a/dummypow.c +++ /dev/null @@ -1 +0,0 @@ -double pow(double a, double b) { return 0.0; } diff --git a/object.c b/object.c index 670ef44..d3ca90c 100644 --- a/object.c +++ b/object.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include 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; +} \ No newline at end of file diff --git a/runtime.c b/runtime.c index c4058f7..8a800dc 100644 --- a/runtime.c +++ b/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; } } diff --git a/sol.h b/sol.h index 405b317..59fc857 100644 --- a/sol.h +++ b/sol.h @@ -5,6 +5,7 @@ #define NULL ((void *) 0) #endif +#include #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 *); diff --git a/state.c b/state.c index 9fde208..68181fb 100644 --- a/state.c +++ b/state.c @@ -1,8 +1,10 @@ #include +#include #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)); + sol_map_invert(state, mod); + sol_register_module_name(state, "ast", mod); + + btype = sol_new_map(state); + sol_map_set_name(state, btype, "none", sol_new_int(state, BUF_NONE)); sol_map_set_name(state, btype, "uint8", sol_new_int(state, BUF_UINT8)); sol_map_set_name(state, btype, "uint16", sol_new_int(state, BUF_UINT16)); sol_map_set_name(state, btype, "uint32", sol_new_int(state, BUF_UINT32)); @@ -220,7 +261,9 @@ int sol_state_init(sol_state_t *state) { sol_map_set_name(state, btype, "double", sol_new_int(state, BUF_DOUBLE)); sol_map_set_name(state, btype, "cstr", sol_new_int(state, BUF_CSTR)); sol_map_set_name(state, btype, "ptr", sol_new_int(state, BUF_PTR)); + sol_map_invert(state, btype); + bsize = sol_new_map(state); sol_map_set_name(state, bsize, "uint8", sol_new_int(state, sizeof(uint8_t))); sol_map_set_name(state, bsize, "uint16", sol_new_int(state, sizeof(uint16_t))); sol_map_set_name(state, bsize, "uint32", sol_new_int(state, sizeof(uint32_t))); @@ -239,30 +282,84 @@ int sol_state_init(sol_state_t *state) { sol_map_set_name(state, bsize, "double", sol_new_int(state, sizeof(double))); sol_map_set_name(state, bsize, "cstr", sol_new_int(state, sizeof(char *))); sol_map_set_name(state, bsize, "ptr", sol_new_int(state, sizeof(void *))); - - state->ListFuncs = sol_new_map(state); - sol_map_set_name(state, state->ListFuncs, "copy", sol_new_cfunc(state, sol_f_list_copy)); - sol_map_set_name(state, state->ListFuncs, "insert", sol_new_cfunc(state, sol_f_list_insert)); - sol_map_set_name(state, state->ListFuncs, "remove", sol_new_cfunc(state, sol_f_list_remove)); - sol_map_set_name(state, state->ListFuncs, "truncate", sol_new_cfunc(state, sol_f_list_truncate)); - sol_map_set_name(state, state->ListFuncs, "map", sol_new_cfunc(state, sol_f_list_map)); - sol_map_set_name(state, state->ListFuncs, "filter", sol_new_cfunc(state, sol_f_list_filter)); - sol_map_set_name(state, globals, "list", state->ListFuncs); - state->BufferFuncs = sol_new_map(state); - sol_map_set_name(state, state->BufferFuncs, "new", sol_new_cfunc(state, sol_f_buffer_new)); - sol_map_set_name(state, state->BufferFuncs, "get", sol_new_cfunc(state, sol_f_buffer_get)); - sol_map_set_name(state, state->BufferFuncs, "set", sol_new_cfunc(state, sol_f_buffer_set)); - sol_map_set_name(state, state->BufferFuncs, "address", sol_new_cfunc(state, sol_f_buffer_address)); - sol_map_set_name(state, state->BufferFuncs, "size", sol_new_cfunc(state, sol_f_buffer_size)); - sol_map_set_name(state, state->BufferFuncs, "fromstring", sol_new_cfunc(state, sol_f_buffer_fromstring)); - sol_map_set_name(state, state->BufferFuncs, "fromobject", sol_new_cfunc(state, sol_f_buffer_fromobject)); - sol_map_set_name(state, state->BufferFuncs, "fromaddress", sol_new_cfunc(state, sol_f_buffer_fromaddress)); - sol_map_set_name(state, state->BufferFuncs, "type", btype); - sol_map_set_name(state, state->BufferFuncs, "size", bsize); - sol_map_set_name(state, globals, "buffer", state->BufferFuncs); + bobj = sol_new_map(state); + sol_map_set_name(state, bobj, "SOL_SINGLET", sol_new_int(state, SOL_SINGLET)); + sol_map_set_name(state, bobj, "SOL_INTEGER", sol_new_int(state, SOL_INTEGER)); + sol_map_set_name(state, bobj, "SOL_FLOAT", sol_new_int(state, SOL_FLOAT)); + sol_map_set_name(state, bobj, "SOL_STRING", sol_new_int(state, SOL_STRING)); + sol_map_set_name(state, bobj, "SOL_LIST", sol_new_int(state, SOL_LIST)); + sol_map_set_name(state, bobj, "SOL_MAP", sol_new_int(state, SOL_MAP)); + sol_map_set_name(state, bobj, "SOL_MCELL", sol_new_int(state, SOL_MCELL)); + sol_map_set_name(state, bobj, "SOL_FUNCTION", sol_new_int(state, SOL_FUNCTION)); + sol_map_set_name(state, bobj, "SOL_CFUNCTION", sol_new_int(state, SOL_CFUNCTION)); + sol_map_set_name(state, bobj, "SOL_STMT", sol_new_int(state, SOL_STMT)); + sol_map_set_name(state, bobj, "SOL_EXPR", sol_new_int(state, SOL_EXPR)); + sol_map_set_name(state, bobj, "SOL_BUFFER", sol_new_int(state, SOL_BUFFER)); + sol_map_set_name(state, bobj, "SOL_DYLIB", sol_new_int(state, SOL_DYLIB)); + sol_map_set_name(state, bobj, "SOL_DYSYM", sol_new_int(state, SOL_DYSYM)); + sol_map_set_name(state, bobj, "SOL_STREAM", sol_new_int(state, SOL_STREAM)); + sol_map_set_name(state, bobj, "SOL_CDATA", sol_new_int(state, SOL_CDATA)); + sol_map_invert(state, bobj); - sol_obj_free(globals); + mod = sol_new_map(state); + sol_map_set_name(state, mod, "new", sol_new_cfunc(state, sol_f_buffer_new)); + sol_map_set_name(state, mod, "fromstring", sol_new_cfunc(state, sol_f_buffer_fromstring)); + sol_map_set_name(state, mod, "fromobject", sol_new_cfunc(state, sol_f_buffer_fromobject)); + sol_map_set_name(state, mod, "fromaddress", sol_new_cfunc(state, sol_f_buffer_fromaddress)); + sol_map_set_name(state, mod, "type", btype); + sol_map_set_name(state, mod, "sizeof", bsize); + sol_map_set_name(state, mod, "objtype", bobj); + sol_register_module_name(state, "buffer", mod); + sol_obj_free(mod); + sol_obj_free(bobj); + sol_obj_free(bsize); + sol_obj_free(btype); + + mod = sol_new_map(state); + sol_map_set_name(state, mod, "MODE_READ", sol_new_int(state, MODE_READ)); + sol_map_set_name(state, mod, "MODE_WRITE", sol_new_int(state, MODE_WRITE)); + sol_map_set_name(state, mod, "MODE_APPEND", sol_new_int(state, MODE_APPEND)); + sol_map_set_name(state, mod, "MODE_TRUNCATE", sol_new_int(state, MODE_TRUNCATE)); + sol_map_set_name(state, mod, "MODE_BINARY", sol_new_int(state, MODE_BINARY)); + sol_map_set_name(state, mod, "SEEK_SET", sol_new_int(state, SEEK_SET)); + sol_map_set_name(state, mod, "SEEK_CUR", sol_new_int(state, SEEK_CUR)); + sol_map_set_name(state, mod, "SEEK_END", sol_new_int(state, SEEK_END)); + sol_map_set_name(state, mod, "ALL", sol_new_string(state, "ALL")); + sol_map_set_name(state, mod, "LINE", sol_new_string(state, "LINE")); + sol_map_set_name(state, mod, "stdin", sol_new_stream(state, stdin, MODE_READ)); + sol_map_set_name(state, mod, "stdout", sol_new_stream(state, stdout, MODE_WRITE)); + sol_map_set_name(state, mod, "stderr", sol_new_stream(state, stderr, MODE_WRITE)); + sol_map_set_name(state, mod, "open", sol_new_cfunc(state, sol_f_stream_open)); + sol_register_module_name(state, "io", mod); + sol_obj_free(mod); + + meths = sol_new_map(state); + sol_map_set_name(state, meths, "get", sol_new_cfunc(state, sol_f_buffer_get)); + sol_map_set_name(state, meths, "set", sol_new_cfunc(state, sol_f_buffer_set)); + sol_map_set_name(state, meths, "address", sol_new_cfunc(state, sol_f_buffer_address)); + sol_map_set_name(state, meths, "size", sol_new_cfunc(state, sol_f_buffer_size)); + sol_register_methods_name(state, "buffer", meths); + sol_obj_free(meths); + + meths = sol_new_map(state); + sol_map_set_name(state, meths, "copy", sol_new_cfunc(state, sol_f_list_copy)); + sol_map_set_name(state, meths, "insert", sol_new_cfunc(state, sol_f_list_insert)); + sol_map_set_name(state, meths, "remove", sol_new_cfunc(state, sol_f_list_remove)); + sol_map_set_name(state, meths, "truncate", sol_new_cfunc(state, sol_f_list_truncate)); + sol_map_set_name(state, meths, "map", sol_new_cfunc(state, sol_f_list_map)); + sol_map_set_name(state, meths, "filter", sol_new_cfunc(state, sol_f_list_filter)); + sol_register_methods_name(state, "list", meths); + sol_obj_free(meths); + + meths = sol_new_map(state); + sol_map_set_name(state, meths, "read", sol_new_cfunc(state, sol_f_stream_read)); + sol_map_set_name(state, meths, "write", sol_new_cfunc(state, sol_f_stream_write)); + sol_map_set_name(state, meths, "seek", sol_new_cfunc(state, sol_f_stream_seek)); + sol_map_set_name(state, meths, "tell", sol_new_cfunc(state, sol_f_stream_tell)); + sol_map_set_name(state, meths, "flush", sol_new_cfunc(state, sol_f_stream_flush)); + sol_register_methods_name(state, "stream", meths); + sol_obj_free(meths); if(sol_has_error(state)) goto cleanup; @@ -283,7 +380,8 @@ void sol_state_cleanup(sol_state_t *state) { sol_obj_free(state->OutOfMemory); sol_obj_free(state->StopIteration); sol_obj_free(state->ret); - sol_obj_free(state->ListFuncs); + sol_obj_free(state->modules); + sol_obj_free(state->methods); } sol_object_t *sol_state_resolve(sol_state_t *state, sol_object_t *key) { @@ -305,6 +403,11 @@ sol_object_t *sol_state_resolve(sol_state_t *state, sol_object_t *key) { } dsl_free_seq_iter(iter); sol_obj_free(args); + + temp = sol_get_module(state, key); + if(!sol_is_none(state, temp)) { + return temp; + } return sol_incref(state->None); } @@ -413,7 +516,73 @@ void sol_clear_error(sol_state_t *state) { sol_obj_free(olderr); } +void sol_register_module(sol_state_t *state, sol_object_t *key, sol_object_t *val) { + sol_map_set(state, state->modules, key, val); +} + +void sol_register_module_name(sol_state_t *state, char *name, sol_object_t *val) { + sol_map_set_name(state, state->modules, name, val); +} + +sol_object_t *sol_get_module(sol_state_t *state, sol_object_t *key) { + return sol_map_get(state, state->modules, key); +} + +sol_object_t *sol_get_module_name(sol_state_t *state, char *name) { + return sol_map_get_name(state, state->modules, name); +} + +void sol_register_methods(sol_state_t *state, sol_object_t *key, sol_object_t *val) { + sol_map_set(state, state->methods, key, val); +} + +void sol_register_methods_name(sol_state_t *state, char *name, sol_object_t *val) { + sol_map_set_name(state, state->methods, name, val); +} + +sol_object_t *sol_get_methods(sol_state_t *state, sol_object_t *key) { + return sol_map_get(state, state->methods, key); +} + +sol_object_t *sol_get_methods_name(sol_state_t *state, char *name) { + return sol_map_get_name(state, state->methods, name); +} + +sol_object_t *sol_get_stdin(sol_state_t *state) { + sol_object_t *io = sol_state_resolve_name(state, "io"); + sol_object_t *res = sol_map_get_name(state, io, "stdin"); + sol_obj_free(io); + if(sol_is_none(state, res)) { + printf("WARNING: No io.stdin, returning a new ref\n"); + return sol_new_stream(state, stdin, MODE_READ); + } + return res; +} + +sol_object_t *sol_get_stdout(sol_state_t *state) { + sol_object_t *io = sol_state_resolve_name(state, "io"); + sol_object_t *res = sol_map_get_name(state, io, "stdout"); + sol_obj_free(io); + if(sol_is_none(state, res)) { + printf("WARNING: No io.stdout, returning a new ref\n"); + return sol_new_stream(state, stdout, MODE_WRITE); + } + return res; +} + +sol_object_t *sol_get_stderr(sol_state_t *state) { + sol_object_t *io = sol_state_resolve_name(state, "io"); + sol_object_t *res = sol_map_get_name(state, io, "stderr"); + sol_obj_free(io); + if(sol_is_none(state, res)) { + printf("WARNING: No io.stderr, returning a new ref\n"); + return sol_new_stream(state, stderr, MODE_WRITE); + } + return res; +} + void sol_ops_init(sol_ops_t *ops) { + ops->tname = "unknown"; ops->add = sol_f_not_impl; ops->sub = sol_f_not_impl; ops->mul = sol_f_not_impl; @@ -433,7 +602,8 @@ void sol_ops_init(sol_ops_t *ops) { ops->iter = sol_f_not_impl; ops->toint = sol_f_not_impl; ops->tofloat = sol_f_not_impl; - ops->tostring = sol_f_not_impl; + ops->tostring = sol_f_default_tostring; + ops->repr = sol_f_default_repr; ops->init = sol_f_no_op; ops->free = sol_f_no_op; } diff --git a/test.sol b/test.sol index faa7e4b..cd449d2 100644 --- a/test.sol +++ b/test.sol @@ -304,8 +304,10 @@ print(e) print('--- Basic buffers') +print('(buffer.fromstring = ', buffer.fromstring, ')') b = buffer.fromstring("Hello, world!") print(b) +print('(b.get = ', b.get, ')') print(b:get(buffer.type.cstr)) b:set(buffer.type.char, "Q") b:set(buffer.type.char, "L", 2) @@ -316,5 +318,54 @@ print(b:get(buffer.type.uint32)) b:set(buffer.type.uint32, 1886545252) print(b:get(buffer.type.uint32)) print(b:get(buffer.type.cstr)) +q = buffer.fromaddress(b:address(), b:size()) +print(q:get(buffer.type.cstr)) +q:set(buffer.type.cstr, "Goodbye!") +print(q:get(buffer.type.cstr), b:get(buffer.type.cstr)) + +s = "A string!" +b = buffer.fromobject(s) +prepr(s) +print('...is a', buffer.objtype[b:get(buffer.type.int, 0)]) +print('(buffer.sizeof.ptr = ', buffer.sizeof.ptr, ')') +print('(buffer.sizeof.int = ', buffer.sizeof.int, ')') +print('(buffer.sizeof.int*2 = ', buffer.sizeof.int*2, ')') +print('(buffer.sizeof.int*2 + buffer.sizeof.ptr = ', buffer.sizeof.int*2 + (buffer.sizeof.ptr), ')') +print('...with value:', b:get(buffer.type.ptr, buffer.sizeof.int*2 + (buffer.sizeof.ptr)):get(buffer.type.cstr)) + +print('--- IO redirection') + +oldstdout = io.stdout +io.stdout = io.open('stdout', io.MODE_WRITE|io.MODE_TRUNCATE) + +print('A line!') +print('An object:', {a=1, b=2, c="turkey"}) +print('Something mysterious :o') +io.stdout:write('Writing directly to a file :D') +io.stdout:flush() + +io.stdout = oldstdout + +print('...restored stdout.') + +f = io.open('stdout', io.MODE_READ) +s = f:read(io.ALL) +print('Buffered output was:') +prepr(s) +f = None + +print('...second time.') + +io.stdout = io.open('stdout', io.MODE_WRITE|io.MODE_TRUNCATE) + +print('Hey there!') +print('l'+'ol'*32) +io.stdout:flush() + +io.stdout = oldstdout + +print('...restored.') +print('Output was:') +prepr(io.open('stdout', io.MODE_READ):read(io.ALL)) print('--- All done!')