mirror of
https://github.com/janet-lang/janet
synced 2025-03-25 17:46:56 +00:00
Add errorParent to threads.
This commit is contained in:
parent
6c597f6b5b
commit
70478a410b
11
Makefile
11
Makefile
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 &&
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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]);
|
||||
|
@ -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);
|
||||
|
31
core/stl.c
31
core/stl.c
@ -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},
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
15
core/util.c
15
core/util.c
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
)
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user