summaryrefslogtreecommitdiff
path: root/uscript/vm.c
diff options
context:
space:
mode:
authoriamcheeseman <[email protected]>2026-04-14 12:47:56 -0400
committeriamcheeseman <[email protected]>2026-04-14 12:47:56 -0400
commit968a7292f0b88f9485f4511e48acbee36cf71036 (patch)
tree1b0f5c68774c81a939b8c408c33517f53aae5518 /uscript/vm.c
parentca004156cbb1c525900f444994112fc17b71d63d (diff)
microscript: add c functions
Diffstat (limited to 'uscript/vm.c')
-rw-r--r--uscript/vm.c63
1 files changed, 49 insertions, 14 deletions
diff --git a/uscript/vm.c b/uscript/vm.c
index 363912a..c01bb0f 100644
--- a/uscript/vm.c
+++ b/uscript/vm.c
@@ -76,12 +76,59 @@ void close_upvals(struct us_val *to)
vm.open_upvals = upval;
}
+
+static
+void call_val(struct us_val callee, int argc)
+{
+ switch (callee.type) {
+ case VAL_FUNC: {
+ struct us_func *func = get_func(callee);
+ if (argc != func->proto->argc) {
+ log_fatal(
+ 1,
+ "wrong number of arguments to '%s()' (%d/%d)",
+ func->proto->name->chars,
+ argc,
+ func->proto->argc
+ );
+ }
+ us_exec(func);
+ break;
+ }
+ case VAL_CFUNC: {
+ struct us_cfunc *cfunc = get_cfunc(callee);
+ if (argc != cfunc->argc) {
+ log_fatal(
+ 1,
+ "wrong number of arguments to '%s()' (%d/%d)",
+ cfunc->name->chars,
+ argc,
+ cfunc->argc
+ );
+ }
+
+ vm.cf++;
+ vm.cf->func = wrap_cfunc(cfunc);
+ vm.cf->stackbot = vm.stacktop - argc;
+ cfunc->c(argc);
+ struct us_val ret_val = vm_pop();
+ vm.stacktop = vm.cf->stackbot - 1;
+ vm.cf--;
+ vm_push(ret_val);
+ break;
+ }
+ default:
+ log_fatal(1, "cannot call that value");
+ break;
+ }
+}
+
void us_exec(struct us_func *func)
{
#define read_byte() (func->proto->bytecode[++i])
#define read_const() (func->proto->constants[read_byte()])
vm.cf++;
- vm.cf->func = func;
+ vm.cf->func = wrap_func(func);
vm.cf->stackbot = vm.stacktop - func->proto->argc;
for (int i = 0; i < da_len(func->proto->bytecode); i++) {
@@ -344,19 +391,7 @@ void us_exec(struct us_func *func)
case BC_CALL: {
int argc = read_byte();
struct us_val callee = vm.stacktop[-argc - 1];
- if (callee.type != VAL_FUNC)
- log_fatal(1, "can only call functions");
- struct us_func *func = get_func(callee);
- if (argc != func->proto->argc) {
- log_fatal(
- 1,
- "wrong number of arguments to '%s()' (%d/%d)",
- func->proto->name->chars,
- argc,
- func->proto->argc
- );
- }
- us_exec(func);
+ call_val(callee, argc);
break;
}
case BC_RET: {