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, }; 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) => *parser { let p = cast(*parser, arena_alloc(ar, sizeof(parser))); (*p).tokens = ts; (*p).tokens_len = ts_len; (*p).offset = 0; (*p).arena = ar; 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; /* 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)); 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); /* TODO: Typecheck struct access */ (*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; }; /* 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); }; /* TODO: Body */ 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); }; /* 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; }; 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_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); /* TODO */ 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); }; printf("DIFF TYPE: %d\n", (*tok).type); 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, parse_function_call_statement); 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; ((*new_lhs_data).expression) = parser_parse_unary_expression(p); /* TODO: try? */ 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); 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); 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); 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); 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) { printf("IS DECLARATION\n"); is_declaration = true; }; /* TODO: is_dereference */ let lhs = parser_parse_expression(p); /* TODO */ if lhs == cast(*Node, null) { printf("ANOTHER BNLL\n"); return cast(*Node, null); }; if parser_accept_token(p, TOKEN_EQUALS) == cast(*token, null) { return cast(*Node, null); }; let rhs = parser_parse_expression(p); /* TODO */ if rhs == cast(*Node, null) { printf("NUL EXP\n"); 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 = false; (*d).lhs = lhs; (*d).rhs = rhs; let n = Node{}; n.type = NODE_ASSIGNMENT_STATEMENT; 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); if ident == cast(*token, null) { return cast(*Node, null); }; /* TODO: Function definition call */ 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 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); let d = cast(*NODE_FUNCTION_CALL_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_FUNCTION_CALL_STATEMENT_DATA))); (*d).expression = expression; (*d).arguments = cast(**Node, (*arguments).data); (*d).arguments_len = (*arguments).data_len; 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 { 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_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; }; 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) * 1000)); 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); }; /* For example -2: * parsing assignment statement * parsing ident and num literals */