]> Repositories - zlox.git/blob - src/ast_printer.zig
Implement parser
[zlox.git] / src / ast_printer.zig
1 const std = @import("std");
2 const Allocator = std.mem.Allocator;
3 const Expr = @import("expr.zig").Expr;
4 const Token = @import("Token.zig");
5
6 pub fn print(allocator: Allocator, expr: *const Expr) Allocator.Error![]const u8 {
7     return switch (expr.*) {
8         .binary => |binary| try parenthesize(allocator, binary.operator.lexeme, &.{ binary.left, binary.right }),
9         .grouping => |grouping| try parenthesize(allocator, "group", &.{grouping.expression}),
10         .literal => |literal| switch (literal.value) {
11             .nil => "nil",
12             .boolean => |boolean| if (boolean) "true" else "false",
13             .string => |string| string,
14             .number => |number| try std.fmt.allocPrint(allocator, "{}", .{number}),
15         },
16         .unary => |unary| try parenthesize(allocator, unary.operator.lexeme, &.{unary.right}),
17     };
18 }
19
20 fn parenthesize(allocator: Allocator, name: []const u8, exprs: []const *const Expr) ![]const u8 {
21     var builder: std.ArrayList(u8) = .empty;
22
23     try builder.append(allocator, '(');
24     try builder.appendSlice(allocator, name);
25     for (exprs) |expr| {
26         try builder.append(allocator, ' ');
27         const printed = try print(allocator, expr);
28         defer allocator.free(printed);
29         try builder.appendSlice(allocator, printed);
30     }
31     try builder.append(allocator, ')');
32
33     return try builder.toOwnedSlice(allocator);
34 }