ast: rename IfBranch to Block, add LoopStmt

This commit is contained in:
Luna 2019-08-25 16:57:22 -03:00
parent 460055e186
commit 19b79514b4
2 changed files with 43 additions and 20 deletions

View file

@ -97,12 +97,17 @@ pub const Expr = union(ExprType) {
Grouping: *Expr, Grouping: *Expr,
}; };
pub const IfBranch = std.ArrayList(*Stmt); pub const Block = std.ArrayList(*Stmt);
pub const IfStmt = struct { pub const IfStmt = struct {
condition: *Expr, condition: *Expr,
then_branch: IfBranch, then_branch: Block,
else_branch: ?IfBranch, else_branch: ?Block,
};
pub const LoopStmt = struct {
condition: ?*Expr,
then_branch: Block,
}; };
pub const Stmt = union(enum) { pub const Stmt = union(enum) {
@ -110,28 +115,46 @@ pub const Stmt = union(enum) {
Println: *Expr, Println: *Expr,
If: IfStmt, If: IfStmt,
Loop: LoopStmt,
pub fn mkPrintln(allocator: *std.mem.Allocator, expr: *Expr) !*Stmt { pub fn mkPrintln(allocator: *std.mem.Allocator, expr: *Expr) !*Stmt {
var println = try allocator.create(Stmt); var stmt = try allocator.create(Stmt);
println.* = Stmt{ .Println = expr }; stmt.* = Stmt{ .Println = expr };
return println; return stmt;
} }
pub fn mkIfStmt( pub fn mkIfStmt(
allocator: *std.mem.Allocator, allocator: *std.mem.Allocator,
condition: *Expr, condition: *Expr,
then: IfBranch, then: Block,
else_branch: ?IfBranch, else_branch: ?Block,
) !*Stmt { ) !*Stmt {
var println = try allocator.create(Stmt); var stmt = try allocator.create(Stmt);
println.* = Stmt{ stmt.* = Stmt{
.If = IfStmt{ .If = IfStmt{
.condition = condition, .condition = condition,
.then_branch = then, .then_branch = then,
.else_branch = else_branch, .else_branch = else_branch,
}, },
}; };
return println;
return stmt;
}
pub fn mkLoop(
allocator: *std.mem.Allocator,
condition: ?*Expr,
then: Block,
) !*Stmt {
var stmt = try allocator.create(Stmt);
stmt.* = Stmt{
.Loop = LoopStmt{
.condition = condition,
.then_branch = then,
},
};
return stmt;
} }
}; };

View file

@ -456,35 +456,35 @@ pub const Parser = struct {
}; };
} }
/// Copy of parseBlock for if branches /// Copy of parseBlock for blocks in statements
fn parseIfBranch(self: *@This()) !ast.IfBranch { fn parseStmtBlock(self: *@This()) !ast.Block {
var branch = ast.IfBranch.init(self.allocator); var block = ast.Block.init(self.allocator);
errdefer branch.deinit(); errdefer block.deinit();
_ = try self.consumeSingle(.LeftBrace); _ = try self.consumeSingle(.LeftBrace);
while (self.peek().ttype != .RightBrace) { while (self.peek().ttype != .RightBrace) {
var stmt = try self.parseDecl(); var stmt = try self.parseDecl();
ast.printNode(try self.mkStmt(stmt), 0); ast.printNode(try self.mkStmt(stmt), 0);
try branch.append(stmt); try block.append(stmt);
} }
_ = try self.consumeSingle(.RightBrace); _ = try self.consumeSingle(.RightBrace);
return branch; return block;
} }
fn parseIfStmt(self: *@This()) !*Stmt { fn parseIfStmt(self: *@This()) !*Stmt {
_ = try self.consumeSingle(.If); _ = try self.consumeSingle(.If);
var condition = (try self.parseExpr()).Expr; var condition = (try self.parseExpr()).Expr;
const then_branch = try self.parseIfBranch(); const then_branch = try self.parseStmtBlock();
var else_branch: ?ast.IfBranch = null; var else_branch: ?ast.Block = null;
if (self.check(.Else)) { if (self.check(.Else)) {
_ = try self.consumeSingle(.Else); _ = try self.consumeSingle(.Else);
else_branch = try self.parseIfBranch(); else_branch = try self.parseStmtBlock();
} }
return try Stmt.mkIfStmt( return try Stmt.mkIfStmt(