summaryrefslogtreecommitdiff
path: root/src/codegen.zig
blob: a200e23598596b020d4390a0163ca016102e766a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
const std = @import("std");
const parse = @import("parser.zig");

pub const Generator = struct {
    root: []const parse.NodeStmt,
    allocator: std.mem.Allocator,
    code: std.ArrayList(u8),

    pub fn init(allocator: std.mem.Allocator, stmts: []const parse.NodeStmt) Generator {
        return .{
            .root = stmts,
            .allocator = allocator,
            .code = std.ArrayList(u8).init(allocator),
        };
    }

    pub fn deinit(self: *Generator) void {
        self.code.deinit();
    }

    fn genExit(self: *Generator, expr: parse.NodeExpr) ![]const u8 {
        return try std.fmt.allocPrint(self.allocator,
            \\  mov rax, 60
            \\  mov rdi, {d}
            \\  syscall
            \\
        , .{switch (expr) {
            .intLit => expr.intLit.intlit.intLit,
            else => return error.NotImplemented,
        }});
    }

    fn genValue(self: *Generator) ![]const u8 {
        _ = self;
        return error.NotImplemented;
    }

    pub fn generate(self: *Generator) ![]const u8 {
        try self.code.appendSlice(
            \\global _start:
            \\
        );
        for (self.root) |stmt| {
            const code = switch (stmt) {
                .exit => try self.genExit(stmt.exit.expr),
                .value => try self.genValue(),
            };
            try self.code.appendSlice(code);
        }
        return self.code.items;
    }
};