1
0
Fork 0
forked from fun/fun

Refactored all OP_ functions to vm/CATEGORY/ and renamed the files.

This commit is contained in:
Johannes Findeisen 2025-09-15 23:26:42 +02:00
commit 50a91d0b6f
67 changed files with 91 additions and 92 deletions

View file

@ -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
View file

135
src/vm.c
View file

@ -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",

View file

@ -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);

View file

@ -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) {

View file

@ -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
View 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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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;
}