1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-27 15:43:17 +00:00

Add errorParent to threads.

This commit is contained in:
Calvin Rose 2017-06-19 23:01:34 -04:00
parent 6c597f6b5b
commit 70478a410b
12 changed files with 90 additions and 32 deletions

View File

@ -19,12 +19,10 @@ GST_CORE_SOURCES=$(addprefix core/,\
compile.c disasm.c parse.c stl.c ids.c util.c\ compile.c disasm.c parse.c stl.c ids.c util.c\
value.c vm.c ds.c gc.c thread.c serialize.c) value.c vm.c ds.c gc.c thread.c serialize.c)
GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES)) GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES))
$(GST_CORELIB): $(GST_CORE_OBJECTS) $(GST_HEADERS)
ar rcs $(GST_CORELIB) $(GST_CORE_OBJECTS)
############################## ######################
##### The example client ##### ##### The client #####
############################## ######################
GST_CLIENT_SOURCES=client/main.c GST_CLIENT_SOURCES=client/main.c
GST_CLIENT_OBJECTS=$(patsubst %.c,%.o,$(GST_CLIENT_SOURCES)) GST_CLIENT_OBJECTS=$(patsubst %.c,%.o,$(GST_CLIENT_SOURCES))
$(GST_TARGET): $(GST_CLIENT_OBJECTS) $(GST_CORE_OBJECTS) $(GST_TARGET): $(GST_CLIENT_OBJECTS) $(GST_CORE_OBJECTS)
@ -50,4 +48,7 @@ clean:
rm $(GST_CLIENT_OBJECTS) || true rm $(GST_CLIENT_OBJECTS) || true
rm vgcore.* || true rm vgcore.* || true
test: $(GST_TARGET)
gsttests/basic.gst
.PHONY: clean install run debug valgrind .PHONY: clean install run debug valgrind

View File

