working expressions
This commit is contained in:
parent
f9cc734965
commit
ea5de0914a
3 changed files with 119 additions and 37 deletions
|
@ -1,8 +1,10 @@
|
|||
const (
|
||||
Cock = 1
|
||||
Ball = 2
|
||||
Deals = 3
|
||||
Businesses = 4
|
||||
)
|
||||
//const (
|
||||
// Cock = 1
|
||||
// Ball = 2
|
||||
// Deals = 3
|
||||
// Businesses = 4
|
||||
//)
|
||||
|
||||
fn main(a int) {}
|
||||
fn main(a int) int {
|
||||
1 + 2
|
||||
}
|
||||
|
|
46
src/ast.zig
46
src/ast.zig
|
@ -26,7 +26,7 @@ pub const ParamDecl = struct {
|
|||
pub const FnDecl = struct {
|
||||
func_name: Token,
|
||||
params: ParamList,
|
||||
body: NodeList,
|
||||
body: ExprList,
|
||||
};
|
||||
|
||||
pub const SingleConst = struct {
|
||||
|
@ -65,6 +65,8 @@ pub const Node = union(NodeType) {
|
|||
Root: NodeList,
|
||||
FnDecl: FnDecl,
|
||||
ConstDecl: ConstList,
|
||||
|
||||
// TODO StmtList
|
||||
Block: ExprList,
|
||||
Expr: *Expr,
|
||||
};
|
||||
|
@ -75,12 +77,15 @@ pub fn mkRoot(allocator: *std.mem.Allocator) !*Node {
|
|||
return node;
|
||||
}
|
||||
|
||||
fn print(ident: usize, comptime fmt: []const u8, args: ...) void {
|
||||
fn printIdent(ident: usize) void {
|
||||
var i: usize = 0;
|
||||
while (i < ident) : (i += 1) {
|
||||
std.debug.warn("\t");
|
||||
}
|
||||
}
|
||||
|
||||
fn print(ident: usize, comptime fmt: []const u8, args: ...) void {
|
||||
printIdent(ident);
|
||||
std.debug.warn(fmt, args);
|
||||
}
|
||||
|
||||
|
@ -97,6 +102,10 @@ pub fn printNode(node: *Node, ident: usize) void {
|
|||
param.typ.lexeme,
|
||||
);
|
||||
}
|
||||
|
||||
for (decl.body.toSlice()) |expr| {
|
||||
printExpr(expr, ident + 1);
|
||||
}
|
||||
},
|
||||
|
||||
.ConstDecl => |consts| {
|
||||
|
@ -117,8 +126,41 @@ pub fn printNode(node: *Node, ident: usize) void {
|
|||
}
|
||||
},
|
||||
|
||||
.Expr => |expr| printExpr(expr, 0),
|
||||
|
||||
else => {
|
||||
print(ident, "unknown node: {}\n", node);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn parenthetize(ident: usize, name: []const u8, exprs: []*Expr) void {
|
||||
printIdent(ident);
|
||||
std.debug.warn("({}", name);
|
||||
|
||||
for (exprs) |expr| {
|
||||
std.debug.warn(" ");
|
||||
printExpr(expr, ident);
|
||||
}
|
||||
|
||||
std.debug.warn(")");
|
||||
}
|
||||
|
||||
pub fn printExpr(expr: *Expr, ident: usize) void {
|
||||
switch (expr.*) {
|
||||
.Binary => |binary| parenthetize(ident, binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }),
|
||||
.Unary => |unary| parenthetize(ident, unary.op.lexeme, &[_]*Expr{unary.right}),
|
||||
.Grouping => |expr_ptr| parenthetize(ident, "group", &[_]*Expr{expr_ptr}),
|
||||
|
||||
.Literal => |literal| {
|
||||
switch (literal) {
|
||||
.Bool => |val| std.debug.warn("{}", val),
|
||||
.Integer => |val| std.debug.warn("{}", val),
|
||||
.Float => |val| std.debug.warn("{}", val),
|
||||
.String => |val| std.debug.warn("'{}'", val),
|
||||
}
|
||||
},
|
||||
|
||||
else => std.debug.warn("unknown"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ pub const Parser = struct {
|
|||
if (self.check(ttype)) {
|
||||
var cur = self.peek();
|
||||
_ = try self.nextToken();
|
||||
std.debug.warn("now has {}\n", self.peek());
|
||||
std.debug.warn("consumed {}, now has {}\n", ttype, self.peek());
|
||||
return cur;
|
||||
}
|
||||
|
||||
|
@ -111,21 +111,21 @@ pub const Parser = struct {
|
|||
|
||||
fn compareAnyOf(self: *@This(), ttypes: []TokenType) bool {
|
||||
for (ttypes) |ttype| {
|
||||
if (self.peek().ttype == ttype) return true;
|
||||
if (self.check(ttype)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
fn mkFnDecl(self: *Parser, name: Token, params: ast.ParamList) !*ast.Node {
|
||||
fn mkFnDecl(self: *Parser, name: Token, params: ast.ParamList, block: ast.ExprList) !*ast.Node {
|
||||
var node = try self.allocator.create(Node);
|
||||
node.* = Node{
|
||||
.FnDecl = ast.FnDecl{
|
||||
.func_name = name,
|
||||
.params = params,
|
||||
|
||||
// TODO replace by arg when statements work
|
||||
.body = ast.NodeList.init(self.allocator),
|
||||
// TODO stmt
|
||||
.body = block,
|
||||
},
|
||||
};
|
||||
return node;
|
||||
|
@ -156,6 +156,8 @@ pub const Parser = struct {
|
|||
}
|
||||
|
||||
fn mkUnary(self: *Parser, op: Token, right: *Expr) !*Expr {
|
||||
std.debug.warn("Unary\n");
|
||||
|
||||
var expr = try self.allocator.create(Expr);
|
||||
expr.* = Expr{
|
||||
.Unary = ast.UnaryExpr{
|
||||
|
@ -167,6 +169,8 @@ pub const Parser = struct {
|
|||
}
|
||||
|
||||
fn mkBinary(self: *Parser, left: *Expr, op: Token, right: *Expr) !*Expr {
|
||||
std.debug.warn("Binary\n");
|
||||
|
||||
var expr = try self.allocator.create(Expr);
|
||||
expr.* = Expr{
|
||||
.Binary = ast.BinaryExpr{
|
||||
|
@ -293,7 +297,7 @@ pub const Parser = struct {
|
|||
errdefer param_list.deinit();
|
||||
|
||||
_ = try self.consumeSingle(.Fn);
|
||||
var name = try self.consumeSingle(.Identifier);
|
||||
const name = try self.consumeSingle(.Identifier);
|
||||
|
||||
_ = try self.consumeSingle(.LeftParen);
|
||||
|
||||
|
@ -310,11 +314,12 @@ pub const Parser = struct {
|
|||
_ = try self.consumeSingle(.RightParen);
|
||||
|
||||
// TODO return type
|
||||
const return_type = try self.consumeSingle(.Identifier);
|
||||
|
||||
var block = try self.parseBlock();
|
||||
|
||||
std.debug.warn("!fn name: {}\n", name);
|
||||
return try self.mkFnDecl(name, param_list);
|
||||
return try self.mkFnDecl(name, param_list, block.Block);
|
||||
}
|
||||
|
||||
fn parseConstDecl(self: *@This()) !?*Node {
|
||||
|
@ -354,14 +359,18 @@ pub const Parser = struct {
|
|||
};
|
||||
}
|
||||
|
||||
fn parseBlock(self: *@This()) !?*Node {
|
||||
fn parseBlock(self: *@This()) !*Node {
|
||||
var exprs = ast.ExprList.init(self.allocator);
|
||||
errdefer exprs.deinit();
|
||||
|
||||
_ = try self.consumeSingle(.LeftBrace);
|
||||
|
||||
while (self.peek().ttype != .RightBrace)
|
||||
try exprs.append((try self.parseExpr()).Expr);
|
||||
|
||||
while (self.peek().ttype != .RightBrace) {
|
||||
var node = try self.parseExpr();
|
||||
ast.printNode(node, 0);
|
||||
try exprs.append(node.Expr);
|
||||
//_ = try self.nextToken();
|
||||
}
|
||||
_ = try self.consumeSingle(.RightBrace);
|
||||
|
||||
return try self.mkBlock(exprs);
|
||||
|
@ -418,21 +427,47 @@ pub const Parser = struct {
|
|||
fn parseAddition(self: *@This()) !*Expr {
|
||||
var expr = try self.parseMultiplication();
|
||||
|
||||
std.debug.warn("left expr at addition:");
|
||||
ast.printExpr(expr, 0);
|
||||
std.debug.warn("\n");
|
||||
|
||||
while (self.compareAnyOf(&[_]TokenType{
|
||||
.Minus, .Plus,
|
||||
})) {
|
||||
var op = self.previous();
|
||||
var op = self.peek();
|
||||
_ = try self.nextToken();
|
||||
|
||||
std.debug.warn("==OP token {}\n", op);
|
||||
|
||||
var right = try self.parseMultiplication();
|
||||
|
||||
expr.* = ast.Expr{
|
||||
.Binary = ast.BinaryExpr{
|
||||
.left = expr,
|
||||
.op = op,
|
||||
.right = right,
|
||||
},
|
||||
};
|
||||
std.debug.warn("right expr at addition:");
|
||||
ast.printExpr(right, 0);
|
||||
std.debug.warn("\n");
|
||||
|
||||
std.debug.warn("left expr at combination:");
|
||||
ast.printExpr(expr, 0);
|
||||
std.debug.warn("\n");
|
||||
|
||||
expr = try self.mkBinary(expr, op, right);
|
||||
|
||||
//expr.* = ast.Expr{
|
||||
// .Binary = ast.BinaryExpr{
|
||||
// .left = expr,
|
||||
// .op = op,
|
||||
// .right = right,
|
||||
// },
|
||||
//};
|
||||
|
||||
std.debug.warn("final expr at addition:");
|
||||
ast.printExpr(expr, 0);
|
||||
std.debug.warn("\n");
|
||||
}
|
||||
|
||||
std.debug.warn("ret expr at addition:");
|
||||
ast.printExpr(expr, 0);
|
||||
std.debug.warn("\n");
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
@ -465,22 +500,24 @@ pub const Parser = struct {
|
|||
return try self.mkUnary(op, right);
|
||||
}
|
||||
|
||||
return try self.parsePrimary();
|
||||
var expr = try self.parsePrimary();
|
||||
return expr;
|
||||
}
|
||||
|
||||
fn parsePrimary(self: *@This()) !*Expr {
|
||||
const curtype = self.peek().ttype;
|
||||
const lexeme = self.peek().lexeme;
|
||||
|
||||
_ = switch (curtype) {
|
||||
.False => return try self.mkBool(false),
|
||||
.True => return try self.mkBool(true),
|
||||
var expr = switch (curtype) {
|
||||
.False => try self.mkBool(false),
|
||||
.True => try self.mkBool(true),
|
||||
|
||||
.Integer => return try self.mkInteger(lexeme),
|
||||
.Float => return try self.mkFloat(lexeme),
|
||||
.String => return try self.mkString(lexeme),
|
||||
.Integer => try self.mkInteger(lexeme),
|
||||
.Float => try self.mkFloat(lexeme),
|
||||
.String => try self.mkString(lexeme),
|
||||
|
||||
.LeftParen => blk: {
|
||||
_ = try self.nextToken();
|
||||
var expr = (try self.parseExpr()).Expr;
|
||||
_ = try self.consume(.RightParen, "Expected ')' after expression");
|
||||
break :blk try self.mkGrouping(expr);
|
||||
|
@ -492,7 +529,8 @@ pub const Parser = struct {
|
|||
},
|
||||
};
|
||||
|
||||
std.debug.warn("SHOULD NOT HAVE HAPPENED\n");
|
||||
return Result.CompileError;
|
||||
_ = try self.nextToken();
|
||||
|
||||
return expr;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue