94 lines
2.2 KiB
Zig
94 lines
2.2 KiB
Zig
const std = @import("std");
|
|
|
|
const scanners = @import("scanners.zig");
|
|
const parsers = @import("parsers.zig");
|
|
const printer = @import("ast_printer.zig");
|
|
const codegen = @import("codegen.zig");
|
|
const types = @import("types.zig");
|
|
|
|
pub const Result = enum {
|
|
Ok,
|
|
TokenizeError,
|
|
ParseError,
|
|
CompileError,
|
|
};
|
|
|
|
pub fn run(allocator: *std.mem.Allocator, slice: []const u8) !Result {
|
|
var scan = scanners.Scanner.init(allocator, slice);
|
|
|
|
// do a full scan pass, then reset, then do it again (with parser)
|
|
while (true) {
|
|
var tok_opt = scan.nextToken() catch |err| {
|
|
std.debug.warn(
|
|
"error at '{}': {}\n",
|
|
scan.currentLexeme(),
|
|
err,
|
|
);
|
|
|
|
return Result.TokenizeError;
|
|
};
|
|
|
|
if (tok_opt) |tok| {
|
|
if (tok.typ == .EOF) break;
|
|
|
|
// TODO remove
|
|
std.debug.warn("{x}\n", tok);
|
|
}
|
|
}
|
|
|
|
scan.reset();
|
|
|
|
var parser = parsers.Parser.init(allocator, &scan);
|
|
var root_opt = try parser.parse();
|
|
|
|
if (root_opt == null) {
|
|
return Result.ParseError;
|
|
}
|
|
|
|
var root = root_opt.?;
|
|
|
|
std.debug.warn("parse tree\n");
|
|
printer.printNode(root, 0);
|
|
|
|
var solver = types.TypeSolver.init(allocator);
|
|
var ctx = try solver.pass(root);
|
|
|
|
std.debug.warn("symbol table\n");
|
|
printer.printContext(ctx);
|
|
|
|
var cgen = codegen.Codegen.init(allocator);
|
|
try cgen.gen(root);
|
|
|
|
return Result.Ok;
|
|
}
|
|
|
|
pub fn main() anyerror!void {
|
|
const allocator = std.heap.direct_allocator;
|
|
var args_it = std.process.args();
|
|
_ = args_it.skip();
|
|
|
|
const filepath = try (args_it.next(allocator) orelse @panic("expected file path"));
|
|
|
|
var file = try std.fs.File.openRead(filepath);
|
|
defer file.close();
|
|
|
|
const total_bytes = try file.getEndPos();
|
|
|
|
var slice = try allocator.alloc(u8, total_bytes);
|
|
defer allocator.free(slice);
|
|
|
|
_ = try file.read(slice);
|
|
|
|
const result = try run(allocator, slice);
|
|
switch (result) {
|
|
.Ok => std.os.exit(0),
|
|
|
|
.TokenizeError,
|
|
.ParseError,
|
|
.CompileError,
|
|
=> {
|
|
std.debug.warn("error: {}\n", result);
|
|
std.os.exit(1);
|
|
},
|
|
}
|
|
}
|