change variable declarations to statements
doing them as expressions was a hack since no 'var' keyword, also, yeet the := operator from the parser.
This commit is contained in:
parent
e69451cdd9
commit
45275d73db
7 changed files with 44 additions and 47 deletions
|
@ -1,6 +1,7 @@
|
|||
// import std;
|
||||
|
||||
fn f() i32 {
|
||||
var a = 2;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
|
27
src/ast.zig
27
src/ast.zig
|
@ -97,9 +97,6 @@ pub const AssignExpr = struct {
|
|||
pub const ExprType = enum {
|
||||
Assign,
|
||||
|
||||
// vardecls as expressions is a hack
|
||||
VarDecl,
|
||||
|
||||
Binary,
|
||||
Unary,
|
||||
Literal,
|
||||
|
@ -112,11 +109,6 @@ pub const ExprType = enum {
|
|||
Set,
|
||||
};
|
||||
|
||||
pub const VarDecl = struct {
|
||||
assign: AssignExpr,
|
||||
mutable: bool = false,
|
||||
};
|
||||
|
||||
pub const CallExpr = struct {
|
||||
callee: *Expr,
|
||||
paren: Token,
|
||||
|
@ -148,7 +140,6 @@ pub const SetExpr = struct {
|
|||
|
||||
pub const Expr = union(ExprType) {
|
||||
Assign: AssignExpr,
|
||||
VarDecl: VarDecl,
|
||||
|
||||
Binary: BinaryExpr,
|
||||
Unary: UnaryExpr,
|
||||
|
@ -181,10 +172,16 @@ pub const ForStmt = struct {
|
|||
block: Block,
|
||||
};
|
||||
|
||||
pub const VarDeclStmt = struct {
|
||||
name: Token,
|
||||
value: *Expr,
|
||||
};
|
||||
|
||||
pub const Stmt = union(enum) {
|
||||
Expr: *Expr,
|
||||
Println: *Expr,
|
||||
|
||||
VarDecl: VarDeclStmt,
|
||||
If: IfStmt,
|
||||
Loop: LoopStmt,
|
||||
For: ForStmt,
|
||||
|
@ -261,6 +258,18 @@ pub const Stmt = union(enum) {
|
|||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
pub fn mkVarDecl(allocator: *std.mem.Allocator, name: Token, value: *Expr) !*Stmt {
|
||||
var stmt = try allocator.create(Stmt);
|
||||
stmt.* = Stmt{
|
||||
.VarDecl = VarDeclStmt{
|
||||
.name = name,
|
||||
.value = value,
|
||||
},
|
||||
};
|
||||
|
||||
return stmt;
|
||||
}
|
||||
};
|
||||
|
||||
pub const FieldList = std.ArrayList(StructField);
|
||||
|
|
|
@ -239,18 +239,6 @@ pub fn printExpr(expr: *const Expr) void {
|
|||
|
||||
.Variable => |token| std.debug.warn("{}", token.lexeme),
|
||||
|
||||
.VarDecl => |decl| {
|
||||
if (decl.mutable) {
|
||||
std.debug.warn("(mut ");
|
||||
} else {
|
||||
std.debug.warn("(");
|
||||
}
|
||||
|
||||
std.debug.warn("let {} ", decl.assign.name.lexeme);
|
||||
printExpr(decl.assign.value);
|
||||
std.debug.warn(")");
|
||||
},
|
||||
|
||||
.Assign => |assign| {
|
||||
std.debug.warn("(set ");
|
||||
std.debug.warn("{} ", assign.name.lexeme);
|
||||
|
@ -305,6 +293,12 @@ pub fn printStmt(ident: usize, stmt: *const Stmt) void {
|
|||
.Println => |expr| printSimpleOp("println", expr),
|
||||
.Expr => |expr| printExpr(expr),
|
||||
|
||||
.VarDecl => |decl| {
|
||||
std.debug.warn("(let {} ", decl.name.lexeme);
|
||||
printExpr(decl.value);
|
||||
std.debug.warn(")");
|
||||
},
|
||||
|
||||
.If => |ifstmt| {
|
||||
std.debug.warn("(if ");
|
||||
printExpr(ifstmt.condition);
|
||||
|
|
|
@ -79,8 +79,6 @@ pub const Codegen = struct {
|
|||
|
||||
// TODO VarDecl add things to the symbol table
|
||||
// TODO Assign modify symbol table
|
||||
|
||||
// TODO Calls fetch symbol table, check arity of it at codegen level
|
||||
return switch (expr.*) {
|
||||
|
||||
// TODO handle all literals, construct llvm values for them
|
||||
|
@ -168,7 +166,6 @@ pub const Codegen = struct {
|
|||
|
||||
.Call => |call| {
|
||||
const name = call.callee.*.Variable.lexeme;
|
||||
//var sym = try self.ctx.fetchGlobalSymbol(func_name, .Function);
|
||||
|
||||
var llvm_func = self.llvm_table.get(name);
|
||||
if (llvm_func == null) {
|
||||
|
@ -176,7 +173,6 @@ pub const Codegen = struct {
|
|||
return CompileError.EmitError;
|
||||
}
|
||||
|
||||
// TODO args
|
||||
var args = LLVMValueList.init(self.allocator);
|
||||
errdefer args.deinit();
|
||||
|
||||
|
@ -342,7 +338,6 @@ pub const Codegen = struct {
|
|||
llvm.LLVMPositionBuilderAtEnd(builder, entry);
|
||||
|
||||
for (decl.body.toSlice()) |stmt| {
|
||||
// TODO custom function context for us
|
||||
try self.emitStmt(builder, &stmt);
|
||||
}
|
||||
|
||||
|
|
|
@ -295,21 +295,6 @@ pub const Parser = struct {
|
|||
return expr;
|
||||
}
|
||||
|
||||
fn mkVarDecl(self: *@This(), name: Token, value: *Expr, mutable: bool) !*Expr {
|
||||
var vardecl = try self.allocator.create(Expr);
|
||||
vardecl.* = Expr{
|
||||
.VarDecl = ast.VarDecl{
|
||||
.assign = ast.AssignExpr{
|
||||
.name = name,
|
||||
.value = value,
|
||||
},
|
||||
.mutable = mutable,
|
||||
},
|
||||
};
|
||||
|
||||
return vardecl;
|
||||
}
|
||||
|
||||
fn mkCall(self: *@This(), callee: *Expr, paren: Token, args: ast.ExprList) !*Expr {
|
||||
var expr = try self.allocator.create(Expr);
|
||||
expr.* = Expr{
|
||||
|
@ -716,6 +701,7 @@ pub const Parser = struct {
|
|||
|
||||
fn parseStmt(self: *@This()) anyerror!*Stmt {
|
||||
return switch (self.peek().typ) {
|
||||
.Var => try self.parseVarDecl(),
|
||||
.If => try self.parseIfStmt(),
|
||||
.Loop => try self.parseLoop(),
|
||||
.For => try self.parseForStmt(),
|
||||
|
@ -725,6 +711,14 @@ pub const Parser = struct {
|
|||
};
|
||||
}
|
||||
|
||||
fn parseVarDecl(self: *@This()) !*Stmt {
|
||||
_ = try self.consumeSingle(.Var);
|
||||
var name = try self.consumeSingle(.Identifier);
|
||||
_ = try self.consumeSingle(.Equal);
|
||||
var value = try self.parseExpr();
|
||||
return try Stmt.mkVarDecl(self.allocator, name, value);
|
||||
}
|
||||
|
||||
/// Parse a list of statements.
|
||||
fn parseBlock(self: *@This()) !*Node {
|
||||
var stmts = try self.parseBlockInternal(ast.StmtList);
|
||||
|
@ -840,8 +834,8 @@ pub const Parser = struct {
|
|||
|
||||
fn parseAssignment(self: *@This()) anyerror!*Expr {
|
||||
// there can be two assignments coming out of this function:
|
||||
// - a mutable/immutable variable declaration with :=
|
||||
// - an assignment to a variable with =, +=, -=
|
||||
// - an assignment to a variable with =
|
||||
// - an update to a variable with +=, -=
|
||||
|
||||
// one is a statement, other is an expression. since the normal result
|
||||
// of this is an Expr, we wrap variable assignments in an Expr as well.
|
||||
|
@ -855,7 +849,7 @@ pub const Parser = struct {
|
|||
var expr = try self.parseOr();
|
||||
|
||||
if (self.compareAnyOf(&[_]TokenType{
|
||||
.ColonEqual, .Equal, .PlusEqual, .MinusEqual, .StarEqual,
|
||||
.Equal, .PlusEqual, .MinusEqual, .StarEqual,
|
||||
.SlashEqual,
|
||||
})) {
|
||||
return try self.finishAssignment(expr, mutable);
|
||||
|
@ -871,8 +865,7 @@ pub const Parser = struct {
|
|||
var value = try self.parseAssignment();
|
||||
|
||||
// expr can be a (Variable|Set)
|
||||
// op_tok can be one of three categories:
|
||||
// - ColonEqual, parses to VarDecl (only when expr = Variable)
|
||||
// op_tok can be one of two categories:
|
||||
// - Equal, parses to (Assign|Set)
|
||||
// - Inplace (+=, -=, *=, /=), parses to (Assign|Set)
|
||||
|
||||
|
@ -893,7 +886,6 @@ pub const Parser = struct {
|
|||
switch (expr.*) {
|
||||
.Variable => {
|
||||
switch (op_tok.typ) {
|
||||
.ColonEqual => return try self.mkVarDecl(expr.Variable, value, mutable),
|
||||
.Equal => return try self.mkAssign(expr.Variable, value),
|
||||
|
||||
.PlusEqual, .MinusEqual, .StarEqual, .SlashEqual => {
|
||||
|
@ -909,6 +901,7 @@ pub const Parser = struct {
|
|||
|
||||
.Get => |get| {
|
||||
switch (op_tok.typ) {
|
||||
// TODO remove .ColonEqual from language
|
||||
.ColonEqual => {
|
||||
return self.doError("can not initialize struct field");
|
||||
},
|
||||
|
|
|
@ -54,6 +54,7 @@ const keywords = [_][]const u8{
|
|||
"pub",
|
||||
"and",
|
||||
"or",
|
||||
"var",
|
||||
};
|
||||
|
||||
const keyword_ttypes = [_]TokenType{
|
||||
|
@ -86,9 +87,12 @@ const keyword_ttypes = [_]TokenType{
|
|||
.Pub,
|
||||
.And,
|
||||
.Or,
|
||||
.Var,
|
||||
};
|
||||
|
||||
fn getKeyword(keyword: []const u8) ?TokenType {
|
||||
std.debug.assert(keywords.len == keyword_ttypes.len);
|
||||
|
||||
for (keywords) |kw, idx| {
|
||||
if (std.mem.eql(u8, keyword, kw)) {
|
||||
return keyword_ttypes[idx];
|
||||
|
|
|
@ -77,6 +77,7 @@ pub const TokenType = enum {
|
|||
|
||||
Println,
|
||||
Pub,
|
||||
Var,
|
||||
|
||||
EOF,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue