Skip to content

Commit

Permalink
Restructure Compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
yukiisbored committed Apr 13, 2024
1 parent 0f0405c commit 1c08668
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 197 deletions.
82 changes: 82 additions & 0 deletions src/Ast.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const std = @import("std");
const Scanner = @import("./Scanner.zig");

const Self = @This();

i: Inner,
t: Scanner.Token,

pub const Inner = union(enum) {
n: i32,
b: bool,
s: []const u8,
id: []const u8,
@"if": If,
@"while": []const Self,
add,
sub,
div,
mul,

pub const If = struct {
if_true: []const Self,
if_false: []const Self,
};

pub fn print(self: Inner, writer: anytype) !void {
try switch (self) {
.n => |n| std.fmt.format(writer, "(n {})", .{n}),
.b => |b| std.fmt.format(writer, "(b {})", .{b}),
.s => |s| std.fmt.format(writer, "(s '{s}')", .{s}),
.id => |i| std.fmt.format(writer, "(id '{s}')", .{i}),
.@"if" => |i| {
try writer.writeAll("(if (");
for (0.., i.if_true) |n, x| {
try x.i.print(writer);
if (n < i.if_true.len - 1) {
try writer.writeAll(" ");
}
}
try writer.writeAll(") (");
for (0.., i.if_false) |n, x| {
try x.i.print(writer);
if (n < i.if_false.len - 1) {
try writer.writeAll(" ");
}
}
try writer.writeAll("))");
},
.@"while" => |w| {
try writer.writeAll("(while (");
for (0.., w) |n, x| {
try x.i.print(writer);
if (n < w.len - 1) {
try writer.writeAll(" ");
}
}
try writer.writeAll("))");
},
.add => writer.writeAll("(add)"),
.sub => writer.writeAll("(sub)"),
.div => writer.writeAll("(div)"),
.mul => writer.writeAll("(mul)"),
};
}
};

pub const Routine = struct {
name: []const u8,
ast: []const Self,
token: Scanner.Token,

pub fn print(self: Routine, writer: anytype) !void {
try std.fmt.format(writer, "(routine '{s}' (", .{self.name});
for (0.., self.ast) |n, x| {
try x.i.print(writer);
if (n < self.ast.len - 1) {
try writer.writeAll(" ");
}
}
try writer.writeAll("))");
}
};
113 changes: 113 additions & 0 deletions src/Compiler.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
const std = @import("std");

const Scanner = @import("./Scanner.zig");
const Vm = @import("./Vm.zig");
const Ast = @import("./Ast.zig");

const Self = @This();

allocator: std.mem.Allocator,
routines: std.ArrayList(Routine),

pub fn init(allocator: std.mem.Allocator) !Self {
return Self{
.allocator = allocator,
.routines = std.ArrayList(Routine).init(allocator),
};
}

pub fn deinit(self: *Self) void {
for (self.routines.items) |ir| {
ir.deinit();
}
self.routines.deinit();
}

pub fn compile(self: *Self, vm: *Vm, routines: []const Ast.Routine) !void {
for (routines) |r| {
var i = try Routine.init(self.allocator);
try i.compile(r.ast);
try i.emit(.ret, r.token);
try vm.addRoutine(r.name, i.instructions.items, i.tokens.items);
try self.routines.append(i);
}
}

pub const Routine = struct {
instructions: std.ArrayList(Vm.Instruction),
tokens: std.ArrayList(Scanner.Token),

pub fn init(allocator: std.mem.Allocator) !Routine {
return Routine{
.instructions = std.ArrayList(Vm.Instruction).init(allocator),
.tokens = std.ArrayList(Scanner.Token).init(allocator),
};
}

pub fn deinit(self: *const Routine) void {
self.instructions.deinit();
self.tokens.deinit();
}

pub fn emit(
self: *Routine,
instruction: Vm.Instruction,
token: Scanner.Token,
) !void {
try self.instructions.append(instruction);
try self.tokens.append(token);
}

pub fn compile(
self: *Routine,
routine: []const Ast,
) !void {
for (routine) |c| {
switch (c.i) {
.add => try self.emit(.add, c.t),
.sub => try self.emit(.sub, c.t),
.div => try self.emit(.div, c.t),
.mul => try self.emit(.mul, c.t),
.n => |n| try self.emit(.{ .psh = .{ .n = n } }, c.t),
.b => |b| try self.emit(.{ .psh = .{ .b = b } }, c.t),
.s => |s| try self.emit(.{ .psh = .{ .s = s } }, c.t),
.id => |s| try self.emit(.{ .cal = s }, c.t),
.@"if" => |s| {
try self.emit(.{ .jif = 0 }, c.t);
const false_jump_index = self.instructions.items.len - 1;

try self.compile(s.if_true);

try self.emit(.{ .jmp = 0 }, c.t);
const end_jump_index = self.instructions.items.len - 1;

const false_jump = end_jump_index + 1;
try self.compile(s.if_false);

try self.emit(.nop, c.t);

const end_jump = self.instructions.items.len - 1;

self.instructions.items[false_jump_index] = .{ .jif = false_jump };
self.instructions.items[end_jump_index] = .{ .jmp = end_jump };
},
.@"while" => |s| {
const start_index = self.instructions.items.len;

try self.compile(s);
try self.emit(.{ .jif = 0 }, c.t);

const false_jump_index = self.instructions.items.len - 1;

try self.emit(.{ .jmp = start_index }, c.t);

const false_jump = self.instructions.items.len;

self.instructions.items[false_jump_index] = .{ .jif = false_jump };
},
}
}
}
};


10 changes: 4 additions & 6 deletions src/Parser.zig
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
const std = @import("std");

const Scanner = @import("./Scanner.zig");
const compiler = @import("./compiler.zig");
const Ast = compiler.Ast;
const Program = compiler.Program;
const Ast = @import("./Ast.zig");


const Self = @This();

arena: std.heap.ArenaAllocator,

scanner: *Scanner,
routines: *std.ArrayList(Program.Routine),
routines: *std.ArrayList(Ast.Routine),

current: Scanner.Token,
previous: Scanner.Token,
Expand All @@ -28,7 +26,7 @@ pub const Error = error{
pub fn init(
allocator: std.mem.Allocator,
scanner: *Scanner,
routines: *std.ArrayList(Program.Routine),
routines: *std.ArrayList(Ast.Routine),
) Self {
const initToken = Scanner.Token{
.type = .eof,
Expand Down Expand Up @@ -243,7 +241,7 @@ fn routine(self: *Self) Error!void {
}

try self.routines.append(
Program.Routine{
Ast.Routine{
.name = routine_name,
.ast = commands.items,
.token = t,
Expand Down
Loading

0 comments on commit 1c08668

Please sign in to comment.