diff options
| author | iamcheeseman <[email protected]> | 2026-04-14 12:47:56 -0400 |
|---|---|---|
| committer | iamcheeseman <[email protected]> | 2026-04-14 12:47:56 -0400 |
| commit | 968a7292f0b88f9485f4511e48acbee36cf71036 (patch) | |
| tree | 1b0f5c68774c81a939b8c408c33517f53aae5518 /uscript/vm.c | |
| parent | ca004156cbb1c525900f444994112fc17b71d63d (diff) | |
microscript: add c functions
Diffstat (limited to 'uscript/vm.c')
| -rw-r--r-- | uscript/vm.c | 63 |
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: { |
