Compare commits

..

No commits in common. "e3fdf5399b0f0d69835ed0eb8fefa9b77953949a" and "11f810a5f31cc94a9a146e8b228aae74a087af85" have entirely different histories.

3 changed files with 16 additions and 100 deletions

View file

@ -1 +1,3 @@
fn main() {} fn main(a int) {
// println("hello world!");
}

View file

@ -5,12 +5,9 @@ const Token = tokens.Token;
pub const NodeList = std.ArrayList(*Node); pub const NodeList = std.ArrayList(*Node);
pub const ParamList = std.ArrayList(*ParamDecl); pub const ParamList = std.ArrayList(*ParamDecl);
// TODO convert FnCall to something like PrefixOp / InfixOp / SuffixOp
pub const NodeType = enum { pub const NodeType = enum {
Root, Root,
FnDecl, FnDecl,
FnCall,
String,
}; };
pub const ParamDecl = struct { pub const ParamDecl = struct {
@ -26,16 +23,9 @@ pub const FnDecl = struct {
body: NodeList, body: NodeList,
}; };
pub const FnCall = struct {
func_name: Token,
arguments: NodeList,
};
pub const Node = union(NodeType) { pub const Node = union(NodeType) {
Root: NodeList, Root: NodeList,
FnDecl: FnDecl, FnDecl: FnDecl,
FnCall: FnCall,
String: Token,
}; };
pub fn mkRoot(allocator: *std.mem.Allocator) !*Node { pub fn mkRoot(allocator: *std.mem.Allocator) !*Node {

View file

@ -18,18 +18,16 @@ pub const Parser = struct {
tokens: []Token = undefined, tokens: []Token = undefined,
hadError: bool = false,
pub fn init(allocator: *Allocator, scanner: *Scanner) Parser { pub fn init(allocator: *Allocator, scanner: *Scanner) Parser {
return Parser{ .allocator = allocator, .scanner = scanner }; return Parser{ .allocator = allocator, .scanner = scanner };
} }
fn doError(self: *Parser, comptime fmt: []const u8, args: ...) void { fn doError(self: *Parser, comptime fmt: []const u8, args: ...) Result!void {
self.hadError = true;
std.debug.warn("parser error at line {}\n\t", self.scanner.line); std.debug.warn("parser error at line {}\n\t", self.scanner.line);
std.debug.warn(fmt, args); std.debug.warn(fmt, args);
std.debug.warn("\n"); std.debug.warn("\n");
return Result.CompileError;
} }
fn peek(self: *Parser) Token { fn peek(self: *Parser) Token {
@ -132,10 +130,9 @@ pub const Parser = struct {
while (true) { while (true) {
var tok = self.peek(); var tok = self.peek();
switch (tok.ttype) { if (tok.ttype == .RightParen) break;
.RightParen => break, if (tok.ttype != .Identifier) {
.Identifier => {}, try self.doError("expected identifier, got {}", tok.ttype);
else => try self.doError("expected identifier, got {}", tok.ttype),
} }
var typetok = try self.nextToken(); var typetok = try self.nextToken();
@ -148,24 +145,15 @@ pub const Parser = struct {
std.debug.warn("param! {}\n", param); std.debug.warn("param! {}\n", param);
try param_list.append(param); try param_list.append(param);
tok = try self.nextToken();
} }
// function body // function body
_ = try self.nextToken();
_ = try self.consumeSingle(.LeftBrace); _ = try self.consumeSingle(.LeftBrace);
var body = ast.NodeList.init(self.allocator);
while (true) { while (true) {
var tok = self.peek(); var tok = self.peek();
if (tok.ttype == .RightBrace) break; if (tok.ttype == .RightBrace) break;
// TODO statements?
// TODO statements //var node = self.processToken(tok);
//var node = try self.processToken(tok);
//std.debug.warn("stmt:{}\n", node);
//try body.append(node);
tok = try self.nextToken();
} }
_ = try self.consumeSingle(.RightBrace); _ = try self.consumeSingle(.RightBrace);
@ -173,38 +161,9 @@ pub const Parser = struct {
return try self.mkFnDecl(name, param_list); return try self.mkFnDecl(name, param_list);
} }
fn functionCall(self: *Parser) !*ast.Node { fn processToken(self: *Parser, token: Token) !*ast.Node {
var identifier = try self.consumeSingle(.Identifier);
_ = try self.consumeSingle(.LeftParen);
// arguments
var args = ast.NodeList.init(self.allocator);
while (true) {
var tok = self.peek();
switch (tok.ttype) {
.RightParen => break,
.String => blk: {
var node = try self.allocator.create(Node);
node.* = Node{ .String = tok };
try args.append(node);
},
else => {},
}
tok = try self.nextToken();
}
_ = try self.consumeSingle(.RightParen);
return Node{ .FnCall = ast.FnCall{ .func_name = identifier, .arguments = args } };
}
fn processToken(self: *Parser, token: Token) anyerror!*ast.Node {
var node = switch (token.ttype) { var node = switch (token.ttype) {
.Fn => try self.functionDecl(), .Fn => try self.functionDecl(),
.Identifier => try self.functionCall(),
else => blk: { else => blk: {
try self.doError("TODO handle {}\n", token.ttype); try self.doError("TODO handle {}\n", token.ttype);
return Result.CompileError; return Result.CompileError;
@ -214,53 +173,18 @@ pub const Parser = struct {
return node; return node;
} }
fn block(self: *Parser) anyerror!*ast.Node {
// TODO if(self.accept(.Const))
// while receiving functions, process more
while (self.accept(.Fn)) {
try self.consumeSingle(.LeftParen);
try self.consumeSingle(.RightParen);
var block = try self.block();
}
self.statement();
}
fn topDecl(self: *@This()) !?*Node {
return switch (self.peek().ttype) {
.Fn => blk: {
_ = try self.consumeSingle(.Fn);
var name = try self.consumeSingle(.Identifier);
std.debug.warn("!fn name: {}\n", name);
break :blk try self.mkFnDecl(
name,
ast.ParamList.init(self.allocator),
);
},
else => |ttype| blk: {
self.doError("expected fn, got {}\n", ttype);
break :blk null;
},
};
}
pub fn parse(self: *Parser) !*ast.Node { pub fn parse(self: *Parser) !*ast.Node {
self.tokens = try self.allocator.alloc(Token, 0); self.tokens = try self.allocator.alloc(Token, 0);
var root = try ast.mkRoot(self.allocator); var root = try ast.mkRoot(self.allocator);
while (true) { while (true) {
var token = try self.nextToken(); var token = try self.nextToken();
if (token.ttype == .EOF) break; if (token.ttype == .EOF) break;
var node = try self.topDecl(); var node = try self.processToken(token);
if (node == null) continue; std.debug.warn("{}\n", node.*);
try root.Root.append(node.?); try root.Root.append(node);
}
if (self.hadError) {
return error.ParseError;
} }
return root; return root;