Compare commits
No commits in common. "2736bee8d8552ae80d7d4079a0ffa81792354b36" and "7d7aabbdd7df8da75cc510fd1165f475b5c7acc6" have entirely different histories.
2736bee8d8
...
7d7aabbdd7
3 changed files with 27 additions and 105 deletions
114
src/compiler.zig
114
src/compiler.zig
|
@ -1,124 +1,54 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const scanner = @import("new_scanner.zig");
|
const scanner = @import("new_scanner.zig");
|
||||||
const vm = @import("vm.zig");
|
const vm = @import("vm.zig");
|
||||||
const chunks = @import("chunk.zig");
|
|
||||||
const tokens = @import("token.zig");
|
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const Scanner = scanner.Scanner;
|
const TokenType = @import("token.zig").TokenType;
|
||||||
const Chunk = chunks.Chunk;
|
|
||||||
const Token = tokens.Token;
|
|
||||||
const TokenType = tokens.TokenType;
|
|
||||||
|
|
||||||
pub const Parser = struct {
|
|
||||||
previous: Token = undefined,
|
|
||||||
current: Token = undefined,
|
|
||||||
|
|
||||||
// TODO are those needed
|
|
||||||
hadError: bool = false,
|
|
||||||
panicMode: bool = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Compiler = struct {
|
pub const Compiler = struct {
|
||||||
src: []const u8,
|
src: []const u8,
|
||||||
stdout: vm.StdOut,
|
stdout: vm.StdOut,
|
||||||
allocator: *Allocator,
|
allocator: *Allocator,
|
||||||
parser: Parser,
|
|
||||||
scanr: Scanner = undefined,
|
|
||||||
chunk: *chunks.Chunk,
|
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(
|
||||||
allocator: *Allocator,
|
allocator: *Allocator,
|
||||||
chunk: *chunks.Chunk,
|
|
||||||
stdout: vm.StdOut,
|
stdout: vm.StdOut,
|
||||||
source: []const u8,
|
source: []const u8,
|
||||||
) Compiler {
|
) Compiler {
|
||||||
return Compiler{
|
return Compiler{
|
||||||
.src = source,
|
.src = source,
|
||||||
.chunk = chunk,
|
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.stdout = stdout,
|
.stdout = stdout,
|
||||||
.parser = Parser{},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn errorAt(self: *Compiler, token: Token, msg: []const u8) void {
|
pub fn compile(self: *Compiler) !void {
|
||||||
if (self.parser.panicMode) return;
|
var scanr = try scanner.Scanner.init(self.allocator, self.src);
|
||||||
self.parser.panicMode = true;
|
var line: usize = 0;
|
||||||
|
|
||||||
std.debug.warn("[line {}] Error", token.line);
|
|
||||||
if (token.ttype == TokenType.EOF) {
|
|
||||||
std.debug.warn(" at end");
|
|
||||||
} else {
|
|
||||||
std.debug.warn(" at '{}'", token.lexeme);
|
|
||||||
}
|
|
||||||
|
|
||||||
std.debug.warn(": {}\n", msg);
|
|
||||||
self.parser.hadError = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn errorCurrent(self: *Compiler, msg: []const u8) void {
|
|
||||||
self.errorAt(self.parser.current, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn errorPrevious(self: *Compiler, msg: []const u8) void {
|
|
||||||
self.errorAt(self.parser.previous, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn advance(self: *Compiler) !void {
|
|
||||||
self.parser.previous = self.parser.current;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
var token_opt = try self.scanr.scanToken();
|
var token_opt = scanr.scanToken() catch |err| {
|
||||||
if (token_opt) |token| {
|
std.debug.warn("Scan Error: {x}\n", err);
|
||||||
self.parser.current = token;
|
std.debug.warn(
|
||||||
|
"line: {}, cur lexeme: {}\n",
|
||||||
|
scanr.line,
|
||||||
|
scanr.currentLexeme(),
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (token_opt) |token| {
|
||||||
|
if (token.line != line) {
|
||||||
|
try self.stdout.print("{} ", token.line);
|
||||||
|
line = token.line;
|
||||||
} else {
|
} else {
|
||||||
self.errorCurrent(self.parser.current.lexeme);
|
try self.stdout.print(" | ");
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consume(self: *Compiler, ttype: TokenType, msg: []const u8) !void {
|
try self.stdout.print("{} '{}'\n", token.ttype, token.lexeme);
|
||||||
if (self.parser.current.ttype == ttype) {
|
if (token.ttype == TokenType.EOF) break;
|
||||||
try self.advance();
|
} else {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.errorCurrent(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn currentChunk(self: *Compiler) *chunks.Chunk {
|
|
||||||
return self.chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn emitByte(self: *Compiler, byte: u8) !void {
|
|
||||||
try self.currentChunk().write(byte, self.parser.previous.line);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn emitBytes(self: *Compiler, byte1: u8, byte2: u82) !void {
|
|
||||||
try self.emitByte(byte1);
|
|
||||||
try self.emitByte(byte2);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn writeReturn(self: *Compiler) !void {
|
|
||||||
try self.emitByte(chunks.OpCode.Return);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(self: *Compiler) !void {
|
|
||||||
try self.writeReturn();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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.");
|
|
||||||
try self.end();
|
|
||||||
|
|
||||||
return !self.parser.hadError;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -230,7 +230,6 @@ pub const Scanner = struct {
|
||||||
pub fn scanToken(self: *Scanner) !?Token {
|
pub fn scanToken(self: *Scanner) !?Token {
|
||||||
self.skipWhitespace();
|
self.skipWhitespace();
|
||||||
self.start = self.current;
|
self.start = self.current;
|
||||||
|
|
||||||
if (self.isAtEnd()) return self.makeToken(TokenType.EOF);
|
if (self.isAtEnd()) return self.makeToken(TokenType.EOF);
|
||||||
|
|
||||||
var c = self.advance();
|
var c = self.advance();
|
||||||
|
|
13
src/vm.zig
13
src/vm.zig
|
@ -165,16 +165,9 @@ pub const VM = struct {
|
||||||
//var res = try self.run();
|
//var res = try self.run();
|
||||||
//self.debug("VM end\n");
|
//self.debug("VM end\n");
|
||||||
//return res;
|
//return res;
|
||||||
var chk = try Chunk.init(self.allocator);
|
var cmpr = Compiler.init(self.allocator, self.stdout, self.src);
|
||||||
|
try cmpr.compile();
|
||||||
var cmpr = Compiler.init(self.allocator, &chk, self.stdout, self.src);
|
return InterpretResult.Ok;
|
||||||
if (!try cmpr.compile(&chk)) {
|
|
||||||
return InterpretResult.CompileError;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.chk = &chk;
|
|
||||||
self.ip = 0;
|
|
||||||
return try self.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(self: *VM, val: Value) !void {
|
pub fn push(self: *VM, val: Value) !void {
|
||||||
|
|
Loading…
Reference in a new issue