diff options
Diffstat (limited to 'src/parser.pry')
| -rw-r--r-- | src/parser.pry | 1456 |
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); +}; |