vig/src/parser.zig

74 lines
1.9 KiB
Zig
Raw Normal View History

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);
}
}
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();
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;
}
};