M Parser.zig => Parser.zig +11 -0
@@ 100,6 100,9 @@ fn parseExpression(self: *Parser, expr: *Ast.Expression) error{OutOfMemory}!void
try self.pushNode(self.node.indent, .{ .if_expr = &expr.if_ });
return self.pushNode(self.node.indent, .{ .expr = expr.if_.cond });
},
+ .keyword_else => {
+ @panic("I haven't figured out how to support non-inline else");
+ },
else => @panic("expected expression"),
};
expr.* = value;
@@ 129,6 132,14 @@ fn parseAfterExpression(self: *Parser, expr: *Ast.Expression) error{OutOfMemory}
try self.pushNode(prev.indent, .{ .expr = prev.want.if_expr.true_ });
return;
},
+ .keyword_else => {
+ const prev = self.node.prev.?;
+ if (prev.want != .if_expr) @panic("else only allowed after if statement");
+ self.popNode();
+ prev.want.if_expr.false_ = try self.alloc.create(Ast.Expression);
+ try self.pushNode(prev.indent, .{ .expr = prev.want.if_expr.false_.? });
+ return;
+ },
else => @panic("expected binary op or newline"),
};
var left = try self.alloc.create(Ast.Expression);
M file => file +3 -3
@@ 1,5 1,5 @@
fn main
- if a:
- if b:
- c
+ if b:
+ c
+ else
d
M main.zig => main.zig +7 -0
@@ 48,6 48,9 @@ fn printAst(ast: Ast) void {
}
fn printExpr(expr: Ast.Expression, indent: u8) void {
switch (expr) {
+ .name => |n| {
+ std.debug.print("{s}", .{n});
+ },
.block => |b| {
for (b.items) |e| {
std.debug.print("\n", .{});
@@ 63,6 66,10 @@ fn printExpr(expr: Ast.Expression, indent: u8) void {
printExpr(i.cond.*, indent);
std.debug.print(": ", .{});
printExpr(i.true_.*, indent);
+ if (i.false_) |false_| {
+ std.debug.print(" else ", .{});
+ printExpr(false_.*, indent);
+ }
},
else => std.debug.print("{}", .{expr}),
}
M syntax => syntax +7 -0
@@ 10,3 10,10 @@ fn main
case1:
case2:
+what currently works with if/else
+fn main
+ if a: b
+ if a: b else c
+ if a:
+ b
+ c