Global Variables 21

This commit is contained in:
nazrin 2025-06-07 08:05:31 +00:00
parent a7b7348f61
commit 4f2211eb72
9 changed files with 178 additions and 36 deletions

View file

@ -3,6 +3,7 @@ module clox.vm;
import core.stdc.stdio;
import clox.chunk;
import clox.util;
import clox.dbg;
import clox.object;
import clox.value;
@ -18,16 +19,19 @@ struct VM{
Chunk* chunk;
ubyte* ip;
Stack!(Value, 256) stack;
Table globals;
Table strings;
Obj* objects;
enum InterpretResult{ Ok, CompileError, RuntimeError }
void initialise(){
stack.reset();
strings.initialise();
globals.initialise();
}
void free(){
freeObjects();
strings.free();
globals.free();
}
InterpretResult interpret(const char* source){
Chunk cnk;
@ -53,7 +57,8 @@ struct VM{
InterpretResult run(){
ubyte readByte() => *vm.ip++;
auto readConstant() => chunk.constants.values[readByte()];
Value peek(int distance) => stack.top[-1 - distance];
Obj.String* readString() => readConstant().asObj.asString;
Value peek(int distance = 0) => stack.top[-1 - distance];
bool checkBinaryType(alias type)() => peek(0).isType(type) && peek(1).isType(type);
bool checkSameType()() => peek(0).type == peek(1).type;
int binaryOp(string op, alias check, string checkMsg, alias pre)(){
@ -68,14 +73,14 @@ struct VM{
}
while(true){
debug(traceExec){
printf(" ");
disassembleInstruction(vm.chunk, cast(int)(vm.ip - vm.chunk.code));
printf(" ");
foreach(slot; stack.live){
printf("[ ");
printf("");
slot.print();
printf(" ]");
printf(colour!(", ", Colour.Black).ptr);
}
printf("\n");
disassembleInstruction(vm.chunk, cast(int)(vm.ip - vm.chunk.code));
}
OpCode instruction;
opSwitch: final switch(instruction = cast(OpCode)readByte()){
@ -86,6 +91,30 @@ struct VM{
case OpCode.Nil: stack.push(Value.nil); break;
case OpCode.True: stack.push(Value.from(true)); break;
case OpCode.False: stack.push(Value.from(false)); break;
case OpCode.Pop: stack.pop(); break;
case OpCode.GetGlobal:
Obj.String* name = readString();
Value value;
if(!globals.get(name, value)){
runtimeError("Undefined variable '%s'.", name.chars.ptr);
return InterpretResult.RuntimeError;
}
stack.push(value);
break;
case OpCode.DefineGlobal:
Obj.String* name = readString();
globals.set(name, peek(0));
stack.pop();
break;
case OpCode.SetGlobal:
Obj.String* name = readString();
if(globals.set(name, peek(0))){
globals.del(name);
runtimeError("Undefined variable '%s'.", name.chars.ptr);
return InterpretResult.RuntimeError;
}
break;
static foreach(k, op; [ OpCode.Equal: "==", OpCode.NotEqual: "!=" ]){
case k:
@ -125,9 +154,11 @@ struct VM{
}
stack.push(Value.from(-stack.pop().asNumber));
break;
case OpCode.Return:
case OpCode.Print:
stack.pop().print();
printf("\n");
break;
case OpCode.Return:
return InterpretResult.Ok;
}
}