Compare commits
No commits in common. "c0c93183cb693afc291320b4b1114476a2b1fe30" and "4f0c43865f427558cd036923048dc43fe202cfa4" have entirely different histories.
c0c93183cb
...
4f0c43865f
3 changed files with 2 additions and 119 deletions
|
@ -30,8 +30,4 @@ fn main(a int) int {
|
||||||
loop a > 2 {
|
loop a > 2 {
|
||||||
println('skirts')
|
println('skirts')
|
||||||
}
|
}
|
||||||
|
|
||||||
cock_and_ball_torture('cbt', 1, 2, 3)
|
|
||||||
|
|
||||||
return 23
|
|
||||||
}
|
}
|
||||||
|
|
45
src/ast.zig
45
src/ast.zig
|
@ -76,7 +76,6 @@ pub const ExprType = enum {
|
||||||
Logical,
|
Logical,
|
||||||
Literal,
|
Literal,
|
||||||
Variable,
|
Variable,
|
||||||
Call,
|
|
||||||
Grouping,
|
Grouping,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,12 +84,6 @@ pub const VarDecl = struct {
|
||||||
mutable: bool = false,
|
mutable: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CallExpr = struct {
|
|
||||||
callee: *Expr,
|
|
||||||
paren: Token,
|
|
||||||
arguments: ExprList,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Expr = union(ExprType) {
|
pub const Expr = union(ExprType) {
|
||||||
Assign: AssignExpr,
|
Assign: AssignExpr,
|
||||||
VarDecl: VarDecl,
|
VarDecl: VarDecl,
|
||||||
|
@ -102,7 +95,6 @@ pub const Expr = union(ExprType) {
|
||||||
|
|
||||||
Variable: Token,
|
Variable: Token,
|
||||||
Grouping: *Expr,
|
Grouping: *Expr,
|
||||||
Call: CallExpr,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Block = std.ArrayList(*Stmt);
|
pub const Block = std.ArrayList(*Stmt);
|
||||||
|
@ -125,13 +117,6 @@ pub const Stmt = union(enum) {
|
||||||
If: IfStmt,
|
If: IfStmt,
|
||||||
Loop: LoopStmt,
|
Loop: LoopStmt,
|
||||||
|
|
||||||
Return: ReturnStmt,
|
|
||||||
|
|
||||||
pub const ReturnStmt = struct {
|
|
||||||
keyword: Token,
|
|
||||||
value: *Expr,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn mkPrintln(allocator: *std.mem.Allocator, expr: *Expr) !*Stmt {
|
pub fn mkPrintln(allocator: *std.mem.Allocator, expr: *Expr) !*Stmt {
|
||||||
var stmt = try allocator.create(Stmt);
|
var stmt = try allocator.create(Stmt);
|
||||||
stmt.* = Stmt{ .Println = expr };
|
stmt.* = Stmt{ .Println = expr };
|
||||||
|
@ -171,18 +156,6 @@ pub const Stmt = union(enum) {
|
||||||
|
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mkReturn(allocator: *std.mem.Allocator, tok: Token, value: *Expr) !*Stmt {
|
|
||||||
var stmt = try allocator.create(Stmt);
|
|
||||||
stmt.* = Stmt{
|
|
||||||
.Return = ReturnStmt{
|
|
||||||
.keyword = tok,
|
|
||||||
.value = value,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return stmt;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Node = union(NodeType) {
|
pub const Node = union(NodeType) {
|
||||||
|
@ -332,18 +305,6 @@ pub fn printExpr(expr: *Expr) void {
|
||||||
std.debug.warn(")");
|
std.debug.warn(")");
|
||||||
},
|
},
|
||||||
|
|
||||||
.Call => |call| {
|
|
||||||
std.debug.warn("(");
|
|
||||||
printExpr(call.callee);
|
|
||||||
|
|
||||||
for (call.arguments.toSlice()) |arg| {
|
|
||||||
std.debug.warn(" ");
|
|
||||||
printExpr(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
std.debug.warn(")");
|
|
||||||
},
|
|
||||||
|
|
||||||
else => std.debug.warn("UnknownExpr-{}", @tagName(expr.*)),
|
else => std.debug.warn("UnknownExpr-{}", @tagName(expr.*)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,12 +341,6 @@ pub fn printStmt(ident: usize, stmt: *Stmt) void {
|
||||||
std.debug.warn(")\n");
|
std.debug.warn(")\n");
|
||||||
},
|
},
|
||||||
|
|
||||||
.Return => |ret| {
|
|
||||||
std.debug.warn("(return ");
|
|
||||||
printExpr(ret.value);
|
|
||||||
std.debug.warn(")\n");
|
|
||||||
},
|
|
||||||
|
|
||||||
else => std.debug.warn("UnknownStmt-{}", @tagName(stmt.*)),
|
else => std.debug.warn("UnknownStmt-{}", @tagName(stmt.*)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,19 +241,6 @@ pub const Parser = struct {
|
||||||
return vardecl;
|
return vardecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mkCall(self: *@This(), callee: *Expr, paren: Token, args: ast.ExprList) !*Expr {
|
|
||||||
var expr = try self.allocator.create(Expr);
|
|
||||||
expr.* = Expr{
|
|
||||||
.Call = ast.CallExpr{
|
|
||||||
.callee = callee,
|
|
||||||
.paren = paren,
|
|
||||||
.arguments = args,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mkBool(self: *Parser, val: bool) !*ast.Expr {
|
fn mkBool(self: *Parser, val: bool) !*ast.Expr {
|
||||||
var expr = try self.allocator.create(Expr);
|
var expr = try self.allocator.create(Expr);
|
||||||
expr.* = Expr{
|
expr.* = Expr{
|
||||||
|
@ -464,7 +451,6 @@ pub const Parser = struct {
|
||||||
.If => try self.parseIfStmt(),
|
.If => try self.parseIfStmt(),
|
||||||
.Loop => try self.parseLoop(),
|
.Loop => try self.parseLoop(),
|
||||||
.Println => try self.parsePrintln(),
|
.Println => try self.parsePrintln(),
|
||||||
.Return => try self.parseReturn(),
|
|
||||||
|
|
||||||
// TODO make newlines tokens and consume newline?
|
// TODO make newlines tokens and consume newline?
|
||||||
else => try self.parseStmtExpr(),
|
else => try self.parseStmtExpr(),
|
||||||
|
@ -526,20 +512,14 @@ pub const Parser = struct {
|
||||||
return try Stmt.mkLoop(self.allocator, expr, body);
|
return try Stmt.mkLoop(self.allocator, expr, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseReturn(self: *@This()) !*Stmt {
|
|
||||||
const tok = try self.consumeSingle(.Return);
|
|
||||||
const expr = (try self.parseExpr()).Expr;
|
|
||||||
return try Stmt.mkReturn(self.allocator, tok, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parsePrintln(self: *@This()) !*Stmt {
|
fn parsePrintln(self: *@This()) !*Stmt {
|
||||||
_ = try self.consumeSingle(.Println);
|
_ = try self.consumeSingle(.Println);
|
||||||
|
|
||||||
_ = try self.consumeSingle(.LeftParen);
|
_ = try self.consumeSingle(.LeftParen);
|
||||||
var expr = (try self.parseExpr()).Expr;
|
var expr = try self.parseExpr();
|
||||||
_ = try self.consumeSingle(.RightParen);
|
_ = try self.consumeSingle(.RightParen);
|
||||||
|
|
||||||
return try Stmt.mkPrintln(self.allocator, expr);
|
return try Stmt.mkPrintln(self.allocator, expr.Expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseStmtExpr(self: *@This()) !*Stmt {
|
fn parseStmtExpr(self: *@This()) !*Stmt {
|
||||||
|
@ -696,58 +676,10 @@ pub const Parser = struct {
|
||||||
return try self.mkUnary(op, right);
|
return try self.mkUnary(op, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
var expr = try self.parseCall();
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parseCall(self: *@This()) !*Expr {
|
|
||||||
// we parse a primary expression instead of consuming a .Identifier
|
|
||||||
// since parseCall is connected to the rest of the parser. doing
|
|
||||||
// identifiers would break the rest of the rules that want primaries.
|
|
||||||
|
|
||||||
// nothing stops us from ensuring expr is a Variable though ;)
|
|
||||||
var expr = try self.parsePrimary();
|
var expr = try self.parsePrimary();
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (self.check(.LeftParen)) {
|
|
||||||
if (ast.ExprType(expr.*) != .Variable) {
|
|
||||||
self.doError("cannot call non-variable{}", ast.ExprType(expr.*));
|
|
||||||
return Result.CompileError;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = try self.consumeSingle(.LeftParen);
|
|
||||||
expr = try self.finishCall(expr);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finishCall(self: *@This(), callee: *Expr) !*Expr {
|
|
||||||
var args = ast.ExprList.init(self.allocator);
|
|
||||||
errdefer args.deinit();
|
|
||||||
|
|
||||||
if (!self.check(.RightParen)) {
|
|
||||||
|
|
||||||
// emulating do-while really badly
|
|
||||||
var arg = (try self.parseExpr()).Expr;
|
|
||||||
try args.append(arg);
|
|
||||||
|
|
||||||
while (self.check(.Comma)) {
|
|
||||||
_ = try self.consumeSingle(.Comma);
|
|
||||||
|
|
||||||
arg = (try self.parseExpr()).Expr;
|
|
||||||
try args.append(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var paren = try self.consume(.RightParen, "Expected ')' after arguments");
|
|
||||||
|
|
||||||
return self.mkCall(callee, paren, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue