|
|
|
@ -636,6 +636,7 @@ pub const Parser = struct {
|
|
|
|
|
return switch (self.peek().ttype) {
|
|
|
|
|
.If => try self.parseIfStmt(),
|
|
|
|
|
.Loop => try self.parseLoop(),
|
|
|
|
|
.For => try self.parseForStmt(),
|
|
|
|
|
.Println => try self.parsePrintln(),
|
|
|
|
|
.Return => try self.parseReturn(),
|
|
|
|
|
else => try self.parseStmtExpr(),
|
|
|
|
@ -675,6 +676,42 @@ pub const Parser = struct {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn parseForStmt(self: *@This()) !*Stmt {
|
|
|
|
|
// There are two types of for in vig's V subset:
|
|
|
|
|
// - for x in y
|
|
|
|
|
// - for idx, x in y
|
|
|
|
|
_ = try self.consumeSingle(.For);
|
|
|
|
|
|
|
|
|
|
var index_var: ?Token = null;
|
|
|
|
|
var value_var: Token = undefined;
|
|
|
|
|
|
|
|
|
|
const subject_1 = try self.consumeSingle(.Identifier);
|
|
|
|
|
|
|
|
|
|
if (self.check(.Comma)) {
|
|
|
|
|
_ = try self.consumeSingle(.Comma);
|
|
|
|
|
|
|
|
|
|
const subject_2 = try self.consumeSingle(.Identifier);
|
|
|
|
|
index_var = subject_1;
|
|
|
|
|
value_var = subject_2;
|
|
|
|
|
} else {
|
|
|
|
|
value_var = subject_1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_ = try self.consumeSingle(.In);
|
|
|
|
|
|
|
|
|
|
// MUST be identifier
|
|
|
|
|
var array = try self.consumeSingle(.Identifier);
|
|
|
|
|
var block = try self.parseStmtBlock();
|
|
|
|
|
|
|
|
|
|
return try Stmt.mkFor(
|
|
|
|
|
self.allocator,
|
|
|
|
|
index_var,
|
|
|
|
|
value_var,
|
|
|
|
|
array,
|
|
|
|
|
block,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn parseLoop(self: *@This()) !*Stmt {
|
|
|
|
|
_ = try self.consumeSingle(.Loop);
|
|
|
|
|
var expr: ?*Expr = null;
|
|
|
|
|