Local Variables 22
This commit is contained in:
parent
4f2211eb72
commit
72a41e81e6
18 changed files with 1335 additions and 115 deletions
|
|
@ -12,19 +12,21 @@ import clox.compiler;
|
|||
import clox.memory;
|
||||
import clox.container.stack;
|
||||
import clox.container.table;
|
||||
import clox.container.varint;
|
||||
|
||||
VM vm;
|
||||
|
||||
struct VM{
|
||||
Chunk* chunk;
|
||||
ubyte* ip;
|
||||
Stack!(Value, 256) stack;
|
||||
Stack!Value stack;
|
||||
Table globals;
|
||||
Table strings;
|
||||
Obj* objects;
|
||||
bool isREPL;
|
||||
enum InterpretResult{ Ok, CompileError, RuntimeError }
|
||||
void initialise(){
|
||||
stack.reset();
|
||||
stack.initialise();
|
||||
strings.initialise();
|
||||
globals.initialise();
|
||||
}
|
||||
|
|
@ -32,6 +34,7 @@ struct VM{
|
|||
freeObjects();
|
||||
strings.free();
|
||||
globals.free();
|
||||
stack.free();
|
||||
}
|
||||
InterpretResult interpret(const char* source){
|
||||
Chunk cnk;
|
||||
|
|
@ -42,21 +45,27 @@ struct VM{
|
|||
if(!compiler.compile(source, &cnk))
|
||||
return InterpretResult.CompileError;
|
||||
this.chunk = &cnk;
|
||||
this.ip = cnk.code;
|
||||
this.ip = cnk.code.ptr;
|
||||
return run();
|
||||
}
|
||||
void runtimeError(Args...)(const char* format, Args args){
|
||||
fprintf(stderr, format, args);
|
||||
fputs("\n", stderr);
|
||||
|
||||
size_t instruction = vm.ip - vm.chunk.code - 1;
|
||||
int line = vm.chunk.lines[instruction];
|
||||
size_t instruction = vm.ip - vm.chunk.code.ptr - 1;
|
||||
uint line = vm.chunk.lines[instruction];
|
||||
fprintf(stderr, "[line %d] in script\n", line);
|
||||
stack.reset();
|
||||
}
|
||||
InterpretResult run(){
|
||||
ubyte readByte() => *vm.ip++;
|
||||
auto readConstant() => chunk.constants.values[readByte()];
|
||||
ubyte readByte() => *ip++;
|
||||
long readVarUint(){
|
||||
VarUint vi = VarUint.read(ip);
|
||||
ip += vi.len;
|
||||
return vi.i;
|
||||
}
|
||||
Value readConstant(){
|
||||
return chunk.constants[readVarUint()];
|
||||
}
|
||||
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);
|
||||
|
|
@ -73,7 +82,7 @@ struct VM{
|
|||
}
|
||||
while(true){
|
||||
debug(traceExec){
|
||||
disassembleInstruction(vm.chunk, cast(int)(vm.ip - vm.chunk.code));
|
||||
disassembleInstruction(vm.chunk, vm.ip - vm.chunk.code.ptr);
|
||||
printf(" ");
|
||||
foreach(slot; stack.live){
|
||||
printf("");
|
||||
|
|
@ -93,6 +102,14 @@ struct VM{
|
|||
case OpCode.False: stack.push(Value.from(false)); break;
|
||||
case OpCode.Pop: stack.pop(); break;
|
||||
|
||||
case OpCode.GetLocal:
|
||||
long slot = readVarUint();
|
||||
stack.push(stack[slot]);
|
||||
break;
|
||||
case OpCode.SetLocal:
|
||||
long slot = readVarUint();
|
||||
stack[slot] = peek(0);
|
||||
break;
|
||||
case OpCode.GetGlobal:
|
||||
Obj.String* name = readString();
|
||||
Value value;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue