From 0b516345666b52d29bb10521b4d3c2c2420b3368 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 7 Nov 2025 09:56:50 +0100 Subject: Generate record accessors automatically --- boot/stage15.elna | 1866 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 1115 insertions(+), 751 deletions(-) (limited to 'boot/stage15.elna') diff --git a/boot/stage15.elna b/boot/stage15.elna index c641a62..987d655 100644 --- a/boot/stage15.elna +++ b/boot/stage15.elna @@ -7,7 +7,7 @@ (* Stage 15 compiler. *) type - LexerAction = (none, accumulate, skip, single, eof, finalize, composite, key_id, integer, delimited); + ElnaLexerAction = (none, accumulate, skip, single, eof, finalize, composite, key_id, integer, delimited); (** * Classification table assigns each possible character to a group (class). All @@ -18,7 +18,7 @@ type * next_state: TransitionState * end; *) - LexerClass = ( + ElnaLexerClass = ( invalid, digit, alpha, @@ -42,7 +42,7 @@ type less, other ); - LexerState = ( + ElnaLexerState = ( start, colon, identifier, @@ -61,7 +61,7 @@ type string_escape, finish ); - LexerTokenKind = ( + ElnaLexerKind = ( identifier, _const, _var, @@ -77,7 +77,6 @@ type _do, _extern, _record, - _union, _true, _false, null, @@ -148,10 +147,11 @@ type enumeration_type_expression, named_type_expression, type_declaration, - module_declaration + module_declaration, + record_type_expression ); InfoKind = (type_info, parameter_info, temporary_info, procedure_info); - TypeKind = (primitive, enumeration); + TypeKind = (primitive, enumeration, _record); ElnaTacOperator = ( load_immediate, load_address, @@ -176,8 +176,9 @@ type not, jump, beqz, - ret, - label + label, + start, + ret ); ElnaTacOperand = (register, immediate, symbol, offset); ElnaTacRegister = ( @@ -1101,20 +1102,20 @@ begin elsif instruction_kind = ElnaTacOperator.beqz then argument_count := 2; _write_s("\tbeqz", 5) + elsif instruction_kind = ElnaTacOperator.start then + argument_count := 0; + _write_z("\taddi sp, sp, -128\n\tsw ra, 124(sp)\n\tsw s0, 120(sp)\n\taddi s0, sp, 128\0") elsif instruction_kind = ElnaTacOperator.ret then argument_count := 0; - _write_s("\tret", 4) + _write_z("\tlw ra, 124(sp)\n\tlw s0, 120(sp)\n\taddi sp, sp, 128\0") end; return argument_count end; proc _elna_writer_register(register: Word); -var - number: Word; begin _write_c('x'); - number := register - 1; - _write_i(number) + _write_i(register - 1) end; proc _elna_writer_operand(instruction: Word, n: Word); @@ -1191,18 +1192,6 @@ begin end end; -(* Write the prologue. *) -proc _elna_writer_prologue(); -begin - _write_z("\taddi sp, sp, -128\n\tsw ra, 124(sp)\n\tsw s0, 120(sp)\n\taddi s0, sp, 128\n\0") -end; - -(* Write the epilogue. *) -proc _elna_writer_epilogue(); -begin - _write_z("\tlw ra, 124(sp)\n\tlw s0, 120(sp)\n\taddi sp, sp, 128\n\tret\n\0") -end; - proc _elna_writer_procedure(procedure: Word); var name_pointer: Word; @@ -1224,9 +1213,8 @@ begin _write_s(name_pointer, name_length); _write_z(":\n\0"); - _elna_writer_prologue(); _elna_writer_instructions(body_statements); - _elna_writer_epilogue(); + _write_z("\tret\n\0"); procedure := _elna_tac_declaration_get_next(procedure); if procedure <> 0 then @@ -1335,7 +1323,7 @@ begin this^ := value end; -proc _parse_integer_literal(); +proc _elna_parser_integer_literal(); var integer_token: Word; integer_length: Word; @@ -1345,10 +1333,10 @@ begin literal_size := _integer_literal_node_size(); result := _allocate(literal_size); - integer_token := _lexer_global_get_start(); - integer_length := _lexer_global_get_end(); + integer_token := _elna_lexer_global_get_start(); + integer_length := _elna_lexer_global_get_end(); integer_length := integer_length - integer_token; - _lexer_skip_token(); + _elna_lexer_skip_token(); _node_set_kind(result, NodeKind.integer_literal); _integer_literal_node_set_value(result, integer_token); @@ -1397,7 +1385,7 @@ begin this^ := value end; -proc _parse_character_literal(); +proc _elna_parser_character_literal(); var character: Word; character_length: Word; @@ -1407,10 +1395,10 @@ begin literal_size := _character_literal_node_size(); result := _allocate(literal_size); - character := _lexer_global_get_start(); - character_length := _lexer_global_get_end(); + character := _elna_lexer_global_get_start(); + character_length := _elna_lexer_global_get_end(); character_length := character_length - character; - _lexer_skip_token(); + _elna_lexer_skip_token(); _node_set_kind(result, NodeKind.character_literal); _integer_literal_node_set_value(result, character); @@ -1467,17 +1455,17 @@ begin return result end; -proc _parse_variable_expression(); +proc _elna_parser_variable_expression(); var name: Word; name_token: Word; result: Word; memory_size: Word; begin - name := _lexer_global_get_start(); - name_token := _lexer_global_get_end(); + name := _elna_lexer_global_get_start(); + name_token := _elna_lexer_global_get_end(); name_token := name_token - name; - _lexer_skip_token(); + _elna_lexer_skip_token(); memory_size := _variable_expression_size(); result := _allocate(memory_size); @@ -1536,7 +1524,7 @@ begin this^ := value end; -proc _parse_string_literal(); +proc _elna_parser_string_literal(); var length: Word; token_start: Word; @@ -1546,9 +1534,9 @@ begin memory_size := _string_literal_node_size(); result := _allocate(memory_size); - token_start := _lexer_global_get_start(); + token_start := _elna_lexer_global_get_start(); length := _string_length(token_start); - _lexer_skip_token(); + _elna_lexer_skip_token(); _node_set_kind(result, NodeKind.string_literal); _string_literal_node_set_value(result, token_start); @@ -1579,23 +1567,23 @@ begin return first_instruction end; -proc _parse_simple_expression(); +proc _elna_parser_simple_expression(); var current_character: Word; parser_node: Word; token_kind: Word; begin parser_node := 0; - _lexer_read_token(@token_kind); - - if token_kind = LexerTokenKind.character then - parser_node := _parse_character_literal() - elsif token_kind = LexerTokenKind.integer then - parser_node := _parse_integer_literal() - elsif token_kind = LexerTokenKind.string then - parser_node := _parse_string_literal() - elsif token_kind = LexerTokenKind.identifier then - parser_node := _parse_variable_expression() + _elna_lexer_read_token(@token_kind); + + if token_kind = ElnaLexerKind.character then + parser_node := _elna_parser_character_literal() + elsif token_kind = ElnaLexerKind.integer then + parser_node := _elna_parser_integer_literal() + elsif token_kind = ElnaLexerKind.string then + parser_node := _elna_parser_string_literal() + elsif token_kind = ElnaLexerKind.identifier then + parser_node := _elna_parser_variable_expression() end; return parser_node end; @@ -1616,7 +1604,7 @@ begin this^ := value end; -proc _parse_dereference_expression(simple_expression: Word); +proc _elna_parser_dereference_expression(simple_expression: Word); var result: Word; memory_size: Word; @@ -1626,26 +1614,26 @@ begin _node_set_kind(result, NodeKind.dereference_expression); _dereference_expression_set_pointer(result, simple_expression); - _lexer_skip_token(); + _elna_lexer_skip_token(); return result end; -proc _parse_designator(); +proc _elna_parser_designator(); var simple_expression: Word; token_kind: Word; begin - simple_expression := _parse_simple_expression(); + simple_expression := _elna_parser_simple_expression(); - _lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind); - if token_kind = LexerTokenKind.hat then - simple_expression := _parse_dereference_expression(simple_expression) - elsif token_kind = LexerTokenKind.dot then - simple_expression := _parse_field_access_expression(simple_expression) - elsif token_kind = LexerTokenKind.left_paren then - simple_expression := _parse_call(simple_expression) + if token_kind = ElnaLexerKind.hat then + simple_expression := _elna_parser_dereference_expression(simple_expression) + elsif token_kind = ElnaLexerKind.dot then + simple_expression := _elna_parser_field_access_expression(simple_expression) + elsif token_kind = ElnaLexerKind.left_paren then + simple_expression := _elna_parser_call(simple_expression) end; return simple_expression end; @@ -1700,7 +1688,7 @@ begin this^ := value end; -proc _parse_unary_expression(); +proc _elna_parser_unary_expression(); var token_kind: Word; result: Word; @@ -1708,20 +1696,20 @@ var operand: Word; operator: Word; begin - _lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind); operator := 0; - if token_kind = LexerTokenKind.at then + if token_kind = ElnaLexerKind.at then operator := '@' - elsif token_kind = LexerTokenKind.minus then + elsif token_kind = ElnaLexerKind.minus then operator := '-' - elsif token_kind = LexerTokenKind.not then + elsif token_kind = ElnaLexerKind.not then operator := '~' end; if operator <> 0 then - _lexer_skip_token() + _elna_lexer_skip_token() end; - result := _parse_designator(); + result := _elna_parser_designator(); if operator <> 0 then operand := result; @@ -1818,7 +1806,7 @@ begin this^ := value end; -proc _parse_binary_expression(); +proc _elna_parser_binary_expression(); var lhs_node: Word; rhs_node: Word; @@ -1826,52 +1814,52 @@ var memory_size: Word; result: Word; begin - lhs_node := _parse_unary_expression(); + lhs_node := _elna_parser_unary_expression(); rhs_node := 0; - _lexer_read_token(@token_kind); - - if token_kind = LexerTokenKind.plus then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.minus then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.multiplication then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.and then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind._or then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind._xor then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.equals then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.remainder then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.division then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.less_than then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.greater_than then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.less_equal then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.not_equal then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() - elsif token_kind = LexerTokenKind.greater_equal then - _lexer_skip_token(); - rhs_node := _parse_unary_expression() + _elna_lexer_read_token(@token_kind); + + if token_kind = ElnaLexerKind.plus then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.minus then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.multiplication then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.and then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind._or then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind._xor then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.equals then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.remainder then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.division then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.less_than then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.greater_than then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.less_equal then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.not_equal then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() + elsif token_kind = ElnaLexerKind.greater_equal then + _elna_lexer_skip_token(); + rhs_node := _elna_parser_unary_expression() end; if rhs_node <> 0 then memory_size := _binary_expression_size(); @@ -1921,58 +1909,58 @@ begin _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; - if token_kind = LexerTokenKind.plus then + if token_kind = ElnaLexerKind.plus then instruction := _elna_tac_add(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.minus then + elsif token_kind = ElnaLexerKind.minus then instruction := _elna_tac_sub(ElnaTacRegister.t0, ElnaTacRegister.t1, ElnaTacRegister.t0); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.multiplication then + elsif token_kind = ElnaLexerKind.multiplication then instruction := _elna_tac_mul(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.and then + elsif token_kind = ElnaLexerKind.and then instruction := _elna_tac_and(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind._or then + elsif token_kind = ElnaLexerKind._or then instruction := _elna_tac_or(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind._xor then + elsif token_kind = ElnaLexerKind._xor then instruction := _elna_tac_xor(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.equals then + elsif token_kind = ElnaLexerKind.equals then instruction := _elna_tac_xor(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1); _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; instruction := _elna_tac_seqz(ElnaTacRegister.t0, ElnaTacRegister.t0); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.remainder then + elsif token_kind = ElnaLexerKind.remainder then instruction := _elna_tac_rem(ElnaTacRegister.t0, ElnaTacRegister.t1, ElnaTacRegister.t0); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.division then + elsif token_kind = ElnaLexerKind.division then instruction := _elna_tac_div(ElnaTacRegister.t0, ElnaTacRegister.t1, ElnaTacRegister.t0); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.less_than then + elsif token_kind = ElnaLexerKind.less_than then instruction := _elna_tac_slt(ElnaTacRegister.t0, ElnaTacRegister.t1, ElnaTacRegister.t0); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.greater_than then + elsif token_kind = ElnaLexerKind.greater_than then instruction := _elna_tac_slt(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.less_equal then + elsif token_kind = ElnaLexerKind.less_equal then instruction := _elna_tac_slt(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1); _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; instruction := _elna_tac_xor_immediate(ElnaTacRegister.t0, ElnaTacRegister.t0, 1); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.not_equal then + elsif token_kind = ElnaLexerKind.not_equal then instruction := _elna_tac_xor(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1); _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; instruction := _elna_tac_snez(ElnaTacRegister.t0, ElnaTacRegister.t0); _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = LexerTokenKind.greater_equal then + elsif token_kind = ElnaLexerKind.greater_equal then instruction := _elna_tac_slt(ElnaTacRegister.t0, ElnaTacRegister.t1, ElnaTacRegister.t0); _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; @@ -2017,7 +2005,7 @@ begin this^ := value end; -proc _parse_call(callee: Word); +proc _elna_parser_call(callee: Word); var parsed_expression: Word; result: Word; @@ -2033,27 +2021,27 @@ begin argument_number := 1; _call_set_name(result, callee); - _lexer_read_token(@token_kind); - _lexer_skip_token(); - _lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); + _elna_lexer_read_token(@token_kind); - if token_kind = LexerTokenKind.right_paren then - _lexer_skip_token(); - goto parse_call_end + if token_kind = ElnaLexerKind.right_paren then + _elna_lexer_skip_token(); + goto elna_parser_call_end end; - .parse_call_loop; - parsed_expression := _parse_binary_expression(); + .elna_parser_call_loop; + parsed_expression := _elna_parser_binary_expression(); _call_set_argument(result, argument_number, parsed_expression); argument_number := argument_number + 1; - _lexer_read_token(@token_kind); - _lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); - if token_kind = LexerTokenKind.comma then - goto parse_call_loop + if token_kind = ElnaLexerKind.comma then + goto elna_parser_call_loop end; - .parse_call_end; + .elna_parser_call_end; (* Set the trailing argument to nil. *) _call_set_argument(result, argument_number, 0); @@ -2171,7 +2159,7 @@ begin this^ := value end; -proc _parse_goto_statement(); +proc _elna_parser_goto_statement(); var token_kind: Word; label_name: Word; @@ -2179,12 +2167,12 @@ var statement_size: Word; result: Word; begin - _lexer_skip_token(); - _lexer_read_token(@token_kind); + _elna_lexer_skip_token(); + _elna_lexer_read_token(@token_kind); - label_name := _lexer_global_get_start(); - label_length := _lexer_global_get_end() - label_name; - _lexer_skip_token(); + label_name := _elna_lexer_global_get_start(); + label_length := _elna_lexer_global_get_end() - label_name; + _elna_lexer_skip_token(); statement_size := _goto_statement_size(); result := _allocate(statement_size); @@ -2242,7 +2230,7 @@ begin this^ := value end; -proc _parse_label_declaration(); +proc _elna_parser_label_declaration(); var token_kind: Word; label_name: Word; @@ -2250,12 +2238,12 @@ var statement_size: Word; result: Word; begin - _lexer_skip_token(); - _lexer_read_token(@token_kind); + _elna_lexer_skip_token(); + _elna_lexer_read_token(@token_kind); - label_name := _lexer_global_get_start(); - label_length := _lexer_global_get_end() - label_name; - _lexer_skip_token(); + label_name := _elna_lexer_global_get_start(); + label_length := _elna_lexer_global_get_end() - label_name; + _elna_lexer_skip_token(); statement_size := _label_declaration_size(); result := _allocate(statement_size); @@ -2363,7 +2351,7 @@ begin members := _enumeration_type_get_members(enumeration_type); members_length := _enumeration_type_get_length(enumeration_type); - _lexer_read_token(@token_type); + _elna_lexer_read_token(@token_type); value_name := _field_access_expression_get_field(field_access_expression); name_length := _field_access_expression_get_length(field_access_expression); @@ -2376,7 +2364,7 @@ begin member_length := members + 4; member_length := member_length^; - if _lexer_compare_keyword(value_name, name_length, member_name, member_length) = 0 then + if _string_compare(value_name, name_length, member_name, member_length) = 0 then members_length := members_length - 1; members := members + 8; counter := counter + 1; @@ -2387,7 +2375,7 @@ begin return instruction end; -proc _parse_field_access_expression(aggregate: Word); +proc _elna_parser_field_access_expression(aggregate: Word); var token_kind: Word; name: Word; @@ -2396,13 +2384,13 @@ var memory_size: Word; begin (* Skip dot. Read the enumeration value. *) - _lexer_skip_token(); - _lexer_read_token(@token_kind); + _elna_lexer_skip_token(); + _elna_lexer_read_token(@token_kind); - name := _lexer_global_get_start(); - name_token := _lexer_global_get_end(); + name := _elna_lexer_global_get_start(); + name_token := _elna_lexer_global_get_end(); name_token := name_token - name; - _lexer_skip_token(); + _elna_lexer_skip_token(); memory_size := _field_access_expression_size(); result := _allocate(memory_size); @@ -2473,7 +2461,7 @@ begin this^ := value end; -proc _parse_assign_statement(assignee: Word); +proc _elna_parser_assign_statement(assignee: Word); var statement_size: Word; result: Word; @@ -2488,10 +2476,10 @@ begin _assign_statement_set_assignee(result, assignee); (* Skip the assignment sign (:=) with surrounding whitespaces. *) - _lexer_read_token(@token_kind); - _lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); - assignment_node := _parse_binary_expression(); + assignment_node := _elna_parser_binary_expression(); _assign_statement_set_assignment(result, assignment_node); return result @@ -2542,7 +2530,7 @@ begin this^ := value end; -proc _parse_return_statement(); +proc _elna_parser_return_statement(); var token_kind: Word; returned: Word; @@ -2551,10 +2539,10 @@ var result: Word; begin (* Skip "return" keyword and whitespace after it. *) - _lexer_skip_token(); - _lexer_read_token(@token_kind); + _elna_lexer_skip_token(); + _elna_lexer_read_token(@token_kind); - returned := _parse_binary_expression(); + returned := _elna_parser_binary_expression(); statement_size := _return_statement_size(); result := _allocate(statement_size); @@ -2601,7 +2589,7 @@ begin end end; -proc _parse_conditional_statements(); +proc _elna_parser_conditional_statements(); var conditional_size: Word; token_kind: Word; @@ -2612,16 +2600,16 @@ begin result := _allocate(conditional_size); (* Skip "if", "while" or "elsif". *) - _lexer_skip_token(); + _elna_lexer_skip_token(); - current_node := _parse_binary_expression(); + current_node := _elna_parser_binary_expression(); _conditional_statements_set_condition(result, current_node); (* Skip "then" or "do". *) - _lexer_read_token(@token_kind); - _lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); - current_node := _parse_statements(); + current_node := _elna_parser_statements(); _conditional_statements_set_statements(result, current_node); _conditional_statements_set_next(result, 0); @@ -2732,7 +2720,7 @@ begin this^ := value end; -proc _parse_if_statement(); +proc _elna_parser_if_statement(); var current_node: Word; result: Word; @@ -2747,58 +2735,58 @@ begin _node_set_kind(result, NodeKind.if_statement); _statement_set_next(result, 0); - previous_conditional := _parse_conditional_statements(); + previous_conditional := _elna_parser_conditional_statements(); _if_statement_set_conditionals(result, previous_conditional); - .parse_if_statement_loop; - _lexer_read_token(@token_kind); + .elna_parser_if_statement_loop; + _elna_lexer_read_token(@token_kind); - if token_kind = LexerTokenKind._elsif then - next_conditional := _parse_conditional_statements(); + if token_kind = ElnaLexerKind._elsif then + next_conditional := _elna_parser_conditional_statements(); _conditional_statements_set_next(previous_conditional, next_conditional); previous_conditional = next_conditional; - goto parse_if_statement_loop - elsif token_kind = LexerTokenKind._else then - _lexer_skip_token(); + goto elna_parser_if_statement_loop + elsif token_kind = ElnaLexerKind._else then + _elna_lexer_skip_token(); - current_node := _parse_statements(); + current_node := _elna_parser_statements(); _if_statement_set_else(result, current_node) else _if_statement_set_else(result, 0) end; - _lexer_skip_token(); + _elna_lexer_skip_token(); return result end; -proc _parse_statement(); +proc _elna_parser_statement(); var token_kind: Word; result : Word; begin result := 0; - _lexer_read_token(@token_kind); - - if token_kind = LexerTokenKind._goto then - result := _parse_goto_statement() - elsif token_kind = LexerTokenKind._if then - result := _parse_if_statement() - elsif token_kind = LexerTokenKind._return then - result := _parse_return_statement() - elsif token_kind = LexerTokenKind.dot then - result := _parse_label_declaration() - elsif token_kind = LexerTokenKind.identifier then - result := _parse_designator(); + _elna_lexer_read_token(@token_kind); + + if token_kind = ElnaLexerKind._goto then + result := _elna_parser_goto_statement() + elsif token_kind = ElnaLexerKind._if then + result := _elna_parser_if_statement() + elsif token_kind = ElnaLexerKind._return then + result := _elna_parser_return_statement() + elsif token_kind = ElnaLexerKind.dot then + result := _elna_parser_label_declaration() + elsif token_kind = ElnaLexerKind.identifier then + result := _elna_parser_designator(); if _node_get_kind(result) <> NodeKind.call then - result := _parse_assign_statement(result) + result := _elna_parser_assign_statement(result) end end; return result end; -proc _parse_statements(); +proc _elna_parser_statements(); var token_kind: Word; previous_statement: Word; @@ -2807,27 +2795,27 @@ var begin _skip_empty_lines(); - first_statement := _parse_statement(); + first_statement := _elna_parser_statement(); previous_statement := first_statement; if previous_statement = 0 then - goto parse_statements_end + goto elna_parser_statements_end end; - .parse_statement_loop; - _lexer_read_token(@token_kind); + .elna_parser_statement_loop; + _elna_lexer_read_token(@token_kind); - if token_kind = LexerTokenKind.semicolon then - _lexer_skip_token(); + if token_kind = ElnaLexerKind.semicolon then + _elna_lexer_skip_token(); _skip_empty_lines(); - next_statement := _parse_statement(); + next_statement := _elna_parser_statement(); _statement_set_next(previous_statement, next_statement); previous_statement := next_statement; if previous_statement <> 0 then - goto parse_statement_loop + goto elna_parser_statement_loop end end; - .parse_statements_end; + .elna_parser_statements_end; _skip_empty_lines(); return first_statement @@ -2959,6 +2947,10 @@ begin this^ := value end; +proc _enumeration_type_size(); + return 16 +end; + proc _enumeration_type_get_members(this: Word); begin this := this + 8; @@ -3011,6 +3003,62 @@ begin this^ := value end; +proc _record_type_size(); + return 16 +end; + +proc _record_type_get_members(this: Word); +begin + this := this + 8; + return this^ +end; + +proc _record_type_set_members(this: Word, value: Word); +begin + this := this + 8; + this^ := value +end; + +proc _record_type_get_length(this: Word); +begin + this := this + 12; + return this^ +end; + +proc _record_type_set_length(this: Word, value: Word); +begin + this := this + 12; + this^ := value +end; + +proc _record_type_expression_size(); + return 12 +end; + +proc _record_type_expression_get_members(this: Word); +begin + this := this + 4; + return this^ +end; + +proc _record_type_expression_set_members(this: Word, value: Word); +begin + this := this + 4; + this^ := value +end; + +proc _record_type_expression_get_length(this: Word); +begin + this := this + 8; + return this^ +end; + +proc _record_type_expression_set_length(this: Word, value: Word); +begin + this := this + 8; + this^ := value +end; + proc _named_type_expression_size(); return 12 end; @@ -3039,7 +3087,79 @@ begin this^ := value end; -proc _parse_enumeration_type_expression(); +proc _elna_parser_record_type_expression(); +var + entry: Word; + member_count: Word; + memory_start: Word; + field_name: Word; + field_length: Word; + field_type: Word; + token_kind: Word; + type_expression_size: Word; + result: Word; + previous_entry: Word; +begin + _elna_lexer_skip_token(); + member_count := 0; + memory_start := 0; + + _elna_lexer_read_token(@token_kind); + if token_kind = ElnaLexerKind._end then + goto elna_parser_record_type_expression_end + end; + .elna_parser_record_type_expression_loop; + entry := _allocate(16); + member_count := member_count + 1; + + field_name := _elna_lexer_global_get_start(); + field_length := _elna_lexer_global_get_end() - field_name; + + entry^ := field_name; + entry := entry + 4; + + entry^ := field_length; + entry := entry + 4; + + (* Skip the identifier. *) + _elna_lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); + + field_type := _elna_parser_type_expression(); + + entry^ := field_type; + entry := entry + 4; + + entry^ := 0; + if memory_start = 0 then + memory_start := entry - 12 + else + previous_entry^ := entry - 12 + end; + previous_entry := entry; + + _elna_lexer_read_token(@token_kind); + if token_kind = ElnaLexerKind.semicolon then + _elna_lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + goto elna_parser_record_type_expression_loop + end; + + .elna_parser_record_type_expression_end; + _elna_lexer_skip_token(); + + type_expression_size := _enumeration_type_expression_size(); + result := _allocate(type_expression_size); + + _node_set_kind(result, NodeKind.record_type_expression); + _record_type_expression_set_members(result, memory_start); + _record_type_expression_set_length(result, member_count); + + return result +end; + +proc _elna_parser_enumeration_type_expression(); var token_kind: Word; enumeration_name: Word; @@ -3051,20 +3171,20 @@ var entry: Word; previous_entry: Word; begin - _lexer_skip_token(); + _elna_lexer_skip_token(); memory_start := 0; member_count := 0; - _lexer_read_token(@token_kind); - if token_kind = LexerTokenKind.right_paren then - goto parse_enumeration_type_expression_end + _elna_lexer_read_token(@token_kind); + if token_kind = ElnaLexerKind.right_paren then + goto elna_parser_enumeration_type_expression_end end; - .parse_enumeration_type_expression_loop; + .elna_parser_enumeration_type_expression_loop; entry := _allocate(12); member_count := member_count + 1; - enumeration_name := _lexer_global_get_start(); - name_length := _lexer_global_get_end() - enumeration_name; + enumeration_name := _elna_lexer_global_get_start(); + name_length := _elna_lexer_global_get_end() - enumeration_name; entry^ := enumeration_name; entry := entry + 4; @@ -3081,17 +3201,17 @@ begin previous_entry := entry; (* Skip the identifier. *) - _lexer_skip_token(); + _elna_lexer_skip_token(); - _lexer_read_token(@token_kind); - if token_kind = LexerTokenKind.comma then - _lexer_skip_token(); - _lexer_read_token(@token_kind); - goto parse_enumeration_type_expression_loop + _elna_lexer_read_token(@token_kind); + if token_kind = ElnaLexerKind.comma then + _elna_lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + goto elna_parser_enumeration_type_expression_loop end; - .parse_enumeration_type_expression_end; - _lexer_skip_token(); + .elna_parser_enumeration_type_expression_end; + _elna_lexer_skip_token(); type_expression_size := _enumeration_type_expression_size(); result := _allocate(type_expression_size); @@ -3124,8 +3244,8 @@ var member_array_start: Word; member_array_current: Word; begin - (* The resulting structure is 16 bytes long. *) - result := _allocate(16); + member_array_size := _enumeration_type_size(); + result := _allocate(member_array_size); memory_start := _enumeration_type_expression_get_members(parser_node); member_count := _enumeration_type_expression_get_length(parser_node); @@ -3159,7 +3279,54 @@ begin return _type_info_create(result) end; -proc _parse_named_type_expression(); +proc _elna_name_type_record(parser_node: Word); +var + result: Word; + memory_start: Word; + member_count: Word; + member_array_size: Word; + member_array_start: Word; + member_array_current: Word; +begin + member_array_size := _record_type_size(); + result := _allocate(member_array_size); + + memory_start := _record_type_expression_get_members(parser_node); + member_count := _record_type_expression_get_length(parser_node); + + member_array_size := member_count * 12; + member_array_start := _allocate(member_array_size); + member_array_current := member_array_start; + + .elna_name_type_record_loop; + if member_count > 0 then + member_array_current^ := memory_start^; + member_array_current := member_array_current + 4; + memory_start := memory_start + 4; + + member_array_current^ := memory_start^; + member_array_current := member_array_current + 4; + memory_start := memory_start + 4; + + member_array_current^ := _elna_name_type_expression(memory_start^); + member_array_current := member_array_current + 4; + memory_start := memory_start + 4; + + memory_start := memory_start^; + member_count := member_count - 1; + goto elna_name_type_record_loop + end; + member_count := _record_type_expression_get_length(parser_node); + + _type_set_kind(result, TypeKind._record); + _type_set_size(result, member_count * 4); + _record_type_set_members(result, member_array_start); + _record_type_set_length(result, member_count); + + return _type_info_create(result) +end; + +proc _elna_parser_named_type_expression(); var type_expression_size: Word; result: Word; @@ -3170,27 +3337,29 @@ begin result := _allocate(type_expression_size); _node_set_kind(result, NodeKind.named_type_expression); - type_name := _lexer_global_get_start(); - name_length := _lexer_global_get_end() - type_name; + type_name := _elna_lexer_global_get_start(); + name_length := _elna_lexer_global_get_end() - type_name; _named_type_expression_set_name(result, type_name); _named_type_expression_set_length(result, name_length); - _lexer_skip_token(); + _elna_lexer_skip_token(); return result end; -proc _parse_type_expression(); +proc _elna_parser_type_expression(); var token_kind: Word; result: Word; begin result := 0; - _lexer_read_token(@token_kind); - - if token_kind = LexerTokenKind.identifier then - result := _parse_named_type_expression() - elsif token_kind = LexerTokenKind.left_paren then - result := _parse_enumeration_type_expression() + _elna_lexer_read_token(@token_kind); + + if token_kind = ElnaLexerKind.identifier then + result := _elna_parser_named_type_expression() + elsif token_kind = ElnaLexerKind.left_paren then + result := _elna_parser_enumeration_type_expression() + elsif token_kind = ElnaLexerKind._record then + result := _elna_parser_record_type_expression() end; return result end; @@ -3212,6 +3381,8 @@ begin result := _type_info_get_type(result) elsif token_kind = NodeKind.enumeration_type_expression then result := _elna_name_type_enumeration(parser_node) + elsif token_kind = NodeKind.record_type_expression then + result := _elna_name_type_record(parser_node) end; return result @@ -3354,16 +3525,13 @@ begin temporary_counter := 0; .elna_name_procedure_temporaries_loop; - if parser_node = 0 then - goto elna_name_procedure_temporaries_end - end; - _elna_name_procedure_temporary(parser_node, temporary_counter, symbol_table); - - temporary_counter := temporary_counter + 1; - parser_node := _declaration_get_next(parser_node); - goto elna_name_procedure_temporaries_loop; + if parser_node <> 0 then + _elna_name_procedure_temporary(parser_node, temporary_counter, symbol_table); - .elna_name_procedure_temporaries_end + temporary_counter := temporary_counter + 1; + parser_node := _declaration_get_next(parser_node); + goto elna_name_procedure_temporaries_loop + end end; proc _declaration_get_next(this: Word); @@ -3443,7 +3611,7 @@ begin this^ := value end; -proc _parse_procedure_declaration(); +proc _elna_parser_procedure_declaration(); var name_pointer: Word; name_length: Word; @@ -3459,27 +3627,27 @@ begin _declaration_set_next(result, 0); (* Skip "proc ". *) - _lexer_skip_token(); + _elna_lexer_skip_token(); - _lexer_read_token(@token_kind); - name_pointer := _lexer_global_get_start(); - name_length := _lexer_global_get_end() - name_pointer; + _elna_lexer_read_token(@token_kind); + name_pointer := _elna_lexer_global_get_start(); + name_length := _elna_lexer_global_get_end() - name_pointer; _declaration_set_name(result, name_pointer); _declaration_set_length(result, name_length); (* Skip procedure name. *) - _lexer_skip_token(); + _elna_lexer_skip_token(); (* Skip open paren. *) - _lexer_read_token(@token_kind); - _lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); parameter_head := 0; - .parse_procedure_declaration_parameter; - _lexer_read_token(@token_kind); + .elna_parser_procedure_declaration_parameter; + _elna_lexer_read_token(@token_kind); - if token_kind <> LexerTokenKind.right_paren then - name_pointer := _parse_variable_declaration(); + if token_kind <> ElnaLexerKind.right_paren then + name_pointer := _elna_parser_variable_declaration(); if parameter_head = 0 then parameter_head := name_pointer else @@ -3487,73 +3655,55 @@ begin end; name_length := name_pointer; - _lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind); - if token_kind = LexerTokenKind.comma then - _lexer_skip_token(); - goto parse_procedure_declaration_parameter + if token_kind = ElnaLexerKind.comma then + _elna_lexer_skip_token(); + goto elna_parser_procedure_declaration_parameter end end; (* Skip close paren. *) - _lexer_skip_token(); + _elna_lexer_skip_token(); _procedure_declaration_set_parameters(result, parameter_head); (* Skip semicolon and newline. *) - _lexer_read_token(@token_kind); - _lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); - parameter_head := _parse_var_part(); + parameter_head := _elna_parser_var_part(); _procedure_declaration_set_temporaries(result, parameter_head); (* Skip semicolon, "begin" and newline. *) - _lexer_read_token(@token_kind); - if token_kind = LexerTokenKind._begin then - _lexer_skip_token(); - parameter_head := _parse_statements() - elsif token_kind = LexerTokenKind._return then - parameter_head := _parse_return_statement() + _elna_lexer_read_token(@token_kind); + if token_kind = ElnaLexerKind._begin then + _elna_lexer_skip_token(); + parameter_head := _elna_parser_statements() + elsif token_kind = ElnaLexerKind._return then + parameter_head := _elna_parser_return_statement() end; _procedure_declaration_set_body(result, parameter_head); (* Skip the "end" keyword. *) - _lexer_read_token(@token_kind); - _lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); return result end; -proc _elna_tac_procedure_declaration(parser_node: Word); +proc _elna_tac_parameters(current_parameter: Word, new_symbol_table: Word); var name_pointer: Word; name_length: Word; parameter_counter: Word; - current_parameter: Word; - new_symbol_table: Word; - symbol_info: Word; instruction: Word; first_instruction: Word; current_instruction: Word; - result: Word; - result_size: Word; + symbol_info: Word; begin - result_size := _elna_tac_declaration_size(); - result := _allocate(result_size); - - _elna_tac_declaration_set_next(result, 0); - - name_pointer := _declaration_get_name(parser_node); - name_length := _declaration_get_length(parser_node); - - _elna_tac_declaration_set_name(result, name_pointer); - _elna_tac_declaration_set_length(result, name_length); - - symbol_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length); - new_symbol_table := _procedure_info_get_symbol_table(symbol_info); - - current_parameter := _procedure_declaration_get_parameters(parser_node); first_instruction := 0; parameter_counter := 0; - .elna_tac_procedure_declaration_parameters; + + .elna_tac_parameters_loop; if current_parameter <> 0 then name_pointer := _declaration_get_name(current_parameter); name_length := _declaration_get_length(current_parameter); @@ -3573,22 +3723,59 @@ begin parameter_counter := parameter_counter + 1; current_parameter := _declaration_get_next(current_parameter); - goto elna_tac_procedure_declaration_parameters + goto elna_tac_parameters_loop end; - current_parameter := _procedure_declaration_get_body(parser_node); + return first_instruction +end; + +proc _elna_tac_procedure_declaration(parser_node: Word); +var + name_pointer: Word; + name_length: Word; + current_parameter: Word; + body: Word; + new_symbol_table: Word; + symbol_info: Word; + instruction: Word; + first_instruction: Word; + result: Word; + result_size: Word; +begin + result_size := _elna_tac_declaration_size(); + result := _allocate(result_size); + + _elna_tac_declaration_set_next(result, 0); + + name_pointer := _declaration_get_name(parser_node); + name_length := _declaration_get_length(parser_node); + + _elna_tac_declaration_set_name(result, name_pointer); + _elna_tac_declaration_set_length(result, name_length); + + symbol_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length); + new_symbol_table := _procedure_info_get_symbol_table(symbol_info); + + (* Write the prologue. *) + first_instruction := _elna_tac_instruction_create(ElnaTacOperator.start); + + current_parameter := _procedure_declaration_get_parameters(parser_node); + current_parameter := _elna_tac_parameters(current_parameter, new_symbol_table); + _elna_tac_instruction_set_next(first_instruction, current_parameter); + + body := _procedure_declaration_get_body(parser_node); + instruction := _elna_tac_statements(body, new_symbol_table); + _elna_tac_instruction_set_next(first_instruction, instruction); + + (* Write the epilogue. *) + instruction := _elna_tac_instruction_create(ElnaTacOperator.ret); + _elna_tac_instruction_set_next(first_instruction, instruction); - instruction := _elna_tac_statements(current_parameter, new_symbol_table); - if first_instruction <> 0 then - _elna_tac_instruction_set_next(first_instruction, instruction) - else - first_instruction := instruction - end; _elna_tac_declaration_set_body(result, first_instruction); return result end; -proc _parse_procedures(); +proc _elna_parser_procedures(); var parser_node: Word; result: Word; @@ -3597,12 +3784,12 @@ var begin result := 0; - .parse_procedures_loop; + .elna_parser_procedures_loop; _skip_empty_lines(); - _lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind); - if token_kind = LexerTokenKind._proc then - parser_node := _parse_procedure_declaration(); + if token_kind = ElnaLexerKind._proc then + parser_node := _elna_parser_procedure_declaration(); if result = 0 then result := parser_node else @@ -3611,10 +3798,10 @@ begin current_declaration := parser_node; (* Skip semicolon. *) - _lexer_read_token(@token_kind); - _lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); - goto parse_procedures_loop + goto elna_parser_procedures_loop end; return result end; @@ -3655,10 +3842,10 @@ var begin .skip_empty_lines_rerun; - _lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind); - if token_kind = LexerTokenKind.comment then - _lexer_skip_token(); + if token_kind = ElnaLexerKind.comment then + _elna_lexer_skip_token(); goto skip_empty_lines_rerun end end; @@ -3680,7 +3867,7 @@ begin this^ := value end; -proc _parse_type_declaration(); +proc _elna_parser_type_declaration(); var token_kind: Word; type_name: Word; @@ -3689,15 +3876,15 @@ var result: Word; declaration_size: Word; begin - _lexer_read_token(@token_kind); - type_name := _lexer_global_get_start(); - name_length := _lexer_global_get_end() - type_name; + _elna_lexer_read_token(@token_kind); + type_name := _elna_lexer_global_get_start(); + name_length := _elna_lexer_global_get_end() - type_name; - _lexer_skip_token(); - _lexer_read_token(@token_kind); - _lexer_skip_token(); + _elna_lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); - parser_node := _parse_type_expression(); + parser_node := _elna_parser_type_expression(); declaration_size := _type_declaration_size(); result := _allocate(declaration_size); @@ -3707,8 +3894,8 @@ begin _declaration_set_length(result, name_length); _type_declaration_set_type(result, parser_node); - _lexer_read_token(@token_kind); - _lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); return result end; @@ -3732,7 +3919,7 @@ proc _elna_type_type_declaration(parser_node: Word); begin end; -proc _parse_type_part(); +proc _elna_parser_type_part(); var token_kind: Word; parser_node: Word; @@ -3741,19 +3928,19 @@ var begin result := 0; _skip_empty_lines(); - _lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind); - if token_kind <> LexerTokenKind._type then - goto parse_type_part_end + if token_kind <> ElnaLexerKind._type then + goto elna_parser_type_part_end end; - _lexer_skip_token(); + _elna_lexer_skip_token(); - .parse_type_part_loop; + .elna_parser_type_part_loop; _skip_empty_lines(); - _lexer_read_token(@token_kind); - if token_kind = LexerTokenKind.identifier then - parser_node := _parse_type_declaration(); + _elna_lexer_read_token(@token_kind); + if token_kind = ElnaLexerKind.identifier then + parser_node := _elna_parser_type_declaration(); if result = 0 then result := parser_node @@ -3761,10 +3948,10 @@ begin _declaration_set_next(current_declaration, parser_node) end; current_declaration := parser_node; - goto parse_type_part_loop + goto elna_parser_type_part_loop end; - .parse_type_part_end; + .elna_parser_type_part_end; return result end; @@ -3784,7 +3971,7 @@ begin this^ := value end; -proc _parse_variable_declaration(); +proc _elna_parser_variable_declaration(); var token_kind: Word; name: Word; @@ -3793,16 +3980,16 @@ var result: Word; declaration_size: Word; begin - _lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind); - name := _lexer_global_get_start(); - name_length := _lexer_global_get_end() - name; + name := _elna_lexer_global_get_start(); + name_length := _elna_lexer_global_get_end() - name; (* Skip the variable name and colon with the type. *) - _lexer_skip_token(); - _lexer_read_token(@token_kind); - _lexer_skip_token(); - variable_type := _parse_type_expression(); + _elna_lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); + variable_type := _elna_parser_type_expression(); declaration_size := _variable_declaration_size(); result := _allocate(declaration_size); @@ -3839,7 +4026,7 @@ begin name := _named_type_expression_get_name(variable_type); name_length := _named_type_expression_get_length(variable_type); - if _lexer_compare_keyword("Array", 5, name, name_length) then + if _string_compare("Array", 5, name, name_length) then (* Else we assume this is a zeroed 4096 bytes big array. *) _elna_tac_declaration_set_body(result, 4096) else @@ -3848,7 +4035,170 @@ begin return result end; -proc _parse_var_part(); +proc _elna_tac_type_field(name_pointer: Word, name_length: Word, field_pointer: Word, field_offset: Word); +var + result_size: Word; + first_result: Word; + second_result: Word; + new_name: Word; + new_length: Word; + field_length: Word; + instruction: Word; + name_target: Word; + next_instruction: Word; +begin + result_size := _elna_tac_declaration_size(); + field_length := field_pointer + 4; + field_length := field_length^; + new_length := field_length + name_length; + new_length := new_length + 5; + + first_result := _allocate(result_size); + _elna_tac_declaration_set_next(first_result, 0); + + new_name := _allocate(new_length); + + name_target := new_name; + _memcpy(name_target, name_pointer, name_length); + name_target := name_target + name_length; + _memcpy(name_target, "_get_", 5); + name_target := name_target + 5; + _memcpy(name_target, field_pointer^, field_length); + + _elna_tac_declaration_set_name(first_result, new_name); + _elna_tac_declaration_set_length(first_result, new_length); + + instruction := _elna_tac_add_immediate(ElnaTacRegister.a0, ElnaTacRegister.a0, field_offset, 0); + next_instruction := _elna_tac_load_word(ElnaTacRegister.a0, ElnaTacRegister.a0, 0); + _elna_tac_instruction_set_next(instruction, next_instruction); + _elna_tac_declaration_set_body(first_result, instruction); + + second_result := _allocate(result_size); + _elna_tac_declaration_set_next(second_result, 0); + + new_name := _allocate(new_length); + + name_target := new_name; + _memcpy(name_target, name_pointer, name_length); + name_target := name_target + name_length; + _memcpy(name_target, "_set_", 5); + name_target := name_target + 5; + _memcpy(name_target, field_pointer^, field_length); + + _elna_tac_declaration_set_name(second_result, new_name); + _elna_tac_declaration_set_length(second_result, new_length); + + instruction := _elna_tac_add_immediate(ElnaTacRegister.a0, ElnaTacRegister.a0, field_offset, 0); + next_instruction := _elna_tac_store_word(ElnaTacRegister.a1, ElnaTacRegister.a0, 0); + _elna_tac_instruction_set_next(instruction, next_instruction); + _elna_tac_declaration_set_body(second_result, instruction); + + _elna_tac_declaration_set_next(first_result, second_result); + + return first_result +end; + +proc _elna_tac_type_record(name_pointer: Word, name_length: Word, type_representation: Word, current_result: Word); +var + result_size: Word; + first_result: Word; + result: Word; + type_size: Word; + new_name: Word; + new_length: Word; + instruction: Word; + field_count: Word; + field_offset: Word; + field_pointer: Word; +begin + result_size := _elna_tac_declaration_size(); + first_result := _allocate(result_size); + result := 0; + + (* Debug. Error stream output. + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *) + + type_size := _type_get_size(type_representation); + new_length := name_length + 5; + new_name := _allocate(new_length); + + _memcpy(new_name, name_pointer, name_length); + _memcpy(new_name + name_length, "_size", 5); + + _elna_tac_declaration_set_name(first_result, new_name); + _elna_tac_declaration_set_length(first_result, new_length); + + instruction := _elna_tac_load_immediate(ElnaTacRegister.a0, type_size, 0); + _elna_tac_declaration_set_body(first_result, instruction); + + field_count := _record_type_get_length(type_representation); + field_pointer := _record_type_get_members(type_representation); + field_offset := 0; + current_result^ := first_result; + + .elna_tac_type_record_fields; + if field_count > 0 then + result := _elna_tac_type_field(name_pointer, name_length, field_pointer, field_offset); + + _elna_tac_declaration_set_next(current_result^, result); + current_result^ := _elna_tac_declaration_get_next(result); + + field_offset := field_offset + 4; + field_count := field_count - 1; + field_pointer := field_pointer + 12; + goto elna_tac_type_record_fields + end; + + return first_result +end; + +proc _elna_tac_type_part(parser_node: Word); +var + name_pointer: Word; + name_length: Word; + result: Word; + first_result: Word; + symbol: Word; + info_type: Word; + type_kind: Word; + current_result: Word; + out_result: Word; +begin + first_result := 0; + + .elna_tac_type_part_loop; + if parser_node = 0 then + goto elna_tac_type_part_end + end; + + name_pointer := _declaration_get_name(parser_node); + name_length := _declaration_get_length(parser_node); + symbol := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length); + + info_type := _type_info_get_type(symbol); + type_kind := _type_get_kind(info_type); + + if type_kind = TypeKind._record then + result := _elna_tac_type_record(name_pointer, name_length, info_type, @out_result) + else + result := 0; + out_result := 0 + end; + if first_result = 0 then + first_result := result; + current_result := out_result + elsif result <> 0 then + _elna_tac_declaration_set_next(current_result, result); + current_result := out_result + end; + parser_node := _declaration_get_next(parser_node); + goto elna_tac_type_part_loop; + + .elna_tac_type_part_end; + return first_result +end; + +proc _elna_parser_var_part(); var result: Word; token_kind: Word; @@ -3856,24 +4206,24 @@ var current_declaration: Word; begin result := 0; - _lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind); - if token_kind <> LexerTokenKind._var then - goto parse_var_part_end + if token_kind <> ElnaLexerKind._var then + goto elna_parser_var_part_end end; (* Skip "var". *) - _lexer_skip_token(); + _elna_lexer_skip_token(); - .parse_var_part_loop; + .elna_parser_var_part_loop; _skip_empty_lines(); - _lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind); - if token_kind = LexerTokenKind.identifier then - variable_node := _parse_variable_declaration(); + if token_kind = ElnaLexerKind.identifier then + variable_node := _elna_parser_variable_declaration(); (* Skip semicolon. *) - _lexer_read_token(@token_kind); - _lexer_skip_token(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token(); if result = 0 then result := variable_node @@ -3881,10 +4231,10 @@ begin _declaration_set_next(current_declaration, variable_node) end; current_declaration := variable_node; - goto parse_var_part_loop + goto elna_parser_var_part_loop end; - .parse_var_part_end; + .elna_parser_var_part_end; return result end; @@ -3957,7 +4307,7 @@ begin this^ := value end; -proc _parse_module_declaration(); +proc _elna_parser_module_declaration(); var parser_node: Word; declaration_size: Word; @@ -3968,13 +4318,13 @@ begin _node_set_kind(result, NodeKind.module_declaration); - parser_node := _parse_type_part(); + parser_node := _elna_parser_type_part(); _module_declaration_set_types(result, parser_node); - parser_node := _parse_var_part(); + parser_node := _elna_parser_var_part(); _module_declaration_set_globals(result, parser_node); - parser_node := _parse_procedures(); + parser_node := _elna_parser_procedures(); _module_declaration_set_procedures(result, parser_node); return result @@ -3987,13 +4337,30 @@ proc _elna_tac_module_declaration(parser_node: Word); var data_part: Word; code_part: Word; + type_part: Word; + current_declaration: Word; + next_declaration: Word; begin + type_part := _module_declaration_get_types(parser_node); + type_part := _elna_tac_type_part(type_part); + data_part := _module_declaration_get_globals(parser_node); data_part := _elna_tac_var_part(data_part); code_part := _module_declaration_get_procedures(parser_node); code_part := _elna_tac_procedures(code_part); + current_declaration := code_part; + + .elna_tac_module_declaration_types; + next_declaration := _elna_tac_declaration_get_next(current_declaration); + if next_declaration <> 0 then + current_declaration := next_declaration; + + goto elna_tac_module_declaration_types + end; + _elna_tac_declaration_set_next(current_declaration, type_part); + return _elna_tac_module_create(data_part, code_part) end; @@ -4084,7 +4451,7 @@ var parser_node: Word; tac: Word; begin - parser_node := _parse_module_declaration(); + parser_node := _elna_parser_module_declaration(); _elna_name_module_declaration(parser_node); _elna_type_module_declaration(parser_node); tac := _elna_tac_module_declaration(parser_node); @@ -4270,144 +4637,144 @@ end; (** * Initializes the array with character classes. *) -proc _lexer_classifications(); +proc _elna_lexer_classifications(); var code: Word; begin - _assign_at(@classification, 1, LexerClass.eof); - _assign_at(@classification, 2, LexerClass.invalid); - _assign_at(@classification, 3, LexerClass.invalid); - _assign_at(@classification, 4, LexerClass.invalid); - _assign_at(@classification, 5, LexerClass.invalid); - _assign_at(@classification, 6, LexerClass.invalid); - _assign_at(@classification, 7, LexerClass.invalid); - _assign_at(@classification, 8, LexerClass.invalid); - _assign_at(@classification, 9, LexerClass.invalid); - _assign_at(@classification, 10, LexerClass.space); - _assign_at(@classification, 11, LexerClass.space); - _assign_at(@classification, 12, LexerClass.invalid); - _assign_at(@classification, 13, LexerClass.invalid); - _assign_at(@classification, 14, LexerClass.space); - _assign_at(@classification, 15, LexerClass.invalid); - _assign_at(@classification, 16, LexerClass.invalid); - _assign_at(@classification, 17, LexerClass.invalid); - _assign_at(@classification, 18, LexerClass.invalid); - _assign_at(@classification, 19, LexerClass.invalid); - _assign_at(@classification, 20, LexerClass.invalid); - _assign_at(@classification, 21, LexerClass.invalid); - _assign_at(@classification, 22, LexerClass.invalid); - _assign_at(@classification, 23, LexerClass.invalid); - _assign_at(@classification, 24, LexerClass.invalid); - _assign_at(@classification, 25, LexerClass.invalid); - _assign_at(@classification, 26, LexerClass.invalid); - _assign_at(@classification, 27, LexerClass.invalid); - _assign_at(@classification, 28, LexerClass.invalid); - _assign_at(@classification, 29, LexerClass.invalid); - _assign_at(@classification, 30, LexerClass.invalid); - _assign_at(@classification, 31, LexerClass.invalid); - _assign_at(@classification, 32, LexerClass.invalid); - _assign_at(@classification, 33, LexerClass.space); - _assign_at(@classification, 34, LexerClass.single); - _assign_at(@classification, 35, LexerClass.double_quote); - _assign_at(@classification, 36, LexerClass.other); - _assign_at(@classification, 37, LexerClass.other); - _assign_at(@classification, 38, LexerClass.single); - _assign_at(@classification, 39, LexerClass.single); - _assign_at(@classification, 40, LexerClass.single_quote); - _assign_at(@classification, 41, LexerClass.left_paren); - _assign_at(@classification, 42, LexerClass.right_paren); - _assign_at(@classification, 43, LexerClass.asterisk); - _assign_at(@classification, 44, LexerClass.single); - _assign_at(@classification, 45, LexerClass.single); - _assign_at(@classification, 46, LexerClass.minus); - _assign_at(@classification, 47, LexerClass.dot); - _assign_at(@classification, 48, LexerClass.single); - _assign_at(@classification, 49, LexerClass.zero); - _assign_at(@classification, 50, LexerClass.digit); - _assign_at(@classification, 51, LexerClass.digit); - _assign_at(@classification, 52, LexerClass.digit); - _assign_at(@classification, 53, LexerClass.digit); - _assign_at(@classification, 54, LexerClass.digit); - _assign_at(@classification, 55, LexerClass.digit); - _assign_at(@classification, 56, LexerClass.digit); - _assign_at(@classification, 57, LexerClass.digit); - _assign_at(@classification, 58, LexerClass.digit); - _assign_at(@classification, 59, LexerClass.colon); - _assign_at(@classification, 60, LexerClass.single); - _assign_at(@classification, 61, LexerClass.less); - _assign_at(@classification, 62, LexerClass.equals); - _assign_at(@classification, 63, LexerClass.greater); - _assign_at(@classification, 64, LexerClass.other); - _assign_at(@classification, 65, LexerClass.single); - _assign_at(@classification, 66, LexerClass.alpha); - _assign_at(@classification, 67, LexerClass.alpha); - _assign_at(@classification, 68, LexerClass.alpha); - _assign_at(@classification, 69, LexerClass.alpha); - _assign_at(@classification, 70, LexerClass.alpha); - _assign_at(@classification, 71, LexerClass.alpha); - _assign_at(@classification, 72, LexerClass.alpha); - _assign_at(@classification, 73, LexerClass.alpha); - _assign_at(@classification, 74, LexerClass.alpha); - _assign_at(@classification, 75, LexerClass.alpha); - _assign_at(@classification, 76, LexerClass.alpha); - _assign_at(@classification, 77, LexerClass.alpha); - _assign_at(@classification, 78, LexerClass.alpha); - _assign_at(@classification, 79, LexerClass.alpha); - _assign_at(@classification, 80, LexerClass.alpha); - _assign_at(@classification, 81, LexerClass.alpha); - _assign_at(@classification, 82, LexerClass.alpha); - _assign_at(@classification, 83, LexerClass.alpha); - _assign_at(@classification, 84, LexerClass.alpha); - _assign_at(@classification, 85, LexerClass.alpha); - _assign_at(@classification, 86, LexerClass.alpha); - _assign_at(@classification, 87, LexerClass.alpha); - _assign_at(@classification, 88, LexerClass.alpha); - _assign_at(@classification, 89, LexerClass.alpha); - _assign_at(@classification, 90, LexerClass.alpha); - _assign_at(@classification, 91, LexerClass.alpha); - _assign_at(@classification, 92, LexerClass.single); - _assign_at(@classification, 93, LexerClass.backslash); - _assign_at(@classification, 94, LexerClass.single); - _assign_at(@classification, 95, LexerClass.single); - _assign_at(@classification, 96, LexerClass.alpha); - _assign_at(@classification, 97, LexerClass.other); - _assign_at(@classification, 98, LexerClass.hex); - _assign_at(@classification, 99, LexerClass.hex); - _assign_at(@classification, 100, LexerClass.hex); - _assign_at(@classification, 101, LexerClass.hex); - _assign_at(@classification, 102, LexerClass.hex); - _assign_at(@classification, 103, LexerClass.hex); - _assign_at(@classification, 104, LexerClass.alpha); - _assign_at(@classification, 105, LexerClass.alpha); - _assign_at(@classification, 106, LexerClass.alpha); - _assign_at(@classification, 107, LexerClass.alpha); - _assign_at(@classification, 108, LexerClass.alpha); - _assign_at(@classification, 109, LexerClass.alpha); - _assign_at(@classification, 110, LexerClass.alpha); - _assign_at(@classification, 111, LexerClass.alpha); - _assign_at(@classification, 112, LexerClass.alpha); - _assign_at(@classification, 113, LexerClass.alpha); - _assign_at(@classification, 114, LexerClass.alpha); - _assign_at(@classification, 115, LexerClass.alpha); - _assign_at(@classification, 116, LexerClass.alpha); - _assign_at(@classification, 117, LexerClass.alpha); - _assign_at(@classification, 118, LexerClass.alpha); - _assign_at(@classification, 119, LexerClass.alpha); - _assign_at(@classification, 120, LexerClass.alpha); - _assign_at(@classification, 121, LexerClass.x); - _assign_at(@classification, 122, LexerClass.alpha); - _assign_at(@classification, 123, LexerClass.alpha); - _assign_at(@classification, 124, LexerClass.other); - _assign_at(@classification, 125, LexerClass.single); - _assign_at(@classification, 126, LexerClass.other); - _assign_at(@classification, 127, LexerClass.single); - _assign_at(@classification, 128, LexerClass.invalid); + _assign_at(@classification, 1, ElnaLexerClass.eof); + _assign_at(@classification, 2, ElnaLexerClass.invalid); + _assign_at(@classification, 3, ElnaLexerClass.invalid); + _assign_at(@classification, 4, ElnaLexerClass.invalid); + _assign_at(@classification, 5, ElnaLexerClass.invalid); + _assign_at(@classification, 6, ElnaLexerClass.invalid); + _assign_at(@classification, 7, ElnaLexerClass.invalid); + _assign_at(@classification, 8, ElnaLexerClass.invalid); + _assign_at(@classification, 9, ElnaLexerClass.invalid); + _assign_at(@classification, 10, ElnaLexerClass.space); + _assign_at(@classification, 11, ElnaLexerClass.space); + _assign_at(@classification, 12, ElnaLexerClass.invalid); + _assign_at(@classification, 13, ElnaLexerClass.invalid); + _assign_at(@classification, 14, ElnaLexerClass.space); + _assign_at(@classification, 15, ElnaLexerClass.invalid); + _assign_at(@classification, 16, ElnaLexerClass.invalid); + _assign_at(@classification, 17, ElnaLexerClass.invalid); + _assign_at(@classification, 18, ElnaLexerClass.invalid); + _assign_at(@classification, 19, ElnaLexerClass.invalid); + _assign_at(@classification, 20, ElnaLexerClass.invalid); + _assign_at(@classification, 21, ElnaLexerClass.invalid); + _assign_at(@classification, 22, ElnaLexerClass.invalid); + _assign_at(@classification, 23, ElnaLexerClass.invalid); + _assign_at(@classification, 24, ElnaLexerClass.invalid); + _assign_at(@classification, 25, ElnaLexerClass.invalid); + _assign_at(@classification, 26, ElnaLexerClass.invalid); + _assign_at(@classification, 27, ElnaLexerClass.invalid); + _assign_at(@classification, 28, ElnaLexerClass.invalid); + _assign_at(@classification, 29, ElnaLexerClass.invalid); + _assign_at(@classification, 30, ElnaLexerClass.invalid); + _assign_at(@classification, 31, ElnaLexerClass.invalid); + _assign_at(@classification, 32, ElnaLexerClass.invalid); + _assign_at(@classification, 33, ElnaLexerClass.space); + _assign_at(@classification, 34, ElnaLexerClass.single); + _assign_at(@classification, 35, ElnaLexerClass.double_quote); + _assign_at(@classification, 36, ElnaLexerClass.other); + _assign_at(@classification, 37, ElnaLexerClass.other); + _assign_at(@classification, 38, ElnaLexerClass.single); + _assign_at(@classification, 39, ElnaLexerClass.single); + _assign_at(@classification, 40, ElnaLexerClass.single_quote); + _assign_at(@classification, 41, ElnaLexerClass.left_paren); + _assign_at(@classification, 42, ElnaLexerClass.right_paren); + _assign_at(@classification, 43, ElnaLexerClass.asterisk); + _assign_at(@classification, 44, ElnaLexerClass.single); + _assign_at(@classification, 45, ElnaLexerClass.single); + _assign_at(@classification, 46, ElnaLexerClass.minus); + _assign_at(@classification, 47, ElnaLexerClass.dot); + _assign_at(@classification, 48, ElnaLexerClass.single); + _assign_at(@classification, 49, ElnaLexerClass.zero); + _assign_at(@classification, 50, ElnaLexerClass.digit); + _assign_at(@classification, 51, ElnaLexerClass.digit); + _assign_at(@classification, 52, ElnaLexerClass.digit); + _assign_at(@classification, 53, ElnaLexerClass.digit); + _assign_at(@classification, 54, ElnaLexerClass.digit); + _assign_at(@classification, 55, ElnaLexerClass.digit); + _assign_at(@classification, 56, ElnaLexerClass.digit); + _assign_at(@classification, 57, ElnaLexerClass.digit); + _assign_at(@classification, 58, ElnaLexerClass.digit); + _assign_at(@classification, 59, ElnaLexerClass.colon); + _assign_at(@classification, 60, ElnaLexerClass.single); + _assign_at(@classification, 61, ElnaLexerClass.less); + _assign_at(@classification, 62, ElnaLexerClass.equals); + _assign_at(@classification, 63, ElnaLexerClass.greater); + _assign_at(@classification, 64, ElnaLexerClass.other); + _assign_at(@classification, 65, ElnaLexerClass.single); + _assign_at(@classification, 66, ElnaLexerClass.alpha); + _assign_at(@classification, 67, ElnaLexerClass.alpha); + _assign_at(@classification, 68, ElnaLexerClass.alpha); + _assign_at(@classification, 69, ElnaLexerClass.alpha); + _assign_at(@classification, 70, ElnaLexerClass.alpha); + _assign_at(@classification, 71, ElnaLexerClass.alpha); + _assign_at(@classification, 72, ElnaLexerClass.alpha); + _assign_at(@classification, 73, ElnaLexerClass.alpha); + _assign_at(@classification, 74, ElnaLexerClass.alpha); + _assign_at(@classification, 75, ElnaLexerClass.alpha); + _assign_at(@classification, 76, ElnaLexerClass.alpha); + _assign_at(@classification, 77, ElnaLexerClass.alpha); + _assign_at(@classification, 78, ElnaLexerClass.alpha); + _assign_at(@classification, 79, ElnaLexerClass.alpha); + _assign_at(@classification, 80, ElnaLexerClass.alpha); + _assign_at(@classification, 81, ElnaLexerClass.alpha); + _assign_at(@classification, 82, ElnaLexerClass.alpha); + _assign_at(@classification, 83, ElnaLexerClass.alpha); + _assign_at(@classification, 84, ElnaLexerClass.alpha); + _assign_at(@classification, 85, ElnaLexerClass.alpha); + _assign_at(@classification, 86, ElnaLexerClass.alpha); + _assign_at(@classification, 87, ElnaLexerClass.alpha); + _assign_at(@classification, 88, ElnaLexerClass.alpha); + _assign_at(@classification, 89, ElnaLexerClass.alpha); + _assign_at(@classification, 90, ElnaLexerClass.alpha); + _assign_at(@classification, 91, ElnaLexerClass.alpha); + _assign_at(@classification, 92, ElnaLexerClass.single); + _assign_at(@classification, 93, ElnaLexerClass.backslash); + _assign_at(@classification, 94, ElnaLexerClass.single); + _assign_at(@classification, 95, ElnaLexerClass.single); + _assign_at(@classification, 96, ElnaLexerClass.alpha); + _assign_at(@classification, 97, ElnaLexerClass.other); + _assign_at(@classification, 98, ElnaLexerClass.hex); + _assign_at(@classification, 99, ElnaLexerClass.hex); + _assign_at(@classification, 100, ElnaLexerClass.hex); + _assign_at(@classification, 101, ElnaLexerClass.hex); + _assign_at(@classification, 102, ElnaLexerClass.hex); + _assign_at(@classification, 103, ElnaLexerClass.hex); + _assign_at(@classification, 104, ElnaLexerClass.alpha); + _assign_at(@classification, 105, ElnaLexerClass.alpha); + _assign_at(@classification, 106, ElnaLexerClass.alpha); + _assign_at(@classification, 107, ElnaLexerClass.alpha); + _assign_at(@classification, 108, ElnaLexerClass.alpha); + _assign_at(@classification, 109, ElnaLexerClass.alpha); + _assign_at(@classification, 110, ElnaLexerClass.alpha); + _assign_at(@classification, 111, ElnaLexerClass.alpha); + _assign_at(@classification, 112, ElnaLexerClass.alpha); + _assign_at(@classification, 113, ElnaLexerClass.alpha); + _assign_at(@classification, 114, ElnaLexerClass.alpha); + _assign_at(@classification, 115, ElnaLexerClass.alpha); + _assign_at(@classification, 116, ElnaLexerClass.alpha); + _assign_at(@classification, 117, ElnaLexerClass.alpha); + _assign_at(@classification, 118, ElnaLexerClass.alpha); + _assign_at(@classification, 119, ElnaLexerClass.alpha); + _assign_at(@classification, 120, ElnaLexerClass.alpha); + _assign_at(@classification, 121, ElnaLexerClass.x); + _assign_at(@classification, 122, ElnaLexerClass.alpha); + _assign_at(@classification, 123, ElnaLexerClass.alpha); + _assign_at(@classification, 124, ElnaLexerClass.other); + _assign_at(@classification, 125, ElnaLexerClass.single); + _assign_at(@classification, 126, ElnaLexerClass.other); + _assign_at(@classification, 127, ElnaLexerClass.single); + _assign_at(@classification, 128, ElnaLexerClass.invalid); code := 129; (* Set the remaining 129 - 256 bytes to transitionClassOther. *) .create_classification_loop; - _assign_at(@classification, code, LexerClass.other); + _assign_at(@classification, code, ElnaLexerClass.other); code := code + 1; if code < 257 then @@ -4415,7 +4782,7 @@ begin end end; -proc _lexer_get_transition(current_state: Word, character_class: Word); +proc _elna_lexer_get_transition(current_state: Word, character_class: Word); var transition_table: Word; row_position: Word; @@ -4430,7 +4797,7 @@ begin column_position := character_class - 1; column_position := column_position * 8; - target := _lexer_get_transition_table(); + target := _elna_lexer_get_transition_table(); target := target + row_position; return target + column_position @@ -4443,14 +4810,14 @@ end; * action - Action to assign. * next_state - Next state to assign. *) -proc _lexer_set_transition(current_state: Word, character_class: Word, action: Word, next_state: Word); +proc _elna_lexer_set_transition(current_state: Word, character_class: Word, action: Word, next_state: Word); var transition: Word; begin - transition := _lexer_get_transition(current_state, character_class); + transition := _elna_lexer_get_transition(current_state, character_class); - _lexer_transition_set_action(transition, action); - _lexer_transition_set_state(transition, next_state) + _elna_lexer_transition_set_action(transition, action); + _elna_lexer_transition_set_state(transition, next_state) end; (* Sets same action and state transition for all character classes in one transition row. *) @@ -4461,30 +4828,30 @@ end; * default_action - Default action (Callback). * next_state - Next state (Transition state enumeration). *) -proc _lexer_default_transition(current_state: Word, default_action: Word, next_state: Word); -begin - _lexer_set_transition(current_state, LexerClass.invalid, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.digit, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.alpha, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.space, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.colon, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.equals, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.left_paren, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.right_paren, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.asterisk, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.backslash, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.single, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.hex, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.zero, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.x, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.eof, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.dot, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.minus, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.single_quote, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.double_quote, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.greater, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.less, default_action, next_state); - _lexer_set_transition(current_state, LexerClass.other, default_action, next_state) +proc _elna_lexer_default_transition(current_state: Word, default_action: Word, next_state: Word); +begin + _elna_lexer_set_transition(current_state, ElnaLexerClass.invalid, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.digit, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.alpha, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.space, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.colon, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.equals, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.left_paren, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.right_paren, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.asterisk, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.backslash, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.single, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.hex, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.zero, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.x, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.eof, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.dot, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.minus, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.single_quote, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.double_quote, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.greater, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.less, default_action, next_state); + _elna_lexer_set_transition(current_state, ElnaLexerClass.other, default_action, next_state) end; (** @@ -4495,116 +4862,116 @@ end; * the amount of classes. So given the current state and a classified character * the table can be used to look up the next state. *) -proc _lexer_transitions(); +proc _elna_lexer_transitions(); begin (* Start state. *) - _lexer_set_transition(LexerState.start, LexerClass.invalid, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.start, LexerClass.digit, LexerAction.accumulate, LexerState.decimal); - _lexer_set_transition(LexerState.start, LexerClass.alpha, LexerAction.accumulate, LexerState.identifier); - _lexer_set_transition(LexerState.start, LexerClass.space, LexerAction.skip, LexerState.start); - _lexer_set_transition(LexerState.start, LexerClass.colon, LexerAction.accumulate, LexerState.colon); - _lexer_set_transition(LexerState.start, LexerClass.equals, LexerAction.single, LexerState.finish); - _lexer_set_transition(LexerState.start, LexerClass.left_paren, LexerAction.accumulate, LexerState.left_paren); - _lexer_set_transition(LexerState.start, LexerClass.right_paren, LexerAction.single, LexerState.finish); - _lexer_set_transition(LexerState.start, LexerClass.asterisk, LexerAction.single, LexerState.finish); - _lexer_set_transition(LexerState.start, LexerClass.backslash, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.start, LexerClass.single, LexerAction.single, LexerState.finish); - _lexer_set_transition(LexerState.start, LexerClass.hex, LexerAction.accumulate, LexerState.identifier); - _lexer_set_transition(LexerState.start, LexerClass.zero, LexerAction.accumulate, LexerState.leading_zero); - _lexer_set_transition(LexerState.start, LexerClass.x, LexerAction.accumulate, LexerState.identifier); - _lexer_set_transition(LexerState.start, LexerClass.eof, LexerAction.eof, LexerState.finish); - _lexer_set_transition(LexerState.start, LexerClass.dot, LexerAction.single, LexerState.finish); - _lexer_set_transition(LexerState.start, LexerClass.minus, LexerAction.accumulate, LexerState.minus); - _lexer_set_transition(LexerState.start, LexerClass.single_quote, LexerAction.accumulate, LexerState.character); - _lexer_set_transition(LexerState.start, LexerClass.double_quote, LexerAction.accumulate, LexerState.string); - _lexer_set_transition(LexerState.start, LexerClass.greater, LexerAction.accumulate, LexerState.greater); - _lexer_set_transition(LexerState.start, LexerClass.less, LexerAction.accumulate, LexerState.less); - _lexer_set_transition(LexerState.start, LexerClass.other, LexerAction.none, LexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.invalid, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.digit, ElnaLexerAction.accumulate, ElnaLexerState.decimal); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.alpha, ElnaLexerAction.accumulate, ElnaLexerState.identifier); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.space, ElnaLexerAction.skip, ElnaLexerState.start); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.colon, ElnaLexerAction.accumulate, ElnaLexerState.colon); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.equals, ElnaLexerAction.single, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.left_paren, ElnaLexerAction.accumulate, ElnaLexerState.left_paren); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.right_paren, ElnaLexerAction.single, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.asterisk, ElnaLexerAction.single, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.backslash, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.single, ElnaLexerAction.single, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.hex, ElnaLexerAction.accumulate, ElnaLexerState.identifier); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.zero, ElnaLexerAction.accumulate, ElnaLexerState.leading_zero); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.x, ElnaLexerAction.accumulate, ElnaLexerState.identifier); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.eof, ElnaLexerAction.eof, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.dot, ElnaLexerAction.single, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.minus, ElnaLexerAction.accumulate, ElnaLexerState.minus); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.single_quote, ElnaLexerAction.accumulate, ElnaLexerState.character); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.double_quote, ElnaLexerAction.accumulate, ElnaLexerState.string); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.greater, ElnaLexerAction.accumulate, ElnaLexerState.greater); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.less, ElnaLexerAction.accumulate, ElnaLexerState.less); + _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.other, ElnaLexerAction.none, ElnaLexerState.finish); (* Colon state. *) - _lexer_default_transition(LexerState.colon, LexerAction.finalize, LexerState.finish); - _lexer_set_transition(LexerState.colon, LexerClass.equals, LexerAction.composite, LexerState.finish); + _elna_lexer_default_transition(ElnaLexerState.colon, ElnaLexerAction.finalize, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.colon, ElnaLexerClass.equals, ElnaLexerAction.composite, ElnaLexerState.finish); (* Identifier state. *) - _lexer_default_transition(LexerState.identifier, LexerAction.key_id, LexerState.finish); - _lexer_set_transition(LexerState.identifier, LexerClass.digit, LexerAction.accumulate, LexerState.identifier); - _lexer_set_transition(LexerState.identifier, LexerClass.alpha, LexerAction.accumulate, LexerState.identifier); - _lexer_set_transition(LexerState.identifier, LexerClass.hex, LexerAction.accumulate, LexerState.identifier); - _lexer_set_transition(LexerState.identifier, LexerClass.zero, LexerAction.accumulate, LexerState.identifier); - _lexer_set_transition(LexerState.identifier, LexerClass.x, LexerAction.accumulate, LexerState.identifier); + _elna_lexer_default_transition(ElnaLexerState.identifier, ElnaLexerAction.key_id, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.identifier, ElnaLexerClass.digit, ElnaLexerAction.accumulate, ElnaLexerState.identifier); + _elna_lexer_set_transition(ElnaLexerState.identifier, ElnaLexerClass.alpha, ElnaLexerAction.accumulate, ElnaLexerState.identifier); + _elna_lexer_set_transition(ElnaLexerState.identifier, ElnaLexerClass.hex, ElnaLexerAction.accumulate, ElnaLexerState.identifier); + _elna_lexer_set_transition(ElnaLexerState.identifier, ElnaLexerClass.zero, ElnaLexerAction.accumulate, ElnaLexerState.identifier); + _elna_lexer_set_transition(ElnaLexerState.identifier, ElnaLexerClass.x, ElnaLexerAction.accumulate, ElnaLexerState.identifier); (* Decimal state. *) - _lexer_default_transition(LexerState.decimal, LexerAction.integer, LexerState.finish); - _lexer_set_transition(LexerState.decimal, LexerClass.digit, LexerAction.accumulate, LexerState.decimal); - _lexer_set_transition(LexerState.decimal, LexerClass.alpha, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.decimal, LexerClass.hex, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.decimal, LexerClass.zero, LexerAction.accumulate, LexerState.decimal); - _lexer_set_transition(LexerState.decimal, LexerClass.x, LexerAction.none, LexerState.finish); + _elna_lexer_default_transition(ElnaLexerState.decimal, ElnaLexerAction.integer, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.decimal, ElnaLexerClass.digit, ElnaLexerAction.accumulate, ElnaLexerState.decimal); + _elna_lexer_set_transition(ElnaLexerState.decimal, ElnaLexerClass.alpha, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.decimal, ElnaLexerClass.hex, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.decimal, ElnaLexerClass.zero, ElnaLexerAction.accumulate, ElnaLexerState.decimal); + _elna_lexer_set_transition(ElnaLexerState.decimal, ElnaLexerClass.x, ElnaLexerAction.none, ElnaLexerState.finish); (* Leading zero. *) - _lexer_default_transition(LexerState.leading_zero, LexerAction.integer, LexerState.finish); - _lexer_set_transition(LexerState.leading_zero, LexerClass.digit, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.leading_zero, LexerClass.alpha, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.leading_zero, LexerClass.hex, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.leading_zero, LexerClass.zero, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.leading_zero, LexerClass.x, LexerAction.none, LexerState.dot); + _elna_lexer_default_transition(ElnaLexerState.leading_zero, ElnaLexerAction.integer, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.leading_zero, ElnaLexerClass.digit, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.leading_zero, ElnaLexerClass.alpha, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.leading_zero, ElnaLexerClass.hex, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.leading_zero, ElnaLexerClass.zero, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.leading_zero, ElnaLexerClass.x, ElnaLexerAction.none, ElnaLexerState.dot); (* Greater state. *) - _lexer_default_transition(LexerState.greater, LexerAction.finalize, LexerState.finish); - _lexer_set_transition(LexerState.greater, LexerClass.equals, LexerAction.composite, LexerState.finish); + _elna_lexer_default_transition(ElnaLexerState.greater, ElnaLexerAction.finalize, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.greater, ElnaLexerClass.equals, ElnaLexerAction.composite, ElnaLexerState.finish); (* Minus state. *) - _lexer_default_transition(LexerState.minus, LexerAction.finalize, LexerState.finish); - _lexer_set_transition(LexerState.minus, LexerClass.greater, LexerAction.composite, LexerState.finish); + _elna_lexer_default_transition(ElnaLexerState.minus, ElnaLexerAction.finalize, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.minus, ElnaLexerClass.greater, ElnaLexerAction.composite, ElnaLexerState.finish); (* Left paren state. *) - _lexer_default_transition(LexerState.left_paren, LexerAction.finalize, LexerState.finish); - _lexer_set_transition(LexerState.left_paren, LexerClass.asterisk, LexerAction.accumulate, LexerState.comment); + _elna_lexer_default_transition(ElnaLexerState.left_paren, ElnaLexerAction.finalize, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.left_paren, ElnaLexerClass.asterisk, ElnaLexerAction.accumulate, ElnaLexerState.comment); (* Less state. *) - _lexer_default_transition(LexerState.less, LexerAction.finalize, LexerState.finish); - _lexer_set_transition(LexerState.less, LexerClass.equals, LexerAction.composite, LexerState.finish); - _lexer_set_transition(LexerState.less, LexerClass.greater, LexerAction.composite, LexerState.finish); + _elna_lexer_default_transition(ElnaLexerState.less, ElnaLexerAction.finalize, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.less, ElnaLexerClass.equals, ElnaLexerAction.composite, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.less, ElnaLexerClass.greater, ElnaLexerAction.composite, ElnaLexerState.finish); (* Hexadecimal after 0x. *) - _lexer_default_transition(LexerState.dot, LexerAction.finalize, LexerState.finish); - _lexer_set_transition(LexerState.dot, LexerClass.dot, LexerAction.composite, LexerState.finish); + _elna_lexer_default_transition(ElnaLexerState.dot, ElnaLexerAction.finalize, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.dot, ElnaLexerClass.dot, ElnaLexerAction.composite, ElnaLexerState.finish); (* Comment. *) - _lexer_default_transition(LexerState.comment, LexerAction.accumulate, LexerState.comment); - _lexer_set_transition(LexerState.comment, LexerClass.asterisk, LexerAction.accumulate, LexerState.closing_comment); - _lexer_set_transition(LexerState.comment, LexerClass.eof, LexerAction.none, LexerState.finish); + _elna_lexer_default_transition(ElnaLexerState.comment, ElnaLexerAction.accumulate, ElnaLexerState.comment); + _elna_lexer_set_transition(ElnaLexerState.comment, ElnaLexerClass.asterisk, ElnaLexerAction.accumulate, ElnaLexerState.closing_comment); + _elna_lexer_set_transition(ElnaLexerState.comment, ElnaLexerClass.eof, ElnaLexerAction.none, ElnaLexerState.finish); (* Closing comment. *) - _lexer_default_transition(LexerState.closing_comment, LexerAction.accumulate, LexerState.comment); - _lexer_set_transition(LexerState.closing_comment, LexerClass.invalid, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.closing_comment, LexerClass.right_paren, LexerAction.delimited, LexerState.finish); - _lexer_set_transition(LexerState.closing_comment, LexerClass.asterisk, LexerAction.accumulate, LexerState.closing_comment); - _lexer_set_transition(LexerState.closing_comment, LexerClass.eof, LexerAction.none, LexerState.finish); + _elna_lexer_default_transition(ElnaLexerState.closing_comment, ElnaLexerAction.accumulate, ElnaLexerState.comment); + _elna_lexer_set_transition(ElnaLexerState.closing_comment, ElnaLexerClass.invalid, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.closing_comment, ElnaLexerClass.right_paren, ElnaLexerAction.delimited, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.closing_comment, ElnaLexerClass.asterisk, ElnaLexerAction.accumulate, ElnaLexerState.closing_comment); + _elna_lexer_set_transition(ElnaLexerState.closing_comment, ElnaLexerClass.eof, ElnaLexerAction.none, ElnaLexerState.finish); (* Character. *) - _lexer_default_transition(LexerState.character, LexerAction.accumulate, LexerState.character); - _lexer_set_transition(LexerState.character, LexerClass.invalid, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.character, LexerClass.eof, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.character, LexerClass.single_quote, LexerAction.delimited, LexerState.finish); - _lexer_set_transition(LexerState.character, LexerClass.backslash, LexerAction.accumulate, LexerState.character_escape); + _elna_lexer_default_transition(ElnaLexerState.character, ElnaLexerAction.accumulate, ElnaLexerState.character); + _elna_lexer_set_transition(ElnaLexerState.character, ElnaLexerClass.invalid, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.character, ElnaLexerClass.eof, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.character, ElnaLexerClass.single_quote, ElnaLexerAction.delimited, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.character, ElnaLexerClass.backslash, ElnaLexerAction.accumulate, ElnaLexerState.character_escape); (* Escape sequence in a character. *) - _lexer_default_transition(LexerState.character_escape, LexerAction.accumulate, LexerState.character); - _lexer_set_transition(LexerState.character_escape, LexerClass.invalid, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.character_escape, LexerClass.eof, LexerAction.none, LexerState.finish); + _elna_lexer_default_transition(ElnaLexerState.character_escape, ElnaLexerAction.accumulate, ElnaLexerState.character); + _elna_lexer_set_transition(ElnaLexerState.character_escape, ElnaLexerClass.invalid, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.character_escape, ElnaLexerClass.eof, ElnaLexerAction.none, ElnaLexerState.finish); (* String. *) - _lexer_default_transition(LexerState.string, LexerAction.accumulate, LexerState.string); - _lexer_set_transition(LexerState.string, LexerClass.invalid, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.string, LexerClass.eof, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.string, LexerClass.double_quote, LexerAction.delimited, LexerState.finish); - _lexer_set_transition(LexerState.string, LexerClass.backslash, LexerAction.accumulate, LexerState.string_escape); + _elna_lexer_default_transition(ElnaLexerState.string, ElnaLexerAction.accumulate, ElnaLexerState.string); + _elna_lexer_set_transition(ElnaLexerState.string, ElnaLexerClass.invalid, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.string, ElnaLexerClass.eof, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.string, ElnaLexerClass.double_quote, ElnaLexerAction.delimited, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.string, ElnaLexerClass.backslash, ElnaLexerAction.accumulate, ElnaLexerState.string_escape); (* Escape sequence in a string. *) - _lexer_default_transition(LexerState.string_escape, LexerAction.accumulate, LexerState.string); - _lexer_set_transition(LexerState.string_escape, LexerClass.invalid, LexerAction.none, LexerState.finish); - _lexer_set_transition(LexerState.string_escape, LexerClass.eof, LexerAction.none, LexerState.finish) + _elna_lexer_default_transition(ElnaLexerState.string_escape, ElnaLexerAction.accumulate, ElnaLexerState.string); + _elna_lexer_set_transition(ElnaLexerState.string_escape, ElnaLexerClass.invalid, ElnaLexerAction.none, ElnaLexerState.finish); + _elna_lexer_set_transition(ElnaLexerState.string_escape, ElnaLexerClass.eof, ElnaLexerAction.none, ElnaLexerState.finish) end; (** @@ -4612,7 +4979,7 @@ end; * Each character entry is 1 word long and there are 256 characters. * 1024 = 256 * 4 *) -proc _lexer_get_transition_table(); +proc _elna_lexer_get_transition_table(); return @classification + 1024 end; @@ -4621,78 +4988,74 @@ end; * Each transition table entry is 8 bytes long. The table has 16 rows (transition states) * and 22 columns (character classes), so 2992 = 8 * 17 * 22. *) -proc _lexer_global_state(); +proc _elna_lexer_global_state(); var result: Word; begin - result := _lexer_get_transition_table(); + result := _elna_lexer_get_transition_table(); return result + 2992 end; (** * Gets pointer to the token start. *) -proc _lexer_global_get_start(); +proc _elna_lexer_global_get_start(); var target: Word; begin - target := _lexer_global_state(); - target := target + 4; + target := _elna_lexer_global_state() + 4; return target^ end; (** * Sets pointer to the token start. *) -proc _lexer_global_set_start(new_start: Word); +proc _elna_lexer_global_set_start(new_start: Word); var target: Word; begin - target := _lexer_global_state(); - target := target + 4; + target := _elna_lexer_global_state() + 4; target^ := new_start end; (** * Gets pointer to the token end. *) -proc _lexer_global_get_end(); +proc _elna_lexer_global_get_end(); var target: Word; begin - target := _lexer_global_state(); - target := target + 8; + target := _elna_lexer_global_state() + 8; return target^ end; (** * Sets pointer to the token end. *) -proc _lexer_global_set_end(new_start: Word); +proc _elna_lexer_global_set_end(new_start: Word); var target: Word; begin - target := _lexer_global_state(); - target := target + 8; + target := _elna_lexer_global_state() + 8; target^ := new_start end; -proc _lexer_transition_get_action(this: Word); +proc _elna_lexer_transition_get_action(this: Word); return this^ end; -proc _lexer_transition_set_action(this: Word, value: Word); +proc _elna_lexer_transition_set_action(this: Word, value: Word); begin this^ := value end; -proc _lexer_transition_get_state(this: Word); +proc _elna_lexer_transition_get_state(this: Word); begin this := this + 4; return this^ end; -proc _lexer_transition_set_state(this: Word, value: Word); +proc _elna_lexer_transition_set_state(this: Word, value: Word); begin this := this + 4; this^ := value @@ -4701,48 +5064,48 @@ end; (** * Resets the lexer state for reading the next token. *) -proc _lexer_reset(); +proc _elna_lexer_reset(); var state: Word; begin (* Transition start state is 1. *) - state := _lexer_global_state(); - state^ := LexerState.start; + state := _elna_lexer_global_state(); + state^ := ElnaLexerState.start; - state := _lexer_global_get_start(); - _lexer_global_set_end(state) + state := _elna_lexer_global_get_start(); + _elna_lexer_global_set_end(state) end; (** * One time lexer initialization. *) -proc _lexer_initialize(code_pointer: Word); +proc _elna_lexer_initialize(code_pointer: Word); begin - _lexer_classifications(); - _lexer_transitions(); + _elna_lexer_classifications(); + _elna_lexer_transitions(); - _lexer_global_set_start(code_pointer); - _lexer_global_set_end(code_pointer) + _elna_lexer_global_set_start(code_pointer); + _elna_lexer_global_set_end(code_pointer) end; -proc _lexer_next_transition(); +proc _elna_lexer_next_transition(); var current_character: Word; character_class: Word; current_state: Word; begin - current_character := _lexer_global_get_end(); + current_character := _elna_lexer_global_get_end(); current_character := _load_byte(current_character); character_class := _get_at(@classification, current_character + 1); - current_state := _lexer_global_state(); + current_state := _elna_lexer_global_state(); current_state := current_state^; - return _lexer_get_transition(current_state, character_class) + return _elna_lexer_get_transition(current_state, character_class) end; -proc _lexer_compare_keyword(lhs_pointer: Word, lhs_length: Word, rhs_pointer: Word, rhs_length: Word); +proc _string_compare(lhs_pointer: Word, lhs_length: Word, rhs_pointer: Word, rhs_length: Word); var result: Word; begin @@ -4755,49 +5118,51 @@ begin return result end; -proc _lexer_classify_keyword(position_start: Word, position_end: Word); +proc _elna_lexer_classify_keyword(position_start: Word, position_end: Word); var result: Word; token_length: Word; begin - result := LexerTokenKind.identifier; + result := ElnaLexerKind.identifier; token_length := position_end - position_start; - if _lexer_compare_keyword(position_start, token_length, "const", 5) then - result := LexerTokenKind._const - elsif _lexer_compare_keyword(position_start, token_length, "var", 3) then - result := LexerTokenKind._var - elsif _lexer_compare_keyword(position_start, token_length, "proc", 4) then - result := LexerTokenKind._proc - elsif _lexer_compare_keyword(position_start, token_length, "type", 4) then - result := LexerTokenKind._type - elsif _lexer_compare_keyword(position_start, token_length, "begin", 5) then - result := LexerTokenKind._begin - elsif _lexer_compare_keyword(position_start, token_length, "end", 3) then - result := LexerTokenKind._end - elsif _lexer_compare_keyword(position_start, token_length, "return", 6) then - result := LexerTokenKind._return - elsif _lexer_compare_keyword(position_start, token_length, "goto", 4) then - result := LexerTokenKind._goto - elsif _lexer_compare_keyword(position_start, token_length, "if", 2) then - result := LexerTokenKind._if - elsif _lexer_compare_keyword(position_start, token_length, "while", 5) then - result := LexerTokenKind._while - elsif _lexer_compare_keyword(position_start, token_length, "then", 4) then - result := LexerTokenKind._then - elsif _lexer_compare_keyword(position_start, token_length, "else", 4) then - result := LexerTokenKind._else - elsif _lexer_compare_keyword(position_start, token_length, "elsif", 5) then - result := LexerTokenKind._elsif - elsif _lexer_compare_keyword(position_start, token_length, "or", 2) then - result := LexerTokenKind._or - elsif _lexer_compare_keyword(position_start, token_length, "xor", 2) then - result := LexerTokenKind._xor + if _string_compare(position_start, token_length, "const", 5) then + result := ElnaLexerKind._const + elsif _string_compare(position_start, token_length, "var", 3) then + result := ElnaLexerKind._var + elsif _string_compare(position_start, token_length, "proc", 4) then + result := ElnaLexerKind._proc + elsif _string_compare(position_start, token_length, "type", 4) then + result := ElnaLexerKind._type + elsif _string_compare(position_start, token_length, "begin", 5) then + result := ElnaLexerKind._begin + elsif _string_compare(position_start, token_length, "end", 3) then + result := ElnaLexerKind._end + elsif _string_compare(position_start, token_length, "return", 6) then + result := ElnaLexerKind._return + elsif _string_compare(position_start, token_length, "goto", 4) then + result := ElnaLexerKind._goto + elsif _string_compare(position_start, token_length, "if", 2) then + result := ElnaLexerKind._if + elsif _string_compare(position_start, token_length, "while", 5) then + result := ElnaLexerKind._while + elsif _string_compare(position_start, token_length, "then", 4) then + result := ElnaLexerKind._then + elsif _string_compare(position_start, token_length, "else", 4) then + result := ElnaLexerKind._else + elsif _string_compare(position_start, token_length, "elsif", 5) then + result := ElnaLexerKind._elsif + elsif _string_compare(position_start, token_length, "record", 6) then + result := ElnaLexerKind._record + elsif _string_compare(position_start, token_length, "or", 2) then + result := ElnaLexerKind._or + elsif _string_compare(position_start, token_length, "xor", 2) then + result := ElnaLexerKind._xor end; return result end; -proc _lexer_classify_finalize(start_position: Word); +proc _elna_lexer_classify_finalize(start_position: Word); var character: Word; result: Word; @@ -4806,22 +5171,22 @@ begin character := _load_byte(start_position); if character = ':' then - result := LexerTokenKind.colon + result := ElnaLexerKind.colon elsif character = '.' then - result := LexerTokenKind.dot + result := ElnaLexerKind.dot elsif character = '(' then - result := LexerTokenKind.left_paren + result := ElnaLexerKind.left_paren elsif character = '-' then - result := LexerTokenKind.minus + result := ElnaLexerKind.minus elsif character = '<' then - result := LexerTokenKind.less_than + result := ElnaLexerKind.less_than elsif character = '>' then - result := LexerTokenKind.greater_than + result := ElnaLexerKind.greater_than end; return result end; -proc _lexer_classify_single(start_position: Word); +proc _elna_lexer_classify_single(start_position: Word); var character: Word; result: Word; @@ -4830,36 +5195,36 @@ begin character := _load_byte(start_position); if character = ';' then - result := LexerTokenKind.semicolon + result := ElnaLexerKind.semicolon elsif character = ',' then - result := LexerTokenKind.comma + result := ElnaLexerKind.comma elsif character = ')' then - result := LexerTokenKind.right_paren + result := ElnaLexerKind.right_paren elsif character = '@' then - result := LexerTokenKind.at + result := ElnaLexerKind.at elsif character = '~' then - result := LexerTokenKind.not + result := ElnaLexerKind.not elsif character = '&' then - result := LexerTokenKind.and + result := ElnaLexerKind.and elsif character = '+' then - result := LexerTokenKind.plus + result := ElnaLexerKind.plus elsif character = '*' then - result := LexerTokenKind.multiplication + result := ElnaLexerKind.multiplication elsif character = '=' then - result := LexerTokenKind.equals + result := ElnaLexerKind.equals elsif character = '%' then - result := LexerTokenKind.remainder + result := ElnaLexerKind.remainder elsif character = '/' then - result := LexerTokenKind.division + result := ElnaLexerKind.division elsif character = '.' then - result := LexerTokenKind.dot + result := ElnaLexerKind.dot elsif character = '^' then - result := LexerTokenKind.hat + result := ElnaLexerKind.hat end; return result end; -proc _lexer_classify_composite(start_position: Word, one_before_last: Word); +proc _elna_lexer_classify_composite(start_position: Word, one_before_last: Word); var first_character: Word; last_character: Word; @@ -4869,23 +5234,23 @@ begin last_character := _load_byte(one_before_last); if first_character = ':' then - result := LexerTokenKind.assignment + result := ElnaLexerKind.assignment elsif first_character = '<' then if last_character = '=' then - result := LexerTokenKind.less_equal + result := ElnaLexerKind.less_equal elsif last_character = '>' then - result := LexerTokenKind.not_equal + result := ElnaLexerKind.not_equal end elsif first_character = '>' then if last_character = '=' then - result := LexerTokenKind.greater_equal + result := ElnaLexerKind.greater_equal end end; return result end; -proc _lexer_classify_delimited(start_position: Word, end_position: Word); +proc _elna_lexer_classify_delimited(start_position: Word, end_position: Word); var token_length: Word; delimiter: Word; @@ -4895,112 +5260,111 @@ begin delimiter := _load_byte(start_position); if delimiter = '(' then - result := LexerTokenKind.comment + result := ElnaLexerKind.comment elsif delimiter = '\'' then - result := LexerTokenKind.character + result := ElnaLexerKind.character elsif delimiter = '"' then - result := LexerTokenKind.string + result := ElnaLexerKind.string end; return result end; -proc _lexer_classify_integer(start_position: Word, end_position: Word); -begin - return LexerTokenKind.integer +proc _elna_lexer_classify_integer(start_position: Word, end_position: Word); + return ElnaLexerKind.integer end; -proc _lexer_execute_action(action_to_perform: Word, kind: Word); +proc _elna_lexer_execute_action(action_to_perform: Word, kind: Word); var position_start: Word; position_end: Word; intermediate: Word; begin - position_start := _lexer_global_get_start(); - position_end := _lexer_global_get_end(); + position_start := _elna_lexer_global_get_start(); + position_end := _elna_lexer_global_get_end(); - if action_to_perform = LexerAction.none then - elsif action_to_perform = LexerAction.accumulate then - _lexer_global_set_end(position_end + 1) - elsif action_to_perform = LexerAction.skip then - _lexer_global_set_start(position_start + 1); - _lexer_global_set_end(position_end + 1) - elsif action_to_perform = LexerAction.single then - _lexer_global_set_end(position_end + 1); + if action_to_perform = ElnaLexerAction.none then + elsif action_to_perform = ElnaLexerAction.accumulate then + _elna_lexer_global_set_end(position_end + 1) + elsif action_to_perform = ElnaLexerAction.skip then + _elna_lexer_global_set_start(position_start + 1); + _elna_lexer_global_set_end(position_end + 1) + elsif action_to_perform = ElnaLexerAction.single then + _elna_lexer_global_set_end(position_end + 1); - intermediate := _lexer_classify_single(position_start); + intermediate := _elna_lexer_classify_single(position_start); kind^ := intermediate - elsif action_to_perform = LexerAction.eof then - intermediate := LexerTokenKind.eof; + elsif action_to_perform = ElnaLexerAction.eof then + intermediate := ElnaLexerKind.eof; kind^ := intermediate - elsif action_to_perform = LexerAction.finalize then - intermediate := _lexer_classify_finalize(position_start); + elsif action_to_perform = ElnaLexerAction.finalize then + intermediate := _elna_lexer_classify_finalize(position_start); kind^ := intermediate - elsif action_to_perform = LexerAction.composite then - _lexer_global_set_end(position_end + 1); + elsif action_to_perform = ElnaLexerAction.composite then + _elna_lexer_global_set_end(position_end + 1); - intermediate := _lexer_classify_composite(position_start, position_end); + intermediate := _elna_lexer_classify_composite(position_start, position_end); kind^ := intermediate - elsif action_to_perform = LexerAction.key_id then - intermediate := _lexer_classify_keyword(position_start, position_end); + elsif action_to_perform = ElnaLexerAction.key_id then + intermediate := _elna_lexer_classify_keyword(position_start, position_end); kind^ := intermediate - elsif action_to_perform = LexerAction.integer then - intermediate := _lexer_classify_integer(position_start, position_end); + elsif action_to_perform = ElnaLexerAction.integer then + intermediate := _elna_lexer_classify_integer(position_start, position_end); kind^ := intermediate - elsif action_to_perform = LexerAction.delimited then - _lexer_global_set_end(position_end + 1); + elsif action_to_perform = ElnaLexerAction.delimited then + _elna_lexer_global_set_end(position_end + 1); - intermediate := _lexer_classify_delimited(position_start, position_end + 1); + intermediate := _elna_lexer_classify_delimited(position_start, position_end + 1); kind^ := intermediate - end; + end end; -proc _lexer_execute_transition(kind: Word); +proc _elna_lexer_execute_transition(kind: Word); var next_transition: Word; next_state: Word; global_state: Word; action_to_perform: Word; begin - next_transition := _lexer_next_transition(); - next_state := _lexer_transition_get_state(next_transition); - action_to_perform := _lexer_transition_get_action(next_transition); + next_transition := _elna_lexer_next_transition(); + next_state := _elna_lexer_transition_get_state(next_transition); + action_to_perform := _elna_lexer_transition_get_action(next_transition); - global_state := _lexer_global_state(); + global_state := _elna_lexer_global_state(); global_state^ := next_state; - _lexer_execute_action(action_to_perform, kind); + _elna_lexer_execute_action(action_to_perform, kind); return next_state end; -proc _lexer_advance_token(kind: Word); +proc _elna_lexer_advance_token(kind: Word); var result_state: Word; begin - result_state := _lexer_execute_transition(kind); - if result_state <> LexerState.finish then - _lexer_advance_token(kind) + result_state := _elna_lexer_execute_transition(kind); + if result_state <> ElnaLexerState.finish then + _elna_lexer_advance_token(kind) end end; (** * Reads the next token and writes its type into the address in the kind parameter. *) -proc _lexer_read_token(kind: Word); +proc _elna_lexer_read_token(kind: Word); begin - _lexer_reset(); - _lexer_advance_token(kind) + _elna_lexer_reset(); + _elna_lexer_advance_token(kind) end; (** * Advances the token stream past the last read token. *) -proc _lexer_skip_token(); +proc _elna_lexer_skip_token(); var old_end: Word; begin - old_end := _lexer_global_get_end(); - _lexer_global_set_start(old_end) + old_end := _elna_lexer_global_get_end(); + _elna_lexer_global_set_start(old_end) end; proc _initialize_global_state(); @@ -5020,7 +5384,7 @@ var offset: Word; begin _initialize_global_state(); - _lexer_initialize(source_code); + _elna_lexer_initialize(source_code); _symbol_table_build(); (* Read the source from the standard input. *) -- cgit v1.2.3