Compare commits
No commits in common. "9b3e9e81399db1ede4588e9e81fa4c283e612b1a" and "4534549f41aa012aaa4c409d7d9e3bb9105b0b46" have entirely different histories.
9b3e9e8139
...
4534549f41
3 changed files with 35 additions and 129 deletions
|
@ -11,10 +11,4 @@ fn main(a int) int {
|
||||||
3 / (51 + 2)
|
3 / (51 + 2)
|
||||||
mut a := 1+2
|
mut a := 1+2
|
||||||
a = 2
|
a = 2
|
||||||
|
|
||||||
if a {
|
|
||||||
println(30)
|
|
||||||
} else {
|
|
||||||
println(50)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
97
src/ast.zig
97
src/ast.zig
|
@ -20,13 +20,14 @@ pub const NodeType = enum {
|
||||||
|
|
||||||
pub const ParamDecl = struct {
|
pub const ParamDecl = struct {
|
||||||
name: Token,
|
name: Token,
|
||||||
|
|
||||||
|
// TODO types
|
||||||
typ: Token,
|
typ: Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FnDecl = struct {
|
pub const FnDecl = struct {
|
||||||
func_name: Token,
|
func_name: Token,
|
||||||
params: ParamList,
|
params: ParamList,
|
||||||
return_type: Token,
|
|
||||||
body: StmtList,
|
body: StmtList,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,51 +80,32 @@ pub const VarDecl = struct {
|
||||||
pub const Expr = union(ExprType) {
|
pub const Expr = union(ExprType) {
|
||||||
Assign: AssignExpr,
|
Assign: AssignExpr,
|
||||||
VarDecl: VarDecl,
|
VarDecl: VarDecl,
|
||||||
|
|
||||||
Binary: BinaryExpr,
|
Binary: BinaryExpr,
|
||||||
Unary: UnaryExpr,
|
Unary: UnaryExpr,
|
||||||
Literal: LiteralExpr,
|
Literal: LiteralExpr,
|
||||||
|
|
||||||
Variable: Token,
|
Variable: Token,
|
||||||
Grouping: *Expr,
|
Grouping: *Expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const IfBranch = std.ArrayList(*Stmt);
|
// TODO
|
||||||
|
//pub const IfStmt = struct {
|
||||||
pub const IfStmt = struct {
|
// condition: *Expr,
|
||||||
condition: *Expr,
|
// then_branch: *StmtList,
|
||||||
then_branch: IfBranch,
|
// else_branch: *StmtList,
|
||||||
else_branch: ?IfBranch,
|
//};
|
||||||
};
|
|
||||||
|
|
||||||
pub const Stmt = union(enum) {
|
pub const Stmt = union(enum) {
|
||||||
Expr: *Expr,
|
Expr: *Expr,
|
||||||
Println: *Expr,
|
Println: *Expr,
|
||||||
|
|
||||||
If: IfStmt,
|
// TODO
|
||||||
|
//If: IfStmt,
|
||||||
|
|
||||||
pub fn mkPrintln(allocator: *std.mem.Allocator, expr: *Expr) !*Stmt {
|
pub fn mkPrintln(allocator: *std.mem.Allocator, expr: *Expr) !*Stmt {
|
||||||
var println = try allocator.create(Stmt);
|
var println = try allocator.create(Stmt);
|
||||||
println.* = Stmt{ .Println = expr };
|
println.* = Stmt{ .Println = expr };
|
||||||
return println;
|
return println;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mkIfStmt(
|
|
||||||
allocator: *std.mem.Allocator,
|
|
||||||
condition: *Expr,
|
|
||||||
then: IfBranch,
|
|
||||||
else_branch: ?IfBranch,
|
|
||||||
) !*Stmt {
|
|
||||||
var println = try allocator.create(Stmt);
|
|
||||||
println.* = Stmt{
|
|
||||||
.If = IfStmt{
|
|
||||||
.condition = condition,
|
|
||||||
.then_branch = then,
|
|
||||||
.else_branch = else_branch,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return println;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Node = union(NodeType) {
|
pub const Node = union(NodeType) {
|
||||||
|
@ -155,50 +137,39 @@ fn print(ident: usize, comptime fmt: []const u8, args: ...) void {
|
||||||
std.debug.warn(fmt, args);
|
std.debug.warn(fmt, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn printBlock(ident: usize, block: var, endNewline: bool) void {
|
|
||||||
std.debug.warn("(\n");
|
|
||||||
|
|
||||||
for (block.toSlice()) |stmt| {
|
|
||||||
printIdent(ident);
|
|
||||||
printStmt(ident, stmt);
|
|
||||||
std.debug.warn("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endNewline) {
|
|
||||||
print(ident - 1, ")\n");
|
|
||||||
} else {
|
|
||||||
print(ident - 1, ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn printNode(node: *Node, ident: usize) void {
|
pub fn printNode(node: *Node, ident: usize) void {
|
||||||
switch (node.*) {
|
switch (node.*) {
|
||||||
.FnDecl => |decl| {
|
.FnDecl => |decl| {
|
||||||
print(ident, "(fn {} (", decl.func_name.lexeme);
|
print(ident, "FnDecl name='{}'\n", decl.func_name.lexeme);
|
||||||
|
|
||||||
for (decl.params.toSlice()) |param| {
|
for (decl.params.toSlice()) |param| {
|
||||||
std.debug.warn("({} {}) ", param.name.lexeme, param.typ.lexeme);
|
print(
|
||||||
|
ident + 1,
|
||||||
|
"param: '{}' {}\n",
|
||||||
|
param.name.lexeme,
|
||||||
|
param.typ.lexeme,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
printBlock(ident + 1, decl.body, false);
|
for (decl.body.toSlice()) |stmt| {
|
||||||
std.debug.warn(")\n");
|
printIdent(ident + 1);
|
||||||
|
printStmt(stmt);
|
||||||
|
std.debug.warn("\n");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
.ConstDecl => |consts| {
|
.ConstDecl => |consts| {
|
||||||
print(ident, "(const (\n");
|
print(ident, "ConstDecl ({} consts)\n", consts.len);
|
||||||
|
|
||||||
for (consts.toSlice()) |const_decl| {
|
for (consts.toSlice()) |const_decl| {
|
||||||
print(
|
print(
|
||||||
ident + 1,
|
ident + 1,
|
||||||
"({} ",
|
"{} = ",
|
||||||
const_decl.name.lexeme,
|
const_decl.name.lexeme,
|
||||||
);
|
);
|
||||||
|
|
||||||
printExpr(const_decl.expr);
|
printExpr(const_decl.expr);
|
||||||
std.debug.warn(")\n");
|
std.debug.warn("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
print(ident, "))\n");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.Root => {
|
.Root => {
|
||||||
|
@ -215,7 +186,7 @@ pub fn printNode(node: *Node, ident: usize) void {
|
||||||
|
|
||||||
.Stmt => |stmt| blk: {
|
.Stmt => |stmt| blk: {
|
||||||
printIdent(ident);
|
printIdent(ident);
|
||||||
printStmt(ident, stmt);
|
printStmt(stmt);
|
||||||
std.debug.warn("\n");
|
std.debug.warn("\n");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -276,24 +247,10 @@ pub fn printExpr(expr: *Expr) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn printStmt(ident: usize, stmt: *Stmt) void {
|
pub fn printStmt(stmt: *Stmt) void {
|
||||||
switch (stmt.*) {
|
switch (stmt.*) {
|
||||||
.Println => |expr| parenthetize("println", &[_]*Expr{expr}),
|
.Println => |expr| parenthetize("println", &[_]*Expr{expr}),
|
||||||
.Expr => |expr| printExpr(expr),
|
.Expr => |expr| printExpr(expr),
|
||||||
|
|
||||||
.If => |ifstmt| {
|
|
||||||
std.debug.warn("(if ");
|
|
||||||
printExpr(ifstmt.condition);
|
|
||||||
std.debug.warn(" ");
|
|
||||||
|
|
||||||
printBlock(ident + 1, ifstmt.then_branch, false);
|
|
||||||
if (ifstmt.else_branch) |else_branch| {
|
|
||||||
std.debug.warn(" else ");
|
|
||||||
printBlock(ident + 1, else_branch, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
std.debug.warn(")\n");
|
|
||||||
},
|
|
||||||
else => std.debug.warn("UnknownStmt-{}", @tagName(stmt.*)),
|
else => std.debug.warn("UnknownStmt-{}", @tagName(stmt.*)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,19 +120,12 @@ pub const Parser = struct {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mkFnDecl(
|
fn mkFnDecl(self: *Parser, name: Token, params: ast.ParamList, block: ast.StmtList) !*ast.Node {
|
||||||
self: *Parser,
|
|
||||||
name: Token,
|
|
||||||
params: ast.ParamList,
|
|
||||||
return_type: Token,
|
|
||||||
block: ast.StmtList,
|
|
||||||
) !*ast.Node {
|
|
||||||
var node = try self.allocator.create(Node);
|
var node = try self.allocator.create(Node);
|
||||||
node.* = Node{
|
node.* = Node{
|
||||||
.FnDecl = ast.FnDecl{
|
.FnDecl = ast.FnDecl{
|
||||||
.func_name = name,
|
.func_name = name,
|
||||||
.params = params,
|
.params = params,
|
||||||
.return_type = return_type,
|
|
||||||
.body = block,
|
.body = block,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -355,8 +348,6 @@ pub const Parser = struct {
|
||||||
|
|
||||||
while (self.peek().ttype != .RightParen) {
|
while (self.peek().ttype != .RightParen) {
|
||||||
const param_name = try self.consumeSingle(.Identifier);
|
const param_name = try self.consumeSingle(.Identifier);
|
||||||
|
|
||||||
// TODO dedicated function to consume a type
|
|
||||||
const param_type = try self.consumeSingle(.Identifier);
|
const param_type = try self.consumeSingle(.Identifier);
|
||||||
|
|
||||||
try param_list.append(ast.ParamDecl{
|
try param_list.append(ast.ParamDecl{
|
||||||
|
@ -367,10 +358,13 @@ pub const Parser = struct {
|
||||||
|
|
||||||
_ = try self.consumeSingle(.RightParen);
|
_ = try self.consumeSingle(.RightParen);
|
||||||
|
|
||||||
// TODO dedicated function to consume a type
|
// TODO return type
|
||||||
const return_type = try self.consumeSingle(.Identifier);
|
const return_type = try self.consumeSingle(.Identifier);
|
||||||
var block_node = try self.parseBlock();
|
|
||||||
return try self.mkFnDecl(name, param_list, return_type, block_node.Block);
|
var block = try self.parseBlock();
|
||||||
|
|
||||||
|
std.debug.warn("!fn name: {}\n", name);
|
||||||
|
return try self.mkFnDecl(name, param_list, block.Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseConstDecl(self: *@This()) !?*Node {
|
fn parseConstDecl(self: *@This()) !?*Node {
|
||||||
|
@ -419,6 +413,7 @@ pub const Parser = struct {
|
||||||
_ = try self.consumeSingle(.LeftBrace);
|
_ = try self.consumeSingle(.LeftBrace);
|
||||||
|
|
||||||
while (self.peek().ttype != .RightBrace) {
|
while (self.peek().ttype != .RightBrace) {
|
||||||
|
std.debug.warn("get smt with cur {}\n", self.peek().ttype);
|
||||||
var stmt = try self.parseDecl();
|
var stmt = try self.parseDecl();
|
||||||
ast.printNode(try self.mkStmt(stmt), 0);
|
ast.printNode(try self.mkStmt(stmt), 0);
|
||||||
try stmts.append(stmt);
|
try stmts.append(stmt);
|
||||||
|
@ -435,7 +430,6 @@ pub const Parser = struct {
|
||||||
|
|
||||||
fn parseStmt(self: *@This()) anyerror!*Stmt {
|
fn parseStmt(self: *@This()) anyerror!*Stmt {
|
||||||
return switch (self.peek().ttype) {
|
return switch (self.peek().ttype) {
|
||||||
.If => try self.parseIfStmt(),
|
|
||||||
.Println => try self.parsePrintln(),
|
.Println => try self.parsePrintln(),
|
||||||
|
|
||||||
// TODO make newlines tokens and consume newline?
|
// TODO make newlines tokens and consume newline?
|
||||||
|
@ -443,45 +437,6 @@ pub const Parser = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copy of parseBlock for if branches
|
|
||||||
fn parseIfBranch(self: *@This()) !ast.IfBranch {
|
|
||||||
var branch = ast.IfBranch.init(self.allocator);
|
|
||||||
errdefer branch.deinit();
|
|
||||||
|
|
||||||
_ = try self.consumeSingle(.LeftBrace);
|
|
||||||
|
|
||||||
while (self.peek().ttype != .RightBrace) {
|
|
||||||
var stmt = try self.parseDecl();
|
|
||||||
ast.printNode(try self.mkStmt(stmt), 0);
|
|
||||||
try branch.append(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = try self.consumeSingle(.RightBrace);
|
|
||||||
|
|
||||||
return branch;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parseIfStmt(self: *@This()) !*Stmt {
|
|
||||||
_ = try self.consumeSingle(.If);
|
|
||||||
var condition = (try self.parseExpr()).Expr;
|
|
||||||
|
|
||||||
const then_branch = try self.parseIfBranch();
|
|
||||||
|
|
||||||
var else_branch: ?ast.IfBranch = null;
|
|
||||||
|
|
||||||
if (self.check(.Else)) {
|
|
||||||
_ = try self.consumeSingle(.Else);
|
|
||||||
else_branch = try self.parseIfBranch();
|
|
||||||
}
|
|
||||||
|
|
||||||
return try Stmt.mkIfStmt(
|
|
||||||
self.allocator,
|
|
||||||
condition,
|
|
||||||
then_branch,
|
|
||||||
else_branch,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parsePrintln(self: *@This()) !*Stmt {
|
fn parsePrintln(self: *@This()) !*Stmt {
|
||||||
_ = try self.consumeSingle(.Println);
|
_ = try self.consumeSingle(.Println);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue