add for statements
This commit is contained in:
parent
1ac1e54264
commit
8bce47f5cc
4 changed files with 77 additions and 0 deletions
|
@ -63,6 +63,9 @@ fn main(a int) int {
|
|||
str.len /= 1
|
||||
|
||||
awoo := [1, 2, a(), b + 2, c(31) * d]
|
||||
|
||||
for a in b {}
|
||||
for idx, a in b {}
|
||||
}
|
||||
|
||||
fn (v Typ) voidfunc() {}
|
||||
|
|
22
src/ast.zig
22
src/ast.zig
|
@ -158,12 +158,20 @@ pub const LoopStmt = struct {
|
|||
then_branch: Block,
|
||||
};
|
||||
|
||||
pub const ForStmt = struct {
|
||||
index: ?Token,
|
||||
value: Token,
|
||||
array: Token,
|
||||
block: Block,
|
||||
};
|
||||
|
||||
pub const Stmt = union(enum) {
|
||||
Expr: *Expr,
|
||||
Println: *Expr,
|
||||
|
||||
If: IfStmt,
|
||||
Loop: LoopStmt,
|
||||
For: ForStmt,
|
||||
|
||||
Return: ReturnStmt,
|
||||
|
||||
|
@ -212,6 +220,20 @@ pub const Stmt = union(enum) {
|
|||
return stmt;
|
||||
}
|
||||
|
||||
pub fn mkFor(allocator: *std.mem.Allocator, index: ?Token, value: Token, array: Token, block: Block) !*Stmt {
|
||||
var stmt = try allocator.create(Stmt);
|
||||
stmt.* = Stmt{
|
||||
.For = ForStmt{
|
||||
.index = index,
|
||||
.value = value,
|
||||
.array = array,
|
||||
.block = block,
|
||||
},
|
||||
};
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
pub fn mkReturn(allocator: *std.mem.Allocator, tok: Token, value: *Expr) !*Stmt {
|
||||
var stmt = try allocator.create(Stmt);
|
||||
stmt.* = Stmt{
|
||||
|
|
|
@ -262,6 +262,21 @@ pub fn printStmt(ident: usize, stmt: *Stmt) void {
|
|||
std.debug.warn(")\n");
|
||||
},
|
||||
|
||||
.For => |forstmt| {
|
||||
std.debug.warn("(for ");
|
||||
|
||||
if (forstmt.index) |index| {
|
||||
std.debug.warn("({} {}) ", index.lexeme, forstmt.value.lexeme);
|
||||
} else {
|
||||
std.debug.warn("{} ", forstmt.value.lexeme);
|
||||
}
|
||||
|
||||
std.debug.warn("{} ", forstmt.array.lexeme);
|
||||
|
||||
printBlock(ident + 1, forstmt.block, false);
|
||||
std.debug.warn(")\n");
|
||||
},
|
||||
|
||||
.Return => |ret| {
|
||||
std.debug.warn("(return ");
|
||||
printExpr(ret.value);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue