summaryrefslogtreecommitdiff
path: root/uscript
diff options
context:
space:
mode:
Diffstat (limited to 'uscript')
-rw-r--r--uscript/uscript.c34
-rw-r--r--uscript/val.c8
-rw-r--r--uscript/val.h5
-rw-r--r--uscript/vm.h2
4 files changed, 48 insertions, 1 deletions
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)