1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-21 12:43:15 +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\
value.c vm.c ds.c gc.c thread.c serialize.c)
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_OBJECTS=$(patsubst %.c,%.o,$(GST_CLIENT_SOURCES))
$(GST_TARGET): $(GST_CLIENT_OBJECTS) $(GST_CORE_OBJECTS)
@ -50,4 +48,7 @@ clean:
rm $(GST_CLIENT_OBJECTS) || true
rm vgcore.* || true
test: $(GST_TARGET)
gsttests/basic.gst
.PHONY: clean install run debug valgrind

View File

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

View File

@ -945,6 +945,7 @@ static SpecialFormHelper get_special(const GstValue *form) {
return compile_apply;
}
}
break;
case 'd':
{
if (gst_string_length(name) == 2 &&
@ -989,6 +990,7 @@ static SpecialFormHelper get_special(const GstValue *form) {
return compile_tran;
}
}
break;
case 'w':
{
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);
if (thread->parent)
gst_mark_value(vm, gst_wrap_thread(thread->parent));
if (thread->errorParent)
gst_mark_value(vm, gst_wrap_thread(thread->errorParent));
}
break;

View File

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

View File

@ -38,7 +38,7 @@
* Byte 207: Buffer - [u32 capacity][u32 length]*[u8... characters]
* Byte 208: Array - [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]]
* Byte 211: Table - [u32 length]*2*[value... kvs]
* 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) {
t->parent = ret.data.thread;
} 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);
statusbyte = *data++;
@ -520,10 +529,10 @@ const char *gst_serialize_impl(
}
/* 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
* 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 */
if (x.type == GST_STRUCT || x.type == GST_TUPLE) {
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));
else
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;
/* Write the status byte */
write_byte(t->status);

View File

@ -446,9 +446,21 @@ int gst_stl_string(Gst *vm) {
int gst_stl_thread(Gst *vm) {
GstThread *t;
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)
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;
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 */
int gst_stl_namespace_get(Gst *vm) {
GstValue name = gst_arg(vm, 0);
GstValue check;
if (name.type != GST_STRING)
gst_c_throwc(vm, "expected string");
check = gst_table_get(vm->modules, name);
gst_c_return(vm, check);
return gst_callc(vm, gst_stl_get, 2, gst_wrap_table(vm->modules), gst_arg(vm, 0));
/*GstValue name = gst_arg(vm, 0);*/
/*GstValue check;*/
/*if (name.type != GST_STRING)*/
/*gst_c_throwc(vm, "expected string");*/
/*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 */
static const GstModuleItem const io_dat[] = {
static const GstModuleItem io_dat[] = {
{"open", gst_stl_open},
{"slurp", gst_stl_slurp},
{"read", gst_stl_read},
@ -914,7 +927,7 @@ int gst_stl_debugp(Gst *vm) {
/* Bootstraping */
/****/
static const GstModuleItem const std_module[] = {
static const GstModuleItem std_module[] = {
/* Arithmetic */
{"+", gst_stl_add},
{"*", 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_thread_endframe(vm, thread);
thread->parent = NULL; /* Need to set parent manually */
thread->errorParent = NULL;
return thread;
}

View File

@ -237,3 +237,18 @@ GstInteger gst_endrange(GstInteger raw, uint32_t len) {
return len + raw + 1;
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 */
vm_error:
vm->thread->status = GST_THREAD_ERROR;
if (vm->thread->parent == NULL)
if (vm->thread->errorParent == NULL)
return GST_RETURN_ERROR;
vm->thread = vm->thread->parent;
vm->thread = vm->thread->errorParent;
stack = vm->thread->data + vm->thread->count;
stack[gst_frame_ret(stack)] = vm->ret;
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)))))
# Basic Math
(assert (= 10 (+ 1 2 3 4), "addition")
(assert (= -8 (- 1 2 3 4), "subtraction")
(assert (= 24 (* 1 2 3 4), "multiplication")
(assert (= 0.1 (/ 1 10), "division")
# All good
(assert (= 10 (+ 1 2 3 4)) "addition")
(assert (= -8 (- 1 2 3 4)) "subtraction")
(assert (= 24 (* 1 2 3 4)) "multiplication")
(assert (= 0.1 (/ 1.0 10)) "division")
(exit 0)
)

View File

@ -24,6 +24,7 @@
#define GST_H_defined
#include <stdint.h>
#include <stdarg.h>
/* String utils */
#define gst_string_raw(s) ((uint32_t *)(s) - 2)
@ -206,6 +207,7 @@ struct GstThread {
uint32_t capacity;
GstValue *data;
GstThread *parent;
GstThread *errorParent;
enum {
GST_THREAD_PENDING = 0,
GST_THREAD_ALIVE,
@ -490,10 +492,13 @@ uint32_t gst_count_args(Gst *vm);
/* C Api */
/****/
void gst_module(Gst *vm, const char *packagename, const GstModuleItem *mod);
void gst_module_mutable(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 *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);
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 */
GstValue gst_wrap_nil();