From 9cf052dfebd2c5d62d26d5b46a0d8881d82a7a43 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 28 Feb 2026 22:41:26 +0100 Subject: [PATCH] Pass lexer state explicitly --- boot/stage19/cl.elna | 5 +- boot/stage20/cl.elna | 1086 +++++++++++++++++++++--------------------- 2 files changed, 545 insertions(+), 546 deletions(-) diff --git a/boot/stage19/cl.elna b/boot/stage19/cl.elna index 76ee09b..ed2937d 100644 --- a/boot/stage19/cl.elna +++ b/boot/stage19/cl.elna @@ -8,6 +8,7 @@ program; (* Stage 19 compiler. *) (* - Aggregates can be allocated on the stack. *) +(* - Procedure return type is parsed. *) type (** @@ -3565,7 +3566,9 @@ begin _elna_lexer_skip_token(); if token_kind = ElnaLexerKind.arrow then - result^.return_type := elna_parser_type_expression() + result^.return_type := elna_parser_type_expression(); + _elna_lexer_read_token(@token_kind); + _elna_lexer_skip_token() else result^.return_type := nil end; diff --git a/boot/stage20/cl.elna b/boot/stage20/cl.elna index 3938ca5..d47c418 100644 --- a/boot/stage20/cl.elna +++ b/boot/stage20/cl.elna @@ -318,10 +318,31 @@ type end; ElnaLexerAction = (none, accumulate, skip, single, eof, finalize, composite, key_id, integer, delimited); + ElnaLexerState = ( + start, + colon, + identifier, + decimal, + leading_zero, + greater, + minus, + left_paren, + less, + dot, + comment, + closing_comment, + character, + character_escape, + string, + string_escape, + number_sign, + trait, + finish + ); ElnaLexerTransition = record action: ElnaLexerAction; - next_state: Word + next_state: ElnaLexerState end; (** * Classification table assigns each possible character to a group (class). All @@ -352,27 +373,6 @@ type other, number_sign ); - ElnaLexerState = ( - start, - colon, - identifier, - decimal, - leading_zero, - greater, - minus, - left_paren, - less, - dot, - comment, - closing_comment, - character, - character_escape, - string, - string_escape, - number_sign, - trait, - finish - ); ElnaLexerKind = ( identifier, _const, @@ -443,6 +443,11 @@ type start: Word; finish: Word end; + ElnaLexerToken = record + kind: ElnaLexerKind; + start: Word; + length: Word + end; ElnaTacOperator = ( get_address, @@ -618,8 +623,6 @@ var * and 23 columns (character classes), so 3496 = 8 * 19 * 23. *) transition_table: [19][23]ElnaLexerTransition; - lexer_state: ElnaLexerCursor; - word_type: ^ElnaType; source_code: Word; @@ -1655,19 +1658,19 @@ begin _write_c('\n'); end; -proc elna_parser_integer_literal(); +proc elna_parser_integer_literal(cursor: ^ElnaLexerCursor); var integer_length: Word; result: ^ElnaTreeIntegerLiteral; buffer: Word; begin result := malloc(#size(ElnaTreeIntegerLiteral)); - integer_length := lexer_state.finish - lexer_state.start; + integer_length := cursor^.finish - cursor^.start; buffer := malloc(integer_length + 1); bzero(buffer, integer_length + 1); - memcpy(buffer, lexer_state.start, integer_length); - _elna_lexer_skip_token(); + memcpy(buffer, cursor^.start, integer_length); + elna_lexer_skip_token(cursor); result^.kind := ElnaTreeKind.integer_literal; result^.value := atoi(buffer); @@ -1676,26 +1679,26 @@ begin return result end; -proc elna_parser_boolean_literal(); +proc elna_parser_boolean_literal(cursor: ^ElnaLexerCursor); var result: ^ElnaTreeBooleanLiteral; begin result := malloc(#size(ElnaTreeBooleanLiteral)); result^.kind := ElnaTreeKind.boolean_literal; - result^.value := string_compare(lexer_state.start, 4, "true", 4); + result^.value := string_compare(cursor^.start, 4, "true", 4); result^.type_decoration := nil; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); return result end; -proc elna_parser_nil_literal(); +proc elna_parser_nil_literal(cursor: ^ElnaLexerCursor); var result: ^ElnaTreeNilLiteral; begin - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); result := malloc(#size(ElnaTreeNilLiteral)); result^.kind := ElnaTreeKind.null; @@ -1725,17 +1728,17 @@ begin operand^.length := 0 end; -proc elna_parser_character_literal(); +proc elna_parser_character_literal(cursor: ^ElnaLexerCursor); var result: ^ElnaTreeCharacterLiteral; begin result := malloc(#size(ElnaTreeCharacterLiteral)); result^.kind := ElnaTreeKind.character_literal; - result^.value := lexer_state.start; - result^.length := lexer_state.finish - lexer_state.start; + result^.value := cursor^.start; + result^.length := cursor^.finish - cursor^.start; result^.type_decoration := nil; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); return result end; @@ -1747,18 +1750,18 @@ begin operand^.length := character_literal_node^.length end; -proc elna_parser_variable_expression(); +proc elna_parser_variable_expression(cursor: ^ElnaLexerCursor); var result: ^ElnaTreeVariableExpression; begin result := malloc(#size(ElnaTreeVariableExpression)); result^.kind := ElnaTreeKind.variable_expression; - result^.name := lexer_state.start; - result^.length := lexer_state.finish - lexer_state.start; + result^.name := cursor^.start; + result^.length := cursor^.finish - cursor^.start; result^.type_decoration := nil; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); return result end; @@ -1781,18 +1784,18 @@ begin end end; -proc elna_parser_string_literal(); +proc elna_parser_string_literal(cursor: ^ElnaLexerCursor); var result: ^ElnaTreeStringLiteral; begin result := malloc(#size(ElnaTreeStringLiteral)); result^.kind := ElnaTreeKind.string_literal; - result^.value := lexer_state.start; - result^.length := lexer_state.finish - lexer_state.start; + result^.value := cursor^.start; + result^.length := cursor^.finish - cursor^.start; result^.type_decoration := nil; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); return result end; @@ -1820,57 +1823,56 @@ begin elna_list_append(instructions, instruction) end; -proc elna_parser_trait_expression(); +proc elna_parser_trait_expression(cursor: ^ElnaLexerCursor); var result: ^ElnaTreeTraitExpression; - token_kind: Word; begin result := malloc(#size(ElnaTreeTraitExpression)); result^.kind := ElnaTreeKind.trait_expression; - result^.name := lexer_state.start; - result^.length := lexer_state.finish - lexer_state.start; + result^.name := cursor^.start; + result^.length := cursor^.finish - cursor^.start; - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); - result^.argument := elna_parser_type_expression(); + result^.argument := elna_parser_type_expression(cursor); - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); return result end; -proc elna_parser_simple_expression(); +proc elna_parser_simple_expression(cursor: ^ElnaLexerCursor); var current_character: Word; parser_node: Word; - token_kind: Word; + token: ^ElnaLexerToken; begin parser_node := 0; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - 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.boolean then - parser_node := elna_parser_boolean_literal() - elsif token_kind = ElnaLexerKind.null then - parser_node := elna_parser_nil_literal() - elsif token_kind = ElnaLexerKind.trait then - parser_node := elna_parser_trait_expression() - elsif token_kind = ElnaLexerKind.identifier then - parser_node := elna_parser_variable_expression() + if token^.kind = ElnaLexerKind.character then + parser_node := elna_parser_character_literal(cursor) + elsif token^.kind = ElnaLexerKind.integer then + parser_node := elna_parser_integer_literal(cursor) + elsif token^.kind = ElnaLexerKind.string then + parser_node := elna_parser_string_literal(cursor) + elsif token^.kind = ElnaLexerKind.boolean then + parser_node := elna_parser_boolean_literal(cursor) + elsif token^.kind = ElnaLexerKind.null then + parser_node := elna_parser_nil_literal(cursor) + elsif token^.kind = ElnaLexerKind.trait then + parser_node := elna_parser_trait_expression(cursor) + elsif token^.kind = ElnaLexerKind.identifier then + parser_node := elna_parser_variable_expression(cursor) end; return parser_node end; -proc elna_parser_dereference_expression(simple_expression: Word); +proc elna_parser_dereference_expression(cursor: ^ElnaLexerCursor, simple_expression: Word); var result: ^ElnaTreeDereferenceExpression; begin @@ -1879,32 +1881,32 @@ begin result^.kind := ElnaTreeKind.dereference_expression; result^.pointer := simple_expression; result^.type_decoration := nil; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); return result end; -proc elna_parser_designator(); +proc elna_parser_designator(cursor: ^ElnaLexerCursor); var simple_expression: Word; - token_kind: Word; + token: ^ElnaLexerToken; begin - simple_expression := elna_parser_simple_expression(); + simple_expression := elna_parser_simple_expression(cursor); .elna_parser_designator_loop; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - if token_kind = ElnaLexerKind.hat then - simple_expression := elna_parser_dereference_expression(simple_expression); + if token^.kind = ElnaLexerKind.hat then + simple_expression := elna_parser_dereference_expression(cursor, simple_expression); goto elna_parser_designator_loop - elsif token_kind = ElnaLexerKind.dot then - simple_expression := elna_parser_field_access_expression(simple_expression); + elsif token^.kind = ElnaLexerKind.dot then + simple_expression := elna_parser_field_access_expression(cursor, simple_expression); goto elna_parser_designator_loop - elsif token_kind = ElnaLexerKind.left_square then - simple_expression := elna_parser_array_access_expression(simple_expression); + elsif token^.kind = ElnaLexerKind.left_square then + simple_expression := elna_parser_array_access_expression(cursor, simple_expression); goto elna_parser_designator_loop - elsif token_kind = ElnaLexerKind.left_paren then - simple_expression := elna_parser_call(simple_expression); + elsif token^.kind = ElnaLexerKind.left_paren then + simple_expression := elna_parser_call(cursor, simple_expression); goto elna_parser_designator_loop end; return simple_expression @@ -1945,27 +1947,27 @@ begin end end; -proc elna_parser_unary_expression(); +proc elna_parser_unary_expression(cursor: ^ElnaLexerCursor); var - token_kind: Word; result: ^ElnaTreeUnaryExpression; operand: Word; operator: Word; + token: ^ElnaLexerToken; begin - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); operator := 0; - if token_kind = ElnaLexerKind.at then + if token^.kind = ElnaLexerKind.at then operator := '@' - elsif token_kind = ElnaLexerKind.minus then + elsif token^.kind = ElnaLexerKind.minus then operator := '-' - elsif token_kind = ElnaLexerKind.not then + elsif token^.kind = ElnaLexerKind.not then operator := '~' end; if operator <> 0 then - _elna_lexer_skip_token() + elna_lexer_skip_token(cursor) end; - result := elna_parser_designator(); + result := elna_parser_designator(cursor); if operator <> 0 then operand := result; @@ -2038,69 +2040,65 @@ begin elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction) else - (* Debug - printf("# Here %i %.*s\n\0", base.value, base.length, base.value); - fflush(nil); *) - operand^.kind := base.kind; operand^.value := base.value; operand^.length := base.length end end; -proc elna_parser_binary_expression(); +proc elna_parser_binary_expression(cursor: ^ElnaLexerCursor); var lhs_node: Word; rhs_node: Word; - token_kind: Word; result: ^ElnaTreeBinaryExpression; + token: ^ElnaLexerToken; begin - lhs_node := elna_parser_unary_expression(); + lhs_node := elna_parser_unary_expression(cursor); rhs_node := 0; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - 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() + if token^.kind = ElnaLexerKind.plus then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.minus then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.multiplication then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.and then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind._or then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind._xor then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.equals then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.remainder then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.division then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.less_than then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.greater_than then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.less_equal then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.not_equal then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) + elsif token^.kind = ElnaLexerKind.greater_equal then + elna_lexer_skip_token(cursor); + rhs_node := elna_parser_unary_expression(cursor) end; if rhs_node <> 0 then result := malloc(#size(ElnaTreeBinaryExpression)); @@ -2108,7 +2106,7 @@ begin result^.kind := ElnaTreeKind.binary_expression; result^.lhs := lhs_node; result^.rhs := rhs_node; - result^.operator := token_kind; + result^.operator := token^.kind; result^.type_decoration := nil else result := lhs_node @@ -2168,12 +2166,12 @@ begin return instructions^.first end; -proc elna_parser_call(callee: Word); +proc elna_parser_call(cursor: ^ElnaLexerCursor, callee: Word); var result: ^ElnaTreeCall; argument_number: Word; - token_kind: Word; argument_entry: ^ElnaTreeExpressionList; + token: ^ElnaLexerToken; begin result := malloc(#size(ElnaTreeCall)); result^.kind := ElnaTreeKind.call; @@ -2183,12 +2181,12 @@ begin argument_number := 1; result^.callee := callee; - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); + token := elna_lexer_read_token(cursor); - if token_kind = ElnaLexerKind.right_paren then - _elna_lexer_skip_token(); + if token^.kind = ElnaLexerKind.right_paren then + elna_lexer_skip_token(cursor); goto elna_parser_call_end end; @@ -2201,13 +2199,13 @@ begin argument_entry := argument_entry^.next end; argument_entry^.next := nil; - argument_entry^.expression := elna_parser_binary_expression(); + argument_entry^.expression := elna_parser_binary_expression(cursor); argument_number := argument_number + 1; - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + token := elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); - if token_kind = ElnaLexerKind.comma then + if token^.kind = ElnaLexerKind.comma then goto elna_parser_call_loop end; @@ -2248,21 +2246,20 @@ begin elna_list_append(instructions, call_instruction) end; -proc elna_parser_goto_statement(); +proc elna_parser_goto_statement(cursor: ^ElnaLexerCursor); var - token_kind: Word; result: ^ElnaTreeGotoStatement; begin - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); result := malloc(#size(ElnaTreeGotoStatement)); result^.kind := ElnaTreeKind.goto_statement; result^.next := nil; - result^.label := lexer_state.start; - result^.length := lexer_state.finish - lexer_state.start; + result^.label := cursor^.start; + result^.length := cursor^.finish - cursor^.start; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); return result end; @@ -2284,22 +2281,21 @@ begin elna_list_append(instructions, instruction) end; -proc elna_parser_label_declaration(); +proc elna_parser_label_declaration(cursor: ^ElnaLexerCursor); var - token_kind: Word; result: ^ElnaTreeGotoStatement; begin - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); result := malloc(#size(ElnaTreeLabelDeclaration)); result^.kind := ElnaTreeKind.label_declaration; result^.next := nil; - result^.label := lexer_state.start; - result^.length := lexer_state.finish - lexer_state.start; + result^.label := cursor^.start; + result^.length := cursor^.finish - cursor^.start; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); return result end; @@ -2328,8 +2324,6 @@ begin enumeration_type := symbol_info^._type; members := enumeration_type^.members; members_length := enumeration_type^.length; - - _elna_lexer_read_token(@token_type); counter := 1; .elna_tac_enumeration_value_members; @@ -2351,44 +2345,42 @@ begin end end; -proc elna_parser_field_access_expression(aggregate: Word); +proc elna_parser_field_access_expression(cursor: ^ElnaLexerCursor, aggregate: Word); var - token_kind: Word; result: ^ElnaTreeFieldAccessExpression; begin (* Skip dot. Read the enumeration value. *) - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); result := malloc(#size(ElnaTreeFieldAccessExpression)); result^.kind := ElnaTreeKind.field_access_expression; result^.type_decoration := nil; result^.aggregate := aggregate; - result^.field := lexer_state.start; - result^.length := lexer_state.finish - lexer_state.start; + result^.field := cursor^.start; + result^.length := cursor^.finish - cursor^.start; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); return result end; -proc elna_parser_array_access_expression(array: Word); +proc elna_parser_array_access_expression(cursor: ^ElnaLexerCursor, array: Word); var - token_kind: Word; result: ^ElnaTreeArrayAccessExpression; begin - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); result := malloc(#size(ElnaTreeArrayAccessExpression)); result^.kind := ElnaTreeKind.array_access_expression; result^.type_decoration := nil; result^.array := array; - result^.index := elna_parser_binary_expression(); + result^.index := elna_parser_binary_expression(cursor); - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); return result end; @@ -2527,10 +2519,9 @@ begin elna_list_append(instructions, instruction) end; -proc elna_parser_assign_statement(assignee: Word); +proc elna_parser_assign_statement(cursor: ^ElnaLexerCursor, assignee: Word); var result: ^ElnaTreeAssignStatement; - token_kind: Word; begin result := malloc(#size(ElnaTreeAssignStatement)); @@ -2539,10 +2530,10 @@ begin result^.assignee := assignee; (* Skip the assignment sign (:=) with surrounding whitespaces. *) - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); - result^.assignment := elna_parser_binary_expression(); + result^.assignment := elna_parser_binary_expression(cursor); return result end; @@ -2603,18 +2594,17 @@ begin end end; -proc elna_parser_return_statement(); +proc elna_parser_return_statement(cursor: ^ElnaLexerCursor); var - token_kind: Word; returned: Word; label_length: Word; result: ^ElnaTreeReturnStatement; begin (* Skip "return" keyword and whitespace after it. *) - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); - returned := elna_parser_binary_expression(); + returned := elna_parser_binary_expression(cursor); result := malloc(#size(ElnaTreeReturnStatement)); result^.kind := ElnaTreeKind.return_statement; @@ -2654,20 +2644,19 @@ begin fflush(nil) end; -proc elna_parser_conditional_statements(); +proc elna_parser_conditional_statements(cursor: ^ElnaLexerCursor); var - token_kind: Word; result: ^ElnaTreeConditionalStatements; begin result := malloc(#size(ElnaTreeConditionalStatements)); (* Skip "if", "while" or "elsif". *) - _elna_lexer_skip_token(); - result^.condition := elna_parser_binary_expression(); + elna_lexer_skip_token(cursor); + result^.condition := elna_parser_binary_expression(cursor); (* Skip "then" or "do". *) - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); result^.statements := elna_parser_statements(); result^.next := nil; @@ -2703,89 +2692,89 @@ begin elna_tac_label(instructions, condition_label, 0) end; -proc elna_parser_if_statement(); +proc elna_parser_if_statement(cursor: ^ElnaLexerCursor); var result: ^ElnaTreeIfStatement; - token_kind: Word; previous_conditional: ^ElnaTreeConditionalStatements; next_conditional: ^ElnaTreeConditionalStatements; + token: ^ElnaLexerToken; begin result := malloc(#size(ElnaTreeIfStatement)); result^.kind := ElnaTreeKind.if_statement; result^.next := nil; - previous_conditional := elna_parser_conditional_statements(); + previous_conditional := elna_parser_conditional_statements(cursor); result^.conditionals := previous_conditional; .elna_parser_if_statement_loop; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - if token_kind = ElnaLexerKind._elsif then - next_conditional := elna_parser_conditional_statements(); + if token^.kind = ElnaLexerKind._elsif then + next_conditional := elna_parser_conditional_statements(cursor); previous_conditional^.next := next_conditional; previous_conditional = next_conditional; goto elna_parser_if_statement_loop - elsif token_kind = ElnaLexerKind._else then - _elna_lexer_skip_token(); + elsif token^.kind = ElnaLexerKind._else then + elna_lexer_skip_token(cursor); result^._else := elna_parser_statements() else result^._else := nil end; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); return result end; -proc elna_parser_statement(); +proc elna_parser_statement(cursor: ^ElnaLexerCursor); var - token_kind: Word; result : ^ElnaTreeNode; + token: ^ElnaLexerToken; begin result := nil; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - 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 token^.kind = ElnaLexerKind._goto then + result := elna_parser_goto_statement(cursor) + elsif token^.kind = ElnaLexerKind._if then + result := elna_parser_if_statement(cursor) + elsif token^.kind = ElnaLexerKind._return then + result := elna_parser_return_statement(cursor) + elsif token^.kind = ElnaLexerKind.dot then + result := elna_parser_label_declaration(cursor) + elsif token^.kind = ElnaLexerKind.identifier then + result := elna_parser_designator(cursor); if result^.kind <> ElnaTreeKind.call then - result := elna_parser_assign_statement(result) + result := elna_parser_assign_statement(cursor, result) end end; return result end; -proc elna_parser_statements(); +proc elna_parser_statements(cursor: ^ElnaLexerCursor); var - token_kind: Word; previous_statement: ^ElnaTreeStatement; next_statement: ^ElnaTreeStatement; first_statement: ^ElnaTreeStatement; + token: ^ElnaLexerToken; begin - _skip_empty_lines(); + elna_lexer_skip_empty_lines(cursor); - first_statement := elna_parser_statement(); + first_statement := elna_parser_statement(cursor); previous_statement := first_statement; if previous_statement = 0 then goto elna_parser_statements_end end; .elna_parser_statement_loop; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - if token_kind = ElnaLexerKind.semicolon then - _elna_lexer_skip_token(); - _skip_empty_lines(); - next_statement := elna_parser_statement(); + if token^.kind = ElnaLexerKind.semicolon then + elna_lexer_skip_token(cursor); + elna_lexer_skip_empty_lines(cursor); + next_statement := elna_parser_statement(cursor); previous_statement^.next := next_statement; previous_statement := next_statement; @@ -2794,7 +2783,7 @@ begin end end; .elna_parser_statements_end; - _skip_empty_lines(); + elna_lexer_skip_empty_lines(cursor); return first_statement end; @@ -2871,40 +2860,40 @@ begin _write_c(register_number + '0') end; -proc elna_parser_record_type_expression(); +proc elna_parser_record_type_expression(cursor: ^ElnaLexerCursor); var entry: Word; member_count: Word; memory_start: Word; field_type: Word; - token_kind: Word; result: ^ElnaTreeEnumerationTypeExpression; previous_entry: Word; + token: ^ElnaLexerToken; begin - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); member_count := 0; memory_start := 0; - _elna_lexer_read_token(@token_kind); - if token_kind = ElnaLexerKind._end then + token := elna_lexer_read_token(cursor); + if token^.kind = ElnaLexerKind._end then goto elna_parser_record_type_expression_end end; .elna_parser_record_type_expression_loop; entry := malloc(16); member_count := member_count + 1; - entry^ := lexer_state.start; + entry^ := cursor^.start; entry := entry + 4; - entry^ := lexer_state.finish - lexer_state.start; + entry^ := cursor^.finish - cursor^.start; entry := entry + 4; (* Skip the identifier. *) - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); - field_type := elna_parser_type_expression(); + field_type := elna_parser_type_expression(cursor); entry^ := field_type; entry := entry + 4; @@ -2917,15 +2906,15 @@ begin 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); + token := elna_lexer_read_token(cursor); + if token^.kind = ElnaLexerKind.semicolon then + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); goto elna_parser_record_type_expression_loop end; .elna_parser_record_type_expression_end; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); result := malloc(#size(ElnaTreeEnumerationTypeExpression)); @@ -2936,31 +2925,31 @@ begin return result end; -proc elna_parser_enumeration_type_expression(); +proc elna_parser_enumeration_type_expression(cursor: ^ElnaLexerCursor); var - token_kind: Word; memory_start: Word; member_count: Word; result: ^ElnaTreeEnumerationTypeExpression; entry: Word; previous_entry: Word; + token: ^ElnaLexerToken; begin - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); memory_start := 0; member_count := 0; - _elna_lexer_read_token(@token_kind); - if token_kind = ElnaLexerKind.right_paren then + token := elna_lexer_read_token(cursor); + if token^.kind = ElnaLexerKind.right_paren then goto elna_parser_enumeration_type_expression_end end; .elna_parser_enumeration_type_expression_loop; entry := malloc(12); member_count := member_count + 1; - entry^ := lexer_state.start; + entry^ := cursor^.start; entry := entry + 4; - entry^ := lexer_state.finish - lexer_state.start; + entry^ := cursor^.finish - cursor^.start; entry := entry + 4; entry^ := 0; @@ -2972,17 +2961,17 @@ begin previous_entry := entry; (* Skip the identifier. *) - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); - _elna_lexer_read_token(@token_kind); - if token_kind = ElnaLexerKind.comma then - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); + if token^.kind = ElnaLexerKind.comma then + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); goto elna_parser_enumeration_type_expression_loop end; .elna_parser_enumeration_type_expression_end; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); result := malloc(#size(ElnaTreeEnumerationTypeExpression)); @@ -3125,71 +3114,70 @@ begin return result end; -proc elna_parser_named_type_expression(); +proc elna_parser_named_type_expression(cursor: ^ElnaLexerCursor); var result: ^ElnaTreeNamedTypeExpression; begin result := malloc(#size(ElnaTreeNamedTypeExpression)); result^.kind := ElnaTreeKind.named_type_expression; - result^.name := lexer_state.start; - result^.length := lexer_state.finish - lexer_state.start; - _elna_lexer_skip_token(); + result^.name := cursor^.start; + result^.length := cursor^.finish - cursor^.start; + elna_lexer_skip_token(cursor); return result end; -proc elna_parser_pointer_type_expression(); +proc elna_parser_pointer_type_expression(cursor: ^ElnaLexerCursor); var result: ^ElnaTreePointerTypeExpression; begin - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); result := malloc(#size(ElnaTreePointerTypeExpression)); result^.kind := ElnaTreeKind.pointer_type_expression; - result^.base := elna_parser_type_expression(); + result^.base := elna_parser_type_expression(cursor); return result end; -proc elna_parser_array_type_expression(); +proc elna_parser_array_type_expression(cursor: ^ElnaLexerCursor); var result: ^ElnaTreeArrayTypeExpression; - token_kind: Word; begin - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); result := malloc(#size(ElnaTreeArrayTypeExpression)); result^.kind := ElnaTreeKind.array_type_expression; - result^.length := elna_parser_binary_expression(); + result^.length := elna_parser_binary_expression(cursor); (* Read and skip square bracket. *) - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); - result^.base := elna_parser_type_expression(); + result^.base := elna_parser_type_expression(cursor); return result end; -proc elna_parser_type_expression(); +proc elna_parser_type_expression(cursor: ^ElnaLexerCursor); var - token_kind: Word; result: Word; + token: ^ElnaLexerToken; begin result := nil; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - 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() - elsif token_kind = ElnaLexerKind.hat then - result := elna_parser_pointer_type_expression() - elsif token_kind = ElnaLexerKind.left_square then - result := elna_parser_array_type_expression() + if token^.kind = ElnaLexerKind.identifier then + result := elna_parser_named_type_expression(cursor) + elsif token^.kind = ElnaLexerKind.left_paren then + result := elna_parser_enumeration_type_expression(cursor) + elsif token^.kind = ElnaLexerKind._record then + result := elna_parser_record_type_expression(cursor) + elsif token^.kind = ElnaLexerKind.hat then + result := elna_parser_pointer_type_expression(cursor) + elsif token^.kind = ElnaLexerKind.left_square then + result := elna_parser_array_type_expression(cursor) end; return result end; @@ -3290,13 +3278,13 @@ begin end end; -proc elna_parser_procedure_declaration(); +proc elna_parser_procedure_declaration(cursor: ^ElnaLexerCursor); var next_declaration: ^ElnaTreeDeclaration; current_declaration: ^ElnaTreeDeclaration; - token_kind: Word; result: ^ElnaTreeProcedureDeclaration; parameter_head: ^ElnaTreeDeclaration; + token: ^ElnaLexerToken; begin result := malloc(#size(ElnaTreeProcedureDeclaration)); @@ -3304,25 +3292,25 @@ begin result^.next := nil; (* Skip "proc ". *) - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); - _elna_lexer_read_token(@token_kind); + elna_lexer_read_token(cursor); - result^.name := lexer_state.start; - result^.length := lexer_state.finish - lexer_state.start; + result^.name := cursor^.start; + result^.length := cursor^.finish - cursor^.start; (* Skip procedure name. *) - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); (* Skip open paren. *) - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); parameter_head := nil; .elna_parser_procedure_declaration_parameter; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - if token_kind <> ElnaLexerKind.right_paren then - next_declaration := elna_parser_variable_declaration(); + if token^.kind <> ElnaLexerKind.right_paren then + next_declaration := elna_parser_variable_declaration(cursor); if parameter_head = nil then parameter_head := next_declaration else @@ -3330,43 +3318,45 @@ begin end; current_declaration := next_declaration; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - if token_kind = ElnaLexerKind.comma then - _elna_lexer_skip_token(); + if token^.kind = ElnaLexerKind.comma then + elna_lexer_skip_token(cursor); goto elna_parser_procedure_declaration_parameter end end; (* Skip close paren. *) - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); result^.parameters := parameter_head; (* Skip semicolon or arrow. *) - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + token := elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); - if token_kind = ElnaLexerKind.arrow then - result^.return_type := elna_parser_type_expression() + if token^.kind = ElnaLexerKind.arrow then + result^.return_type := elna_parser_type_expression(cursor); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor) else result^.return_type := nil end; - parameter_head := elna_parser_var_part(); + parameter_head := elna_parser_var_part(cursor); result^.temporaries := parameter_head; (* Skip semicolon, "begin" and newline. *) - _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() + token := elna_lexer_read_token(cursor); + if token^.kind = ElnaLexerKind._begin then + elna_lexer_skip_token(cursor); + parameter_head := elna_parser_statements(cursor) + elsif token^.kind = ElnaLexerKind._return then + parameter_head := elna_parser_return_statement(cursor) end; result^.body := parameter_head; (* Skip the "end" keyword. *) - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); return result end; @@ -3558,21 +3548,21 @@ begin return result end; -proc elna_parser_procedures(); +proc elna_parser_procedures(cursor: ^ElnaLexerCursor); var parser_node: ^ElnaTreeDeclaration; result: ^ElnaTreeDeclaration; current_declaration: ^ElnaTreeDeclaration; - token_kind: Word; + token: ^ElnaLexerToken; begin result := nil; .elna_parser_procedures_loop; - _skip_empty_lines(); - _elna_lexer_read_token(@token_kind); + elna_lexer_skip_empty_lines(cursor); + token := elna_lexer_read_token(cursor); - if token_kind = ElnaLexerKind._proc then - parser_node := elna_parser_procedure_declaration(); + if token^.kind = ElnaLexerKind._proc then + parser_node := elna_parser_procedure_declaration(cursor); if result = 0 then result := parser_node else @@ -3581,8 +3571,8 @@ begin current_declaration := parser_node; (* Skip semicolon. *) - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); goto elna_parser_procedures_loop end; @@ -3675,34 +3665,33 @@ end; (** * Skips comments. *) -proc _skip_empty_lines(); +proc elna_lexer_skip_empty_lines(cursor: ^ElnaLexerCursor); var - token_kind: Word; + token: ^ElnaLexerToken; begin .skip_empty_lines_rerun; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - if token_kind = ElnaLexerKind.comment then - _elna_lexer_skip_token(); + if token^.kind = ElnaLexerKind.comment then + elna_lexer_skip_token(cursor); goto skip_empty_lines_rerun end end; -proc elna_parser_type_declaration(); +proc elna_parser_type_declaration(cursor: ^ElnaLexerCursor); var - token_kind: Word; type_name: Word; name_length: Word; result: ^ElnaTreeTypeDeclaration; begin - _elna_lexer_read_token(@token_kind); - type_name := lexer_state.start; - name_length := lexer_state.finish - lexer_state.start; + elna_lexer_read_token(cursor); + type_name := cursor^.start; + name_length := cursor^.finish - cursor^.start; - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); result := malloc(#size(ElnaTreeTypeDeclaration)); @@ -3710,10 +3699,10 @@ begin result^.next := nil; result^.name := type_name; result^.length := name_length; - result^._type := elna_parser_type_expression(); + result^._type := elna_parser_type_expression(cursor); - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); return result end; @@ -3738,28 +3727,28 @@ proc elna_type_type_declaration(parser_node: Word); begin end; -proc elna_parser_type_part(); +proc elna_parser_type_part(cursor: ^ElnaLexerCursor); var - token_kind: Word; parser_node: ^ElnaTreeDeclaration; result: ^ElnaTreeDeclaration; current_declaration: ^ElnaTreeDeclaration; + token: ^ElnaLexerToken; begin result := nil; - _skip_empty_lines(); - _elna_lexer_read_token(@token_kind); + elna_lexer_skip_empty_lines(cursor); + token := elna_lexer_read_token(cursor); - if token_kind <> ElnaLexerKind._type then + if token^.kind <> ElnaLexerKind._type then goto elna_parser_type_part_end end; - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); .elna_parser_type_part_loop; - _skip_empty_lines(); + elna_lexer_skip_empty_lines(cursor); - _elna_lexer_read_token(@token_kind); - if token_kind = ElnaLexerKind.identifier then - parser_node := elna_parser_type_declaration(); + token := elna_lexer_read_token(cursor); + if token^.kind = ElnaLexerKind.identifier then + parser_node := elna_parser_type_declaration(cursor); if result = nil then result := parser_node @@ -3774,25 +3763,24 @@ begin return result end; -proc elna_parser_variable_declaration(); +proc elna_parser_variable_declaration(cursor: ^ElnaLexerCursor); var - token_kind: Word; name: Word; name_length: Word; variable_type: Word; result: ^ElnaTreeVariableDeclaration; begin - _elna_lexer_read_token(@token_kind); + elna_lexer_read_token(cursor); - name := lexer_state.start; - name_length := lexer_state.finish - lexer_state.start; + name := cursor^.start; + name_length := cursor^.finish - cursor^.start; (* Skip the variable name and colon with the type. *) - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); - variable_type := elna_parser_type_expression(); + variable_type := elna_parser_type_expression(cursor); result := malloc(#size(ElnaTreeVariableDeclaration)); result^.kind := ElnaTreeKind.variable_declaration; @@ -3820,32 +3808,32 @@ begin return result end; -proc elna_parser_var_part(); +proc elna_parser_var_part(cursor: ^ElnaLexerCursor); var result: Word; - token_kind: Word; variable_node: Word; current_declaration: ^ElnaTreeDeclaration; + token: ^ElnaLexerToken; begin result := 0; - _elna_lexer_read_token(@token_kind); + token := elna_lexer_read_token(cursor); - if token_kind <> ElnaLexerKind._var then + if token^.kind <> ElnaLexerKind._var then goto elna_parser_var_part_end end; (* Skip "var". *) - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); .elna_parser_var_part_loop; - _skip_empty_lines(); - _elna_lexer_read_token(@token_kind); + elna_lexer_skip_empty_lines(cursor); + token := elna_lexer_read_token(cursor); - if token_kind = ElnaLexerKind.identifier then - variable_node := elna_parser_variable_declaration(); + if token^.kind = ElnaLexerKind.identifier then + variable_node := elna_parser_variable_declaration(cursor); (* Skip semicolon. *) - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); if result = 0 then result := variable_node @@ -3889,34 +3877,34 @@ begin return first_variable end; -proc elna_parser_module_declaration(error_list: ^ElnaList); +proc elna_parser_module_declaration(cursor: ^ElnaLexerCursor, error_list: ^ElnaList); var parser_node: Word; result: ^ElnaTreeModuleDeclaration; - token_kind: Word; parser_error: ^ElnaError; + token: ^ElnaLexerToken; begin result := malloc(#size(ElnaTreeModuleDeclaration)); result^.kind := ElnaTreeKind.module_declaration; (* Skip "program;". *) - _skip_empty_lines(); - _elna_lexer_read_token(@token_kind); + elna_lexer_skip_empty_lines(cursor); + token := elna_lexer_read_token(cursor); - if token_kind <> ElnaLexerKind._program then + if token^.kind <> ElnaLexerKind._program then parser_error := malloc(#size(ElnaError)); parser_error^.next := nil; error_list^.first := parser_error; error_list^.last := parser_error else - _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); - _elna_lexer_skip_token(); + elna_lexer_skip_token(cursor); + elna_lexer_read_token(cursor); + elna_lexer_skip_token(cursor); - result^.types := elna_parser_type_part(); - result^.globals := elna_parser_var_part(); - result^.procedures := elna_parser_procedures() + result^.types := elna_parser_type_part(cursor); + result^.globals := elna_parser_var_part(cursor); + result^.procedures := elna_parser_procedures(cursor) end; return result end; @@ -4277,7 +4265,7 @@ begin end end; -proc _compile(); +proc _compile(cursor: ^ElnaLexerCursor); var parser_node: Word; tac: Word; @@ -4287,7 +4275,7 @@ var begin elna_list_initialize(@error_list); - parser_node := elna_parser_module_declaration(@error_list); + parser_node := elna_parser_module_declaration(cursor, @error_list); compiled := error_list.first = nil; if compiled then @@ -4435,7 +4423,7 @@ end; (** * Initializes the array with character classes. *) -proc _elna_lexer_classifications(); +proc elna_lexer_classifications(); var code: Word; begin @@ -4580,7 +4568,7 @@ begin end end; -proc _elna_lexer_get_transition(current_state: Word, character_class: Word); +proc elna_lexer_get_transition(current_state: Word, character_class: Word); var column_position: Word; target: Word; @@ -4602,11 +4590,11 @@ end; * action - Action to assign. * next_state - Next state to assign. *) -proc _elna_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: ElnaLexerState); var transition: ^ElnaLexerTransition; begin - transition := _elna_lexer_get_transition(current_state, character_class); + transition := elna_lexer_get_transition(current_state, character_class); transition^.action := action; transition^.next_state := next_state @@ -4620,31 +4608,31 @@ end; * default_action - Default action (Callback). * next_state - Next state (Transition state enumeration). *) -proc _elna_lexer_default_transition(current_state: Word, default_action: Word, next_state: Word); +proc elna_lexer_default_transition(current_state: Word, default_action: Word, next_state: ElnaLexerState); 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); - _elna_lexer_set_transition(current_state, ElnaLexerClass.number_sign, default_action, next_state) + 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); + elna_lexer_set_transition(current_state, ElnaLexerClass.number_sign, default_action, next_state) end; (** @@ -4655,152 +4643,152 @@ 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 _elna_lexer_transitions(); +proc elna_lexer_transitions(); begin (* Start state. *) - _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); - _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.number_sign, ElnaLexerAction.accumulate, ElnaLexerState.number_sign); + 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); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.number_sign, ElnaLexerAction.accumulate, ElnaLexerState.number_sign); (* Colon state. *) - _elna_lexer_default_transition(ElnaLexerState.colon, ElnaLexerAction.finalize, ElnaLexerState.finish); - _elna_lexer_set_transition(ElnaLexerState.colon, ElnaLexerClass.equals, ElnaLexerAction.composite, ElnaLexerState.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. *) - _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); + 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. *) - _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); + 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. *) - _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); + 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. *) - _elna_lexer_default_transition(ElnaLexerState.greater, ElnaLexerAction.finalize, ElnaLexerState.finish); - _elna_lexer_set_transition(ElnaLexerState.greater, ElnaLexerClass.equals, ElnaLexerAction.composite, ElnaLexerState.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. *) - _elna_lexer_default_transition(ElnaLexerState.minus, ElnaLexerAction.finalize, ElnaLexerState.finish); - _elna_lexer_set_transition(ElnaLexerState.minus, ElnaLexerClass.greater, ElnaLexerAction.composite, ElnaLexerState.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. *) - _elna_lexer_default_transition(ElnaLexerState.left_paren, ElnaLexerAction.finalize, ElnaLexerState.finish); - _elna_lexer_set_transition(ElnaLexerState.left_paren, ElnaLexerClass.asterisk, ElnaLexerAction.accumulate, ElnaLexerState.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. *) - _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); + 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. *) - _elna_lexer_default_transition(ElnaLexerState.dot, ElnaLexerAction.finalize, ElnaLexerState.finish); - _elna_lexer_set_transition(ElnaLexerState.dot, ElnaLexerClass.dot, ElnaLexerAction.composite, ElnaLexerState.finish); + elna_lexer_default_transition(ElnaLexerState.dot, ElnaLexerAction.finalize, ElnaLexerState.finish); + elna_lexer_set_transition(ElnaLexerState.dot, ElnaLexerClass.dot, ElnaLexerAction.composite, ElnaLexerState.finish); (* Comment. *) - _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); + 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. *) - _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); + 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. *) - _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); + 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. *) - _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); + 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. *) - _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); + 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. *) - _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); + 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); (* Number sign state. *) - _elna_lexer_default_transition(ElnaLexerState.number_sign, ElnaLexerAction.key_id, ElnaLexerState.finish); - _elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.alpha, ElnaLexerAction.accumulate, ElnaLexerState.trait); - _elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.hex, ElnaLexerAction.accumulate, ElnaLexerState.trait); - _elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.x, ElnaLexerAction.accumulate, ElnaLexerState.trait); + elna_lexer_default_transition(ElnaLexerState.number_sign, ElnaLexerAction.key_id, ElnaLexerState.finish); + elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.alpha, ElnaLexerAction.accumulate, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.hex, ElnaLexerAction.accumulate, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.x, ElnaLexerAction.accumulate, ElnaLexerState.trait); (* Trait state. *) - _elna_lexer_default_transition(ElnaLexerState.trait, ElnaLexerAction.key_id, ElnaLexerState.finish); - _elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.digit, ElnaLexerAction.accumulate, ElnaLexerState.trait); - _elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.alpha, ElnaLexerAction.accumulate, ElnaLexerState.trait); - _elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.hex, ElnaLexerAction.accumulate, ElnaLexerState.trait); - _elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.zero, ElnaLexerAction.accumulate, ElnaLexerState.trait); - _elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.x, ElnaLexerAction.accumulate, ElnaLexerState.trait) + elna_lexer_default_transition(ElnaLexerState.trait, ElnaLexerAction.key_id, ElnaLexerState.finish); + elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.digit, ElnaLexerAction.accumulate, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.alpha, ElnaLexerAction.accumulate, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.hex, ElnaLexerAction.accumulate, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.zero, ElnaLexerAction.accumulate, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.x, ElnaLexerAction.accumulate, ElnaLexerState.trait) end; (** * One time lexer initialization. *) -proc _elna_lexer_initialize(code_pointer: Word); +proc elna_lexer_initialize(cursor: ^ElnaLexerCursor, code_pointer: Word); begin - _elna_lexer_classifications(); - _elna_lexer_transitions(); + elna_lexer_classifications(); + elna_lexer_transitions(); - lexer_state.start := code_pointer; - lexer_state.finish := code_pointer + cursor^.start := code_pointer; + cursor^.finish := code_pointer end; -proc _elna_lexer_next_transition(); +proc elna_lexer_next_transition(cursor: ^ElnaLexerCursor); var current_character: Word; begin - current_character := _load_byte(lexer_state.finish); + current_character := _load_byte(cursor^.finish); - return _elna_lexer_get_transition(lexer_state.state, classification[current_character + 1]) + return elna_lexer_get_transition(cursor^.state, classification[current_character + 1]) end; proc string_compare(lhs_pointer: Word, lhs_length: Word, rhs_pointer: Word, rhs_length: Word); @@ -4989,94 +4977,101 @@ proc elna_lexer_classify_integer(start_position: Word, end_position: Word); return ElnaLexerKind.integer end; -proc _elna_lexer_execute_action(action_to_perform: Word, kind: Word); +proc elna_lexer_execute_action(cursor: ^ElnaLexerCursor, action_to_perform: Word, kind: ^ElnaLexerKind); var intermediate: Word; begin if action_to_perform = ElnaLexerAction.none then elsif action_to_perform = ElnaLexerAction.accumulate then - lexer_state.finish := lexer_state.finish + 1 + cursor^.finish := cursor^.finish + 1 elsif action_to_perform = ElnaLexerAction.skip then - lexer_state.start := lexer_state.start + 1; - lexer_state.finish := lexer_state.finish + 1 + cursor^.start := cursor^.start + 1; + cursor^.finish := cursor^.finish + 1 elsif action_to_perform = ElnaLexerAction.single then - lexer_state.finish := lexer_state.finish + 1; + cursor^.finish := cursor^.finish + 1; - intermediate := elna_lexer_classify_single(lexer_state.start); + intermediate := elna_lexer_classify_single(cursor^.start); kind^ := intermediate elsif action_to_perform = ElnaLexerAction.eof then intermediate := ElnaLexerKind.eof; kind^ := intermediate elsif action_to_perform = ElnaLexerAction.finalize then - intermediate := elna_lexer_classify_finalize(lexer_state.start); + intermediate := elna_lexer_classify_finalize(cursor^.start); kind^ := intermediate elsif action_to_perform = ElnaLexerAction.composite then - intermediate := elna_lexer_classify_composite(lexer_state.start, lexer_state.finish); + intermediate := elna_lexer_classify_composite(cursor^.start, cursor^.finish); kind^ := intermediate; - lexer_state.finish := lexer_state.finish + 1 + cursor^.finish := cursor^.finish + 1 elsif action_to_perform = ElnaLexerAction.key_id then - intermediate := elna_lexer_classify_keyword(lexer_state.start, lexer_state.finish); + intermediate := elna_lexer_classify_keyword(cursor^.start, cursor^.finish); kind^ := intermediate elsif action_to_perform = ElnaLexerAction.integer then - intermediate := elna_lexer_classify_integer(lexer_state.start, lexer_state.finish); + intermediate := elna_lexer_classify_integer(cursor^.start, cursor^.finish); kind^ := intermediate elsif action_to_perform = ElnaLexerAction.delimited then - lexer_state.finish := lexer_state.finish + 1; + cursor^.finish := cursor^.finish + 1; - intermediate := elna_lexer_classify_delimited(lexer_state.start, lexer_state.finish); + intermediate := elna_lexer_classify_delimited(cursor^.start, cursor^.finish); kind^ := intermediate end end; -proc _elna_lexer_execute_transition(kind: Word); +proc elna_lexer_execute_transition(cursor: ^ElnaLexerCursor, kind: ^ElnaLexerKind) -> ElnaLexerState; var next_transition: ^ElnaLexerTransition; - global_state: Word; begin - next_transition := _elna_lexer_next_transition(); - global_state := @lexer_state; + next_transition := elna_lexer_next_transition(cursor); + cursor^.state := next_transition^.next_state; - global_state^ := next_transition^.next_state; - _elna_lexer_execute_action(next_transition^.action, kind); + elna_lexer_execute_action(cursor, next_transition^.action, kind); return next_transition^.next_state end; -proc _elna_lexer_advance_token(kind: Word); +proc elna_lexer_advance_token(cursor: ^ElnaLexerCursor); var - result_state: Word; + result_state: ElnaLexerState; + kind: ElnaLexerKind; begin - result_state := _elna_lexer_execute_transition(kind); + result_state := elna_lexer_execute_transition(cursor, @kind); if result_state <> ElnaLexerState.finish then - _elna_lexer_advance_token(kind) - end + kind := elna_lexer_advance_token(cursor) + end; + return kind end; (** * Reads the next token and writes its type into the address in the kind parameter. * Resets the lexer state for reading the next token. *) -proc _elna_lexer_read_token(kind: Word); +proc elna_lexer_read_token(cursor: ^ElnaLexerCursor) -> ^ElnaLexerToken; +var + result: ^ElnaLexerToken; begin - lexer_state.state := ElnaLexerState.start; - lexer_state.finish := lexer_state.start; + cursor^.state := ElnaLexerState.start; + cursor^.finish := cursor^.start; - _elna_lexer_advance_token(kind) + result := malloc(#size(ElnaLexerToken)); + result^.kind := elna_lexer_advance_token(cursor); + result^.start := cursor^.start; + result^.length := cursor^.finish - cursor^.start; + + return result end; (** * Advances the token stream past the last read token. *) -proc _elna_lexer_skip_token(); +proc elna_lexer_skip_token(cursor: ^ElnaLexerCursor); begin - lexer_state.start := lexer_state.finish + cursor^.start := cursor^.finish end; proc _initialize_global_state(); begin compiler_strings_position := @compiler_strings; - source_code := malloc(495616); + source_code := malloc(495616) end; (* @@ -5086,9 +5081,10 @@ proc main(); var last_read: Word; offset: Word; + lexer_state: ElnaLexerCursor; begin _initialize_global_state(); - _elna_lexer_initialize(source_code); + elna_lexer_initialize(@lexer_state, source_code); elna_symbol_table_build(); (* Read the source from the standard input. *) @@ -5101,9 +5097,9 @@ begin offset := offset + last_read; goto start_read end; - if _compile() then + if _compile(@lexer_state) then exit(0) else exit(4) - end; + end end;