summaryrefslogtreecommitdiff
path: root/uscript/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'uscript/vm.c')
-rw-r--r--uscript/vm.c77
1 files changed, 50 insertions, 27 deletions
diff --git a/uscript/vm.c b/uscript/vm.c
index 9fbd8c0..c381112 100644
--- a/uscript/vm.c
+++ b/uscript/vm.c
@@ -1,6 +1,7 @@
#include "vm.h"
#include <math.h>
+#include <stdarg.h>
#include <string.h>
#include "dyn_arr.h"
@@ -14,6 +15,7 @@ void init_vm(void)
vm.objs = da_create(struct us_val, 128);
vm.gstack = da_create(struct global, 128);
vm.cf = vm.cf_stack;
+ vm.cf->stackbot = NULL;
vm.stacktop = vm.stack;
}
@@ -28,6 +30,32 @@ void deinit_vm(void)
da_free(vm.gstack);
}
+void us_err(const char *msg, ...)
+{
+ va_list args;
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+ putc('\n', stderr);
+
+ for (struct call_frame *cf = vm.cf; vm.cf > vm.cf_stack; cf--) {
+ if (!cf->stackbot)
+ break;
+ if (cf->func.type == VAL_FUNC) {
+ struct us_func *func = get_func(cf->func);
+ fprintf(stderr, "\tby %s()\n", func->proto->name->chars);
+ } else if (cf->func.type == VAL_CFUNC) {
+ struct us_cfunc *cfunc = get_cfunc(cf->func);
+ fprintf(stderr, "\tby [c] %s()\n", cfunc->name->chars);
+ } else {
+ fprintf(stderr, "\tunknown\n");
+ }
+ }
+
+ // TODO: Replace with a longjmp
+ exit(1);
+}
+
static
bool as_bool(struct us_val v)
{
@@ -76,14 +104,13 @@ void index_val(struct us_val idx_val, struct us_val idxee_val)
switch (idxee_val.type) {
case VAL_ARR: {
if (idx_val.type != VAL_NUM)
- log_fatal(1, "arrays must be indexed by numbers");
+ us_err("arrays must be indexed by numbers");
int idx = (int)get_num(idx_val);
struct us_arr *arr = get_arr(idxee_val);
if (idx < 0)
idx += da_len(arr->e);
if (idx < 0 || idx >= da_len(arr->e)) {
- log_fatal(
- 1,
+ us_err(
"index out of range (%d/%d)",
idx,
da_len(arr->e) - 1
@@ -94,14 +121,13 @@ void index_val(struct us_val idx_val, struct us_val idxee_val)
}
case VAL_STR: {
if (idx_val.type != VAL_NUM)
- log_fatal(1, "strings must be indexed by numbers");
+ us_err("strings must be indexed by numbers");
int idx = (int)get_num(idx_val);
struct us_str *str = get_str(idxee_val);
if (idx < 0)
idx += str->len;
if (idx < 0 || (size_t)idx >= str->len) {
- log_fatal(
- 1,
+ us_err(
"index out of range (%d/%d)",
idx,
str->len - 1
@@ -111,7 +137,7 @@ void index_val(struct us_val idx_val, struct us_val idxee_val)
break;
}
default:
- log_fatal(1, "cannot index that value");
+ us_err("cannot index that value");
break;
}
}
@@ -123,8 +149,7 @@ void call_val(struct us_val callee, int argc)
case VAL_FUNC: {
struct us_func *func = get_func(callee);
if (argc != func->proto->argc) {
- log_fatal(
- 1,
+ us_err(
"wrong number of arguments to '%s()' (%d/%d)",
func->proto->name->chars,
argc,
@@ -137,8 +162,7 @@ void call_val(struct us_val callee, int argc)
case VAL_CFUNC: {
struct us_cfunc *cfunc = get_cfunc(callee);
if (argc != cfunc->argc) {
- log_fatal(
- 1,
+ us_err(
"wrong number of arguments to '%s()' (%d/%d)",
cfunc->name->chars,
argc,
@@ -157,7 +181,7 @@ void call_val(struct us_val callee, int argc)
break;
}
default:
- log_fatal(1, "cannot call that value");
+ us_err("cannot call that value");
break;
}
}
@@ -276,16 +300,15 @@ void us_exec(struct us_func *func)
struct us_val idx_val = vm_pop();
struct us_val arr_val = vm_pop();
if (idx_val.type != VAL_NUM)
- log_fatal(1, "index type must be number");
+ us_err("index type must be number");
if (arr_val.type != VAL_ARR)
- log_fatal(1, "only arrays can be indexed");
+ us_err("only arrays can be indexed");
int idx = (int)get_num(idx_val);
struct us_arr *arr = get_arr(arr_val);
if (idx < 0)
idx += da_len(arr->e);
if (idx < 0 || idx >= da_len(arr->e)) {
- log_fatal(
- 1,
+ us_err(
"index out of range (%d/%d)",
idx,
da_len(arr->e) - 1
@@ -304,7 +327,7 @@ void us_exec(struct us_func *func)
struct us_val b = vm_pop();
struct us_val a = vm_pop();
if (b.type != VAL_NUM || a.type != VAL_NUM)
- log_fatal(1, "Invalid operands");
+ us_err("Invalid operands");
vm_push(create_num(get_num(a) + get_num(b)));
break;
}
@@ -312,7 +335,7 @@ void us_exec(struct us_func *func)
struct us_val b = vm_pop();
struct us_val a = vm_pop();
if (b.type != VAL_NUM || a.type != VAL_NUM)
- log_fatal(1, "Invalid operands");
+ us_err("Invalid operands");
vm_push(create_num(get_num(a) - get_num(b)));
break;
}
@@ -320,7 +343,7 @@ void us_exec(struct us_func *func)
struct us_val b = vm_pop();
struct us_val a = vm_pop();
if (b.type != VAL_NUM || a.type != VAL_NUM)
- log_fatal(1, "Invalid operands");
+ us_err("Invalid operands");
vm_push(create_num(get_num(a) * get_num(b)));
break;
}
@@ -328,7 +351,7 @@ void us_exec(struct us_func *func)
struct us_val b = vm_pop();
struct us_val a = vm_pop();
if (b.type != VAL_NUM || a.type != VAL_NUM)
- log_fatal(1, "Invalid operands");
+ us_err("Invalid operands");
vm_push(create_num(get_num(a) / get_num(b)));
break;
}
@@ -336,7 +359,7 @@ void us_exec(struct us_func *func)
struct us_val b = vm_pop();
struct us_val a = vm_pop();
if (b.type != VAL_NUM || a.type != VAL_NUM)
- log_fatal(1, "Invalid operands");
+ us_err("Invalid operands");
vm_push(create_num(fmod(get_num(a), get_num(b))));
break;
}
@@ -344,7 +367,7 @@ void us_exec(struct us_func *func)
struct us_val b = vm_pop();
struct us_val a = vm_pop();
if (b.type != VAL_NUM || a.type != VAL_NUM)
- log_fatal(1, "Invalid operands");
+ us_err("Invalid operands");
vm_push(create_bool(get_num(a) > get_num(b)));
break;
}
@@ -352,7 +375,7 @@ void us_exec(struct us_func *func)
struct us_val b = vm_pop();
struct us_val a = vm_pop();
if (b.type != VAL_NUM || a.type != VAL_NUM)
- log_fatal(1, "Invalid operands");
+ us_err("Invalid operands");
vm_push(create_bool(get_num(a) >= get_num(b)));
break;
}
@@ -360,7 +383,7 @@ void us_exec(struct us_func *func)
struct us_val b = vm_pop();
struct us_val a = vm_pop();
if (b.type != VAL_NUM || a.type != VAL_NUM)
- log_fatal(1, "Invalid operands");
+ us_err("Invalid operands");
vm_push(create_bool(get_num(a) < get_num(b)));
break;
}
@@ -368,14 +391,14 @@ void us_exec(struct us_func *func)
struct us_val b = vm_pop();
struct us_val a = vm_pop();
if (b.type != VAL_NUM || a.type != VAL_NUM)
- log_fatal(1, "Invalid operands");
+ us_err("Invalid operands");
vm_push(create_bool(get_num(a) <= get_num(b)));
break;
}
case BC_NEG: {
struct us_val a = vm_pop();
if (a.type != VAL_NUM)
- log_fatal(1, "Invalid operand");
+ us_err("Invalid operand");
vm_push(create_num(-get_num(a)));
break;
}
@@ -436,7 +459,7 @@ void us_exec(struct us_func *func)
return;
}
default:
- log_fatal(1, "unhandled instruction %d", instruction);
+ us_err("unhandled instruction %d", instruction);
break;
}
}