diff --git a/Makefile b/Makefile index 2de36a55..858140c4 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ debug: $(GST_TARGET) gdb $(GST_TARGET) valgrind: $(GST_TARGET) - valgrind ./$(GST_TARGET) --leak-check=full + valgrind ./$(GST_TARGET) clean: rm $(GST_TARGET) || true diff --git a/client/main.c b/client/main.c index 1959a4e4..ab08e11e 100644 --- a/client/main.c +++ b/client/main.c @@ -6,64 +6,19 @@ #include #include -/* Parse a file and execute it */ -int debug_run(Gst *vm, FILE *in) { - char buffer[1024] = {0}; - const char *reader = buffer; - GstValue func; - GstParser p; +/* Compile and run an ast */ +int debug_compile_and_run(Gst *vm, GstValue ast) { GstCompiler c; - - gst_parser(&p, vm); - - /* Create do struct */ - GstArray *arr = gst_array(vm, 10); - gst_array_push(vm, arr, gst_string_cv(vm, "do")); - - /* Get and parse input until we have a full form */ - while (p.status != GST_PARSER_ERROR) { - if (*reader == '\0') { - if (!fgets(buffer, sizeof(buffer), in)) { - break; - } - reader = buffer; - } - reader += gst_parse_cstring(&p, reader); - if (gst_parse_hasvalue(&p)) - gst_array_push(vm, arr, gst_parse_consume(&p)); - } - - /* Turn array into tuple */ - GstValue *tup = gst_tuple_begin(vm, arr->count); - gst_memcpy(tup, arr->data, arr->count * sizeof(GstValue)); - vm->ret.type = GST_TUPLE; - vm->ret.data.tuple = gst_tuple_end(vm, tup); - - /* Check if file read in correctly */ - if (p.error) { - printf("Parse error: %s\n", p.error); - return 1; - } - - /* Check that parser is complete */ - if (p.status != GST_PARSER_FULL && p.status != GST_PARSER_ROOT) { - printf("Unexpected end of source\n"); - return 1; - } - + GstValue func; /* Try to compile generated AST */ gst_compiler(&c, vm); - func.type = GST_NIL; gst_compiler_usemodule(&c, "std"); - func.type = GST_FUNCTION; - func.data.function = gst_compiler_compile(&c, vm->ret); - + func = gst_wrap_function(gst_compiler_compile(&c, ast)); /* Check for compilation errors */ if (c.error) { printf("Compiler error: %s\n", c.error); return 1; } - /* Execute function */ if (gst_run(vm, func)) { if (vm->crash) { @@ -76,23 +31,101 @@ int debug_run(Gst *vm, FILE *in) { return 0; } -int main(int argc, const char **argv) { +/* Parse a file and execute it */ +int debug_run(Gst *vm, FILE *in) { + char buffer[1024] = {0}; + const char *reader = buffer; + GstValue ast; + GstValue *tup; + GstArray *arr; + GstParser p; + /* Init parser */ + gst_parser(&p, vm); + /* Create do struct */ + arr = gst_array(vm, 10); + gst_array_push(vm, arr, gst_string_cv(vm, "do")); + /* Get and parse input until we have a full form */ + while (p.status != GST_PARSER_ERROR) { + if (*reader == '\0') { + if (!fgets(buffer, sizeof(buffer), in)) { + break; + } + reader = buffer; + } + reader += gst_parse_cstring(&p, reader); + if (gst_parse_hasvalue(&p)) + gst_array_push(vm, arr, gst_parse_consume(&p)); + } + /* Turn array into tuple */ + tup = gst_tuple_begin(vm, arr->count); + gst_memcpy(tup, arr->data, arr->count * sizeof(GstValue)); + ast = gst_wrap_tuple(gst_tuple_end(vm, tup)); + /* Check if file read in correctly */ + if (p.error) { + printf("Parse error: %s\n", p.error); + return 1; + } + /* Check that parser is complete */ + if (p.status != GST_PARSER_FULL && p.status != GST_PARSER_ROOT) { + printf("Unexpected end of source\n"); + return 1; + } + return debug_compile_and_run(vm, ast); +} +/* A simple repl */ +int debug_repl(Gst *vm) { + char buffer[10] = {0}; + const char *reader = buffer; + GstParser p; + int reset; + for (;;) { + /* Init parser */ + gst_parser(&p, vm); + reset = 1; + while (p.status != GST_PARSER_ERROR && p.status != GST_PARSER_FULL) { + if (*reader == '\0') { + if (reset) + printf(">> "); + reset = 0; + if (!fgets(buffer, sizeof(buffer), stdin)) { + break; + } + reader = buffer; + } + reader += gst_parse_cstring(&p, reader); + } + /* Check if file read in correctly */ + if (p.error) { + printf("Parse error: %s\n", p.error); + continue; + } + /* Check that parser is complete */ + if (p.status != GST_PARSER_FULL && p.status != GST_PARSER_ROOT) { + printf("Unexpected end of source\n"); + continue; + } + if (0 == debug_compile_and_run(vm, gst_parse_consume(&p))) { + printf("%s\n", gst_to_string(vm, vm->ret)); + } + } +} + +int main(int argc, const char **argv) { Gst vm; int status = 0; + gst_init(&vm); gst_stl_load(&vm); - - const char *filename; - - // if (argc > 1) { - // filename = argv[1]; - //} else { - filename = "libs/stl.gst"; - //} - - FILE *f = fopen(filename, "rb"); - status = debug_run(&vm, f); + if (argc > 1) { + const char *filename; + FILE *f; + filename = argv[1]; + f = fopen(filename, "rb"); + status = debug_run(&vm, f); + } else { + status = debug_repl(&vm); + } gst_deinit(&vm); diff --git a/core/parse.c b/core/parse.c index 618037cc..97082548 100644 --- a/core/parse.c +++ b/core/parse.c @@ -422,7 +422,7 @@ static void dispatch_char(GstParser *p, uint8_t c) { } } /* Dispatch character to state */ - while (!done && (p->status == GST_PARSER_PENDING || p->status == GST_PARSER_ROOT)) { + while (!done) { GstParseState *top = parser_peek(p); switch (top->type) { case PTYPE_ROOT: diff --git a/core/stl.c b/core/stl.c index 7c0e08f2..3447f4a7 100644 --- a/core/stl.c +++ b/core/stl.c @@ -391,6 +391,21 @@ int gst_stl_serialize(Gst *vm) { /* TODO - add userdata to allow for manipulation of FILE pointers. */ +int gst_stl_open(Gst *vm) { + GstValue ret; + const uint8_t *fname = gst_to_string(vm, gst_arg(vm, 0)); + const uint8_t *fmode = gst_to_string(vm, gst_arg(vm, 1)); + FILE *f; + if (gst_count_args(vm) < 2) + gst_c_throwc(vm, "expected filename and filemode"); + f = fopen((const char *)fname, (const char *)fmode); + if (!f) + gst_c_throwc(vm, "could not open file"); + ret.type = GST_USERDATA; + ret.data.pointer = f; + gst_c_return(vm, ret); +} + /****/ /* Bootstraping */ /****/ @@ -421,6 +436,7 @@ static const GstModuleItem const std_module[] = { {"rawset", gst_stl_rawset}, {"error", gst_stl_error}, {"serialize", gst_stl_serialize}, + {"open", gst_stl_open}, {NULL, NULL} }; diff --git a/libs/stl.gst b/libs/stl.gst index 26ddb05b..4180ef7d 100644 --- a/libs/stl.gst +++ b/libs/stl.gst @@ -1,2 +1,4 @@ (print 1) +(: counter 0) +(while (< counter 100) (print counter) (: counter (+ 1 counter)))