1
0
Fork 0
forked from fun/fun

Some variable refactoring in vm.h and cleanups.

This commit is contained in:
Johannes Findeisen 2025-09-16 11:59:48 +02:00
commit c641599366
9 changed files with 32 additions and 43 deletions

View file

@ -27,9 +27,7 @@
* - Exits with an error if file loading or parsing fails.
*
* Example:
* ```bash
* $ fun script.fun
* ```
*
* @author Johannes Findeisen
* @date 2025-10-16
@ -474,7 +472,7 @@ int main(int argc, char **argv) {
int filtered = (pattern && *pattern);
printf("=== globals%s%s ===\n", filtered ? " matching '" : "", filtered ? pattern : "");
if (filtered) printf("'\n");
for (int i = 0; i < VM_MAX_GLOBALS; ++i) {
for (int i = 0; i < MAX_GLOBALS; ++i) {
if (vm.globals[i].type == VAL_NIL) continue;
char *sv = value_to_string_alloc(&vm.globals[i]);
if (!filtered || (sv && strstr(sv, pattern))) {

View file

@ -88,7 +88,7 @@ static void calc_line_col(const char *src, size_t len, size_t pos, int *out_line
/* very small global symbol table for LOAD_GLOBAL/STORE_GLOBAL */
static struct {
char *names[VM_MAX_GLOBALS];
char *names[MAX_GLOBALS];
int count;
} G = { {0}, 0 };
@ -96,8 +96,8 @@ static int sym_index(const char *name) {
for (int i = 0; i < G.count; ++i) {
if (strcmp(G.names[i], name) == 0) return i;
}
if (G.count >= VM_MAX_GLOBALS) {
parser_fail(0, "Too many globals (max %d)", VM_MAX_GLOBALS);
if (G.count >= MAX_GLOBALS) {
parser_fail(0, "Too many globals (max %d)", MAX_GLOBALS);
return 0;
}
G.names[G.count] = strdup(name);
@ -106,7 +106,7 @@ static int sym_index(const char *name) {
/* ---- locals environment for functions ---- */
typedef struct {
char *names[FRAME_MAX_LOCALS];
char *names[MAX_FRAME_LOCALS];
int count;
} LocalEnv;
@ -133,8 +133,8 @@ static int local_find(const char *name) {
static int local_add(const char *name) {
if (!g_locals) return -1;
if (g_locals->count >= FRAME_MAX_LOCALS) {
parser_fail(0, "Too many local variables/parameters (max %d)", FRAME_MAX_LOCALS);
if (g_locals->count >= MAX_FRAME_LOCALS) {
parser_fail(0, "Too many local variables/parameters (max %d)", MAX_FRAME_LOCALS);
return -1;
}
int idx = g_locals->count++;

View file

@ -85,10 +85,10 @@ Dev tips:
static const char* value_type_name(ValueType t) {
switch (t) {
case VAL_INT: return "int";
case VAL_STRING: return "string";
case VAL_FUNCTION: return "function";
case VAL_INT: return "int";
case VAL_NIL: return "nil";
case VAL_STRING: return "string";
default: return "unknown";
}
}
@ -115,7 +115,7 @@ void vm_reset(VM *vm) {
// Clear stack
vm->sp = -1;
// Free globals
for (int i = 0; i < VM_MAX_GLOBALS; ++i) {
for (int i = 0; i < MAX_GLOBALS; ++i) {
free_value(vm->globals[i]);
vm->globals[i] = make_nil();
}
@ -125,7 +125,7 @@ void vm_reset(VM *vm) {
void vm_dump_globals(VM *vm) {
printf("=== globals ===\n");
for (int i = 0; i < VM_MAX_GLOBALS; ++i) {
for (int i = 0; i < MAX_GLOBALS; ++i) {
if (vm->globals[i].type != VAL_NIL) {
printf("[%d] ", i);
print_value(&vm->globals[i]);
@ -136,7 +136,7 @@ void vm_dump_globals(VM *vm) {
}
static void push_value(VM *vm, Value v) {
if (vm->sp >= VM_STACK_SIZE - 1) {
if (vm->sp >= STACK_SIZE - 1) {
fprintf(stderr, "Runtime error: stack overflow\n");
exit(1);
}
@ -154,7 +154,7 @@ static Value pop_value(VM *vm) {
static void frame_init(Frame *f) {
f->fn = NULL;
f->ip = 0;
for (int i = 0; i < FRAME_MAX_LOCALS; ++i) f->locals[i] = make_nil();
for (int i = 0; i < MAX_FRAME_LOCALS; ++i) f->locals[i] = make_nil();
}
void vm_init(VM *vm) {
@ -162,13 +162,13 @@ void vm_init(VM *vm) {
vm->fp = -1;
vm->output_count = 0;
vm->instr_count = 0;
for (int i = 0; i < VM_MAX_GLOBALS; ++i)
for (int i = 0; i < MAX_GLOBALS; ++i)
vm->globals[i] = make_nil();
}
/* push a new frame, transferring ownership of args[] into frame->locals[0..argc-1] */
static void vm_push_frame(VM *vm, Bytecode *fn, int argc, Value *args) {
if (vm->fp >= VM_MAX_FRAMES - 1) {
if (vm->fp >= MAX_FRAMES - 1) {
fprintf(stderr, "Runtime error: too many frames\n");
exit(1);
}
@ -177,7 +177,7 @@ static void vm_push_frame(VM *vm, Bytecode *fn, int argc, Value *args) {
f->fn = fn;
f->ip = 0;
/* move args into locals 0..argc-1 */
for (int i = 0; i < argc && i < FRAME_MAX_LOCALS; ++i) {
for (int i = 0; i < argc && i < MAX_FRAME_LOCALS; ++i) {
f->locals[i] = args[i]; /* transfer ownership */
}
}
@ -189,7 +189,7 @@ static void vm_pop_frame(VM *vm) {
exit(1);
}
Frame *f = &vm->frames[vm->fp];
for (int i = 0; i < FRAME_MAX_LOCALS; ++i) {
for (int i = 0; i < MAX_FRAME_LOCALS; ++i) {
free_value(f->locals[i]);
f->locals[i] = make_nil();
}

View file

@ -7,25 +7,16 @@
* https://opensource.org/license/isc-license-txt
*/
/**
* This file is part of the Fun programming language.
* https://hanez.org/project/fun/
*
* Copyright 2025 Johannes Findeisen <you@hanez.org>
* Licensed under the terms of the ISC license.
* https://opensource.org/license/isc-license-txt
*/
#ifndef FUN_VM_H
#define FUN_VM_H
#include "bytecode.h"
#define VM_STACK_SIZE 1024
#define VM_MAX_FRAMES 128
#define VM_MAX_GLOBALS 128
#define VM_OUTPUT_SIZE 1024
#define FRAME_MAX_LOCALS 64
#define MAX_FRAMES 128
#define MAX_FRAME_LOCALS 64
#define MAX_GLOBALS 128
#define OUTPUT_SIZE 1024
#define STACK_SIZE 1024
static const char *opcode_names[] = {
"NOP","LOAD_CONST","LOAD_LOCAL","STORE_LOCAL",
@ -48,19 +39,19 @@ static const char *opcode_names[] = {
typedef struct {
Bytecode *fn;
int ip;
Value locals[FRAME_MAX_LOCALS];
Value locals[MAX_FRAME_LOCALS];
} Frame;
typedef struct {
Value stack[VM_STACK_SIZE];
Value stack[STACK_SIZE];
int sp;
Frame frames[VM_MAX_FRAMES];
Frame frames[MAX_FRAMES];
int fp; // frame pointer, -1 when no frame
Value globals[VM_MAX_GLOBALS];
Value globals[MAX_GLOBALS];
Value output[VM_OUTPUT_SIZE]; // store printed values
Value output[OUTPUT_SIZE]; // store printed values
int output_count;
long long instr_count; // executed instructions in the last vm_run

View file

@ -32,7 +32,7 @@
case OP_LOAD_GLOBAL: {
int idx = inst.operand;
if (idx < 0 || idx >= VM_MAX_GLOBALS) {
if (idx < 0 || idx >= MAX_GLOBALS) {
fprintf(stderr, "Runtime error: global index out of range\n");
exit(1);
}

View file

@ -32,7 +32,7 @@
case OP_LOAD_LOCAL: {
int slot = inst.operand;
if (slot < 0 || slot >= FRAME_MAX_LOCALS) {
if (slot < 0 || slot >= MAX_FRAME_LOCALS) {
fprintf(stderr, "Runtime error: local slot out of range\n");
exit(1);
}

View file

@ -32,7 +32,7 @@
case OP_STORE_GLOBAL: {
int idx = inst.operand;
if (idx < 0 || idx >= VM_MAX_GLOBALS) {
if (idx < 0 || idx >= MAX_GLOBALS) {
fprintf(stderr, "Runtime error: global index out of range\n");
exit(1);
}

View file

@ -32,7 +32,7 @@
case OP_STORE_LOCAL: {
int slot = inst.operand;
if (slot < 0 || slot >= FRAME_MAX_LOCALS) {
if (slot < 0 || slot >= MAX_FRAME_LOCALS) {
fprintf(stderr, "Runtime error: local slot out of range\n");
exit(1);
}

View file

@ -31,7 +31,7 @@ case OP_PRINT: {
Value v = pop_value(vm);
Value snap = deep_copy_value(&v);
free_value(v);
if (vm->output_count < VM_OUTPUT_SIZE) {
if (vm->output_count < OUTPUT_SIZE) {
vm->output[vm->output_count++] = snap;
} else {
free_value(snap);