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, }; 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); }; /* PrimaryExpression ::= NULL | NUMBER | BOOLEAN | CHAR | STRING | IDENTIFIER | FunctionDefinition | StructDefinition | StructInstantiation | FieldAccess | LPAREN Expression RPAREN */ let parser_parse_primary_expression = (p: *parser) => *Node { let tok = parser_consume_token(p); if tok == cast(*token, null) { 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); }; 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) { println("IS DECLARATION"); is_declaration = true; }; /* TODO: is_dereference */ let lhs = parser_parse_primary_expression(p); /* TODO */ 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_primary_expression(p); /* TODO */ 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 = false; (*d).lhs = lhs; (*d).rhs = rhs; let n = Node{}; n.type = NODE_ASSIGNMENT_STATEMENT; n.data = cast(*void, d); println("CONTINUE"); return create_node(p, n); }; /* Statement ::= (AssignmentStatement | ImportDeclaration | ExternDeclaration | CastStatement | SizeOfStatement | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement | "break" | "continue") SEMICOLON */ let parse_statement = (p: *parser) => *Node { let assignment = parse_assignment_statement(p); if assignment == cast(*Node, null) { return cast(*Node, null); }; if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) { return cast(*Node, null); }; return assignment; }; /* 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 = parse_statement(p); if s == cast(*Node, null) { println("ERROR! Null node %d", (*p).offset); return s; }; (*(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 */