From 24e600e7c3ce6dab4c6c3f421e5d1ae35dc04bad Mon Sep 17 00:00:00 2001 From: iamcheeseman Date: Tue, 14 Apr 2026 19:35:49 -0400 Subject: microscript: add core:range() --- uscript/uscript.c | 34 ++++++++++++++++++++++++++++++++++ uscript/val.c | 8 +++++++- uscript/val.h | 5 +++++ uscript/vm.h | 2 ++ 4 files changed, 48 insertions(+), 1 deletion(-) (limited to 'uscript') diff --git a/uscript/uscript.c b/uscript/uscript.c index a7e3ca1..0e6fc4b 100644 --- a/uscript/uscript.c +++ b/uscript/uscript.c @@ -36,12 +36,46 @@ void core_len(int argc) } } +void core_range_next(int argc) +{ + (void)argc; + + struct us_cfunc *cfunc = get_cfunc(vm_get(-1)); + double min = get_num(cfunc_get_upval(cfunc, 0)); + double max = get_num(cfunc_get_upval(cfunc, 1)); + + if (min == max) { + vm_push(create_zilch()); + return; + } + + vm_push(create_num(min)); + + int inc = max > min ? 1 : -1; + cfunc_set_upval(cfunc, 0, create_num(min + inc)); +} + +void core_range(int argc) +{ + if (vm_get(1).type != VAL_NUM || vm_get(2).type != VAL_NUM) + log_fatal(1, "core:range expected two numbers"); + + struct us_str *str = copy_str("rangenext", -1); + struct us_cfunc *cfunc = create_cfunc(str, core_range_next, 0); + + for (int i = 0; i < argc; i++) + cfunc_add_upval(cfunc, vm_get(i)); + + vm_push(wrap_cfunc(cfunc)); +} + void us_init(void) { init_vm(); us_set_cfunc("core:len", core_len, 1); us_set_cfunc("core:log", core_print, 1); + us_set_cfunc("core:range", core_range, 2); } void us_deinit(void) diff --git a/uscript/val.c b/uscript/val.c index 357facc..76f1376 100644 --- a/uscript/val.c +++ b/uscript/val.c @@ -74,6 +74,7 @@ struct us_cfunc *create_cfunc(struct us_str *name, us_cfunc_sig func, int argc) cfunc->name = name; cfunc->c = func; cfunc->argc = argc; + cfunc->upvals = da_create(struct us_val, 0); init_obj(wrap_cfunc(cfunc), &cfunc->header); return cfunc; } @@ -116,7 +117,12 @@ void free_val(struct us_val v) mem_free(func); break; } - case VAL_CFUNC: + case VAL_CFUNC: { + struct us_cfunc *cfunc = get_cfunc(v); + da_free(cfunc->upvals); + mem_free(cfunc); + break; + } case VAL_UPVAL: mem_free(get_obj(v)); break; diff --git a/uscript/val.h b/uscript/val.h index 5140fc2..8ea91dd 100644 --- a/uscript/val.h +++ b/uscript/val.h @@ -28,6 +28,10 @@ #define proto_add_byte(func, op) da_append(u8, &(func)->bytecode, op) +#define cfunc_add_upval(c, v) da_append(struct us_val, &c->upvals, v) +#define cfunc_set_upval(c, i, v) (c->upvals[i] = (v)) +#define cfunc_get_upval(c, i) (c->upvals[i]) + enum val_type { VAL_NUM, VAL_BOOL, @@ -90,6 +94,7 @@ struct us_cfunc { struct us_obj header; us_cfunc_sig c; const struct us_str *name; + struct us_val *upvals; int argc; }; diff --git a/uscript/vm.h b/uscript/vm.h index d3487b1..9ab1407 100644 --- a/uscript/vm.h +++ b/uscript/vm.h @@ -11,6 +11,8 @@ #define vm_peek() (vm.stacktop[-1]) #define vm_push(v) (*vm.stacktop++ = (v)) +#define vm_get(i) (vm.cf->stackbot[i]) + #define set_global(idx, v) (vm.gstack[idx].val = (v)) #define get_global(idx) (vm.gstack[idx].val) -- cgit v1.3-2-g0d8e