aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-10-15 14:46:38 +0200
committerEugen Wissner <belka@caraus.de>2026-10-15 14:46:38 +0200
commit56a1244380133ab400f98d2da15353e080ffb360 (patch)
treef4e0aef02c8d356fc2c67bfdb2f1c490858c24cf /source
parentde6ecae0f072bb32be95382c536a517eabe4b1f1 (diff)
downloadelna-56a1244380133ab400f98d2da15353e080ffb360.tar.gz
Restrict index types to Int and WordHEADcpp
Diffstat (limited to 'source')
-rw-r--r--source/elna/lexer.elna608
-rw-r--r--source/elna/source.elna20
-rw-r--r--source/main.elna3
-rw-r--r--source/std.elna6
4 files changed, 637 insertions, 0 deletions
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.