add assignment of mutable variables
This commit is contained in:
parent
7c4aa04b00
commit
366be14cea
5 changed files with 45 additions and 12 deletions
|
@ -9,5 +9,6 @@ fn main(a int) int {
|
||||||
1 + 2 + 3 + 4
|
1 + 2 + 3 + 4
|
||||||
1 + 1 * 1
|
1 + 1 * 1
|
||||||
3 / (51 + 2)
|
3 / (51 + 2)
|
||||||
|
mut a := 1+2
|
||||||
println(2 * 1956 + a)
|
println(2 * 1956 + a)
|
||||||
}
|
}
|
||||||
|
|
20
src/ast.zig
20
src/ast.zig
|
@ -65,6 +65,7 @@ pub const Expr = union(enum) {
|
||||||
pub const VarDecl = struct {
|
pub const VarDecl = struct {
|
||||||
name: Token,
|
name: Token,
|
||||||
initializer: *Expr,
|
initializer: *Expr,
|
||||||
|
mutable: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Stmt = union(enum) {
|
pub const Stmt = union(enum) {
|
||||||
|
@ -78,9 +79,15 @@ pub const Stmt = union(enum) {
|
||||||
return println;
|
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);
|
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;
|
return vardecl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -210,6 +217,13 @@ pub fn printStmt(stmt: *Stmt) void {
|
||||||
.Println => |expr| parenthetize("println", &[_]*Expr{expr}),
|
.Println => |expr| parenthetize("println", &[_]*Expr{expr}),
|
||||||
.Expr => |expr| printExpr(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.*)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -389,9 +389,9 @@ pub const Parser = struct {
|
||||||
|
|
||||||
while (self.peek().ttype != .RightBrace) {
|
while (self.peek().ttype != .RightBrace) {
|
||||||
std.debug.warn("get smt with cur {}\n", self.peek().ttype);
|
std.debug.warn("get smt with cur {}\n", self.peek().ttype);
|
||||||
var node = try self.parseStmt();
|
var stmt = try self.parseDecl();
|
||||||
ast.printNode(node, 0);
|
ast.printNode(try self.mkStmt(stmt), 0);
|
||||||
try stmts.append(node.Stmt);
|
try stmts.append(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = try self.consumeSingle(.RightBrace);
|
_ = try self.consumeSingle(.RightBrace);
|
||||||
|
@ -399,15 +399,31 @@ pub const Parser = struct {
|
||||||
return try self.mkBlock(stmts);
|
return try self.mkBlock(stmts);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseStmt(self: *@This()) anyerror!*Node {
|
fn parseDecl(self: *@This()) !*Stmt {
|
||||||
var stmt = switch (self.peek().ttype) {
|
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(),
|
.Println => try self.parsePrintln(),
|
||||||
|
|
||||||
// TODO make newlines tokens and consume newline?
|
// TODO make newlines tokens and consume newline?
|
||||||
else => try self.parseStmtExpr(),
|
else => try self.parseStmtExpr(),
|
||||||
};
|
};
|
||||||
|
|
||||||
return try self.mkStmt(stmt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parsePrintln(self: *@This()) !*Stmt {
|
fn parsePrintln(self: *@This()) !*Stmt {
|
||||||
|
@ -531,7 +547,7 @@ pub const Parser = struct {
|
||||||
},
|
},
|
||||||
|
|
||||||
else => blk: {
|
else => blk: {
|
||||||
self.doError("expected false/true/int/float/string/leftparen, got {}", curtype);
|
self.doError("expected literal, got {}", curtype);
|
||||||
return Result.CompileError;
|
return Result.CompileError;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -288,7 +288,6 @@ pub const Scanner = struct {
|
||||||
'.' => self.makeToken(.Dot),
|
'.' => self.makeToken(.Dot),
|
||||||
';' => self.makeToken(.Semicolon),
|
';' => self.makeToken(.Semicolon),
|
||||||
',' => self.makeToken(.Comma),
|
',' => self.makeToken(.Comma),
|
||||||
':' => self.makeToken(.Colon),
|
|
||||||
'&' => self.makeToken(.Ampersand),
|
'&' => self.makeToken(.Ampersand),
|
||||||
'|' => self.makeToken(.Pipe),
|
'|' => self.makeToken(.Pipe),
|
||||||
'?' => self.makeToken(.QuestionMark),
|
'?' => self.makeToken(.QuestionMark),
|
||||||
|
@ -298,6 +297,8 @@ pub const Scanner = struct {
|
||||||
'*' => self.makeToken(.Star),
|
'*' => self.makeToken(.Star),
|
||||||
'%' => self.makeToken(.Modulo),
|
'%' => self.makeToken(.Modulo),
|
||||||
|
|
||||||
|
':' => self.makeMatchToken('=', .Assign, .Colon),
|
||||||
|
|
||||||
'!' => self.makeMatchToken('=', .BangEqual, .Bang),
|
'!' => self.makeMatchToken('=', .BangEqual, .Bang),
|
||||||
'=' => self.makeMatchToken('=', .EqualEqual, .Equal),
|
'=' => self.makeMatchToken('=', .EqualEqual, .Equal),
|
||||||
'>' => self.makeMatchToken('=', .GreaterEqual, .Greater),
|
'>' => self.makeMatchToken('=', .GreaterEqual, .Greater),
|
||||||
|
|
|
@ -29,6 +29,7 @@ pub const TokenType = enum {
|
||||||
PlusPlus,
|
PlusPlus,
|
||||||
PlusEqual,
|
PlusEqual,
|
||||||
MinusEqual,
|
MinusEqual,
|
||||||
|
Assign,
|
||||||
|
|
||||||
// comparison ones
|
// comparison ones
|
||||||
EqualEqual,
|
EqualEqual,
|
||||||
|
|
Loading…
Reference in a new issue