Compare commits
3 commits
3f2a8f3801
...
aa94396e51
Author | SHA1 | Date | |
---|---|---|---|
aa94396e51 | |||
06df2d37ee | |||
bea6e34365 |
3 changed files with 74 additions and 3 deletions
|
@ -25,6 +25,9 @@ const AllOpcodes = struct {
|
|||
pub Equal: u8 = 12,
|
||||
pub Greater: u8 = 13,
|
||||
pub Less: u8 = 14,
|
||||
|
||||
pub Print: u8 = 15,
|
||||
pub Pop: u8 = 16,
|
||||
};
|
||||
|
||||
pub const OpCode = AllOpcodes{};
|
||||
|
@ -189,6 +192,10 @@ pub const Chunk = struct {
|
|||
return try simpleInstruction(stdout, "OP_GREATER", index);
|
||||
} else if (instruction == OpCode.Less) {
|
||||
return try simpleInstruction(stdout, "OP_LESS", index);
|
||||
} else if (instruction == OpCode.Print) {
|
||||
return try simpleInstruction(stdout, "OP_PRINT", index);
|
||||
} else if (instruction == OpCode.Pop) {
|
||||
return try simpleInstruction(stdout, "OP_POP", index);
|
||||
} else {
|
||||
try stdout.print("Unknown opcode: {}\n", instruction);
|
||||
return index + 1;
|
||||
|
|
|
@ -186,6 +186,17 @@ pub const Compiler = struct {
|
|||
self.errorCurrent(msg);
|
||||
}
|
||||
|
||||
fn check(self: *Compiler, ttype: TokenType) bool {
|
||||
return self.parser.current.ttype == ttype;
|
||||
}
|
||||
|
||||
fn match(self: *Compiler, ttype: TokenType) !bool {
|
||||
if (!(self.check(ttype))) return false;
|
||||
|
||||
try self.advance();
|
||||
return true;
|
||||
}
|
||||
|
||||
fn currentChunk(self: *Compiler) *chunks.Chunk {
|
||||
return self.chunk;
|
||||
}
|
||||
|
@ -314,14 +325,57 @@ pub const Compiler = struct {
|
|||
try self.parsePrecedence(.Assignment);
|
||||
}
|
||||
|
||||
fn printStmt(self: *Compiler) !void {
|
||||
try self.expression();
|
||||
try self.consume(.SEMICOLON, "Expect ';' after value.");
|
||||
try self.emitByte(OpCode.Print);
|
||||
}
|
||||
|
||||
fn exprStmt(self: *Compiler) !void {
|
||||
try self.expression();
|
||||
try self.consume(.SEMICOLON, "Expect ';' after expression.");
|
||||
try self.emitByte(OpCode.Pop);
|
||||
}
|
||||
|
||||
fn synchronize(self: *Compiler) !void {
|
||||
self.parser.panicMode = false;
|
||||
|
||||
while (self.parser.current.ttype != .EOF) {
|
||||
if (self.parser.previous.ttype == .SEMICOLON) return;
|
||||
|
||||
switch (self.parser.current.ttype) {
|
||||
.CLASS, .FUN, .VAR, .FOR, .IF, .WHILE, .PRINT, .RETURN => return,
|
||||
else => {},
|
||||
}
|
||||
|
||||
try self.advance();
|
||||
}
|
||||
}
|
||||
|
||||
fn declaration(self: *Compiler) !void {
|
||||
try self.statement();
|
||||
if (self.parser.panicMode) try self.synchronize();
|
||||
}
|
||||
|
||||
fn statement(self: *Compiler) !void {
|
||||
if (try self.match(.PRINT)) {
|
||||
try self.printStmt();
|
||||
} else {
|
||||
try self.exprStmt();
|
||||
}
|
||||
}
|
||||
|
||||
/// Compile the source given when initializing the compiler
|
||||
/// into the given chunk.
|
||||
pub fn compile(self: *Compiler, chunk: *Chunk) !bool {
|
||||
self.scanr = try scanner.Scanner.init(self.allocator, self.src);
|
||||
|
||||
try self.advance();
|
||||
try self.expression();
|
||||
try self.consume(.EOF, "Expect end of expression.");
|
||||
while (!(try self.match(.EOF))) {
|
||||
try self.declaration();
|
||||
}
|
||||
// try self.expression();
|
||||
// try self.consume(.EOF, "Expect end of expression.");
|
||||
try self.end();
|
||||
|
||||
return !self.parser.hadError;
|
||||
|
|
12
src/vm.zig
12
src/vm.zig
|
@ -240,9 +240,14 @@ pub const VM = struct {
|
|||
break :blk;
|
||||
},
|
||||
|
||||
chunk.OpCode.Return => blk: {
|
||||
chunk.OpCode.Print => blk: {
|
||||
try value.printValue(self.stdout, self.pop());
|
||||
try self.stdout.print("\n");
|
||||
break :blk;
|
||||
},
|
||||
|
||||
chunk.OpCode.Return => blk: {
|
||||
// Exit VM
|
||||
return InterpretResult.Ok;
|
||||
},
|
||||
|
||||
|
@ -250,6 +255,11 @@ pub const VM = struct {
|
|||
chunk.OpCode.True => try self.push(values.BoolVal(true)),
|
||||
chunk.OpCode.False => try self.push(values.BoolVal(false)),
|
||||
|
||||
chunk.OpCode.Pop => blk: {
|
||||
_ = self.pop();
|
||||
break :blk;
|
||||
},
|
||||
|
||||
chunk.OpCode.Equal => blk: {
|
||||
var a = self.pop();
|
||||
var b = self.pop();
|
||||
|
|
Loading…
Reference in a new issue