Some variable refactoring in vm.h and cleanups.
This commit is contained in:
parent
6b14c2776e
commit
c641599366
9 changed files with 32 additions and 43 deletions
|
|
@ -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))) {
|
||||
|
|
|
|||
12
src/parser.c
12
src/parser.c
|
|
@ -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++;
|
||||
|
|
|
|||
20
src/vm.c
20
src/vm.c
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
29
src/vm.h
29
src/vm.h
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue