Global Variables 21
This commit is contained in:
parent
a7b7348f61
commit
4f2211eb72
9 changed files with 178 additions and 36 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue