diff options
Diffstat (limited to 'src/parse.zig')
-rw-r--r-- | src/parse.zig | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/src/parse.zig b/src/parse.zig index 422b4f5..92fb219 100644 --- a/src/parse.zig +++ b/src/parse.zig @@ -74,6 +74,7 @@ pub const Expr = struct { bin_op: BinOp, call: Call, identifier, + @"if": If, pub const BinOp = struct { lhs: *const Expr, @@ -97,6 +98,12 @@ pub const Expr = struct { proc: *const Expr, arg: *const Expr, }; + + pub const If = struct { + cond: *const Expr, + then: Block, + @"else": ?Block, + }; }; fn format(self: Expr, writer: anytype, source: []const u8, indent: usize) !void { @@ -109,6 +116,15 @@ pub const Expr = struct { try writer.print("{}({})", .{ fmt(call.proc, source, indent), fmt(call.arg, source, indent) }); }, .identifier => try writer.print("{s}", .{self.loc.getIdent(source)}), + .@"if" => |@"if"| { + try writer.print("if {} {}", .{ + fmt(@"if".cond, source, indent), + fmt(@"if".then, source, indent), + }); + if (@"if".@"else") |@"else"| { + try writer.print(" else {}", .{fmt(@"else", source, indent)}); + } + }, } } }; @@ -162,7 +178,7 @@ pub fn expression(allocator: Allocator, lexer: *Lexer) ParseError!*Expr { } pub fn parseTerms(allocator: Allocator, lexer: *Lexer) !*Expr { - var lhs = try parseInvocations(allocator, lexer); + var lhs = try parseIf(allocator, lexer); while (true) { const op: Expr.Type.BinOp.Op = switch (lexer.peek().type) { .plus => .plus, @@ -171,7 +187,7 @@ pub fn parseTerms(allocator: Allocator, lexer: *Lexer) !*Expr { }; _ = lexer.next(); - const rhs = try parseInvocations(allocator, lexer); + const rhs = try parseIf(allocator, lexer); lhs = try allocate(Expr, allocator, .{ .loc = lhs.loc.combine(rhs.loc), .type = .{ .bin_op = .{ .lhs = lhs, .op = op, .rhs = rhs } }, @@ -180,6 +196,29 @@ pub fn parseTerms(allocator: Allocator, lexer: *Lexer) !*Expr { return lhs; } +pub fn parseIf(allocator: Allocator, lexer: *Lexer) !*Expr { + switch (lexer.peek().type) { + .@"if" => { + const @"if" = lexer.next(); + const cond = try expression(allocator, lexer); + const then = try block(allocator, lexer); + const @"else" = if (lexer.peek().type == .@"else") blk: { + _ = lexer.next(); + break :blk try block(allocator, lexer); + } else null; + return try allocate(Expr, allocator, .{ + .loc = @"if".loc.combine((@"else" orelse then).loc), + .type = .{ .@"if" = .{ + .cond = cond, + .then = then, + .@"else" = @"else", + } }, + }); + }, + else => return try parseInvocations(allocator, lexer), + } +} + pub fn parseInvocations(allocator: Allocator, lexer: *Lexer) !*Expr { var proc = try parsePrimaryExpr(allocator, lexer); while (true) { |