Compare commits

...

3 Commits

Author SHA1 Message Date
Luna f9e8543b7c fixes for latest zig 2019-12-07 19:45:12 -03:00
Luna 79b2d37ac0 readme: for is implemented 2019-08-29 14:30:48 -03:00
Luna 8bce47f5cc add for statements 2019-08-29 14:30:33 -03:00
6 changed files with 84 additions and 6 deletions

View File

@ -37,7 +37,6 @@ negatively charged towards
## wip
- no `for` yet
- no `map` yet
- no `in` yet (probably will be dropped)
- no `module`, `import` yet

View File

@ -17,6 +17,8 @@ fn main(a int) int {
mut a := 1+2
a = 2
a = 1 && 0
if a {
println(30)
} else {
@ -63,6 +65,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() {}

View File

@ -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{

View File

@ -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);

View File

@ -13,7 +13,7 @@ pub const Result = error{
pub const StdOut = *std.io.OutStream(std.fs.File.WriteError);
fn run(allocator: *Allocator, data: []u8) !void {
var stdout_file = try std.io.getStdOut();
var stdout_file = std.io.getStdOut();
const stdout = &stdout_file.outStream().stream;
var runner = runners.Runner.init(allocator, stdout);
@ -39,7 +39,7 @@ fn runFile(allocator: *Allocator, path: []const u8) !void {
}
fn runPrompt(allocator: *Allocator) !void {
var stdout_file = try std.io.getStdOut();
var stdout_file = std.io.getStdOut();
const stdout = &stdout_file.outStream().stream;
while (true) {
@ -71,7 +71,7 @@ pub fn main() anyerror!void {
defer arena.deinit();
var allocator = &arena.allocator;
var stdout_file = try std.io.getStdOut();
var stdout_file = std.io.getStdOut();
var stdout = &stdout_file.outStream().stream;
var args_it = std.process.args();

View File

@ -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;
@ -992,8 +1029,8 @@ pub const Parser = struct {
fn finishStructVal(self: *@This(), expr: *Expr) !*Expr {
// <expr>{a: 10 b: 10}
// for this to work properly, <expr> must be Variable, since its a type.
if (ast.ExprType(expr.*) != .Variable) {
self.doError("Expected variable for struct type, got {}", ast.ExprType(expr.*));
if (@as(ast.ExprType, expr.*) != .Variable) {
self.doError("Expected variable for struct type, got {}", @as(ast.ExprType, expr.*));
return Result.CompileError;
}