working expressions

This commit is contained in:
Luna 2019-08-24 11:07:23 -03:00
parent f9cc734965
commit ea5de0914a
3 changed files with 119 additions and 37 deletions

View file

@ -1,8 +1,10 @@
const ( //const (
Cock = 1 // Cock = 1
Ball = 2 // Ball = 2
Deals = 3 // Deals = 3
Businesses = 4 // Businesses = 4
) //)
fn main(a int) {} fn main(a int) int {
1 + 2
}

View file

@ -26,7 +26,7 @@ pub const ParamDecl = struct {
pub const FnDecl = struct { pub const FnDecl = struct {
func_name: Token, func_name: Token,
params: ParamList, params: ParamList,
body: NodeList, body: ExprList,
}; };
pub const SingleConst = struct { pub const SingleConst = struct {
@ -65,6 +65,8 @@ pub const Node = union(NodeType) {
Root: NodeList, Root: NodeList,
FnDecl: FnDecl, FnDecl: FnDecl,
ConstDecl: ConstList, ConstDecl: ConstList,
// TODO StmtList
Block: ExprList, Block: ExprList,
Expr: *Expr, Expr: *Expr,
}; };
@ -75,12 +77,15 @@ pub fn mkRoot(allocator: *std.mem.Allocator) !*Node {
return node; return node;
} }
fn print(ident: usize, comptime fmt: []const u8, args: ...) void { fn printIdent(ident: usize) void {
var i: usize = 0; var i: usize = 0;
while (i < ident) : (i += 1) { while (i < ident) : (i += 1) {
std.debug.warn("\t"); std.debug.warn("\t");
} }
}
fn print(ident: usize, comptime fmt: []const u8, args: ...) void {
printIdent(ident);
std.debug.warn(fmt, args); std.debug.warn(fmt, args);
} }
@ -97,6 +102,10 @@ pub fn printNode(node: *Node, ident: usize) void {
param.typ.lexeme, param.typ.lexeme,
); );
} }
for (decl.body.toSlice()) |expr| {
printExpr(expr, ident + 1);
}
}, },
.ConstDecl => |consts| { .ConstDecl => |consts| {
@ -117,8 +126,41 @@ pub fn printNode(node: *Node, ident: usize) void {
} }
}, },
.Expr => |expr| printExpr(expr, 0),
else => { else => {
print(ident, "unknown node: {}\n", node); 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"),
}
}

View file

@ -93,7 +93,7 @@ pub const Parser = struct {
if (self.check(ttype)) { if (self.check(ttype)) {
var cur = self.peek(); var cur = self.peek();
_ = try self.nextToken(); _ = try self.nextToken();
std.debug.warn("now has {}\n", self.peek()); std.debug.warn("consumed {}, now has {}\n", ttype, self.peek());
return cur; return cur;
} }
@ -111,21 +111,21 @@ pub const Parser = struct {
fn compareAnyOf(self: *@This(), ttypes: []TokenType) bool { fn compareAnyOf(self: *@This(), ttypes: []TokenType) bool {
for (ttypes) |ttype| { for (ttypes) |ttype| {
if (self.peek().ttype == ttype) return true; if (self.check(ttype)) return true;
} }
return false; 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); 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,
// TODO replace by arg when statements work // TODO stmt
.body = ast.NodeList.init(self.allocator), .body = block,
}, },
}; };
return node; return node;
@ -156,6 +156,8 @@ pub const Parser = struct {
} }
fn mkUnary(self: *Parser, op: Token, right: *Expr) !*Expr { fn mkUnary(self: *Parser, op: Token, right: *Expr) !*Expr {
std.debug.warn("Unary\n");
var expr = try self.allocator.create(Expr); var expr = try self.allocator.create(Expr);
expr.* = Expr{ expr.* = Expr{
.Unary = ast.UnaryExpr{ .Unary = ast.UnaryExpr{
@ -167,6 +169,8 @@ pub const Parser = struct {
} }
fn mkBinary(self: *Parser, left: *Expr, op: Token, right: *Expr) !*Expr { fn mkBinary(self: *Parser, left: *Expr, op: Token, right: *Expr) !*Expr {
std.debug.warn("Binary\n");
var expr = try self.allocator.create(Expr); var expr = try self.allocator.create(Expr);
expr.* = Expr{ expr.* = Expr{
.Binary = ast.BinaryExpr{ .Binary = ast.BinaryExpr{
@ -293,7 +297,7 @@ pub const Parser = struct {
errdefer param_list.deinit(); errdefer param_list.deinit();
_ = try self.consumeSingle(.Fn); _ = try self.consumeSingle(.Fn);
var name = try self.consumeSingle(.Identifier); const name = try self.consumeSingle(.Identifier);
_ = try self.consumeSingle(.LeftParen); _ = try self.consumeSingle(.LeftParen);
@ -310,11 +314,12 @@ pub const Parser = struct {
_ = try self.consumeSingle(.RightParen); _ = try self.consumeSingle(.RightParen);
// TODO return type // TODO return type
const return_type = try self.consumeSingle(.Identifier);
var block = try self.parseBlock(); var block = try self.parseBlock();
std.debug.warn("!fn name: {}\n", name); 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 { 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); var exprs = ast.ExprList.init(self.allocator);
errdefer exprs.deinit(); errdefer exprs.deinit();
_ = try self.consumeSingle(.LeftBrace); _ = try self.consumeSingle(.LeftBrace);
while (self.peek().ttype != .RightBrace) while (self.peek().ttype != .RightBrace) {
try exprs.append((try self.parseExpr()).Expr); var node = try self.parseExpr();
ast.printNode(node, 0);
try exprs.append(node.Expr);
//_ = try self.nextToken();
}
_ = try self.consumeSingle(.RightBrace); _ = try self.consumeSingle(.RightBrace);
return try self.mkBlock(exprs); return try self.mkBlock(exprs);
@ -418,21 +427,47 @@ pub const Parser = struct {
fn parseAddition(self: *@This()) !*Expr { fn parseAddition(self: *@This()) !*Expr {
var expr = try self.parseMultiplication(); var expr = try self.parseMultiplication();
std.debug.warn("left expr at addition:");
ast.printExpr(expr, 0);
std.debug.warn("\n");
while (self.compareAnyOf(&[_]TokenType{ while (self.compareAnyOf(&[_]TokenType{
.Minus, .Plus, .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(); var right = try self.parseMultiplication();
expr.* = ast.Expr{ std.debug.warn("right expr at addition:");
.Binary = ast.BinaryExpr{ ast.printExpr(right, 0);
.left = expr, std.debug.warn("\n");
.op = op,
.right = right, 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; return expr;
} }
@ -465,22 +500,24 @@ pub const Parser = struct {
return try self.mkUnary(op, right); return try self.mkUnary(op, right);
} }
return try self.parsePrimary(); var expr = try self.parsePrimary();
return expr;
} }
fn parsePrimary(self: *@This()) !*Expr { fn parsePrimary(self: *@This()) !*Expr {
const curtype = self.peek().ttype; const curtype = self.peek().ttype;
const lexeme = self.peek().lexeme; const lexeme = self.peek().lexeme;
_ = switch (curtype) { var expr = switch (curtype) {
.False => return try self.mkBool(false), .False => try self.mkBool(false),
.True => return try self.mkBool(true), .True => try self.mkBool(true),
.Integer => return try self.mkInteger(lexeme), .Integer => try self.mkInteger(lexeme),
.Float => return try self.mkFloat(lexeme), .Float => try self.mkFloat(lexeme),
.String => return try self.mkString(lexeme), .String => try self.mkString(lexeme),
.LeftParen => blk: { .LeftParen => blk: {
_ = try self.nextToken();
var expr = (try self.parseExpr()).Expr; var expr = (try self.parseExpr()).Expr;
_ = try self.consume(.RightParen, "Expected ')' after expression"); _ = try self.consume(.RightParen, "Expected ')' after expression");
break :blk try self.mkGrouping(expr); break :blk try self.mkGrouping(expr);
@ -492,7 +529,8 @@ pub const Parser = struct {
}, },
}; };
std.debug.warn("SHOULD NOT HAVE HAPPENED\n"); _ = try self.nextToken();
return Result.CompileError;
return expr;
} }
}; };