Refactored all OP_ functions to vm/CATEGORY/ and renamed the files.
This commit is contained in:
parent
108be8c41e
commit
50a91d0b6f
67 changed files with 91 additions and 92 deletions
|
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
project(fun VERSION 0.2.1 LANGUAGES C)
|
||||
project(fun VERSION 0.2.2 LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
|
|
|||
0
examples/objects_more.fun
Normal file → Executable file
0
examples/objects_more.fun
Normal file → Executable file
135
src/vm.c
135
src/vm.c
|
|
@ -193,69 +193,78 @@ void vm_run(VM *vm, Bytecode *entry) {
|
|||
|
||||
switch (inst.op) {
|
||||
/* All opcode handlers as .c includes */
|
||||
#include "vm_cases/core/vm_case_nop.c"
|
||||
#include "vm_cases/core/vm_case_load_const.c"
|
||||
#include "vm_cases/core/vm_case_load_local.c"
|
||||
#include "vm_cases/core/vm_case_store_local.c"
|
||||
#include "vm_cases/arithmetic/vm_case_add.c"
|
||||
#include "vm_cases/arithmetic/vm_case_sub.c"
|
||||
#include "vm_case_mul.c"
|
||||
#include "vm_case_div.c"
|
||||
#include "vm_case_lt.c"
|
||||
#include "vm_case_lte.c"
|
||||
#include "vm_cases/core/vm_case_jump.c"
|
||||
#include "vm_case_gt.c"
|
||||
#include "vm_case_gte.c"
|
||||
#include "vm_cases/logic/vm_case_eq.c"
|
||||
#include "vm_case_neq.c"
|
||||
#include "vm_cases/core/vm_case_jump_if_false.c"
|
||||
#include "vm_case_call.c"
|
||||
#include "vm_case_return.c"
|
||||
#include "vm_case_print.c"
|
||||
#include "vm_cases/core/vm_case_halt.c"
|
||||
#include "vm_case_pop.c"
|
||||
#include "vm_case_dup.c"
|
||||
#include "vm_case_swap.c"
|
||||
#include "vm_case_make_array.c"
|
||||
#include "vm_case_index_get.c"
|
||||
#include "vm_case_index_set.c"
|
||||
#include "vm_case_len.c"
|
||||
#include "vm_case_arr_push.c"
|
||||
#include "vm_case_arr_pop.c"
|
||||
#include "vm_case_arr_set.c"
|
||||
#include "vm_case_arr_insert.c"
|
||||
#include "vm_case_arr_remove.c"
|
||||
#include "vm_case_slice.c"
|
||||
#include "vm_case_to_number.c"
|
||||
#include "vm_case_to_string.c"
|
||||
#include "vm_case_split.c"
|
||||
#include "vm_case_join.c"
|
||||
#include "vm_case_substr.c"
|
||||
#include "vm_case_find.c"
|
||||
#include "vm_case_contains.c"
|
||||
#include "vm_case_index_of.c"
|
||||
#include "vm_case_clear.c"
|
||||
#include "vm_case_enumerate.c"
|
||||
#include "vm_case_zip.c"
|
||||
#include "vm_case_min.c"
|
||||
#include "vm_case_max.c"
|
||||
#include "vm_case_clamp.c"
|
||||
#include "vm_case_abs.c"
|
||||
#include "vm_case_pow.c"
|
||||
#include "vm_case_random_seed.c"
|
||||
#include "vm_case_random_int.c"
|
||||
#include "vm_case_make_map.c"
|
||||
#include "vm_case_keys.c"
|
||||
#include "vm_case_values.c"
|
||||
#include "vm_case_has_key.c"
|
||||
#include "vm_case_read_file.c"
|
||||
#include "vm_case_write_file.c"
|
||||
#include "vm_case_load_global.c"
|
||||
#include "vm_case_store_global.c"
|
||||
#include "vm_case_mod.c"
|
||||
#include "vm_case_and.c"
|
||||
#include "vm_case_or.c"
|
||||
#include "vm_case_not.c"
|
||||
#include "vm/arithmetic/add.c"
|
||||
#include "vm/arithmetic/div.c"
|
||||
#include "vm/arithmetic/mul.c"
|
||||
#include "vm/arithmetic/sub.c"
|
||||
|
||||
#include "vm/arrays/arr_insert.c"
|
||||
#include "vm/arrays/arr_pop.c"
|
||||
#include "vm/arrays/arr_push.c"
|
||||
#include "vm/arrays/arr_remove.c"
|
||||
#include "vm/arrays/arr_set.c"
|
||||
#include "vm/arrays/clear.c"
|
||||
#include "vm/arrays/contains.c"
|
||||
#include "vm/arrays/enumerate.c"
|
||||
#include "vm/arrays/index_get.c"
|
||||
#include "vm/arrays/index_of.c"
|
||||
#include "vm/arrays/index_set.c"
|
||||
#include "vm/arrays/join.c"
|
||||
#include "vm/arrays/make_array.c"
|
||||
#include "vm/arrays/slice.c"
|
||||
#include "vm/arrays/zip.c"
|
||||
|
||||
#include "vm/core/call.c"
|
||||
#include "vm/core/dup.c"
|
||||
#include "vm/core/halt.c"
|
||||
#include "vm/core/jump.c"
|
||||
#include "vm/core/jump_if_false.c"
|
||||
#include "vm/core/load_const.c"
|
||||
#include "vm/core/load_global.c"
|
||||
#include "vm/core/load_local.c"
|
||||
#include "vm/core/nop.c"
|
||||
#include "vm/core/pop.c"
|
||||
#include "vm/core/return.c"
|
||||
#include "vm/core/store_global.c"
|
||||
#include "vm/core/store_local.c"
|
||||
#include "vm/core/swap.c"
|
||||
|
||||
#include "vm/io/read_file.c"
|
||||
#include "vm/io/write_file.c"
|
||||
|
||||
#include "vm/logic/and.c"
|
||||
#include "vm/logic/eq.c"
|
||||
#include "vm/logic/gt.c"
|
||||
#include "vm/logic/gte.c"
|
||||
#include "vm/logic/lt.c"
|
||||
#include "vm/logic/lte.c"
|
||||
#include "vm/logic/neq.c"
|
||||
#include "vm/logic/not.c"
|
||||
#include "vm/logic/or.c"
|
||||
|
||||
#include "vm/maps/has_key.c"
|
||||
#include "vm/maps/keys.c"
|
||||
#include "vm/maps/make_map.c"
|
||||
#include "vm/maps/values.c"
|
||||
|
||||
#include "vm/math/abs.c"
|
||||
#include "vm/math/clamp.c"
|
||||
#include "vm/math/max.c"
|
||||
#include "vm/math/min.c"
|
||||
#include "vm/math/mod.c"
|
||||
#include "vm/math/pow.c"
|
||||
#include "vm/math/random_int.c"
|
||||
#include "vm/math/random_seed.c"
|
||||
|
||||
#include "vm/strings/find.c"
|
||||
#include "vm/strings/split.c"
|
||||
#include "vm/strings/substr.c"
|
||||
|
||||
#include "vm/len.c"
|
||||
#include "vm/print.c"
|
||||
#include "vm/to_number.c"
|
||||
#include "vm/to_string.c"
|
||||
|
||||
default:
|
||||
if (!opcode_is_valid(inst.op)) {
|
||||
fprintf(stderr, "Runtime error: unknown opcode %d (%s) at instruction %d\n",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ case OP_INDEX_GET: {
|
|||
if (idx.type != VAL_STRING) { fprintf(stderr, "INDEX_GET key must be string for map\n"); exit(1); }
|
||||
Value out;
|
||||
if (!map_get_copy(&container, idx.s ? idx.s : "", &out)) {
|
||||
/* missing -> nil */
|
||||
out = make_nil();
|
||||
}
|
||||
free_value(container);
|
||||
|
|
@ -11,7 +11,6 @@ case OP_INDEX_SET: {
|
|||
if (!array_set(&container, (int)idx.i, v)) {
|
||||
fprintf(stderr, "Runtime error: index out of range\n"); exit(1);
|
||||
}
|
||||
/* v moved into array */
|
||||
free_value(container);
|
||||
free_value(idx);
|
||||
} else if (container.type == VAL_MAP) {
|
||||
|
|
@ -4,6 +4,6 @@ case OP_POP: {
|
|||
exit(1);
|
||||
}
|
||||
Value v = pop_value(vm);
|
||||
free_value(v); // free the popped value
|
||||
free_value(v);
|
||||
break;
|
||||
}
|
||||
8
src/vm/core/return.c
Normal file
8
src/vm/core/return.c
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
case OP_RETURN: {
|
||||
Value retv;
|
||||
if (vm->sp >= 0) retv = pop_value(vm);
|
||||
else retv = make_nil();
|
||||
vm_pop_frame(vm);
|
||||
push_value(vm, retv);
|
||||
break;
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@ case OP_MAKE_MAP: {
|
|||
fprintf(stderr, "Map literal set failed\n"); exit(1);
|
||||
}
|
||||
free_value(key);
|
||||
/* val ownership moved */
|
||||
}
|
||||
push_value(vm, m);
|
||||
break;
|
||||
|
|
@ -2,11 +2,16 @@ case OP_CLAMP: {
|
|||
Value hi = pop_value(vm);
|
||||
Value lo = pop_value(vm);
|
||||
Value x = pop_value(vm);
|
||||
if (x.type != VAL_INT || lo.type != VAL_INT || hi.type != VAL_INT) { fprintf(stderr, "CLAMP expects ints\n"); exit(1); }
|
||||
if (x.type != VAL_INT || lo.type != VAL_INT || hi.type != VAL_INT) {
|
||||
fprintf(stderr, "CLAMP expects ints\n");
|
||||
exit(1);
|
||||
}
|
||||
int64_t v = x.i;
|
||||
if (v < lo.i) v = lo.i;
|
||||
if (v > hi.i) v = hi.i;
|
||||
push_value(vm, make_int(v));
|
||||
free_value(x); free_value(lo); free_value(hi);
|
||||
free_value(x);
|
||||
free_value(lo);
|
||||
free_value(hi);
|
||||
break;
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ case OP_POW: {
|
|||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (a.type != VAL_INT || b.type != VAL_INT) { fprintf(stderr, "POW expects ints\n"); exit(1); }
|
||||
/* simple integer pow */
|
||||
int64_t base = a.i;
|
||||
int64_t exp = b.i;
|
||||
int64_t res = 1;
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
case OP_PRINT: {
|
||||
Value v = pop_value(vm);
|
||||
/* snapshot value at print time (deep copy arrays) */
|
||||
Value snap = deep_copy_value(&v);
|
||||
free_value(v);
|
||||
if (vm->output_count < VM_OUTPUT_SIZE) {
|
||||
vm->output[vm->output_count++] = snap; // store snapshot
|
||||
vm->output[vm->output_count++] = snap;
|
||||
} else {
|
||||
free_value(snap); // prevent leak
|
||||
free_value(snap);
|
||||
fprintf(stderr, "Runtime error: output buffer overflow\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -1,28 +1,23 @@
|
|||
case OP_TO_NUMBER: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT) {
|
||||
/* pass-through */
|
||||
Value out = make_int(v.i);
|
||||
free_value(v);
|
||||
push_value(vm, out);
|
||||
} else if (v.type == VAL_STRING) {
|
||||
const char *s = v.s ? v.s : "";
|
||||
/* trim spaces */
|
||||
const char *p = s;
|
||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') p++;
|
||||
char *endp = NULL;
|
||||
long long parsed = strtoll(p, &endp, 10);
|
||||
/* skip trailing spaces */
|
||||
while (endp && (*endp == ' ' || *endp == '\t' || *endp == '\r' || *endp == '\n')) endp++;
|
||||
if (endp && *endp != '\0') {
|
||||
/* non-numeric suffix -> 0 */
|
||||
push_value(vm, make_int(0));
|
||||
} else {
|
||||
push_value(vm, make_int((int64_t)parsed));
|
||||
}
|
||||
free_value(v);
|
||||
} else {
|
||||
/* nil, array, function -> 0 */
|
||||
free_value(v);
|
||||
push_value(vm, make_int(0));
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
case OP_RETURN: {
|
||||
Value retv;
|
||||
/* if there's something on the stack -> return it, else nil */
|
||||
if (vm->sp >= 0) retv = pop_value(vm);
|
||||
else retv = make_nil();
|
||||
|
||||
/* pop frame (free locals) */
|
||||
vm_pop_frame(vm);
|
||||
|
||||
/* push return value into caller frame (or onto stack if no caller) */
|
||||
push_value(vm, retv);
|
||||
break;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue