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 (
|
//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
|
||||||
|
}
|
||||||
|
|
46
src/ast.zig
46
src/ast.zig
|
@ -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"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue