add assignment of mutable variables

This commit is contained in:
Luna 2019-08-24 17:46:42 -03:00
parent 7c4aa04b00
commit 366be14cea
5 changed files with 45 additions and 12 deletions

View file

@ -9,5 +9,6 @@ fn main(a int) int {
1 + 2 + 3 + 4
1 + 1 * 1
3 / (51 + 2)
mut a := 1+2
println(2 * 1956 + a)
}

View file

@ -65,6 +65,7 @@ pub const Expr = union(enum) {
pub const VarDecl = struct {
name: Token,
initializer: *Expr,
mutable: bool = false,
};
pub const Stmt = union(enum) {
@ -78,9 +79,15 @@ pub const Stmt = union(enum) {
return println;
}
pub fn mkVarDecl(allocator: *std.mem.Allocator, name: Token, init: *Expr) !*Stmt {
pub fn mkVarDecl(allocator: *std.mem.Allocator, name: Token, init: *Expr, mutable: bool) !*Stmt {
var vardecl = try allocator.create(Stmt);
vardecl.* = Stmt{ .VarDecl = VarDecl{ .name = name, .initializer = init } };
vardecl.* = Stmt{
.VarDecl = VarDecl{
.name = name,
.initializer = init,
.mutable = mutable,
},
};
return vardecl;
}
};
@ -210,6 +217,13 @@ pub fn printStmt(stmt: *Stmt) void {
.Println => |expr| parenthetize("println", &[_]*Expr{expr}),
.Expr => |expr| printExpr(expr),
else => std.debug.warn("STMT_UNKNOWN"),
.VarDecl => |decl| {
if (decl.mutable)
std.debug.warn("mut ");
std.debug.warn("assign {} := ", decl.name.lexeme);
printExpr(decl.initializer);
},
else => std.debug.warn("UnknownStmt-{}", @tagName(stmt.*)),
}
}

View file

@ -389,9 +389,9 @@ pub const Parser = struct {
while (self.peek().ttype != .RightBrace) {
std.debug.warn("get smt with cur {}\n", self.peek().ttype);
var node = try self.parseStmt();
ast.printNode(node, 0);
try stmts.append(node.Stmt);
var stmt = try self.parseDecl();
ast.printNode(try self.mkStmt(stmt), 0);
try stmts.append(stmt);
}
_ = try self.consumeSingle(.RightBrace);
@ -399,15 +399,31 @@ pub const Parser = struct {
return try self.mkBlock(stmts);
}
fn parseStmt(self: *@This()) anyerror!*Node {
var stmt = switch (self.peek().ttype) {
fn parseDecl(self: *@This()) !*Stmt {
return switch (self.peek().ttype) {
.Mut => try self.parseMutVarDecl(),
else => try self.parseStmt(),
};
}
fn parseMutVarDecl(self: *@This()) !*Stmt {
_ = try self.consumeSingle(.Mut);
var name = try self.consumeSingle(.Identifier);
_ = try self.consumeSingle(.Assign);
var initializer = (try self.parseExpr()).Expr;
return try Stmt.mkVarDecl(self.allocator, name, initializer, true);
}
fn parseStmt(self: *@This()) anyerror!*Stmt {
return switch (self.peek().ttype) {
.Println => try self.parsePrintln(),
// TODO make newlines tokens and consume newline?
else => try self.parseStmtExpr(),
};
return try self.mkStmt(stmt);
}
fn parsePrintln(self: *@This()) !*Stmt {
@ -531,7 +547,7 @@ pub const Parser = struct {
},
else => blk: {
self.doError("expected false/true/int/float/string/leftparen, got {}", curtype);
self.doError("expected literal, got {}", curtype);
return Result.CompileError;
},
};

View file

@ -288,7 +288,6 @@ pub const Scanner = struct {
'.' => self.makeToken(.Dot),
';' => self.makeToken(.Semicolon),
',' => self.makeToken(.Comma),
':' => self.makeToken(.Colon),
'&' => self.makeToken(.Ampersand),
'|' => self.makeToken(.Pipe),
'?' => self.makeToken(.QuestionMark),
@ -298,6 +297,8 @@ pub const Scanner = struct {
'*' => self.makeToken(.Star),
'%' => self.makeToken(.Modulo),
':' => self.makeMatchToken('=', .Assign, .Colon),
'!' => self.makeMatchToken('=', .BangEqual, .Bang),
'=' => self.makeMatchToken('=', .EqualEqual, .Equal),
'>' => self.makeMatchToken('=', .GreaterEqual, .Greater),

View file

@ -29,6 +29,7 @@ pub const TokenType = enum {
PlusPlus,
PlusEqual,
MinusEqual,
Assign,
// comparison ones
EqualEqual,