Types of Values 18
This commit is contained in:
parent
41404633da
commit
10c44eab2e
7 changed files with 230 additions and 28 deletions
|
|
@ -9,6 +9,7 @@ import clox.util;
|
|||
import clox.compiler;
|
||||
import clox.container.stack;
|
||||
import clox.container.varint;
|
||||
import clox.container.int24;
|
||||
|
||||
enum stackMax = 256;
|
||||
|
||||
|
|
@ -33,7 +34,16 @@ struct VM{
|
|||
ip = &chunk.code[0];
|
||||
return run();
|
||||
}
|
||||
private InterpretResult run() @nogc nothrow {
|
||||
private void runtimeError(Args...)(string format, Args args) nothrow {
|
||||
size_t instruction = ip - (&chunk.code[0]) - 1;
|
||||
uint line = chunk.lines[instruction].toUint;
|
||||
try{
|
||||
stderr.writef("[line %d] ", line);
|
||||
stderr.writefln(format, args);
|
||||
} catch(Exception){}
|
||||
/* stack.reset(); */
|
||||
}
|
||||
private InterpretResult run() nothrow {
|
||||
auto readByte() => *ip++;
|
||||
auto readIns() => cast(OpCode)readByte();
|
||||
Value readConstant(){
|
||||
|
|
@ -41,6 +51,9 @@ struct VM{
|
|||
ip += constant.len;
|
||||
return chunk.constants[constant.i];
|
||||
}
|
||||
Value peek(int distance = 0){
|
||||
return stack.top[-1 - distance];
|
||||
}
|
||||
while(true){
|
||||
debug(traceExec){
|
||||
writeln(" ", stack.live);
|
||||
|
|
@ -52,15 +65,42 @@ struct VM{
|
|||
Value constant = readConstant();
|
||||
stack.push(constant);
|
||||
break;
|
||||
case True:
|
||||
stack.push(Value.bln(true));
|
||||
break;
|
||||
case False:
|
||||
stack.push(Value.bln(false));
|
||||
break;
|
||||
case Nil:
|
||||
stack.push(Value.nil());
|
||||
break;
|
||||
static foreach(k, op; [ Add: "+", Subtract: "-", Multiply: "*", Divide: "/" ]){
|
||||
case k:
|
||||
if(!peek(0).isNum || !peek(1).isNum){
|
||||
runtimeError("Operands must be numbers.");
|
||||
return InterpretResult.RuntimeError;
|
||||
}
|
||||
double b = stack.pop().getNum;
|
||||
double a = stack.pop().getNum;
|
||||
stack.push(Value.num(mixin("a", op, "b")));
|
||||
break opSwitch;
|
||||
}
|
||||
static foreach(k, op; [ NotEqual: "!=", Equal: "==", Greater: ">", GreaterEqual: ">=", Less: "<", LessEqual: "<=" ]){
|
||||
case k:
|
||||
Value b = stack.pop();
|
||||
Value a = stack.pop();
|
||||
stack.push(mixin("a", op, "b"));
|
||||
stack.push(Value.bln(compare!op(a, b)));
|
||||
break opSwitch;
|
||||
}
|
||||
case Not:
|
||||
stack.push(Value.bln(stack.pop().isFalsey));
|
||||
break;
|
||||
case Negate:
|
||||
stack.push(-stack.pop());
|
||||
if(!peek(0).isNum){
|
||||
runtimeError("Operand must be a number.");
|
||||
return InterpretResult.RuntimeError;
|
||||
}
|
||||
stack.push(Value.num(-stack.pop().getNum));
|
||||
break;
|
||||
case Return:
|
||||
debug printValue(stack.pop());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue