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 (
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
}

View file

@ -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"),
}
}

View file

@ -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;
}
};