@ -117,6 +117,8 @@ int debug_repl(Gst *vm) {
break; break;
if (!reader || *reader == '\0') { if (!reader || *reader == '\0') {
buffer = readline(">> "); buffer = readline(">> ");
if (*buffer == '\0')
return 0;
add_history(buffer); add_history(buffer);
reader = buffer; reader = buffer;
} }

View File

@ -945,6 +945,7 @@ static SpecialFormHelper get_special(const GstValue *form) {
return compile_apply; return compile_apply;
} }
} }
break;
case 'd': case 'd':
{ {
if (gst_string_length(name) == 2 && if (gst_string_length(name) == 2 &&
@ -989,6 +990,7 @@ static SpecialFormHelper get_special(const GstValue *form) {
return compile_tran; return compile_tran;
} }
} }
break;
case 'w': case 'w':
{ {
if (gst_string_length(name) == 5 && if (gst_string_length(name) == 5 &&

View File

@ -147,6 +147,8 @@ void gst_mark(Gst *vm, GstValueUnion x, GstType type) {
frame = gst_mark_stackframe(vm, frame); frame = gst_mark_stackframe(vm, frame);
if (thread->parent) if (thread->parent)
gst_mark_value(vm, gst_wrap_thread(thread->parent)); gst_mark_value(vm, gst_wrap_thread(thread->parent));
if (thread->errorParent)
gst_mark_value(vm, gst_wrap_thread(thread->errorParent));
} }
break; break;

View File

@ -101,6 +101,8 @@ static void parser_push(GstParser *p, ParseType type, uint8_t character) {
switch (type) { switch (type) {
case PTYPE_STRING: case PTYPE_STRING:
top->buf.string.state = STRING_STATE_BASE; top->buf.string.state = STRING_STATE_BASE;
top->buf.string.buffer = gst_buffer(p->vm, 10);
break;
case PTYPE_TOKEN: case PTYPE_TOKEN:
top->buf.string.buffer = gst_buffer(p->vm, 10); top->buf.string.buffer = gst_buffer(p->vm, 10);
break; break;
@ -458,6 +460,8 @@ static void dispatch_char(GstParser *p, uint8_t c) {
*/ */
int gst_parse_cstring(GstParser *p, const char *string) { int gst_parse_cstring(GstParser *p, const char *string) {
int bytesRead = 0; int bytesRead = 0;
if (!string)
return 0;
while ((p->status == GST_PARSER_PENDING || p->status == GST_PARSER_ROOT) while ((p->status == GST_PARSER_PENDING || p->status == GST_PARSER_ROOT)
&& (string[bytesRead] != '\0')) { && (string[bytesRead] != '\0')) {
dispatch_char(p, string[bytesRead++]); dispatch_char(p, string[bytesRead++]);
@ -468,6 +472,8 @@ int gst_parse_cstring(GstParser *p, const char *string) {
/* Parse a gst string */ /* Parse a gst string */
int gst_parse_string(GstParser *p, const uint8_t *string) { int gst_parse_string(GstParser *p, const uint8_t *string) {
uint32_t i; uint32_t i;
if (!string)
return 0;
for (i = 0; i < gst_string_length(string); ++i) { for (i = 0; i < gst_string_length(string); ++i) {
if (p->status != GST_PARSER_PENDING && p->status != GST_PARSER_ROOT) break; if (p->status != GST_PARSER_PENDING && p->status != GST_PARSER_ROOT) break;
dispatch_char(p, string[i]); dispatch_char(p, string[i]);

View File

@ -38,7 +38,7 @@
* Byte 207: Buffer - [u32 capacity][u32 length]*[u8... characters] * Byte 207: Buffer - [u32 capacity][u32 length]*[u8... characters]
* Byte 208: Array - [u32 length]*[value... elements] * Byte 208: Array - [u32 length]*[value... elements]
* Byte 209: Tuple - [u32 length]*[value... elements] * Byte 209: Tuple - [u32 length]*[value... elements]
* Byte 210: Thread - [value parent][u8 state][u32 frames]*[[value callee][value env] * Byte 210: Thread - [value parent][value errorParent][u8 state][u32 frames]*[[value callee][value env]
* [u32 pcoffset][u32 ret][u32 args][u32 size]*[value ...stack]] * [u32 pcoffset][u32 ret][u32 args][u32 size]*[value ...stack]]
* Byte 211: Table - [u32 length]*2*[value... kvs] * Byte 211: Table - [u32 length]*2*[value... kvs]
* Byte 212: FuncDef - [u32 locals][u32 arity][u32 flags][u32 literallen]*[value... * Byte 212: FuncDef - [u32 locals][u32 arity][u32 flags][u32 literallen]*[value...
@ -249,7 +249,16 @@ static const char *gst_deserialize_impl(
} else if (ret.type == GST_THREAD) { } else if (ret.type == GST_THREAD) {
t->parent = ret.data.thread; t->parent = ret.data.thread;
} else { } else {
return "expected thread parent to thread"; return "expected thread parent to be thread";
}
err = gst_deserialize_impl(vm, data, end, &data, visited, &ret);
if (err != NULL) return err;
if (ret.type == GST_NIL) {
t->errorParent = NULL;
} else if (ret.type == GST_THREAD) {
t->errorParent = ret.data.thread;
} else {
return "expected thread error parent to be thread";
} }
deser_assert(data < end, UEB); deser_assert(data < end, UEB);
statusbyte = *data++; statusbyte = *data++;
@ -520,10 +529,10 @@ const char *gst_serialize_impl(
} }
/* Check tuples and structs before other reference types. /* Check tuples and structs before other reference types.
* They ae immutable, and thus cannot be referenced by other values * They are immutable, and thus cannot be referenced by other values
* until they are fully constructed. This creates some strange behavior * until they are fully constructed. This creates some strange behavior
* if they are treated like other reference types because they cannot * if they are treated like other reference types because they cannot
* be added to the visited table before recusring into serializing their * be added to the visited table before recursing into serializing their
* arguments */ * arguments */
if (x.type == GST_STRUCT || x.type == GST_TUPLE) { if (x.type == GST_STRUCT || x.type == GST_TUPLE) {
if (x.type == GST_STRUCT) { if (x.type == GST_STRUCT) {
@ -632,6 +641,11 @@ const char *gst_serialize_impl(
err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_thread(t->parent)); err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_thread(t->parent));
else else
err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_nil()); err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_nil());
if (t->errorParent)
err = gst_serialize_impl(vm, buffer, visited, nextId,
gst_wrap_thread(t->errorParent));
else
err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_nil());
if (err != NULL) return err; if (err != NULL) return err;
/* Write the status byte */ /* Write the status byte */
write_byte(t->status); write_byte(t->status);

View File

@ -446,9 +446,21 @@ int gst_stl_string(Gst *vm) {
int gst_stl_thread(Gst *vm) { int gst_stl_thread(Gst *vm) {
GstThread *t; GstThread *t;
GstValue callee = gst_arg(vm, 0); GstValue callee = gst_arg(vm, 0);
GstValue parent = gst_arg(vm, 1);
GstValue errorParent = gst_arg(vm, 2);
t = gst_thread(vm, callee, 10);
if (callee.type != GST_FUNCTION && callee.type != GST_CFUNCTION) if (callee.type != GST_FUNCTION && callee.type != GST_CFUNCTION)
gst_c_throwc(vm, "expected function in thread constructor"); gst_c_throwc(vm, "expected function in thread constructor");
t = gst_thread(vm, callee, 10); if (parent.type == GST_THREAD) {
t->parent = parent.data.thread;
} else if (parent.type != GST_NIL) {
gst_c_throwc(vm, "expected thread/nil as parent");
}
if (errorParent.type == GST_THREAD) {
t->errorParent = errorParent.data.thread;
} else if (errorParent.type != GST_NIL) {
gst_c_throwc(vm, "expected thread/nil as error parent");
}
t->parent = vm->thread; t->parent = vm->thread;
gst_c_return(vm, gst_wrap_thread(t)); gst_c_return(vm, gst_wrap_thread(t));
} }
@ -669,12 +681,13 @@ int gst_stl_namespace_set(Gst *vm) {
/* Get the table or struct associated with a given namespace */ /* Get the table or struct associated with a given namespace */
int gst_stl_namespace_get(Gst *vm) { int gst_stl_namespace_get(Gst *vm) {
GstValue name = gst_arg(vm, 0); return gst_callc(vm, gst_stl_get, 2, gst_wrap_table(vm->modules), gst_arg(vm, 0));
GstValue check; /*GstValue name = gst_arg(vm, 0);*/
if (name.type != GST_STRING) /*GstValue check;*/
gst_c_throwc(vm, "expected string"); /*if (name.type != GST_STRING)*/
check = gst_table_get(vm->modules, name); /*gst_c_throwc(vm, "expected string");*/
gst_c_return(vm, check); /*check = gst_table_get(vm->modules, name);*/
/*gst_c_return(vm, check);*/
} }
/***/ /***/
@ -796,7 +809,7 @@ int gst_stl_close(Gst *vm) {
} }
/* Functions in the io module */ /* Functions in the io module */
static const GstModuleItem const io_dat[] = { static const GstModuleItem io_dat[] = {
{"open", gst_stl_open}, {"open", gst_stl_open},
{"slurp", gst_stl_slurp}, {"slurp", gst_stl_slurp},
{"read", gst_stl_read}, {"read", gst_stl_read},
@ -914,7 +927,7 @@ int gst_stl_debugp(Gst *vm) {
/* Bootstraping */ /* Bootstraping */
/****/ /****/
static const GstModuleItem const std_module[] = { static const GstModuleItem std_module[] = {
/* Arithmetic */ /* Arithmetic */
{"+", gst_stl_add}, {"+", gst_stl_add},
{"*", gst_stl_mul}, {"*", gst_stl_mul},

View File

@ -42,6 +42,7 @@ GstThread *gst_thread(Gst *vm, GstValue callee, uint32_t capacity) {
gst_frame_callee(stack) = callee; gst_frame_callee(stack) = callee;
gst_thread_endframe(vm, thread); gst_thread_endframe(vm, thread);
thread->parent = NULL; /* Need to set parent manually */ thread->parent = NULL; /* Need to set parent manually */
thread->errorParent = NULL;
return thread; return thread;
} }

View File

@ -237,3 +237,18 @@ GstInteger gst_endrange(GstInteger raw, uint32_t len) {
return len + raw + 1; return len + raw + 1;
return raw; return raw;
} }
int gst_callc(Gst *vm, GstCFunction fn, int numargs, ...) {
int result, i;
va_list args;
GstValue *stack;
va_start(args, numargs);
stack = gst_thread_beginframe(vm, vm->thread, gst_wrap_cfunction(fn), numargs);
for (i = 0; i < numargs; ++i) {
stack[i] = va_arg(args, GstValue);
}
va_end(args);
result = fn(vm);
gst_thread_popframe(vm, vm->thread);
return result;
}

View File

@ -394,9 +394,9 @@ int gst_continue(Gst *vm) {
/* Handle errors from c functions and vm opcodes */ /* Handle errors from c functions and vm opcodes */
vm_error: vm_error:
vm->thread->status = GST_THREAD_ERROR; vm->thread->status = GST_THREAD_ERROR;
if (vm->thread->parent == NULL) if (vm->thread->errorParent == NULL)
return GST_RETURN_ERROR; return GST_RETURN_ERROR;
vm->thread = vm->thread->parent; vm->thread = vm->thread->errorParent;
stack = vm->thread->data + vm->thread->count; stack = vm->thread->data + vm->thread->count;
stack[gst_frame_ret(stack)] = vm->ret; stack[gst_frame_ret(stack)] = vm->ret;
pc = gst_frame_pc(stack); pc = gst_frame_pc(stack);

View File

@ -1,11 +1,8 @@
# Define assert (do
(: assert (fn [x e] (if x x (do (print e) (exit 1))))) (: assert (fn [x e] (if x x (do (print e) (exit 1)))))
(assert (= 10 (+ 1 2 3 4)) "addition")
# Basic Math (assert (= -8 (- 1 2 3 4)) "subtraction")
(assert (= 10 (+ 1 2 3 4), "addition") (assert (= 24 (* 1 2 3 4)) "multiplication")
(assert (= -8 (- 1 2 3 4), "subtraction") (assert (= 0.1 (/ 1.0 10)) "division")
(assert (= 24 (* 1 2 3 4), "multiplication")
(assert (= 0.1 (/ 1 10), "division")
# All good
(exit 0) (exit 0)
)

View File

@ -24,6 +24,7 @@
#define GST_H_defined #define GST_H_defined
#include <stdint.h> #include <stdint.h>
#include <stdarg.h>
/* String utils */ /* String utils */
#define gst_string_raw(s) ((uint32_t *)(s) - 2) #define gst_string_raw(s) ((uint32_t *)(s) - 2)
@ -206,6 +207,7 @@ struct GstThread {
uint32_t capacity; uint32_t capacity;
GstValue *data; GstValue *data;
GstThread *parent; GstThread *parent;
GstThread *errorParent;
enum { enum {
GST_THREAD_PENDING = 0, GST_THREAD_PENDING = 0,
GST_THREAD_ALIVE, GST_THREAD_ALIVE,
@ -490,10 +492,13 @@ uint32_t gst_count_args(Gst *vm);
/* C Api */ /* C Api */
/****/ /****/
void gst_module(Gst *vm, const char *packagename, const GstModuleItem *mod); void gst_module(Gst *vm, const char *name, const GstModuleItem *mod);
void gst_module_mutable(Gst *vm, const char *packagename, const GstModuleItem *mod); void gst_module_mutable(Gst *vm, const char *name, const GstModuleItem *mod);
void gst_module_put(Gst *vm, const char *packagename, const char *name, GstValue x);
GstValue gst_module_get(Gst *vm, const char *packagename); GstValue gst_module_get(Gst *vm, const char *packagename);
void gst_module_put(Gst *vm, const char *packagename, const char *name, GstValue v); void gst_register_put(Gst *vm, const char *packagename, GstValue mod);
GstValue gst_register_get(Gst *vm, const char *name);
int gst_callc(Gst *vm, GstCFunction fn, int numargs, ...);
/* Wrap data in GstValue */ /* Wrap data in GstValue */
GstValue gst_wrap_nil(); GstValue gst_wrap_nil();