From 56a1244380133ab400f98d2da15353e080ffb360 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 15 Oct 2026 14:46:38 +0200 Subject: Restrict index types to Int and Word --- source/elna/lexer.elna | 608 ++++++++++++++++++++++++++++++++++++++++++++++++ source/elna/source.elna | 20 ++ source/main.elna | 3 + source/std.elna | 6 + 4 files changed, 637 insertions(+) create mode 100644 source/elna/lexer.elna create mode 100644 source/elna/source.elna create mode 100644 source/std.elna (limited to 'source') diff --git a/source/elna/lexer.elna b/source/elna/lexer.elna new file mode 100644 index 0000000..7fa489a --- /dev/null +++ b/source/elna/lexer.elna @@ -0,0 +1,608 @@ +(* This Source Code Form is subject to the terms of the Mozilla Public License, + 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/. *) + +(* Lexical analysis. *) +module + +import std, elna.source + +type + (* + Classification table assigns each possible character to a group (class). All + characters of the same group are processed equivalently. + *) + ElnaLexerClass = ( + (* Zero has its own class to represent prefixed numbers 0x or 0b. *) + zero, + (* Decimal digits without zero. *) + digit, + (* E and e. *) + exponent, + (* Letters without e and E (exponent) and underscore. *) + alpha, + (* Horizontal whitespace (space, tab and carriage return). *) + space, + (* Newline. *) + new_line, + (* Standalone or starts the assignment operator. *) + colon, + (* Standalone or part of comparison operators or the assignment operator. *) + equals, + (* Standalone or opens a comment. *) + left_paren, + (* Standalone or closes a comment. *) + right_paren, + (* Multiplication, export marker or in comment delimiters. *) + asterisk, + (* Escapes quotes in string and character literals. *) + backslash, + (* Standalone single-character tokens (e.g. ';', '^', '@') that never combine. *) + single, + (* UTF-32 string literal delimiter. *) + backquote, + (* Record initializer or attribute marker (#{). *) + brace, + (* Opening square bracket for array indices and generic parameters. *) + square, + (* Sentinel signaling end of input. *) + eof, + (* Standalone or as decimal separator. *) + dot, + (* Plus for positive exponents. *) + plus, + (* Standalone, arrow (->) or line comment (--). *) + minus, + (* ASCII character literal delimiter. *) + single_quote, + (* UTF-8 string literal delimiter. *) + double_quote, + (* Greater, greater than or an arrow. *) + greater, + (* Less, less than or unequal (<>). *) + less, + (* Attribute, generic parameter or trait marker ('#'). *) + number_sign, + (* Other valid symbols that do not form special tokens. *) + other, + (* Cannot appear in the source code. *) + invalid + ) + (* Lexer state. *) + ElnaLexerState = ( + (* A non-accepting state from which no final state can ever be reached. *) + dead, + (* Start state. *) + start, + (* Entering identifier or keyword. *) + identifier, + (* Skipping whitespaces. *) + skip, + (* Entering a token starting with a colon. *) + colon, + (* Entering a token starting with a left parenthesis. *) + left_paren, + (* Minus or token starting with a minus. *) + minus, + (* Entering comparison operator starting with "greater than". *) + greater, + (* Entering comparison operator starting with "less than". *) + less, + (* Binary or hexadecimal word. *) + leading_zero, + (* Entering integer part of a number. *) + integer, + (* Inside a comment (after eating double minus, --). *) + comment, + (* Inside a docblock (after eating opening paren with asterisk). *) + docblock, + (* Seen an asterisk inside a docblock. *) + closing_docblock, + (* Tail is the last part of the number containing digits and an optional type suffix. *) + number_tail, + (* Seen a period after a number, possible floating point number. *) + dot_after, + (* Entering floating point number fraction part after a decimal point. *) + fraction, + (* An exponent state begins with e or E. *) + exponent, + (* Optional plus or minus sign following the exponent. *) + exponent_sign, + (* Opening a compile-time feature starting with a #. *) + number_sign, + (* Trait identifier. *) + trait, + (* Entering UTF-32 character literal. *) + wide, + (* Seen an escape sequence in a UTF-32 character literal. *) + wide_escape, + (* Entering UTF-8 character literal. *) + narrow, + (* Seen an escape sequence in a UTF-8 character literal. *) + narrow_escape, + (* Entering string literal. *) + string, + (* Seen an escape sequence in a string literal. *) + string_escape, + (* Token is complete, the last byte eaten. *) + stop, + (* Reject the token with an error. *) + reject, + (* Sentinel signaling end of input. *) + eof + ) + +var + (* Initializes the array with character classes. *) + classification: const [256]ElnaLexerClass := [ + ElnaLexerClass.eof, -- nul + ElnaLexerClass.invalid, -- soh + ElnaLexerClass.invalid, -- stx + ElnaLexerClass.invalid, -- etx + ElnaLexerClass.invalid, -- eot + ElnaLexerClass.invalid, -- enq + ElnaLexerClass.invalid, -- ack + ElnaLexerClass.invalid, -- bel + ElnaLexerClass.invalid, -- bs + ElnaLexerClass.space, -- ht + ElnaLexerClass.new_line, -- nl + ElnaLexerClass.invalid, -- vt + ElnaLexerClass.invalid, -- np + ElnaLexerClass.space , -- cr + ElnaLexerClass.invalid, -- so + ElnaLexerClass.invalid, -- si + ElnaLexerClass.invalid, -- dle + ElnaLexerClass.invalid, -- dc1 + ElnaLexerClass.invalid, -- dc2 + ElnaLexerClass.invalid, -- dc3 + ElnaLexerClass.invalid, -- dc4 + ElnaLexerClass.invalid, -- nak + ElnaLexerClass.invalid, -- syn + ElnaLexerClass.invalid, -- etb + ElnaLexerClass.invalid, -- can + ElnaLexerClass.invalid, -- em + ElnaLexerClass.invalid, -- sub + ElnaLexerClass.invalid, -- esc + ElnaLexerClass.invalid, -- fs + ElnaLexerClass.invalid, -- gs + ElnaLexerClass.invalid, -- rs + ElnaLexerClass.invalid, -- us + ElnaLexerClass.space, -- Space + ElnaLexerClass.other, -- ! + ElnaLexerClass.double_quote, -- " + ElnaLexerClass.number_sign, -- # + ElnaLexerClass.other, -- $ + ElnaLexerClass.single, -- % + ElnaLexerClass.single, -- & + ElnaLexerClass.single_quote, -- ' + ElnaLexerClass.left_paren, -- ( + ElnaLexerClass.right_paren, -- ) + ElnaLexerClass.asterisk, -- * + ElnaLexerClass.plus, -- + + ElnaLexerClass.single, -- , + ElnaLexerClass.minus, -- - + ElnaLexerClass.dot, -- . + ElnaLexerClass.single, -- / + ElnaLexerClass.zero, -- 0 + ElnaLexerClass.digit, -- 1 + ElnaLexerClass.digit, -- 2 + ElnaLexerClass.digit, -- 3 + ElnaLexerClass.digit, -- 4 + ElnaLexerClass.digit, -- 5 + ElnaLexerClass.digit, -- 6 + ElnaLexerClass.digit, -- 7 + ElnaLexerClass.digit, -- 8 + ElnaLexerClass.digit, -- 9 + ElnaLexerClass.colon, -- : + ElnaLexerClass.single, -- ; + ElnaLexerClass.less, -- < + ElnaLexerClass.equals, -- = + ElnaLexerClass.greater, -- > + ElnaLexerClass.other, -- ? + ElnaLexerClass.single, -- @ + ElnaLexerClass.alpha, -- A + ElnaLexerClass.alpha, -- B + ElnaLexerClass.alpha, -- C + ElnaLexerClass.alpha, -- D + ElnaLexerClass.exponent, -- E + ElnaLexerClass.alpha, -- F + ElnaLexerClass.alpha, -- G + ElnaLexerClass.alpha, -- H + ElnaLexerClass.alpha, -- I + ElnaLexerClass.alpha, -- J + ElnaLexerClass.alpha, -- K + ElnaLexerClass.alpha, -- L + ElnaLexerClass.alpha, -- M + ElnaLexerClass.alpha, -- N + ElnaLexerClass.alpha, -- O + ElnaLexerClass.alpha, -- P + ElnaLexerClass.alpha, -- Q + ElnaLexerClass.alpha, -- R + ElnaLexerClass.alpha, -- S + ElnaLexerClass.alpha, -- T + ElnaLexerClass.alpha, -- U + ElnaLexerClass.alpha, -- V + ElnaLexerClass.alpha, -- W + ElnaLexerClass.alpha , -- X + ElnaLexerClass.alpha, -- Y + ElnaLexerClass.alpha, -- Z + ElnaLexerClass.square, -- [ + ElnaLexerClass.backslash, -- \ + ElnaLexerClass.single, -- ] + ElnaLexerClass.single, -- ^ + ElnaLexerClass.alpha, -- _ + ElnaLexerClass.backquote, -- ` + ElnaLexerClass.alpha , -- a + ElnaLexerClass.alpha , -- b + ElnaLexerClass.alpha , -- c + ElnaLexerClass.alpha , -- d + ElnaLexerClass.exponent, -- e + ElnaLexerClass.alpha , -- f + ElnaLexerClass.alpha, -- g + ElnaLexerClass.alpha, -- h + ElnaLexerClass.alpha, -- i + ElnaLexerClass.alpha, -- j + ElnaLexerClass.alpha, -- k + ElnaLexerClass.alpha, -- l + ElnaLexerClass.alpha, -- m + ElnaLexerClass.alpha, -- n + ElnaLexerClass.alpha, -- o + ElnaLexerClass.alpha, -- p + ElnaLexerClass.alpha, -- q + ElnaLexerClass.alpha, -- r + ElnaLexerClass.alpha, -- s + ElnaLexerClass.alpha, -- t + ElnaLexerClass.alpha, -- u + ElnaLexerClass.alpha, -- v + ElnaLexerClass.alpha, -- w + ElnaLexerClass.alpha , -- x + ElnaLexerClass.alpha, -- y + ElnaLexerClass.alpha, -- z + ElnaLexerClass.brace, -- { + ElnaLexerClass.single, -- | + ElnaLexerClass.single, -- } + ElnaLexerClass.single, -- ~ + ElnaLexerClass.invalid, -- del + -- 0x80 .. 0xBF - UTF-8 continuation bytes (10xxxxxx). + ElnaLexerClass.other, -- 0x80 + ElnaLexerClass.other, -- 0x81 + ElnaLexerClass.other, -- 0x82 + ElnaLexerClass.other, -- 0x83 + ElnaLexerClass.other, -- 0x84 + ElnaLexerClass.other, -- 0x85 + ElnaLexerClass.other, -- 0x86 + ElnaLexerClass.other, -- 0x87 + ElnaLexerClass.other, -- 0x88 + ElnaLexerClass.other, -- 0x89 + ElnaLexerClass.other, -- 0x8A + ElnaLexerClass.other, -- 0x8B + ElnaLexerClass.other, -- 0x8C + ElnaLexerClass.other, -- 0x8D + ElnaLexerClass.other, -- 0x8E + ElnaLexerClass.other, -- 0x8F + ElnaLexerClass.other, -- 0x90 + ElnaLexerClass.other, -- 0x91 + ElnaLexerClass.other, -- 0x92 + ElnaLexerClass.other, -- 0x93 + ElnaLexerClass.other, -- 0x94 + ElnaLexerClass.other, -- 0x95 + ElnaLexerClass.other, -- 0x96 + ElnaLexerClass.other, -- 0x97 + ElnaLexerClass.other, -- 0x98 + ElnaLexerClass.other, -- 0x99 + ElnaLexerClass.other, -- 0x9A + ElnaLexerClass.other, -- 0x9B + ElnaLexerClass.other, -- 0x9C + ElnaLexerClass.other, -- 0x9D + ElnaLexerClass.other, -- 0x9E + ElnaLexerClass.other, -- 0x9F + ElnaLexerClass.other, -- 0xA0 + ElnaLexerClass.other, -- 0xA1 + ElnaLexerClass.other, -- 0xA2 + ElnaLexerClass.other, -- 0xA3 + ElnaLexerClass.other, -- 0xA4 + ElnaLexerClass.other, -- 0xA5 + ElnaLexerClass.other, -- 0xA6 + ElnaLexerClass.other, -- 0xA7 + ElnaLexerClass.other, -- 0xA8 + ElnaLexerClass.other, -- 0xA9 + ElnaLexerClass.other, -- 0xAA + ElnaLexerClass.other, -- 0xAB + ElnaLexerClass.other, -- 0xAC + ElnaLexerClass.other, -- 0xAD + ElnaLexerClass.other, -- 0xAE + ElnaLexerClass.other, -- 0xAF + ElnaLexerClass.other, -- 0xB0 + ElnaLexerClass.other, -- 0xB1 + ElnaLexerClass.other, -- 0xB2 + ElnaLexerClass.other, -- 0xB3 + ElnaLexerClass.other, -- 0xB4 + ElnaLexerClass.other, -- 0xB5 + ElnaLexerClass.other, -- 0xB6 + ElnaLexerClass.other, -- 0xB7 + ElnaLexerClass.other, -- 0xB8 + ElnaLexerClass.other, -- 0xB9 + ElnaLexerClass.other, -- 0xBA + ElnaLexerClass.other, -- 0xBB + ElnaLexerClass.other, -- 0xBC + ElnaLexerClass.other, -- 0xBD + ElnaLexerClass.other, -- 0xBE + ElnaLexerClass.other, -- 0xBF + ElnaLexerClass.invalid, -- 0xC0 + ElnaLexerClass.invalid, -- 0xC1 + -- 0xC2 .. 0xDF - 2-byte lead (110xxxxx). + ElnaLexerClass.other, -- 0xC2 + ElnaLexerClass.other, -- 0xC3 + ElnaLexerClass.other, -- 0xC4 + ElnaLexerClass.other, -- 0xC5 + ElnaLexerClass.other, -- 0xC6 + ElnaLexerClass.other, -- 0xC7 + ElnaLexerClass.other, -- 0xC8 + ElnaLexerClass.other, -- 0xC9 + ElnaLexerClass.other, -- 0xCA + ElnaLexerClass.other, -- 0xCB + ElnaLexerClass.other, -- 0xCC + ElnaLexerClass.other, -- 0xCD + ElnaLexerClass.other, -- 0xCE + ElnaLexerClass.other, -- 0xCF + ElnaLexerClass.other, -- 0xD0 + ElnaLexerClass.other, -- 0xD1 + ElnaLexerClass.other, -- 0xD2 + ElnaLexerClass.other, -- 0xD3 + ElnaLexerClass.other, -- 0xD4 + ElnaLexerClass.other, -- 0xD5 + ElnaLexerClass.other, -- 0xD6 + ElnaLexerClass.other, -- 0xD7 + ElnaLexerClass.other, -- 0xD8 + ElnaLexerClass.other, -- 0xD9 + ElnaLexerClass.other, -- 0xDA + ElnaLexerClass.other, -- 0xDB + ElnaLexerClass.other, -- 0xDC + ElnaLexerClass.other, -- 0xDD + ElnaLexerClass.other, -- 0xDE + ElnaLexerClass.other, -- 0xDF + -- 0xE0 .. 0xEF - 3-byte lead (1110xxxx). + ElnaLexerClass.other, -- 0xE0 + ElnaLexerClass.other, -- 0xE1 + ElnaLexerClass.other, -- 0xE2 + ElnaLexerClass.other, -- 0xE3 + ElnaLexerClass.other, -- 0xE4 + ElnaLexerClass.other, -- 0xE5 + ElnaLexerClass.other, -- 0xE6 + ElnaLexerClass.other, -- 0xE7 + ElnaLexerClass.other, -- 0xE8 + ElnaLexerClass.other, -- 0xE9 + ElnaLexerClass.other, -- 0xEA + ElnaLexerClass.other, -- 0xEB + ElnaLexerClass.other, -- 0xEC + ElnaLexerClass.other, -- 0xED + ElnaLexerClass.other, -- 0xEE + ElnaLexerClass.other, -- 0xEF + -- 0xF0 .. 0xF4 - 4-byte lead (11110xxx). + ElnaLexerClass.other, -- 0xF0 + ElnaLexerClass.other, -- 0xF1 + ElnaLexerClass.other, -- 0xF2 + ElnaLexerClass.other, -- 0xF3 + ElnaLexerClass.other, -- 0xF4 + ElnaLexerClass.invalid, -- 0xF5 + ElnaLexerClass.invalid, -- 0xF6 + ElnaLexerClass.invalid, -- 0xF7 + ElnaLexerClass.invalid, -- 0xF8 + ElnaLexerClass.invalid, -- 0xF9 + ElnaLexerClass.invalid, -- 0xFA + ElnaLexerClass.invalid, -- 0xFB + ElnaLexerClass.invalid, -- 0xFC + ElnaLexerClass.invalid, -- 0xFD + ElnaLexerClass.invalid, -- 0xFE + ElnaLexerClass.invalid -- 0xFF + ] + transition_table: [cast(#max(ElnaLexerState): Word)][cast(#max(ElnaLexerClass): Word)]ElnaLexerState + +(* + @param current_state First index into transitions table. + @param character_class Second index into transitions table. + @param next_state Next state to assign. +*) +proc elna_lexer_set_transition(current_state: ElnaLexerState; character_class: ElnaLexerClass; + next_state: ElnaLexerState) + transition_table[cast(current_state: Word)][cast(character_class: Word)] := next_state +return + +(* + Sets same state transition for all character classes in one transition row. + + @param current_state Current state. + @param next_state Next state. +*) +proc elna_lexer_default_transition(current_state, next_state: ElnaLexerState) +var + current := cast(#min(ElnaLexerClass): Int) +begin + while current <= cast(#max(ElnaLexerClass): Int) do + elna_lexer_set_transition(current_state, cast(current: ElnaLexerClass), next_state); + current := current + 1 + end +return + +(* + 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*() +var + current := cast(#min(ElnaLexerState): Int) +begin + -- Every transition leads to the dead state by default; + -- valid transitions are filled in below. + while current <= cast(#max(ElnaLexerState): Int) do + elna_lexer_default_transition(cast(current: ElnaLexerState), ElnaLexerState.dead); + current := current + 1 + end; + -- Start state. + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.zero, ElnaLexerState.leading_zero); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.digit, ElnaLexerState.integer); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.exponent, ElnaLexerState.identifier); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.alpha, ElnaLexerState.identifier); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.space, ElnaLexerState.skip); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.new_line, ElnaLexerState.skip); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.colon, ElnaLexerState.colon); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.equals, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.left_paren, ElnaLexerState.left_paren); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.right_paren, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.asterisk, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.single, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.backquote, ElnaLexerState.wide); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.brace, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.square, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.eof, ElnaLexerState.eof); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.dot, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.plus, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.minus, ElnaLexerState.minus); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.single_quote, ElnaLexerState.narrow); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.double_quote, ElnaLexerState.string); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.greater, ElnaLexerState.greater); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.less, ElnaLexerState.less); + elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.number_sign, ElnaLexerState.number_sign); + + -- Identifier state. + elna_lexer_set_transition(ElnaLexerState.identifier, ElnaLexerClass.zero, ElnaLexerState.identifier); + elna_lexer_set_transition(ElnaLexerState.identifier, ElnaLexerClass.digit, ElnaLexerState.identifier); + elna_lexer_set_transition(ElnaLexerState.identifier, ElnaLexerClass.exponent, ElnaLexerState.identifier); + elna_lexer_set_transition(ElnaLexerState.identifier, ElnaLexerClass.alpha, ElnaLexerState.identifier); + + -- Skip whitespaces. + elna_lexer_set_transition(ElnaLexerState.skip, ElnaLexerClass.space, ElnaLexerState.skip); + elna_lexer_set_transition(ElnaLexerState.skip, ElnaLexerClass.new_line, ElnaLexerState.skip); + + -- Colon state. + elna_lexer_set_transition(ElnaLexerState.colon, ElnaLexerClass.equals, ElnaLexerState.stop); + + -- Left paren state. + elna_lexer_set_transition(ElnaLexerState.left_paren, ElnaLexerClass.asterisk, ElnaLexerState.docblock); + + -- Minus state. + elna_lexer_set_transition(ElnaLexerState.minus, ElnaLexerClass.greater, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.minus, ElnaLexerClass.minus, ElnaLexerState.comment); + + -- Greater state. + elna_lexer_set_transition(ElnaLexerState.greater, ElnaLexerClass.greater, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.greater, ElnaLexerClass.equals, ElnaLexerState.stop); + + -- Less state. + elna_lexer_set_transition(ElnaLexerState.less, ElnaLexerClass.less, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.less, ElnaLexerClass.equals, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.less, ElnaLexerClass.greater, ElnaLexerState.stop); + + -- Numbers prefixed by 0 followed by a character (0b, 0x). + elna_lexer_set_transition(ElnaLexerState.leading_zero, ElnaLexerClass.zero, ElnaLexerState.integer); + elna_lexer_set_transition(ElnaLexerState.leading_zero, ElnaLexerClass.digit, ElnaLexerState.integer); + elna_lexer_set_transition(ElnaLexerState.leading_zero, ElnaLexerClass.alpha, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.leading_zero, ElnaLexerClass.exponent, ElnaLexerState.exponent); + elna_lexer_set_transition(ElnaLexerState.leading_zero, ElnaLexerClass.dot, ElnaLexerState.dot_after); + + -- Decimal number. + elna_lexer_set_transition(ElnaLexerState.integer, ElnaLexerClass.zero, ElnaLexerState.integer); + elna_lexer_set_transition(ElnaLexerState.integer, ElnaLexerClass.digit, ElnaLexerState.integer); + elna_lexer_set_transition(ElnaLexerState.integer, ElnaLexerClass.alpha, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.integer, ElnaLexerClass.exponent, ElnaLexerState.exponent); + elna_lexer_set_transition(ElnaLexerState.integer, ElnaLexerClass.dot, ElnaLexerState.dot_after); + + -- Comment. + elna_lexer_default_transition(ElnaLexerState.comment, ElnaLexerState.comment); + elna_lexer_set_transition(ElnaLexerState.comment, ElnaLexerClass.new_line, ElnaLexerState.dead); + elna_lexer_set_transition(ElnaLexerState.comment, ElnaLexerClass.eof, ElnaLexerState.dead); + + -- Docblock. + elna_lexer_default_transition(ElnaLexerState.docblock, ElnaLexerState.docblock); + elna_lexer_set_transition(ElnaLexerState.docblock, ElnaLexerClass.asterisk, ElnaLexerState.closing_docblock); + elna_lexer_set_transition(ElnaLexerState.docblock, ElnaLexerClass.invalid, ElnaLexerState.reject); + elna_lexer_set_transition(ElnaLexerState.docblock, ElnaLexerClass.eof, ElnaLexerState.reject); + + -- Closing docblock. + elna_lexer_default_transition(ElnaLexerState.closing_docblock, ElnaLexerState.docblock); + elna_lexer_set_transition(ElnaLexerState.closing_docblock, ElnaLexerClass.right_paren, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.closing_docblock, ElnaLexerClass.asterisk, ElnaLexerState.closing_docblock); + elna_lexer_set_transition(ElnaLexerState.closing_docblock, ElnaLexerClass.invalid, ElnaLexerState.reject); + elna_lexer_set_transition(ElnaLexerState.closing_docblock, ElnaLexerClass.eof, ElnaLexerState.reject); + + -- Tail is the last part of the number containing digits and an optional type suffix. + elna_lexer_set_transition(ElnaLexerState.number_tail, ElnaLexerClass.exponent, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.number_tail, ElnaLexerClass.alpha, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.number_tail, ElnaLexerClass.zero, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.number_tail, ElnaLexerClass.digit, ElnaLexerState.number_tail); + + -- Seen a period after a number, possible floating point number. + elna_lexer_set_transition(ElnaLexerState.dot_after, ElnaLexerClass.zero, ElnaLexerState.fraction); + elna_lexer_set_transition(ElnaLexerState.dot_after, ElnaLexerClass.digit, ElnaLexerState.fraction); + + -- Entering floating point number fraction part after a decimal point. + elna_lexer_set_transition(ElnaLexerState.fraction, ElnaLexerClass.zero, ElnaLexerState.fraction); + elna_lexer_set_transition(ElnaLexerState.fraction, ElnaLexerClass.digit, ElnaLexerState.fraction); + elna_lexer_set_transition(ElnaLexerState.fraction, ElnaLexerClass.exponent, ElnaLexerState.exponent); + elna_lexer_set_transition(ElnaLexerState.fraction, ElnaLexerClass.alpha, ElnaLexerState.number_tail); + + -- An exponent state begins with e or E. + elna_lexer_set_transition(ElnaLexerState.exponent, ElnaLexerClass.plus, ElnaLexerState.exponent_sign); + elna_lexer_set_transition(ElnaLexerState.exponent, ElnaLexerClass.minus, ElnaLexerState.exponent_sign); + elna_lexer_set_transition(ElnaLexerState.exponent, ElnaLexerClass.zero, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.exponent, ElnaLexerClass.digit, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.exponent, ElnaLexerClass.exponent, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.exponent, ElnaLexerClass.alpha, ElnaLexerState.number_tail); + + -- Optional plus or minus sign following the exponent. + elna_lexer_set_transition(ElnaLexerState.exponent_sign, ElnaLexerClass.zero, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.exponent_sign, ElnaLexerClass.digit, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.exponent_sign, ElnaLexerClass.exponent, ElnaLexerState.number_tail); + elna_lexer_set_transition(ElnaLexerState.exponent_sign, ElnaLexerClass.alpha, ElnaLexerState.number_tail); + + -- Attribute, generic parameter or trait marker ('#'). + elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.exponent, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.alpha, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.square, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.brace, ElnaLexerState.stop); + + -- Trait identifier. + elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.exponent, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.alpha, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.zero, ElnaLexerState.trait); + elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.digit, ElnaLexerState.trait); + + -- Entering UTF-32 character literal. + elna_lexer_default_transition(ElnaLexerState.wide, ElnaLexerState.wide); + elna_lexer_set_transition(ElnaLexerState.wide, ElnaLexerClass.backslash, ElnaLexerState.wide_escape); + elna_lexer_set_transition(ElnaLexerState.wide, ElnaLexerClass.backquote, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.wide, ElnaLexerClass.eof, ElnaLexerState.reject); + elna_lexer_set_transition(ElnaLexerState.wide, ElnaLexerClass.invalid, ElnaLexerState.reject); + + elna_lexer_default_transition(ElnaLexerState.wide_escape, ElnaLexerState.wide); + elna_lexer_set_transition(ElnaLexerState.wide_escape, ElnaLexerClass.eof, ElnaLexerState.reject); + elna_lexer_set_transition(ElnaLexerState.wide_escape, ElnaLexerClass.invalid, ElnaLexerState.reject); + + -- Entering ASCII character literal. + elna_lexer_default_transition(ElnaLexerState.narrow, ElnaLexerState.narrow); + elna_lexer_set_transition(ElnaLexerState.narrow, ElnaLexerClass.backslash, ElnaLexerState.narrow_escape); + elna_lexer_set_transition(ElnaLexerState.narrow, ElnaLexerClass.backquote, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.narrow, ElnaLexerClass.eof, ElnaLexerState.reject); + elna_lexer_set_transition(ElnaLexerState.narrow, ElnaLexerClass.invalid, ElnaLexerState.reject); + + elna_lexer_default_transition(ElnaLexerState.narrow_escape, ElnaLexerState.narrow); + elna_lexer_set_transition(ElnaLexerState.narrow_escape, ElnaLexerClass.eof, ElnaLexerState.reject); + elna_lexer_set_transition(ElnaLexerState.narrow_escape, ElnaLexerClass.invalid, ElnaLexerState.reject); + + -- Entering UTF-8 string literal. + elna_lexer_default_transition(ElnaLexerState.string, ElnaLexerState.string); + elna_lexer_set_transition(ElnaLexerState.string, ElnaLexerClass.backslash, ElnaLexerState.string_escape); + elna_lexer_set_transition(ElnaLexerState.string, ElnaLexerClass.backquote, ElnaLexerState.stop); + elna_lexer_set_transition(ElnaLexerState.string, ElnaLexerClass.eof, ElnaLexerState.reject); + elna_lexer_set_transition(ElnaLexerState.string, ElnaLexerClass.invalid, ElnaLexerState.reject); + + elna_lexer_default_transition(ElnaLexerState.string_escape, ElnaLexerState.string); + elna_lexer_set_transition(ElnaLexerState.string_escape, ElnaLexerClass.eof, ElnaLexerState.reject); + elna_lexer_set_transition(ElnaLexerState.string_escape, ElnaLexerClass.invalid, ElnaLexerState.reject) +return + +end. diff --git a/source/elna/source.elna b/source/elna/source.elna new file mode 100644 index 0000000..7dfc2ac --- /dev/null +++ b/source/elna/source.elna @@ -0,0 +1,20 @@ +(* This Source Code Form is subject to the terms of the Mozilla Public License, + 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/. *) + +(* + Source code representation. +*) +module + +type + ElnaSourceLocation* = record + line: Word; + column: Word + end + ElnaSourcePosition* = record + start_location: ElnaSourceLocation; + end_location: ElnaSourceLocation + end + +end. diff --git a/source/main.elna b/source/main.elna index b45b283..12486bd 100644 --- a/source/main.elna +++ b/source/main.elna @@ -2,5 +2,8 @@ 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/. *) program() +import elna.lexer +begin + elna_lexer_transitions() end. diff --git a/source/std.elna b/source/std.elna new file mode 100644 index 0000000..33612dc --- /dev/null +++ b/source/std.elna @@ -0,0 +1,6 @@ +module + +type + String* = []Word8 + +end. -- cgit v1.2.3