diff options
-rw-r--r-- | src/main.zig | 28 | ||||
-rw-r--r-- | src/parse.zig | 45 |
2 files changed, 57 insertions, 16 deletions
diff --git a/src/main.zig b/src/main.zig index d4951e6..dd34c53 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,5 +1,6 @@ const std = @import("std"); const codegen = @import("./codegen.zig"); +const target = @import("builtin").target; pub const parse = @import("./parse.zig"); pub const Lexer = @import("./Lexer.zig"); @@ -12,7 +13,16 @@ pub fn main() !void { var args = std.process.args(); _ = args.next(); - const out_file = if (args.next()) |path| try std.fs.cwd().createFile(path, .{ .mode = 0o777 }) else std.io.getStdOut(); + const arg = args.next() orelse ""; + + const run_path, const out_file = if (std.mem.eql(u8, arg, "run")) blk: { + const path = try std.fmt.allocPrint(allocator, "/tmp/{}.elf", .{std.crypto.random.int(u32)}); + break :blk .{ path, try std.fs.createFileAbsolute(path, .{ .mode = 0o777 }) }; + } else if (arg.len > 0) + .{ null, try std.fs.cwd().createFile(arg, .{ .mode = 0o777 }) } + else + .{ null, std.io.getStdOut() }; + defer if (run_path) |path| allocator.free(path); const output = out_file.writer(); // var br = std.io.bufferedReader(std.io.getStdIn().reader()); @@ -28,7 +38,6 @@ pub fn main() !void { // try stdout.print("{s}\n", .{line.items}); // } - // const source = "17216961135462248174 + 4095 - 4294967295 + 2147483647"; const source = \\print 18446744073709551615; \\print (0 - 1); @@ -45,7 +54,7 @@ pub fn main() !void { const stmts = try parse.statements(allocator, &lexer); std.debug.print("Statements:\n", .{}); for (stmts) |stmt| { - std.debug.print(" {}\n", .{stmt}); + std.debug.print(" {}\n", .{stmt.fmt(source)}); } if (lexer.peek().type != .eof) { std.debug.print("Unexpected token {}, expected end of file\n", .{lexer.next()}); @@ -57,7 +66,18 @@ pub fn main() !void { } const elf = try codegen.create_elf(allocator, block); try output.writeAll(elf); - // try stdout.print("{x}\n", .{elf}); + std.debug.print("Run output:\n", .{}); + if (run_path) |path| { + out_file.close(); + + std.debug.print("{}\n", .{std.process.execv( + allocator, + if (target.cpu.arch == .riscv64 and target.os.tag == .linux) + &.{path} + else + &.{ "qemu-riscv64", path }, + )}); + } } fn HashMapFormatter(HashMap: type) type { diff --git a/src/parse.zig b/src/parse.zig index 1dda517..cadc489 100644 --- a/src/parse.zig +++ b/src/parse.zig @@ -12,6 +12,21 @@ pub const Stmt = struct { pub const Type = union(enum) { expr: *const Expr, }; + + pub fn fmt(self: Stmt, file_source: []const u8) Format { + return .{ .data = .{ self, file_source } }; + } + + const Format = std.fmt.Formatter(struct { + fn format(data: struct { Stmt, []const u8 }, comptime f: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { + const self, const file_source = data; + _ = f; + _ = options; + return switch (self.type) { + .expr => |expr| writer.print("{};", .{expr.fmt(file_source)}), + }; + } + }.format); }; pub const Expr = struct { @@ -33,8 +48,8 @@ pub const Expr = struct { plus, minus, - pub fn format(self: Op, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { - _ = fmt; + pub fn format(self: Op, comptime f: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { + _ = f; _ = options; try writer.writeByte(switch (self) { .plus => '+', @@ -50,16 +65,23 @@ pub const Expr = struct { }; }; - pub fn format(self: Expr, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { - _ = fmt; - _ = options; - switch (self.type) { - .integer_literal => try writer.print("<int>", .{}), - .bin_op => |bin_op| try writer.print("({} {} {})", .{ bin_op.lhs, bin_op.op, bin_op.rhs }), - .call => |call| try writer.print("({} {})", .{ call.proc, call.arg }), - .identifier => try writer.print("<identifier>", .{}), - } + pub fn fmt(self: Expr, file_source: []const u8) Format { + return .{ .data = .{ self, file_source } }; } + + const Format = std.fmt.Formatter(struct { + fn format(data: struct { Expr, []const u8 }, comptime f: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { + const self, const file_source = data; + _ = f; + _ = options; + switch (self.type) { + .integer_literal => try writer.print("{}", .{self.loc.getInt(file_source)}), + .bin_op => |bin_op| try writer.print("({} {} {})", .{ bin_op.lhs.fmt(file_source), bin_op.op, bin_op.rhs.fmt(file_source) }), + .call => |call| try writer.print("({} {})", .{ call.proc.fmt(file_source), call.arg.fmt(file_source) }), + .identifier => try writer.print("{s}", .{self.loc.getIdent(file_source)}), + } + } + }.format); }; pub fn statements(allocator: Allocator, lexer: *Lexer) ![]Stmt { @@ -120,7 +142,6 @@ pub fn callExpr(allocator: Allocator, lexer: *Lexer) !*Expr { pub fn primaryExpr(allocator: Allocator, lexer: *Lexer) !*Expr { const token = lexer.next(); - // std.debug.print("term {}\n", .{token}); return allocate(Expr, allocator, switch (token.type) { .left_paren => { const res = expression(allocator, lexer); |