about summary refs log tree commit diff
path: root/src/parser.pry
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.pry')
-rw-r--r--src/parser.pry1456
1 files changed, 1456 insertions, 0 deletions
diff --git a/src/parser.pry b/src/parser.pry
new file mode 100644
index 0000000..0b448d0
--- /dev/null
+++ b/src/parser.pry
@@ -0,0 +1,1456 @@
+import "tokenizer.pry";
+
+extern fopen = (*i8, *i8) => *i8;
+extern fgets = (*i8, i64, *i8) => void;
+extern feof = (*i8) => bool;
+extern fseek = (*i8, i64, i64) => i64;
+extern lseek = (i64, i64, i64) => i64;
+extern ftell = (*i8) => i64;
+extern fread = (*i8, i64, i64, *i8) => i64;
+extern fclose = (*i8) => *i8;
+
+extern strcpy = (*i8, *i8) => *i8;
+extern dirname = (*i8) => *i8;
+extern open = (*i8, i64) => i64;
+extern openat = (i64, *i8, i64) => i64;
+extern read = (i64, *i8, i64) => i64;
+extern realpath = (*i8, *i8) => *i8;
+extern snprintf = (*i8, i64, *i8, *i8, *i8) => i64;
+extern strcpy = (*i8, *i8) => *i8;
+extern strlen = (*i8) => i64;
+
+let Node = struct {
+	type: i64,
+	data: *void,
+};
+
+let NODE_PROGRAM = 1;
+let NODE_STATEMENT = 2;
+let NODE_ASSIGNMENT_STATEMENT = 3;
+let NODE_IMPORT_DECLARATION = 4;
+let NODE_FUNCTION_CALL_STATEMENT = 5;
+let NODE_IF_STATEMENT = 6;
+let NODE_WHILE_STATEMENT = 7;
+let NODE_EQUALITY_EXPRESSION = 8;
+let NODE_ADDITIVE_EXPRESSION = 9;
+let NODE_MULTIPLICATIVE_EXPRESSION = 10;
+let NODE_UNARY_EXPRESSION = 11;
+let NODE_POSTFIX_EXPRESSION = 12;
+let NODE_PRIMARY_EXPRESSION_NUMBER = 13;
+let NODE_PRIMARY_EXPRESSION_BOOLEAN = 14;
+let NODE_PRIMARY_EXPRESSION_NULL = 15;
+let NODE_PRIMARY_EXPRESSION_CHAR = 16;
+let NODE_PRIMARY_EXPRESSION_STRING = 17;
+let NODE_PRIMARY_EXPRESSION_IDENTIFIER = 18;
+let NODE_FUNCTION_DEFINITION = 19;
+let NODE_STRUCT_INSTANCIATION = 20;
+let NODE_FIELD_ACCESS = 21;
+let NODE_TYPE_SIMPLE_TYPE = 22;
+let NODE_TYPE_FUNCTION_TYPE = 23;
+let NODE_TYPE_POINTER_TYPE = 24;
+let NODE_TYPE_STRUCT_TYPE = 25;
+let NODE_RETURN_STATEMENT = 26;
+let NODE_CAST_STATEMENT = 27;
+let NODE_SIZEOF_STATEMENT = 28;
+let NODE_BREAK_STATEMENT = 29;
+let NODE_CONTINUE_STATEMENT = 30;
+
+let EQUALITY_EXPRESSION_TYPE_EQ = 0;
+let EQUALITY_EXPRESSION_TYPE_NE = 1;
+let EQUALITY_EXPRESSION_TYPE_GE = 2;
+let EQUALITY_EXPRESSION_TYPE_LE = 3;
+let EQUALITY_EXPRESSION_TYPE_LT = 4;
+let EQUALITY_EXPRESSION_TYPE_GT = 5;
+
+let MULTIPLICATIVE_EXPRESSION_TYPE_MUL = 0;
+let MULTIPLICATIVE_EXPRESSION_TYPE_DIV = 1;
+let MULTIPLICATIVE_EXPRESSION_TYPE_MOD = 2;
+
+let UNARY_EXPRESSION_TYPE_NOT = 0;
+let UNARY_EXPRESSION_TYPE_MINUS = 1;
+let UNARY_EXPRESSION_TYPE_STAR = 2;
+
+let NODE_PROGRAM_DATA = struct {
+    statements: **Node,
+    statements_len: i64,
+};
+
+let NODE_STATEMENT_DATA = struct {
+    statement: *Node,
+};
+
+let NODE_ASSIGNMENT_STATEMENT_DATA = struct {
+    is_declaration: bool,
+    is_dereference: bool,
+    lhs: *Node,
+    rhs: *Node,
+};
+
+let NODE_IMPORT_DECLARATION_DATA = struct {
+    filename: *i8,
+    program: *Node,
+};
+
+let NODE_FUNCTION_CALL_STATEMENT_DATA = struct {
+    expression: *Node,
+    arguments: **Node,
+    arguments_len: i64,
+};
+
+let NODE_IF_STATEMENT_DATA = struct {
+    condition: *Node,
+    statements: **Node,
+    statements_len: i64,
+};
+
+let NODE_WHILE_STATEMENT_DATA = struct {
+    condition: *Node,
+    statements: **Node,
+    statements_len: i64,
+};
+
+let NODE_EQUALITY_EXPRESSION_DATA = struct {
+    lhs: *Node,
+    rhs: *Node,
+    typ: i64,
+};
+
+let NODE_ADDITIVE_EXPRESSION_DATA = struct {
+    addition: bool,
+    lhs: *Node,
+    rhs: *Node,
+};
+
+let NODE_MULTIPLICATIVE_EXPRESSION_DATA = struct {
+    lhs: *Node,
+    rhs: *Node,
+    typ: i64,
+};
+
+let NODE_UNARY_EXPRESSION_DATA = struct {
+    typ: i64,
+    expression: *Node,
+};
+
+let NODE_POSTFIX_EXPRESSION_DATA = struct {
+    lhs: *Node,
+    rhs: *Node,
+};
+
+let NODE_PRIMARY_EXPRESSION_NUMBER_DATA = struct {
+    value: i64,
+};
+
+let NODE_PRIMARY_EXPRESSION_BOOLEAN_DATA = struct {
+    value: bool,
+};
+
+let NODE_PRIMARY_EXPRESSION_CHAR_DATA = struct {
+    value: i8,
+};
+
+let NODE_PRIMARY_EXPRESSION_STRING_DATA = struct {
+    value: *i8,
+};
+
+let NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA = struct {
+    name: *i8,
+    type: *Node,
+};
+
+let NODE_FUNCTION_DEFINITION_DATA = struct {
+    statements: **Node,
+    statements_len: i64,
+    parameters: **Node,
+    parameters_len: i64,
+    retur_type: *Node,
+};
+
+let NODE_STRUCT_INSTANCIATION_DATA = struct {
+    typ: *i8,
+};
+
+let NODE_FIELD_ACCESS_DATA = struct {
+    expression: *Node,
+    name: *i8,
+};
+
+let NODE_TYPE_SIMPLE_TYPE_DATA = struct {
+    name: *i8,
+    underlying_type: *Node,
+};
+
+let NODE_TYPE_FUNCTION_TYPE_DATA = struct {
+    parameters: **Node,
+    parameters_len: i64,
+    retur_type: *Node,
+};
+
+let NODE_TYPE_POINTER_TYPE_DATA = struct {
+    type: *Node,
+};
+
+let NODE_TYPE_STRUCT_TYPE_DATA = struct {
+    fields: **Node,
+    fields_len: i64,
+};
+
+let NODE_RETURN_STATEMENT_DATA = struct {
+    expression: *Node,
+};
+
+let NODE_CAST_STATEMENT_DATA = struct {
+    typ: *Node,
+    expression: *Node,
+};
+
+let NODE_SIZEOF_STATEMENT_DATA = struct {
+    typ: *Node,
+};
+
+
+let parser = struct {
+	tokens: *token,
+	tokens_len: i64,
+
+	offset: i64,
+
+	arena: *arena,
+	filename: *i8,
+};
+
+extern parser_parse_statement = (*parser) => *Node;
+extern parser_parse_expression = (*parser) => *Node;
+extern parse_function_call_statement = (*parser) => *Node;
+extern parser_parse_additive_expression = (*parser) => *Node;
+
+let parser_init = (ts: *token, ts_len: i64, ar: *arena, filename: *i8) => *parser {
+	let p = cast(*parser, arena_alloc(ar, sizeof(parser)));
+
+	(*p).tokens = ts;
+	(*p).tokens_len = ts_len;
+	(*p).offset = 0;
+	(*p).arena = ar;
+	(*p).filename = filename;
+
+	return p;
+};
+
+let create_node = (p: *parser, n: Node) => *Node {
+	let res = cast(*Node, arena_alloc((*p).arena, sizeof(Node)));
+	*res = n;
+	return res;
+};
+
+let parser_peek_token = (p: *parser) => *token {
+    if (*p).offset >= (*p).tokens_len {
+	return cast(*token, null);
+     };
+
+    return ((*p).tokens + cast(*token, (*p).offset));
+};
+
+ let parser_consume_token = (p: *parser) => *token {
+    if (*p).offset >= (*p).tokens_len {
+	return cast(*token, null);
+     };
+	
+    let t = ((*p).tokens + cast(*token, (*p).offset));
+    (*p).offset = (*p).offset + 1;
+    return t;
+};
+
+let parser_accept_token = (p: *parser, t: i64) => *token {
+    let curr_token = parser_peek_token(p);
+    if curr_token == cast(*token, null) {
+	return cast(*token, null);
+    };
+
+    if (*curr_token).type == t {
+	return parser_consume_token(p);
+    };
+    return cast(*token, null);
+};
+
+let parser_accept_parse = (p: *parser, parsing_func: (*parser) => *Node) => *Node {
+	let prev_offset = (*p).offset;
+	let node = parsing_func(p);
+	if node == cast(*Node, null) {
+		(*p).offset = prev_offset;
+	};
+	return node;
+};
+
+/* ReturnStatement ::= RETURN (Expression)? */
+let parser_parse_return_statement = (p: *parser) => *Node {
+	if parser_accept_token(p, TOKEN_RETURN) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let maybe_expr = parser_accept_parse(p, parser_parse_expression);
+	
+	let d = cast(*NODE_RETURN_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_RETURN_STATEMENT_DATA )));
+	(*d).expression = maybe_expr;
+
+	let r = Node{};
+	r.type = NODE_RETURN_STATEMENT;
+	r.data = cast(*void, d);
+
+	return create_node(p, r);
+};
+
+extern parser_parse_type = (*parser) => *Node;
+
+/* CastStatement ::= "cast" LPAREN TYPE "," Expression RPAREN */
+let parser_parse_cast_statement = (p: *parser) => *Node {
+	let ident = parser_accept_token(p, TOKEN_IDENTIFIER);
+	if ident == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	if !strcmp(cast(*i8, (*ident).data), "cast") {
+		return cast(*Node, null);
+	};
+
+	if parser_accept_token(p, TOKEN_LPAREN) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	
+	let typ = parser_parse_type(p);
+	if typ == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+	
+	if parser_accept_token(p, TOKEN_COMMA) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let expression = parser_parse_expression(p);
+	if expression == cast(*Node, null) {
+	    return cast(*Node, null);
+	};
+	
+	if parser_accept_token(p, TOKEN_RPAREN) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let d = cast(*NODE_CAST_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_CAST_STATEMENT_DATA )));
+	(*d).typ = typ;
+	(*d).expression = expression;
+
+	let r = Node{};
+	r.type = NODE_CAST_STATEMENT;
+	r.data = cast(*void, d);
+
+	return create_node(p, r);
+};
+
+/* SizeOfStatement ::= "sizeof" LPAREN TYPE RPAREN */
+let parser_parse_sizeof_statement = (p: *parser) => *Node {
+	let ident = parser_accept_token(p, TOKEN_IDENTIFIER);
+	if ident == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	if !strcmp(cast(*i8, (*ident).data), "sizeof") {
+		return cast(*Node, null);
+	};
+
+	if parser_accept_token(p, TOKEN_LPAREN) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	
+	let typ = parser_parse_type(p);
+	if typ == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+	
+	if parser_accept_token(p, TOKEN_RPAREN) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let d = cast(*NODE_SIZEOF_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_SIZEOF_STATEMENT_DATA )));
+	(*d).typ = typ;
+
+	let r = Node{};
+	r.type = NODE_SIZEOF_STATEMENT;
+	r.data = cast(*void, d);
+
+	return create_node(p, r);
+};
+
+/* FunctionType ::= LPAREN (Type ("," Type)*)? RPAREN ARROW Type */
+let parser_parse_function_type = (p: *parser) => *Node {
+	if parser_accept_token(p, TOKEN_LPAREN) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let parameters = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 20));
+	let parameters_len = 0;
+	let first = true;
+	while true {
+		if !first {
+			parser_accept_token(p, TOKEN_COMMA);
+		};
+		first = false;
+		let type_annotation = parser_accept_parse(p, parser_parse_type);
+		if type_annotation == cast(*Node, null) {
+			break;
+		};
+		(*(parameters + cast(**Node, parameters_len))) = type_annotation;
+		parameters_len = parameters_len + 1;
+
+	};
+	
+	if parser_accept_token(p, TOKEN_RPAREN) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	if parser_accept_token(p, TOKEN_ARROW) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let retur_typ = parser_parse_type(p);
+	if retur_typ == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+
+	let d = cast(*NODE_TYPE_FUNCTION_TYPE_DATA, arena_alloc((*p).arena, sizeof(NODE_TYPE_FUNCTION_TYPE_DATA)));
+	(*d).parameters = parameters;
+	(*d).parameters_len = parameters_len;
+	(*d).retur_type = retur_typ;
+
+	let r = Node{};
+	r.type = NODE_TYPE_FUNCTION_TYPE;
+	r.data = cast(*void, d);
+
+	return create_node(p, r);
+};
+
+/* Type ::= IDENTIFIER | FunctionType */
+let parser_parse_type = (p: *parser) => *Node {
+	let typ = parser_accept_parse(p, parser_parse_function_type);
+	if typ != cast(*Node, null) {
+		return typ;
+	};
+
+	let to = parser_consume_token(p);
+	assert(to != cast(*token, null));
+
+	/* TODO: we should only accept specific type identifiers */
+	if (*to).type == TOKEN_IDENTIFIER {
+		let d = cast(*NODE_TYPE_SIMPLE_TYPE_DATA, arena_alloc((*p).arena, sizeof(NODE_TYPE_SIMPLE_TYPE_DATA)));
+		(*d).name = cast(*i8, (*to).data);
+		(*d).underlying_type = cast(*Node, null);
+
+		let r = Node{};
+		r.type = NODE_TYPE_SIMPLE_TYPE;
+		r.data = cast(*void, d);
+
+		return create_node(p, r);
+	};
+
+	if (*to).type == TOKEN_MUL {
+		let d = cast(*NODE_TYPE_POINTER_TYPE_DATA, arena_alloc((*p).arena, sizeof(NODE_TYPE_POINTER_TYPE_DATA)));
+		(*d).type = parser_parse_type(p);
+
+		let r = Node{};
+		r.type = NODE_TYPE_POINTER_TYPE;
+		r.data = cast(*void, d);
+
+		return create_node(p, r);
+	};
+
+	return cast(*Node, null);
+};
+
+/* IfStatement ::= "if" Expression LBRACE Statement* RBRACE */
+let parser_parse_if_statement = (p: *parser) => *Node {
+	if parser_accept_token(p, TOKEN_IF) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let expression = parser_parse_expression(p);
+	if expression == cast(*Node, null) {
+	    return cast(*Node, null);
+	};
+	
+	if parser_accept_token(p, TOKEN_LBRACE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let statements = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 100));
+	let i = 0;
+	while true {
+		let n = parser_accept_parse(p, parser_parse_statement);
+		if n == cast(*Node, null) {
+			break;
+		};
+		(*(statements + cast(**Node, i))) = n;
+		i = i + 1;
+	};
+	
+	if parser_accept_token(p, TOKEN_RBRACE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	
+	let dd = cast(*NODE_IF_STATEMENT_DATA, arena_alloc((*p).arena, sizeof(NODE_IF_STATEMENT_DATA)));
+	(*dd).condition = expression;
+	(*dd).statements = statements;
+	(*dd).statements_len = i;
+
+	let r = Node{};
+	r.type = NODE_IF_STATEMENT;
+	r.data = cast(*void, dd);
+
+	return create_node(p, r);
+};
+
+/* WhileStatement ::= "while" Expression LBRACE Statement* RBRACE */
+let parser_parse_while_statement = (p: *parser) => *Node {
+	if parser_accept_token(p, TOKEN_WHILE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let expression = parser_parse_expression(p);
+	if expression == cast(*Node, null) {
+	    return cast(*Node, null);
+	};
+	
+	if parser_accept_token(p, TOKEN_LBRACE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let statements = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 100));
+	let i = 0;
+	while true {
+		let n = parser_accept_parse(p, parser_parse_statement);
+		if n == cast(*Node, null) {
+			break;
+		};
+		(*(statements + cast(**Node, i))) = n;
+		i = i + 1;
+	};
+	
+	if parser_accept_token(p, TOKEN_RBRACE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	
+	let dd = cast(*NODE_WHILE_STATEMENT_DATA, arena_alloc((*p).arena, sizeof(NODE_WHILE_STATEMENT_DATA)));
+	(*dd).condition = expression;
+	(*dd).statements = statements;
+	(*dd).statements_len = i;
+
+	let r = Node{};
+	r.type = NODE_WHILE_STATEMENT;
+	r.data = cast(*void, dd);
+
+	return create_node(p, r);
+};
+
+/* ExternDeclaration ::= "extern" IDENTIFIER EQUALS Type */
+let parser_parse_extern_declaration = (p: *parser) => *Node {
+	if parser_accept_token(p, TOKEN_EXTERN) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let ident = parser_accept_token(p, TOKEN_IDENTIFIER);
+	if ident == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	if parser_accept_token(p, TOKEN_EQUALS) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	let typ = parser_parse_type(p);
+	if typ == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+
+	let d = cast(*NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA)));
+	(*d).name = cast(*i8, (*ident).data);
+	(*d).type = cast(*Node, null);
+
+	let n = Node{};
+	n.type = NODE_PRIMARY_EXPRESSION_IDENTIFIER;
+	n.data = cast(*void, d);
+
+	let dd = cast(*NODE_ASSIGNMENT_STATEMENT_DATA, arena_alloc((*p).arena, sizeof(NODE_ASSIGNMENT_STATEMENT_DATA)));
+	(*dd).is_declaration = false;
+	(*dd).is_dereference = false;
+	(*dd).lhs = create_node(p, n);
+	(*dd).rhs = typ;
+
+	let r = Node{};
+	r.type = NODE_ASSIGNMENT_STATEMENT;
+	r.data = cast(*void, dd);
+
+	return create_node(p, r);
+};
+
+/* FunctionParameters ::= IDENTIFIER ":" Type ("," IDENTIFIER ":" Type)* */
+let parser_parse_function_parameters = (p: *parser) => *slice {
+	let node_list = cast(**Node, arena_alloc((*p).arena, sizeof(**Node) * 20));
+	let i = 0;
+	while true {
+		if i != 0 {
+			parser_accept_token(p, TOKEN_COMMA);
+		};
+		let ident = parser_accept_token(p, TOKEN_IDENTIFIER);
+		if ident == cast(*token, null) {
+			break;
+		};
+		if parser_accept_token(p, TOKEN_COLON) == cast(*token, null) {
+			return cast(*slice, null);
+		};
+		let type_annotation = parser_parse_type(p);
+		if type_annotation == cast(*Node, null) {
+			return cast(*slice, null);
+		};
+
+		let d = cast(*NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA)));
+		(*d).name = cast(*i8, (*ident).data);
+		(*d).type = type_annotation;
+		let n = Node{};
+		n.type = NODE_PRIMARY_EXPRESSION_IDENTIFIER;
+		n.data = cast(*void, d);
+		(*(node_list + cast(**Node, i))) = create_node(p, n);
+
+		i = i + 1;
+	};
+
+	let s = cast(*slice, arena_alloc((*p).arena, sizeof(slice)));
+	(*s).data = cast(*void, node_list);
+	(*s).data_len = i;
+	return s;
+};
+
+/* TypeDefinition ::= "newtype" Type */
+let parser_parse_type_definition = (p: *parser) => *Node {
+	if parser_accept_token(p, TOKEN_TYPE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let typ = parser_parse_type(p);
+	if typ == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+
+	let d = cast(*NODE_TYPE_SIMPLE_TYPE_DATA, arena_alloc((*p).arena, sizeof(NODE_TYPE_SIMPLE_TYPE_DATA)));
+	(*d).name = "";
+	(*d).underlying_type = typ;
+
+	let r = Node{};
+	r.type = NODE_TYPE_SIMPLE_TYPE;
+	r.data = cast(*void, d);
+
+	return create_node(p, r);
+};
+
+/* StructDefinition ::= "struct" LBRACE StructFields? RBRACE */
+let parser_parse_struct_definition = (p: *parser) => *Node {
+	if parser_accept_token(p, TOKEN_STRUCT) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	if parser_accept_token(p, TOKEN_LBRACE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let fields = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 20));
+	let i = 0;
+	while true {
+		let field = parser_accept_parse(p, (ip: *parser) => *Node {
+			let ident = parser_accept_token(ip, TOKEN_IDENTIFIER);
+			if ident == cast(*token, null) {
+				return cast(*Node, null);
+			};
+			if parser_accept_token(ip, TOKEN_COLON) == cast(*token, null) {
+				return cast(*Node, null);
+			};
+			let typ_annotation = parser_parse_type(ip);
+			if typ_annotation == cast(*Node, null) {
+				return cast(*Node, null);
+			};
+			printf("STRUCT TYP: %d\n" (*typ_annotation).type);
+			let d = cast(*NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA, arena_alloc((*ip).arena, sizeof(NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA)));
+			(*d).name = cast(*i8, (*ident).data);
+			(*d).type = typ_annotation;
+			let n = Node{};
+			n.type = NODE_PRIMARY_EXPRESSION_IDENTIFIER;
+			n.data = cast(*void, d);
+			return create_node(ip, n);
+		});
+		if field == cast(*Node, null) {
+			break;
+		};
+
+		parser_accept_token(p, TOKEN_COMMA);
+
+		(*(fields + cast(**Node, i))) = field;
+		i = i + 1;
+	};
+
+	if parser_accept_token(p, TOKEN_RBRACE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let d = cast(*NODE_TYPE_STRUCT_TYPE_DATA, arena_alloc((*p).arena, sizeof(NODE_TYPE_STRUCT_TYPE_DATA)));
+	(*d).fields = fields;
+	(*d).fields_len = i;
+	let n = Node{};
+	n.type = NODE_TYPE_STRUCT_TYPE;
+	n.data = cast(*void, d);
+	return create_node(p, n);
+};
+
+/* FunctionDefinition ::= LPAREN FunctionParameters? RPAREN ARROW IDENTIFIER LBRACE Statement* ReturnStatement SEMICOLON RBRACE */
+let parser_parse_function_definition = (p: *parser) => *Node {
+	if parser_accept_token(p, TOKEN_LPAREN) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	let params = parser_parse_function_parameters(p);
+	if params == cast(*slice, null) {
+		return cast(*Node, null);
+	};
+	if parser_accept_token(p, TOKEN_RPAREN) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	if parser_accept_token(p, TOKEN_ARROW) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	let retur_type = parser_parse_type(p);
+	if retur_type == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+	if parser_accept_token(p, TOKEN_LBRACE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	
+	let statements = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 100));
+	let i = 0;
+	while true {
+		let n = parser_accept_parse(p, parser_parse_statement);
+		if n == cast(*Node, null) {
+			break;
+		};
+		(*(statements + cast(**Node, i))) = n;
+		i = i + 1;
+	};
+
+
+	if parser_accept_token(p, TOKEN_RBRACE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+
+	let d = cast(*NODE_FUNCTION_DEFINITION_DATA, arena_alloc((*p).arena, sizeof(NODE_FUNCTION_DEFINITION_DATA)));
+	(*d).statements = statements;
+	(*d).statements_len = i;
+	(*d).parameters = cast(**Node, (*params).data);
+	(*d).parameters_len = (*params).data_len;
+	(*d).retur_type = retur_type;
+
+	let n = Node{};
+	n.type = NODE_FUNCTION_DEFINITION;
+	n.data = cast(*void, d);
+
+	return create_node(p, n); 
+};
+
+/* StructInstantiation ::= IDENTIFIER LBRACE RBRACE */
+let parser_parse_struct_instanciation = (p: *parser) => *Node {
+	let typ = parser_accept_token(p, TOKEN_IDENTIFIER);
+	if typ == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	if parser_accept_token(p, TOKEN_LBRACE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	if parser_accept_token(p, TOKEN_RBRACE) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let d = cast(*NODE_STRUCT_INSTANCIATION_DATA, arena_alloc((*p).arena, sizeof(NODE_STRUCT_INSTANCIATION_DATA)));
+	(*d).typ = cast(*i8, (*typ).data);
+
+	let n = Node{};
+	n.type = NODE_STRUCT_INSTANCIATION;
+	n.data = cast(*void, d);
+
+	return create_node(p, n); 
+};
+
+extern parser_parse_primary_expression = (*parser) => *Node;
+
+/* FieldAccess ::= PrimaryExpression DOT IDENTIFIER */
+let parser_parse_field_access = (p: *parser) => *Node {
+	let expression = parser_parse_primary_expression(p);
+	if expression == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+	if parser_accept_token(p, TOKEN_DOT) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+	let ident = parser_accept_token(p, TOKEN_IDENTIFIER);
+	if ident == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let d = cast(*NODE_FIELD_ACCESS_DATA, arena_alloc((*p).arena, sizeof(NODE_FIELD_ACCESS_DATA)));
+	(*d).expression = expression;
+	(*d).name = cast(*i8, (*ident).data);
+
+	let n = Node{};
+	n.type = NODE_FIELD_ACCESS;
+	n.data = cast(*void, d);
+
+	return create_node(p, n); 
+};
+
+/* PrimaryExpression ::= NULL | NUMBER | BOOLEAN | CHAR | STRING | IDENTIFIER | FunctionDefinition | StructDefinition | StructInstantiation | FieldAccess | LPAREN Expression RPAREN */
+let parser_parse_primary_expression = (p: *parser) => *Node {
+	let stmt = parser_accept_parse(p, parser_parse_function_definition);
+	if stmt != cast(*Node, null) {
+		return stmt;
+	};
+	let stmt = parser_accept_parse(p, parser_parse_type_definition);
+	if stmt != cast(*Node, null) {
+		return stmt;
+	};
+	let stmt = parser_accept_parse(p, parser_parse_struct_definition);
+	if stmt != cast(*Node, null) {
+		return stmt;
+	};
+	let stmt = parser_accept_parse(p, parser_parse_struct_instanciation);
+	if stmt != cast(*Node, null) {
+		return stmt;
+	};
+
+	if parser_accept_token(p, TOKEN_LPAREN) != cast(*token, null) {
+		let expr = parser_parse_expression(p);
+		if expr == cast(*Node, null) {
+			return cast(*Node, null);
+		};
+		if parser_accept_token(p, TOKEN_RPAREN) == cast(*token, null) {
+			return cast(*Node, null);
+		};
+		return expr;
+	};
+
+	let tok = parser_consume_token(p);
+	if tok == cast(*token, null) {
+	printf("NO TOK\n");
+	    return cast(*Node, null); 
+	};
+	
+	if (*tok).type == TOKEN_NULL {
+	    let n = Node{};
+	    n.type = NODE_PRIMARY_EXPRESSION_NULL;
+	    return create_node(p, n);
+	};
+
+	if (*tok).type == TOKEN_IDENTIFIER {
+	    let d = cast(*NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA)));
+	    (*d).name = cast(*i8, (*tok).data);
+	    (*d).type = cast(*Node, null);
+	    let n = Node{};
+	    n.type = NODE_PRIMARY_EXPRESSION_IDENTIFIER;
+	    n.data = cast(*void, d);
+	    return create_node(p, n);
+	};
+
+	if (*tok).type == TOKEN_NUMBER {
+	    let d = cast(*NODE_PRIMARY_EXPRESSION_NUMBER_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_NUMBER_DATA)));
+	    (*d).value = *(cast(*i64, (*tok).data));
+	    let n = Node{};
+	    n.type = NODE_PRIMARY_EXPRESSION_NUMBER;
+	    n.data = cast(*void, d);
+	    return create_node(p, n);
+	};
+	
+	if (*tok).type == TOKEN_BOOLEAN {
+	    let d = cast(*NODE_PRIMARY_EXPRESSION_BOOLEAN_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_BOOLEAN_DATA)));
+	    (*d).value = *(cast(*bool, (*tok).data));
+	    let n = Node{};
+	    n.type = NODE_PRIMARY_EXPRESSION_BOOLEAN;
+	    n.data = cast(*void, d);
+	    return create_node(p, n);
+	};
+	
+	if (*tok).type == TOKEN_CHAR {
+	    let d = cast(*NODE_PRIMARY_EXPRESSION_CHAR_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_CHAR_DATA)));
+	    (*d).value = *(cast(*i8, (*tok).data));
+	    let n = Node{};
+	    n.type = NODE_PRIMARY_EXPRESSION_CHAR;
+	    n.data = cast(*void, d);
+	    return create_node(p, n);
+	};
+	
+	if (*tok).type == TOKEN_STRING {
+	    let d = cast(*NODE_PRIMARY_EXPRESSION_STRING_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_STRING_DATA)));
+	    (*d).value = cast(*i8, (*tok).data);
+	    let n = Node{};
+	    n.type = NODE_PRIMARY_EXPRESSION_STRING;
+	    n.data = cast(*void, d);
+	    return create_node(p, n);
+	};
+
+	return cast(*Node, null);
+};
+
+/* EqualityExpression ::= AdditiveExpression ("==" | "!=" | "<=" | ">=" | "<" | ">") AdditiveExpression */
+let parser_parse_equality_expression = (p: *parser) => *Node {
+	let lhs = parser_parse_additive_expression(p);
+	if lhs == cast(*Node, null) {
+	    return cast(*Node, null);
+	};	
+
+	let typ = -1;
+	let ex = parser_accept_parse(p, (ip: *parser) => *Node {
+		if parser_accept_token(ip, TOKEN_EQUALS) == cast(*token, null) {
+			return cast(*Node, null);
+		};
+		if parser_accept_token(ip, TOKEN_EQUALS) == cast(*token, null) {
+			return cast(*Node, null);
+		};
+		let n = Node{};
+		return create_node(ip, n);
+	});
+	if ex != cast(*Node, null) {
+		typ = EQUALITY_EXPRESSION_TYPE_EQ;
+	};
+
+	if (typ == -1) {
+		ex = parser_accept_parse(p, (ip: *parser) => *Node {
+			if (parser_accept_token(ip, TOKEN_BANG) == cast(*token, null)) {
+				return cast(*Node, null);
+			};
+			if (parser_accept_token(ip, TOKEN_EQUALS) == cast(*token, null)) {
+				return cast(*Node, null);
+			};
+			let n = Node{};
+			return create_node(ip, n);
+		});
+		if (ex != cast(*Node, null)) {
+			typ = EQUALITY_EXPRESSION_TYPE_NE;
+		};
+	};
+
+	if (typ == -1) {
+		ex = parser_accept_parse(p, (ip: *parser) => *Node {
+			if (parser_accept_token(ip, TOKEN_LESS) == cast(*token, null)) {
+				return cast(*Node, null);
+			};
+			if (parser_accept_token(ip, TOKEN_EQUALS) == cast(*token, null)) {
+				return cast(*Node, null);
+			};
+			let n = Node{};
+			return create_node(ip, n);
+		});
+		if (ex != cast(*Node, null)) {
+			typ = EQUALITY_EXPRESSION_TYPE_LE;
+		};
+	};
+
+	if (typ == -1) {
+		ex = parser_accept_parse(p, (ip: *parser) => *Node {
+			if (parser_accept_token(ip, TOKEN_GREATER) == cast(*token, null)) {
+				return cast(*Node, null);
+			};
+			if (parser_accept_token(ip, TOKEN_EQUALS) == cast(*token, null)) {
+				return cast(*Node, null);
+			};
+			let n = Node{};
+			return create_node(ip, n);
+		});
+		if (ex != cast(*Node, null)) {
+			typ = EQUALITY_EXPRESSION_TYPE_GE;
+		};
+	};
+
+	if (typ == -1) {
+		if (parser_accept_token(p, TOKEN_LESS) != cast(*token, null)) {
+			typ = EQUALITY_EXPRESSION_TYPE_LT;
+		};
+	};
+
+	if (typ == -1) {
+		if (parser_accept_token(p, TOKEN_GREATER) != cast(*token, null)) {
+			typ = EQUALITY_EXPRESSION_TYPE_GT;
+		};
+	};
+
+	if typ == -1 {
+		return cast(*Node, null);
+	};
+	
+	let rhs = parser_parse_additive_expression(p);
+	if rhs == cast(*Node, null) {
+	    return cast(*Node, null);
+	};	
+	
+	let d = cast(*NODE_EQUALITY_EXPRESSION_DATA, arena_alloc((*p).arena, sizeof(NODE_EQUALITY_EXPRESSION_DATA)));
+	(*d).lhs = lhs;
+	(*d).rhs = rhs;
+	(*d).typ = typ;
+
+	let n = Node{};
+	n.type = NODE_EQUALITY_EXPRESSION ;
+	n.data = cast(*void, d);
+
+	return create_node(p, n); 
+};
+
+/* PostfixExpression ::= PrimaryExpression (CastStatement | SizeOfStatement | FunctionCallStatement | FieldAccess )* */
+let parser_parse_postfix_expression = (p: *parser) => *Node {
+	let ex = parser_accept_parse(p, parser_parse_cast_statement);
+	if ex != cast(*Node, null) {
+		return ex;
+	};
+	let ex = parser_accept_parse(p, parser_parse_sizeof_statement);
+	if ex != cast(*Node, null) {
+		return ex;
+	};
+	let ex = parser_accept_parse(p, parse_function_call_statement);
+	if ex != cast(*Node, null) {
+		return ex;
+	};
+	let ex = parser_accept_parse(p, parser_parse_field_access);
+	if ex != cast(*Node, null) {
+		return ex;
+	};
+	return parser_parse_primary_expression(p);
+};
+
+/* UnaryExpression ::= ("!" | "-" | "*") UnaryExpression | PostfixExpression */
+let parser_parse_unary_expression = (p: *parser) => *Node {
+	let typ = -1;
+	if parser_accept_token(p, TOKEN_BANG) != cast(*token, null) {
+	    typ = UNARY_EXPRESSION_TYPE_NOT;
+	};
+	if typ == -1 {
+		if parser_accept_token(p, TOKEN_MINUS) != cast(*token, null) {
+		    typ = UNARY_EXPRESSION_TYPE_MINUS;
+		};
+	};
+	if typ == -1 {
+		if parser_accept_token(p, TOKEN_MUL) != cast(*token, null) {
+		    typ = UNARY_EXPRESSION_TYPE_STAR;
+		};
+	};
+	if typ == -1 {
+		return parser_parse_postfix_expression(p);
+	};
+
+	let new_lhs_data = cast(*NODE_UNARY_EXPRESSION_DATA, arena_alloc((*p).arena, sizeof(NODE_UNARY_EXPRESSION_DATA)));
+	((*new_lhs_data).typ) = typ;
+	let e = parser_parse_unary_expression(p);
+	if e == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+	((*new_lhs_data).expression) = e;
+	let new_lhs = Node{};
+	new_lhs.type = NODE_UNARY_EXPRESSION;
+	new_lhs.data = cast(*void, new_lhs_data);
+	return create_node(p, new_lhs);
+};
+
+/* MultiplicativeExpression ::= UnaryExpression (("*" | "/" | "%") UnaryExpression)* */
+let parser_parse_multiplicative_expression = (p: *parser) => *Node {
+	let lhs = parser_parse_unary_expression(p);
+	if lhs == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+
+	while true {
+		let typ = -1;
+		if parser_accept_token(p, TOKEN_MUL) != cast(*token, null) {
+		    typ = MULTIPLICATIVE_EXPRESSION_TYPE_MUL;
+		};
+		if parser_accept_token(p, TOKEN_DIV) != cast(*token, null) {
+		    typ = MULTIPLICATIVE_EXPRESSION_TYPE_DIV;
+		};
+		if parser_accept_token(p, TOKEN_MOD) != cast(*token, null) {
+		    typ = MULTIPLICATIVE_EXPRESSION_TYPE_MOD;
+		};
+		if typ == -1 {
+			break;
+		};
+
+		let rhs = parser_parse_unary_expression(p);
+		if rhs == cast(*Node, null) {
+			return cast(*Node, null);
+		};
+
+		let new_lhs_data = cast(*NODE_MULTIPLICATIVE_EXPRESSION_DATA, arena_alloc((*p).arena, sizeof(NODE_MULTIPLICATIVE_EXPRESSION_DATA)));
+		((*new_lhs_data).lhs) = lhs;
+		((*new_lhs_data).rhs) = rhs;
+		((*new_lhs_data).typ) = typ;
+		let new_lhs = Node{};
+		new_lhs.type = NODE_MULTIPLICATIVE_EXPRESSION;
+		new_lhs.data = cast(*void, new_lhs_data);
+		lhs = create_node(p, new_lhs);
+	};
+	return lhs;
+};
+
+/* AdditiveExpression ::= MultiplicativeExpression (("+" | "-") MultiplicativeExpression)* */
+let parser_parse_additive_expression = (p: *parser) => *Node {
+	let lhs = parser_parse_multiplicative_expression(p);
+	if lhs == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+
+	while true {
+		let plus = parser_accept_token(p, TOKEN_PLUS);
+		let minus = parser_accept_token(p, TOKEN_MINUS);
+
+		if plus == cast(*token, null) {
+			if minus == cast(*token, null) {
+				break;
+			};
+		};
+
+		let rhs = parser_parse_multiplicative_expression(p);
+		if rhs == cast(*Node, null) {
+			return cast(*Node, null);
+		};
+
+		let new_lhs_data = cast(*NODE_ADDITIVE_EXPRESSION_DATA, arena_alloc((*p).arena, sizeof(NODE_ADDITIVE_EXPRESSION_DATA)));
+		((*new_lhs_data).addition) = plus != cast(*token, null);
+		((*new_lhs_data).lhs) = lhs;
+		((*new_lhs_data).rhs) = rhs;
+		let new_lhs = Node{};
+		new_lhs.type = NODE_ADDITIVE_EXPRESSION;
+		new_lhs.data = cast(*void, new_lhs_data);
+		lhs = create_node(p, new_lhs);
+	};
+	return lhs;
+};
+
+/* Expression ::= EqualityExpression | AdditiveExpression */
+let parser_parse_expression = (p: *parser) => *Node {
+	let ex = parser_accept_parse(p, parser_parse_equality_expression);
+	if ex != cast(*Node, null) {
+		return ex;
+	};
+	let ax = parser_accept_parse(p, parser_parse_additive_expression);
+	if ax != cast(*Node, null) {
+		return ax;
+	};
+
+	return cast(*Node, null);
+};
+
+/* AssignmentStatement ::= ("let")? ("*")? Expression EQUALS Expression */
+let parse_assignment_statement = (p: *parser) => *Node {
+	let is_declaration = false;
+	if parser_accept_token(p, TOKEN_LET) != cast(*token, null) {
+	    is_declaration = true;
+	};
+	
+	let is_dereference = false;
+	if parser_accept_token(p, TOKEN_MUL) != cast(*token, null) {
+	    is_dereference = true;
+	};
+
+	let lhs = parser_parse_expression(p);
+	if lhs == cast(*Node, null) {
+	    return cast(*Node, null);
+	};	
+	
+	if parser_accept_token(p, TOKEN_EQUALS) == cast(*token, null) {
+	    return cast(*Node, null);
+	};
+	
+	let rhs = parser_parse_expression(p);
+	if rhs == cast(*Node, null) {
+	    return cast(*Node, null);
+	};
+
+	let d = cast(*NODE_ASSIGNMENT_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_ASSIGNMENT_STATEMENT_DATA)));
+	(*d).is_declaration = is_declaration;
+	(*d).is_dereference = is_dereference;
+	(*d).lhs = lhs;
+	(*d).rhs = rhs;
+	let n = Node{};
+	n.type = NODE_ASSIGNMENT_STATEMENT;
+	n.data = cast(*void, d);
+	return create_node(p, n);
+};
+
+extern parse = (*parser) => *Node;
+
+let parser_parse_import_declaration = (p: *parser) => *Node {
+	if parser_accept_token(p, TOKEN_IMPORT) == cast(*token, null) {
+		return cast(*Node, null);
+	};
+
+	let expr = parser_parse_primary_expression(p);
+	if expr == cast(*Node, null) {
+		return cast(*Node, null);
+	};
+
+	assert((*expr).type == NODE_PRIMARY_EXPRESSION_STRING);
+
+	let impor_filename = (*cast(*NODE_PRIMARY_EXPRESSION_STRING_DATA, (*expr).data)).value;
+	let current_file = cast(*i8, arena_alloc((*p).arena, sizeof(i8) * 70));
+	strcpy(current_file, (*p).filename);
+
+	/* stdlib. TODO: this is very hacky and won't work if running the compiler binary by itself */
+	if (*impor_filename) == '!' {
+		let buf = cast(*i8, arena_alloc((*p).arena, sizeof(i8) * 70));
+		sprintf(buf, "./std/%s", (impor_filename + cast(*i8, 1)));
+		impor_filename = buf;
+		current_file = ".";
+	};
+
+	let dirpath = dirname(current_file);
+	let dir = open(dirpath, 0);
+	assert(dir != -1);
+
+	let file = openat(dir, impor_filename, 0);
+	assert(file != -1);
+	
+	let file_size = lseek(file, 0, 2);
+	lseek(file, 0, 0);
+	let file_contents = cast(*i8, arena_alloc((*p).arena, file_size + 1));
+
+	let bytes_read = read(file, file_contents, file_size);
+	(*(file_contents + cast(*i8, bytes_read))) = '\0';
+
+	let f = slice{};
+	f.data = cast(*void, file_contents);
+	f.data_len = file_size;
+	let inner_tokenizer = tokenizer_init((*p).arena, f);
+	let tokens = tokenizer_tokenize(inner_tokenizer);
+
+	let buf2 = cast(*i8, arena_alloc((*p).arena, 90));
+	strcpy(buf2, dirpath);
+	(*(buf2 + cast(*i8, strlen(dirpath)))) = '/';
+	strcpy(buf2 + cast(*i8, strlen(dirpath) + 1), impor_filename);
+	let full_path = realpath(buf2, cast(*i8, null));
+
+	let inner_parser = parser_init(cast(*token, tokens.data), tokens.data_len, (*p).arena, full_path);
+	let ast = parse(inner_parser);
+	
+	let d = cast(*NODE_IMPORT_DECLARATION_DATA , arena_alloc((*p).arena, sizeof(NODE_IMPORT_DECLARATION_DATA)));
+	(*d).filename = impor_filename;
+	(*d).program = ast;
+	let n = Node{};
+	n.type = NODE_IMPORT_DECLARATION;
+	n.data = cast(*void, d);
+	return create_node(p, n);
+};
+
+/* FunctionArguments ::= Expression ("," Expression)* */
+let parser_parse_function_arguments = (p: *parser) => *slice {
+	let node_list = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 20));
+	let first = true;
+
+	let i = 0;
+	while true {
+		if !first {
+			parser_accept_token(p, TOKEN_COMMA);
+		};
+		first = false;
+		let maybe_expr = parser_accept_parse(p, parser_parse_expression);
+		if maybe_expr == cast(*Node, null) {
+			let s = cast(*slice, arena_alloc((*p).arena, sizeof(slice)));
+			(*s).data = cast(*void, node_list);
+			(*s).data_len = i;
+			return s;
+		};
+
+		(*(node_list + cast(**Node, i))) = maybe_expr;
+		i = i + 1;
+	};
+
+	let s = cast(*slice, arena_alloc((*p).arena, sizeof(slice)));
+	(*s).data = cast(*void, node_list);
+	(*s).data_len = i;
+	return s;
+};
+
+/* FunctionCallStatement ::= (IDENTIFIER | FunctionDefinition) LPAREN FunctionArguments? RPAREN */
+let parse_function_call_statement = (p: *parser) => *Node {
+	let ident = parser_accept_token(p, TOKEN_IDENTIFIER);
+	let fn_def = parser_accept_parse(p, parser_parse_function_definition);
+
+	if ident == cast(*token, null) {
+		if fn_def == cast(*Node, null) {
+			return cast(*Node, null);
+		};
+	};
+
+	if parser_accept_token(p, TOKEN_LPAREN) == cast(*token, null) {
+	    return cast(*Node, null);
+	};
+
+	let arguments = parser_parse_function_arguments(p);
+	if arguments == cast(*slice, null) {
+	    return cast(*Node, null);
+	};
+	
+	if parser_accept_token(p, TOKEN_RPAREN) == cast(*token, null) {
+	    return cast(*Node, null);
+	};
+
+	let d = cast(*NODE_FUNCTION_CALL_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_FUNCTION_CALL_STATEMENT_DATA)));
+	(*d).arguments = cast(**Node, (*arguments).data);
+	(*d).arguments_len = (*arguments).data_len;
+
+	if fn_def != cast(*Node, null) {
+		(*d).expression = fn_def;
+	};
+	if fn_def == cast(*Node, null) {
+		let expression_data = cast(*NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA)));
+		(*expression_data).name = cast(*i8, (*ident).data);
+		let expression = cast(*Node, arena_alloc((*p).arena, sizeof(Node)));
+		(*expression).type = NODE_PRIMARY_EXPRESSION_IDENTIFIER;
+		(*expression).data = cast(*void, expression_data);
+		(*d).expression = expression;
+	};
+
+	let n = Node{};
+	n.type = NODE_FUNCTION_CALL_STATEMENT;
+	n.data = cast(*void, d);
+	return create_node(p, n);
+};
+
+/* Statement    ::= (AssignmentStatement | ImportDeclaration | ExternDeclaration | CastStatement | SizeOfStatement | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement | "break" | "continue") SEMICOLON */
+let parser_parse_statement = (p: *parser) => *Node {
+	/* TODO: Can we not deal with cast / sizeof in parser? */
+	let fn_call = parser_accept_parse(p, parser_parse_cast_statement);
+	if fn_call != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return fn_call;
+	};
+	
+	let fn_call = parser_accept_parse(p, parser_parse_sizeof_statement);
+	if fn_call != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return fn_call;
+	};
+
+	let fn_call = parser_accept_parse(p, parse_function_call_statement);
+	if fn_call != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return fn_call;
+	};
+
+	let assignment = parser_accept_parse(p, parse_assignment_statement);
+	if assignment != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return assignment;
+	};
+
+	let retu = parser_accept_parse(p, parser_parse_return_statement);
+	if retu != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return retu;
+	};
+	
+	let retu = parser_accept_parse(p, parser_parse_import_declaration);
+	if retu != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return retu;
+	};
+
+	let retu = parser_accept_parse(p, parser_parse_extern_declaration);
+	if retu != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return retu;
+	};
+	
+	let retu = parser_accept_parse(p, parser_parse_if_statement);
+	if retu != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return retu;
+	};
+	
+	let retu = parser_accept_parse(p, parser_parse_while_statement);
+	if retu != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return retu;
+	};
+	
+	/*  Break and continue */
+	let retu = parser_accept_parse(p, (ip: *parser) => *Node {
+		if parser_accept_token(ip, TOKEN_BREAK) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+		
+		let n = Node{};
+		n.type = NODE_BREAK_STATEMENT;
+		return create_node(ip, n);
+	});
+	if retu != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return retu;
+	};
+
+	let retu = parser_accept_parse(p, (ip: *parser) => *Node {
+		if parser_accept_token(ip, TOKEN_CONTINUE) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+		
+		let n = Node{};
+		n.type = NODE_CONTINUE_STATEMENT;
+		return create_node(ip, n);
+	});
+	if retu != cast(*Node, null) {
+		if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) {
+		    return cast(*Node, null);
+		};
+	    return retu;
+	};
+
+	printf("None\n");
+	
+	return cast(*Node, null);
+};
+
+/* Program ::= Statement+ */
+let parse_program = (p: *parser) => *Node {
+	let nodes = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 50000));
+
+	let i = 0;
+	while (*p).offset < (*p).tokens_len {
+		let s = parser_parse_statement(p);
+		assert(s != cast(*Node, null));
+		(*(nodes + cast(**Node, i))) = s;
+		i = i + 1;
+	};
+
+	let d = cast(*NODE_PROGRAM_DATA, arena_alloc((*p).arena, sizeof(NODE_PROGRAM_DATA)));
+	(*d).statements = nodes;
+	(*d).statements_len = i;
+	let n = Node{};
+	n.type = NODE_PROGRAM;
+	n.data = cast(*void, d);
+	return create_node(p, n);
+};
+
+let parse = (p: *parser) => *Node {
+	return parse_program(p);
+};