#include "uscript.h" #include #include "dyn_arr.h" #include "lex.h" #include "map.h" #include "parser.h" #include "val.h" #include "vm.h" void core_print(int argc) { (void)argc; char *str = val_to_str(vm_peek(0), NULL); olog(str); mem_free(str); vm_push(create_nada()); } void core_len(int argc) { (void)argc; struct us_val val = vm_peek(0); switch (val.type) { case VAL_ARR: vm_push(create_num(da_len(get_arr(val)->e))); break; case VAL_STR: vm_push(create_num(get_str(val)->len)); break; default: vm_push(create_nada()); } } 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)); double inc = get_num(cfunc_get_upval(cfunc, 2)); if (min == max) { vm_push(create_nada()); return; } vm_push(create_num(min)); 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) us_err("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 arr_add(int argc) { (void)argc; if (vm_get(0).type != VAL_ARR) us_err("arr:add expected an array"); struct us_arr *arr = get_arr(vm_get(0)); da_append(struct us_val, &arr->e, vm_get(1)); } void arr_iter_next(int argc) { (void)argc; struct us_cfunc *cfunc = get_cfunc(vm_get(-1)); struct us_arr *arr = get_arr(cfunc_get_upval(cfunc, 0)); double i = get_num(cfunc_get_upval(cfunc, 1)); int len = da_len(arr->e); if (i == len) { vm_push(create_nada()); return; } vm_push(arr->e[(int)i]); cfunc_set_upval(cfunc, 1, create_num(i + 1)); } void arr_iter(int argc) { (void)argc; if (vm_get(0).type != VAL_ARR) us_err("arr:iter expected an array"); struct us_str *str = copy_str("arr:iternext", -1); struct us_cfunc *cfunc = create_cfunc(str, arr_iter_next, 0); cfunc_add_upval(cfunc, vm_get(0)); cfunc_add_upval(cfunc, create_num(0)); vm_push(wrap_cfunc(cfunc)); } void map_has(int argc) { (void)argc; if (vm_get(0).type != VAL_MAP) us_err("map:has expected a map"); struct us_map *map = get_map(vm_get(0)); bool has = map_get_value(map, vm_get(1), NULL); vm_push(create_bool(has)); } 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, 3); us_set_cfunc("arr:iter", arr_iter, 1); us_set_cfunc("arr:add", arr_add, 2); us_set_cfunc("map:has", map_has, 2); } void us_deinit(void) { deinit_vm(); } void us_load_file(const char *file_path) { char *file = read_file(file_path, NULL); us_load_src(file); mem_free(file); } void us_load_src(const char *src) { struct us_proto *proto = compile("main", src); if (!proto) return; us_exec(create_func(proto)); } int us_declare_global(const char *name) { return declare_global(copy_str(name, -1)); } void us_set_cfunc(const char *c_name, us_cfunc_sig c, int argc) { struct us_str *name = copy_str(c_name, -1); int global = declare_global(name); set_global(global, wrap_cfunc(create_cfunc(name, c, argc))); }