diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-07-13 02:49:24 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-07-13 02:49:24 +0200 |
| commit | 97741a01323021ccec8b0b60c6f8318c88ac373a (patch) | |
| tree | 51cd1722073498a749f158b9a6dc998fb4846055 | |
| parent | b2f8be605d2b79d1d4b1995646e7058bec299a22 (diff) | |
| download | elna-97741a01323021ccec8b0b60c6f8318c88ac373a.tar.gz | |
Fix ICE substracting pointers
| -rw-r--r-- | boot/semantic.cc | 11 | ||||
| -rw-r--r-- | cl.elna | 480 | ||||
| -rw-r--r-- | gcc/gcc/elna-tree.cc | 1 | ||||
| -rw-r--r-- | source/common.elna | 13 | ||||
| -rw-r--r-- | source/lexer.elna | 684 | ||||
| -rw-r--r-- | source/main.elna | 4 | ||||
| -rw-r--r-- | testsuite/compilable/pointer_subtraction.elna | 4 |
7 files changed, 600 insertions, 597 deletions
diff --git a/boot/semantic.cc b/boot/semantic.cc index d8a3c41..3486830 100644 --- a/boot/semantic.cc +++ b/boot/semantic.cc @@ -749,6 +749,17 @@ namespace elna::boot case binary_operator::greater_equal: expression->type_decoration = lookup_primitive_type("Bool"); break; + case binary_operator::subtraction: + if (expression->lhs().type_decoration.get<pointer_type>() + && expression->rhs().type_decoration.get<pointer_type>()) + { + expression->type_decoration = lookup_primitive_type("Int"); + } + else + { + expression->type_decoration = expression->lhs().type_decoration; + } + break; default: expression->type_decoration = expression->lhs().type_decoration; break; @@ -601,8 +601,6 @@ var variable_map_global: ^ElnaSymbolTable compiler_strings: [4096]Char - classification: [256]Word - transition_table: [19][23]ElnaLexerTransition word_type: ^ElnaType char_type: ^ElnaType bool_type: ^ElnaType @@ -6165,356 +6163,6 @@ begin elna_symbol_table_enter(symbol_table_global, "String".ptr, 6, current_info) end -proc elna_lexer_classifications1() -begin - classification[1] := ElnaLexerClass.eof; - classification[10] := ElnaLexerClass.space; - classification[11] := ElnaLexerClass.space; - classification[14] := ElnaLexerClass.space; - classification[33] := ElnaLexerClass.space; - classification[34] := ElnaLexerClass.single -end - -proc elna_lexer_classifications2() -begin - classification[35] := ElnaLexerClass.double_quote; - classification[36] := ElnaLexerClass.number_sign; - classification[37] := ElnaLexerClass.other; - classification[38] := ElnaLexerClass.single; - classification[39] := ElnaLexerClass.single; - classification[40] := ElnaLexerClass.single_quote; - classification[41] := ElnaLexerClass.left_paren; - classification[42] := ElnaLexerClass.right_paren; - classification[43] := ElnaLexerClass.asterisk; - classification[44] := ElnaLexerClass.single; - classification[45] := ElnaLexerClass.single; - classification[46] := ElnaLexerClass.minus; - classification[47] := ElnaLexerClass.dot; - classification[48] := ElnaLexerClass.single; - classification[49] := ElnaLexerClass.zero; - classification[50] := ElnaLexerClass.digit; - classification[51] := ElnaLexerClass.digit; - classification[52] := ElnaLexerClass.digit; - classification[53] := ElnaLexerClass.digit; - classification[54] := ElnaLexerClass.digit; - classification[55] := ElnaLexerClass.digit; - classification[56] := ElnaLexerClass.digit; - classification[57] := ElnaLexerClass.digit; - classification[58] := ElnaLexerClass.digit; - classification[59] := ElnaLexerClass.colon; - classification[60] := ElnaLexerClass.single; - classification[61] := ElnaLexerClass.less; - classification[62] := ElnaLexerClass.equals; - classification[63] := ElnaLexerClass.greater; - classification[64] := ElnaLexerClass.other -end - -proc elna_lexer_classifications3() -begin - classification[65] := ElnaLexerClass.single; - classification[66] := ElnaLexerClass.alpha; - classification[67] := ElnaLexerClass.alpha; - classification[68] := ElnaLexerClass.alpha; - classification[69] := ElnaLexerClass.alpha; - classification[70] := ElnaLexerClass.alpha; - classification[71] := ElnaLexerClass.alpha; - classification[72] := ElnaLexerClass.alpha; - classification[73] := ElnaLexerClass.alpha; - classification[74] := ElnaLexerClass.alpha; - classification[75] := ElnaLexerClass.alpha; - classification[76] := ElnaLexerClass.alpha; - classification[77] := ElnaLexerClass.alpha; - classification[78] := ElnaLexerClass.alpha; - classification[79] := ElnaLexerClass.alpha; - classification[80] := ElnaLexerClass.alpha; - classification[81] := ElnaLexerClass.alpha; - classification[82] := ElnaLexerClass.alpha; - classification[83] := ElnaLexerClass.alpha; - classification[84] := ElnaLexerClass.alpha; - classification[85] := ElnaLexerClass.alpha; - classification[86] := ElnaLexerClass.alpha; - classification[87] := ElnaLexerClass.alpha; - classification[88] := ElnaLexerClass.alpha; - classification[89] := ElnaLexerClass.alpha; - classification[90] := ElnaLexerClass.alpha; - classification[91] := ElnaLexerClass.alpha; - classification[92] := ElnaLexerClass.single; - classification[93] := ElnaLexerClass.backslash; - classification[94] := ElnaLexerClass.single; - classification[95] := ElnaLexerClass.single; - classification[96] := ElnaLexerClass.alpha; - classification[97] := ElnaLexerClass.other; - classification[98] := ElnaLexerClass.hex -end - -proc elna_lexer_classifications4() -begin - classification[99] := ElnaLexerClass.hex; - classification[100] := ElnaLexerClass.hex; - classification[101] := ElnaLexerClass.hex; - classification[102] := ElnaLexerClass.hex; - classification[103] := ElnaLexerClass.hex; - classification[104] := ElnaLexerClass.alpha; - classification[105] := ElnaLexerClass.alpha; - classification[106] := ElnaLexerClass.alpha; - classification[107] := ElnaLexerClass.alpha; - classification[108] := ElnaLexerClass.alpha; - classification[109] := ElnaLexerClass.alpha; - classification[110] := ElnaLexerClass.alpha; - classification[111] := ElnaLexerClass.alpha; - classification[112] := ElnaLexerClass.alpha; - classification[113] := ElnaLexerClass.alpha; - classification[114] := ElnaLexerClass.alpha; - classification[115] := ElnaLexerClass.alpha; - classification[116] := ElnaLexerClass.alpha; - classification[117] := ElnaLexerClass.alpha; - classification[118] := ElnaLexerClass.alpha; - classification[119] := ElnaLexerClass.alpha; - classification[120] := ElnaLexerClass.alpha; - classification[121] := ElnaLexerClass.x; - classification[122] := ElnaLexerClass.alpha; - classification[123] := ElnaLexerClass.alpha; - classification[124] := ElnaLexerClass.other; - classification[125] := ElnaLexerClass.single; - classification[126] := ElnaLexerClass.other; - classification[127] := ElnaLexerClass.single -end - -(** - * Initializes the array with character classes. - *) -proc elna_lexer_classifications() -var - code: Word -begin - code := 1; - - (* Set everything by default to invalid. *) - .elna_lexer_classifications_invalid; - classification[code] := ElnaLexerClass.invalid; - code := code + 1; - - if code < 129 then - goto elna_lexer_classifications_invalid - end; - - elna_lexer_classifications1(); - elna_lexer_classifications2(); - elna_lexer_classifications3(); - elna_lexer_classifications4(); - - (* Set the remaining 129 - 256 bytes to transitionClassOther. *) - .elna_lexer_classifications_other; - classification[code] := ElnaLexerClass.other; - code := code + 1; - - if code < 257 then - goto elna_lexer_classifications_other - end -end - -proc elna_lexer_get_transition(current_state, character_class: Word): Word -var - column_position: Word - target: Word -begin - (* Each state is 8 bytes long (2 words: action and next state). - There are 23 character classes, so a transition row 8 * 23 = 184 bytes long. *) - column_position := character_class - 1; - column_position := column_position * 8; - - target := @transition_table[current_state]; - - return target + column_position -end - -(** - * Parameters: - * current_state - First index into transitions table. - * character_class - Second index into transitions table. - * action - Action to assign. - * next_state - Next state to assign. - *) -proc elna_lexer_set_transition(current_state, character_class, action: Word; next_state: ElnaLexerState) -var - transition: ^ElnaLexerTransition -begin - transition := elna_lexer_get_transition(current_state, character_class); - - transition^.action := action; - transition^.next_state := next_state -end - -(* Sets same action and state transition for all character classes in one transition row. *) - -(** - * Parameters: - * current_state - Current state (Transition state enumeration). - * default_action - Default action (Callback). - * next_state - Next state (Transition state enumeration). - *) -proc elna_lexer_default_transition(current_state, 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) -end - -(** - * The transition table describes transitions from one state to another, given - * a symbol (character class). - * - * The table has m rows and n columns, where m is the amount of states and n is - * 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() -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); - - (* Colon state. *) - 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); - - (* 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); - - (* 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); - - (* Greater state. *) - 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); - - (* 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); - - (* 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); - - (* 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); - - (* 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); - - (* 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); - - (* 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); - - (* 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); - - (* 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); - - (* 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); - - (* 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); - - (* 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) -end - (** * One time lexer initialization. *) @@ -6532,87 +6180,6 @@ begin cursor^.position.end_location.column := 1 end -(* Returns true or false depending whether two strings are equal. *) -proc string_compare(lhs_pointer, lhs_length: Word; rhs_pointer: String): Bool -var - result: Bool -begin - if lhs_length = rhs_pointer.length then - result := memcmp(lhs_pointer, rhs_pointer.ptr, lhs_length) = 0 - else - result := false - end; - return result -end - -proc elna_lexer_token_create(kind: ElnaLexerKind; position: ^ElnaPosition): ^ElnaLexerToken -var - result: ^ElnaLexerToken -begin - result := malloc(#size(ElnaLexerToken)); - result^.kind := kind; - result^.position := position; - - return result -end - -proc elna_lexer_classify_keyword(position_start: ^Char; position_end: Word; position: ^ElnaPosition): ^ElnaLexerToken -var - result: ^ElnaLexerToken - result_length: Word -begin - result_length := position_end - position_start; - - result := elna_lexer_token_create(ElnaLexerKind.identifier, position); - result^.start.ptr := position_start; - result^.start.length := result_length; - - if position_start^ = '#' then - result^.kind := ElnaLexerKind.trait - elsif string_compare(position_start, result_length, "const") then - result^.kind := ElnaLexerKind._const - elsif string_compare(position_start, result_length, "var") then - result^.kind := ElnaLexerKind._var - elsif string_compare(position_start, result_length, "proc") then - result^.kind := ElnaLexerKind._proc - elsif string_compare(position_start, result_length, "type") then - result^.kind := ElnaLexerKind._type - elsif string_compare(position_start, result_length, "begin") then - result^.kind := ElnaLexerKind._begin - elsif string_compare(position_start, result_length, "end") then - result^.kind := ElnaLexerKind._end - elsif string_compare(position_start, result_length, "return") then - result^.kind := ElnaLexerKind._return - elsif string_compare(position_start, result_length, "goto") then - result^.kind := ElnaLexerKind._goto - elsif string_compare(position_start, result_length, "if") then - result^.kind := ElnaLexerKind._if - elsif string_compare(position_start, result_length, "extern") then - result^.kind := ElnaLexerKind._extern - elsif string_compare(position_start, result_length, "then") then - result^.kind := ElnaLexerKind._then - elsif string_compare(position_start, result_length, "else") then - result^.kind := ElnaLexerKind._else - elsif string_compare(position_start, result_length, "elsif") then - result^.kind := ElnaLexerKind._elsif - elsif string_compare(position_start, result_length, "record") then - result^.kind := ElnaLexerKind._record - elsif string_compare(position_start, result_length, "or") then - result^.kind := ElnaLexerKind._or - elsif string_compare(position_start, result_length, "xor") then - result^.kind := ElnaLexerKind._xor - elsif string_compare(position_start, result_length, "nil") then - result^.kind := ElnaLexerKind.null - elsif string_compare(position_start, result_length, "true") then - result^.kind := ElnaLexerKind.boolean - elsif string_compare(position_start, result_length, "false") then - result^.kind := ElnaLexerKind.boolean - elsif string_compare(position_start, result_length, "cast") then - result^.kind := ElnaLexerKind._cast - end; - return result -end - proc elna_lexer_classify_finalize(start_position: ^Char; position: ^ElnaPosition): ^ElnaLexerToken var character: Char @@ -6705,37 +6272,6 @@ begin return result end -proc elna_lexer_classify_delimited(start_position: ^Char; end_position: Word; position: ^ElnaPosition): ^ElnaLexerToken -var - delimiter: Char - result: ^ElnaLexerToken -begin - delimiter := start_position^; - - if delimiter = '(' then - result := elna_lexer_token_create(ElnaLexerKind.comment, position) - elsif delimiter = '\'' then - result := elna_lexer_token_create(ElnaLexerKind.character, position) - elsif delimiter = '"' then - result := elna_lexer_token_create(ElnaLexerKind.string, position) - end; - result^.start.ptr := start_position; - result^.start.length := end_position - start_position; - - return result -end - -proc elna_lexer_classify_integer(start_position, end_position: Word; position: ^ElnaPosition): ^ElnaLexerToken -var - result: ^ElnaLexerToken -begin - result := elna_lexer_token_create(ElnaLexerKind.integer, position); - result^.start.ptr := start_position; - result^.start.length := end_position - start_position; - - return result -end - proc elna_lexer_execute_action(cursor: ^ElnaLexerCursor; action_to_perform: Word): ^ElnaLexerToken var token: ^ElnaLexerToken @@ -6786,22 +6322,6 @@ begin return elna_lexer_execute_action(cursor, next_transition^.action, kind) end -proc elna_lexer_classify_space(start_position: ^Char; location: ^ElnaLocation) -begin - if start_position^ = '\n' then - location^.line := location^.line + 1; - location^.column := 1 - else - location^.column := location^.column + 1 - end -end - -proc elna_lexer_advance(cursor: ^ElnaLexerCursor) -begin - cursor^.finish := cursor^.finish + 1; - cursor^.position.end_location.column := cursor^.position.end_location.column + 1 -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. diff --git a/gcc/gcc/elna-tree.cc b/gcc/gcc/elna-tree.cc index 835702a..ebe6a56 100644 --- a/gcc/gcc/elna-tree.cc +++ b/gcc/gcc/elna-tree.cc @@ -182,6 +182,7 @@ namespace elna::gcc { return fold_build2_loc(operation_location, POINTER_DIFF_EXPR, ssizetype, left, right); } + return error_mark_node; } gcc_unreachable(); } diff --git a/source/common.elna b/source/common.elna index 8bba90f..9e6a314 100644 --- a/source/common.elna +++ b/source/common.elna @@ -78,4 +78,17 @@ begin return nil end +(* Returns true or false depending whether two strings are equal. *) +proc string_compare*(lhs_pointer: ^Char; lhs_length: Word; rhs_pointer: String): Bool +var + result: Bool +begin + if lhs_length = rhs_pointer.length then + result := memcmp(lhs_pointer, rhs_pointer.ptr, lhs_length) = 0 + else + result := false + end; + return result +end + end. diff --git a/source/lexer.elna b/source/lexer.elna index 318d740..5029ec5 100644 --- a/source/lexer.elna +++ b/source/lexer.elna @@ -2,37 +2,37 @@ v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. *) -import cstdio, common +import cstdio, common, cstdlib const CHUNK_SIZE := 85536u type - 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 - ) + 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 + ) ElnaLexerToken* = record kind: ElnaLexerKind; - start: String; (* DEPRECATED *) - position: ElnaPosition + start: String; (* DEPRECATED *) + position: ElnaPosition end ElnaLexerBooleanToken* = record(ElnaLexerToken) value: Bool @@ -49,20 +49,20 @@ type TransitionAction = proc(lexer: ^Lexer; token: ^ElnaLexerToken) (* DEPRECATED should be replaced with TransitionAction (but keeping the type name). *) - ElnaLexerAction = (none, accumulate, skip, single, eof, finalize, composite, key_id, integer, delimited) + ElnaLexerAction = (none, accumulate, skip, single, eof, finalize, composite, key_id, integer, delimited) ElnaLexerTransition = record action: ElnaLexerAction; next_state: ElnaLexerState end - ElnaLexerCursor = record - state: ElnaLexerState; - start: ^Char; - finish: ^Char; - token: ^ElnaLexerToken; - position: ElnaPosition - end + ElnaLexerCursor = record + state: ElnaLexerState; + start: ^Char; + finish: ^Char; + token: ^ElnaLexerToken; + position: ElnaPosition + end BufferPosition* = record iterator: ^Char; @@ -76,58 +76,58 @@ type start: BufferPosition; current: BufferPosition end - ElnaLexerKind* = ( - identifier, - _const, - _var, - _proc, - _type, - _begin, - _end, - _if, - _then, - _else, - _elsif, - _extern, - _record, - boolean, - null, - and, - _or, - _xor, - not, - _return, - _cast, - trait, - left_paren, - right_paren, - left_square, - right_square, - greater_equal, - less_equal, - greater_than, - less_than, - not_equal, - equals, - semicolon, - dot, - comma, - plus, - _import, - minus, - multiplication, - division, - remainder, - assignment, - colon, - hat, - at, - comment, - string, - character, - integer, - word, - _while, + ElnaLexerKind* = ( + identifier, + _const, + _var, + _proc, + _type, + _begin, + _end, + _if, + _then, + _else, + _elsif, + _extern, + _record, + boolean, + null, + and, + _or, + _xor, + not, + _return, + _cast, + trait, + left_paren, + right_paren, + left_square, + right_square, + greater_equal, + less_equal, + greater_than, + less_than, + not_equal, + equals, + semicolon, + dot, + comma, + plus, + _import, + minus, + multiplication, + division, + remainder, + assignment, + colon, + hat, + at, + comment, + string, + character, + integer, + word, + _while, _defer, exclamation, shift_right, @@ -136,36 +136,490 @@ type _case, _do, _of, - eof - ) - (** - * Classification table assigns each possible character to a group (class). All - * characters of the same group a handled equivalently. - *) - ElnaLexerClass = ( - invalid, - digit, - alpha, - space, - colon, - equals, - left_paren, - right_paren, - asterisk, - backslash, - single, - hex, - zero, - x, - eof, - dot, - minus, - single_quote, - double_quote, - greater, - less, - other, - number_sign - ) + eof + ) + (** + * Classification table assigns each possible character to a group (class). All + * characters of the same group a handled equivalently. + *) + ElnaLexerClass = ( + invalid, + digit, + alpha, + space, + colon, + equals, + left_paren, + right_paren, + asterisk, + backslash, + single, + hex, + zero, + x, + eof, + dot, + minus, + single_quote, + double_quote, + greater, + less, + other, + number_sign + ) + +var + classification: [256]ElnaLexerClass + transition_table: [19][23]ElnaLexerTransition + +proc elna_lexer_classifications1() +begin + classification[1] := ElnaLexerClass.eof; + classification[10] := ElnaLexerClass.space; + classification[11] := ElnaLexerClass.space; + classification[14] := ElnaLexerClass.space; + classification[33] := ElnaLexerClass.space; + classification[34] := ElnaLexerClass.single +end + +proc elna_lexer_classifications2() +begin + classification[35] := ElnaLexerClass.double_quote; + classification[36] := ElnaLexerClass.number_sign; + classification[37] := ElnaLexerClass.other; + classification[38] := ElnaLexerClass.single; + classification[39] := ElnaLexerClass.single; + classification[40] := ElnaLexerClass.single_quote; + classification[41] := ElnaLexerClass.left_paren; + classification[42] := ElnaLexerClass.right_paren; + classification[43] := ElnaLexerClass.asterisk; + classification[44] := ElnaLexerClass.single; + classification[45] := ElnaLexerClass.single; + classification[46] := ElnaLexerClass.minus; + classification[47] := ElnaLexerClass.dot; + classification[48] := ElnaLexerClass.single; + classification[49] := ElnaLexerClass.zero; + classification[50] := ElnaLexerClass.digit; + classification[51] := ElnaLexerClass.digit; + classification[52] := ElnaLexerClass.digit; + classification[53] := ElnaLexerClass.digit; + classification[54] := ElnaLexerClass.digit; + classification[55] := ElnaLexerClass.digit; + classification[56] := ElnaLexerClass.digit; + classification[57] := ElnaLexerClass.digit; + classification[58] := ElnaLexerClass.digit; + classification[59] := ElnaLexerClass.colon; + classification[60] := ElnaLexerClass.single; + classification[61] := ElnaLexerClass.less; + classification[62] := ElnaLexerClass.equals; + classification[63] := ElnaLexerClass.greater; + classification[64] := ElnaLexerClass.other +end + +proc elna_lexer_classifications3() +begin + classification[65] := ElnaLexerClass.single; + classification[66] := ElnaLexerClass.alpha; + classification[67] := ElnaLexerClass.alpha; + classification[68] := ElnaLexerClass.alpha; + classification[69] := ElnaLexerClass.alpha; + classification[70] := ElnaLexerClass.alpha; + classification[71] := ElnaLexerClass.alpha; + classification[72] := ElnaLexerClass.alpha; + classification[73] := ElnaLexerClass.alpha; + classification[74] := ElnaLexerClass.alpha; + classification[75] := ElnaLexerClass.alpha; + classification[76] := ElnaLexerClass.alpha; + classification[77] := ElnaLexerClass.alpha; + classification[78] := ElnaLexerClass.alpha; + classification[79] := ElnaLexerClass.alpha; + classification[80] := ElnaLexerClass.alpha; + classification[81] := ElnaLexerClass.alpha; + classification[82] := ElnaLexerClass.alpha; + classification[83] := ElnaLexerClass.alpha; + classification[84] := ElnaLexerClass.alpha; + classification[85] := ElnaLexerClass.alpha; + classification[86] := ElnaLexerClass.alpha; + classification[87] := ElnaLexerClass.alpha; + classification[88] := ElnaLexerClass.alpha; + classification[89] := ElnaLexerClass.alpha; + classification[90] := ElnaLexerClass.alpha; + classification[91] := ElnaLexerClass.alpha; + classification[92] := ElnaLexerClass.single; + classification[93] := ElnaLexerClass.backslash; + classification[94] := ElnaLexerClass.single; + classification[95] := ElnaLexerClass.single; + classification[96] := ElnaLexerClass.alpha; + classification[97] := ElnaLexerClass.other; + classification[98] := ElnaLexerClass.hex +end + +proc elna_lexer_classifications4() +begin + classification[99] := ElnaLexerClass.hex; + classification[100] := ElnaLexerClass.hex; + classification[101] := ElnaLexerClass.hex; + classification[102] := ElnaLexerClass.hex; + classification[103] := ElnaLexerClass.hex; + classification[104] := ElnaLexerClass.alpha; + classification[105] := ElnaLexerClass.alpha; + classification[106] := ElnaLexerClass.alpha; + classification[107] := ElnaLexerClass.alpha; + classification[108] := ElnaLexerClass.alpha; + classification[109] := ElnaLexerClass.alpha; + classification[110] := ElnaLexerClass.alpha; + classification[111] := ElnaLexerClass.alpha; + classification[112] := ElnaLexerClass.alpha; + classification[113] := ElnaLexerClass.alpha; + classification[114] := ElnaLexerClass.alpha; + classification[115] := ElnaLexerClass.alpha; + classification[116] := ElnaLexerClass.alpha; + classification[117] := ElnaLexerClass.alpha; + classification[118] := ElnaLexerClass.alpha; + classification[119] := ElnaLexerClass.alpha; + classification[120] := ElnaLexerClass.alpha; + classification[121] := ElnaLexerClass.x; + classification[122] := ElnaLexerClass.alpha; + classification[123] := ElnaLexerClass.alpha; + classification[124] := ElnaLexerClass.other; + classification[125] := ElnaLexerClass.single; + classification[126] := ElnaLexerClass.other; + classification[127] := ElnaLexerClass.single +end + +(** + * Initializes the array with character classes. + *) +proc elna_lexer_classifications() +var + code: Word +begin + code := 1u; + + (* Set everything by default to invalid. *) + while code < 129u do + classification[code] := ElnaLexerClass.invalid; + code := code + 1u + end; + + elna_lexer_classifications1(); + elna_lexer_classifications2(); + elna_lexer_classifications3(); + elna_lexer_classifications4(); + + (* Set the remaining 129 - 256 bytes to transitionClassOther. *) + while code < 257u do + classification[code] := ElnaLexerClass.other; + code := code + 1u + end +end + +proc elna_lexer_get_transition(current_state: ElnaLexerState; character_class: ElnaLexerClass): ^ElnaLexerTransition + (* Each state is 8 bytes long (2 words: action and next state). + There are 23 character classes, so a transition row 8 * 23 = 184 bytes long. *) + + return @transition_table[cast(current_state: Word)][cast(character_class: Word)] +end + +(** + * Parameters: + * current_state - First index into transitions table. + * character_class - Second index into transitions table. + * action - Action to assign. + * next_state - Next state to assign. + *) +proc elna_lexer_set_transition(current_state: ElnaLexerState; character_class: ElnaLexerClass; + action: ElnaLexerAction; next_state: ElnaLexerState) +var + transition: ^ElnaLexerTransition +begin + transition := elna_lexer_get_transition(current_state, character_class); + + transition^.action := action; + transition^.next_state := next_state +end + +(** + * Sets same action and state transition for all character classes in one transition row. + * + * Parameters: + * current_state - Current state (Transition state enumeration). + * default_action - Default action (Callback). + * next_state - Next state (Transition state enumeration). + *) +proc elna_lexer_default_transition(current_state: ElnaLexerState; default_action: ElnaLexerAction; + 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) +end + +(** + * The transition table describes transitions from one state to another, given + * a symbol (character class). + * + * The table has m rows and n columns, where m is the amount of states and n is + * 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() +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); + + (* Colon state. *) + 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); + + (* 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); + + (* 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); + + (* Greater state. *) + 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); + + (* 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); + + (* 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); + + (* 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); + + (* 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); + + (* 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); + + (* 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); + + (* 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); + + (* 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); + + (* 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); + + (* 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); + + (* 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) +end + +proc elna_lexer_advance(cursor: ^ElnaLexerCursor) +begin + cursor^.finish := cursor^.finish + 1; + cursor^.position.end_location.column := cursor^.position.end_location.column + 1u +end + +proc elna_lexer_classify_space(start_position: ^Char; location: ^ElnaLocation) +begin + if start_position^ = '\n' then + location^.line := location^.line + 1u; + location^.column := 1u + else + location^.column := location^.column + 1u + end +end + +proc elna_lexer_token_create(kind: ElnaLexerKind; position: ^ElnaPosition): ^ElnaLexerToken +var + result: ^ElnaLexerToken +begin + result := malloc(#size(ElnaLexerToken)); + result^.kind := kind; + result^.position := position^; + + return result +end + +proc elna_lexer_classify_keyword(position_start, position_end: ^Char; position: ^ElnaPosition): ^ElnaLexerToken +var + result: ^ElnaLexerToken + result_length: Word +begin + result_length := cast(position_end - position_start: Word); + + result := elna_lexer_token_create(ElnaLexerKind.identifier, position); + result^.start := String(position_start, result_length); + + if position_start^ = '#' then + result^.kind := ElnaLexerKind.trait + elsif string_compare(position_start, result_length, "const") then + result^.kind := ElnaLexerKind._const + elsif string_compare(position_start, result_length, "var") then + result^.kind := ElnaLexerKind._var + elsif string_compare(position_start, result_length, "proc") then + result^.kind := ElnaLexerKind._proc + elsif string_compare(position_start, result_length, "type") then + result^.kind := ElnaLexerKind._type + elsif string_compare(position_start, result_length, "begin") then + result^.kind := ElnaLexerKind._begin + elsif string_compare(position_start, result_length, "end") then + result^.kind := ElnaLexerKind._end + elsif string_compare(position_start, result_length, "return") then + result^.kind := ElnaLexerKind._return + elsif string_compare(position_start, result_length, "defer") then + result^.kind := ElnaLexerKind._defer + elsif string_compare(position_start, result_length, "if") then + result^.kind := ElnaLexerKind._if + elsif string_compare(position_start, result_length, "extern") then + result^.kind := ElnaLexerKind._extern + elsif string_compare(position_start, result_length, "then") then + result^.kind := ElnaLexerKind._then + elsif string_compare(position_start, result_length, "else") then + result^.kind := ElnaLexerKind._else + elsif string_compare(position_start, result_length, "elsif") then + result^.kind := ElnaLexerKind._elsif + elsif string_compare(position_start, result_length, "record") then + result^.kind := ElnaLexerKind._record + elsif string_compare(position_start, result_length, "or") then + result^.kind := ElnaLexerKind._or + elsif string_compare(position_start, result_length, "xor") then + result^.kind := ElnaLexerKind._xor + elsif string_compare(position_start, result_length, "nil") then + result^.kind := ElnaLexerKind.null + elsif string_compare(position_start, result_length, "true") then + result^.kind := ElnaLexerKind.boolean + elsif string_compare(position_start, result_length, "false") then + result^.kind := ElnaLexerKind.boolean + elsif string_compare(position_start, result_length, "cast") then + result^.kind := ElnaLexerKind._cast + end; + return result +end + +proc elna_lexer_classify_delimited(start_position, end_position: ^Char; position: ^ElnaPosition): ^ElnaLexerToken +var + delimiter: Char + result: ^ElnaLexerToken +begin + delimiter := start_position^; + + if delimiter = '(' then + result := elna_lexer_token_create(ElnaLexerKind.comment, position) + elsif delimiter = '\'' then + result := elna_lexer_token_create(ElnaLexerKind.character, position) + elsif delimiter = '"' then + result := elna_lexer_token_create(ElnaLexerKind.string, position) + end; + result^.start := String(start_position, cast(end_position - start_position: Word)); + + return result +end + +proc elna_lexer_classify_integer(start_position, end_position: ^Char; position: ^ElnaPosition): ^ElnaLexerToken +var + result: ^ElnaLexerToken +begin + result := elna_lexer_token_create(ElnaLexerKind.integer, position); + result^.start := String(start_position, cast(end_position - start_position: Word)); + + return result +end end. diff --git a/source/main.elna b/source/main.elna index 9a43fb8..37d0f07 100644 --- a/source/main.elna +++ b/source/main.elna @@ -30,8 +30,8 @@ type end var - stdout: ^FILE - stderr: ^FILE + stdout: ^FILE + stderr: ^FILE stdin: ^FILE (* diff --git a/testsuite/compilable/pointer_subtraction.elna b/testsuite/compilable/pointer_subtraction.elna new file mode 100644 index 0000000..400d4f1 --- /dev/null +++ b/testsuite/compilable/pointer_subtraction.elna @@ -0,0 +1,4 @@ +proc test(a, b: ^Char): Int + return a - b +end +end. |
