2019-06-05 01:11:11 +00:00
|
|
|
const std = @import("std");
|
|
|
|
const scanners = @import("scanner.zig");
|
|
|
|
const main = @import("main.zig");
|
|
|
|
const ast = @import("ast.zig");
|
|
|
|
const tokens = @import("tokens.zig");
|
|
|
|
|
|
|
|
const Allocator = std.mem.Allocator;
|
|
|
|
const Scanner = scanners.Scanner;
|
|
|
|
const AstNode = ast.AstNode;
|
|
|
|
const Token = tokens.Token;
|
|
|
|
const TokenType = tokens.TokenType;
|
|
|
|
const Result = main.Result;
|
|
|
|
|
|
|
|
pub const Parser = struct {
|
|
|
|
allocator: *Allocator,
|
|
|
|
scanner: *Scanner,
|
|
|
|
current: Token = undefined,
|
|
|
|
root: AstNode = undefined,
|
|
|
|
|
|
|
|
pub fn init(allocator: *Allocator, scanner: *Scanner) Parser {
|
|
|
|
return Parser{ .allocator = allocator, .scanner = scanner };
|
|
|
|
}
|
|
|
|
|
|
|
|
fn doError(self: *Parser, comptime fmt: []const u8, args: ...) !void {
|
|
|
|
std.debug.warn("parser error at line {}\n\t", self.scanner.line);
|
|
|
|
std.debug.warn(fmt, args);
|
|
|
|
std.debug.warn("\n");
|
|
|
|
|
|
|
|
return Result.CompileError;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn advance(self: *Parser) !void {
|
|
|
|
var tok_opt = try self.scanner.nextToken();
|
|
|
|
if (tok_opt) |tok| {
|
|
|
|
self.current = tok;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn accept(self: *Parser, ttype: TokenType) !bool {
|
|
|
|
if (self.current.ttype == ttype) {
|
|
|
|
try self.advance();
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn expect(self: *Parser, ttype: TokenType) !void {
|
|
|
|
if (!try self.accept(ttype)) {
|
|
|
|
try self.doError("expected {x}, got {}", ttype, self.current.ttype);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-05 02:44:27 +00:00
|
|
|
fn statement(self: *Parser) !void {}
|
|
|
|
|
|
|
|
fn block(self: *Parser) !void {}
|
|
|
|
|
2019-06-05 01:11:11 +00:00
|
|
|
fn program(self: *Parser) !void {
|
|
|
|
try self.advance();
|
2019-06-05 02:44:27 +00:00
|
|
|
try self.block();
|
2019-06-05 01:11:11 +00:00
|
|
|
try self.expect(.EOF);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn parse(self: *Parser) !AstNode {
|
|
|
|
self.root = AstNode{
|
|
|
|
.Program = try self.allocator.alloc(AstNode, 0),
|
|
|
|
};
|
|
|
|
|
|
|
|
try self.program();
|
|
|
|
|
|
|
|
return self.root;
|
|
|
|
}
|
|
|
|
};
|