From 00e557686baa6c1c075531e3bb49bc44669c38d2 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 7 Jun 2025 23:50:53 +0200 Subject: [PATCH] Parse call expressions --- source/Lexer.def | 22 +- source/Lexer.elna | 552 ++++++++++++++++++++++------------------- source/Parser.def | 72 +++++- source/Parser.elna | 179 ++++++++++++- source/Transpiler.elna | 294 ++++++++++------------ 5 files changed, 680 insertions(+), 439 deletions(-) diff --git a/source/Lexer.def b/source/Lexer.def index ce6fd01..faa22c2 100644 --- a/source/Lexer.def +++ b/source/Lexer.def @@ -7,12 +7,12 @@ FROM Common IMPORT Identifier, ShortString; TYPE PLexerBuffer = POINTER TO CHAR; Lexer = RECORD - Input: File; - Buffer: PLexerBuffer; - Size: CARDINAL; - Length: CARDINAL; - Start: PLexerBuffer; - Current: PLexerBuffer + input: File; + buffer: PLexerBuffer; + size: CARDINAL; + length: CARDINAL; + start: PLexerBuffer; + current: PLexerBuffer END; PLexer = POINTER TO Lexer; LexerKind = ( @@ -60,7 +60,7 @@ TYPE lexerKindComma, lexerKindPlus, lexerKindMinus, - lexerKindMultiplication, + lexerKindAsterisk, lexerKindDivision, lexerKindRemainder, lexerKindAssignment, @@ -90,11 +90,11 @@ TYPE END; PLexerToken = POINTER TO LexerToken; -PROCEDURE lexer_initialize(ALexer: PLexer; Input: File); -PROCEDURE lexer_destroy(ALexer: PLexer); +PROCEDURE lexer_initialize(lexer: PLexer; input: File); +PROCEDURE lexer_destroy(lexer: PLexer); (* Returns the last read token. *) -PROCEDURE lexer_current(ALexer: PLexer): LexerToken; +PROCEDURE lexer_current(lexer: PLexer): LexerToken; (* Read and return the next token. *) -PROCEDURE lexer_lex(ALexer: PLexer): LexerToken; +PROCEDURE lexer_lex(lexer: PLexer): LexerToken; END Lexer. diff --git a/source/Lexer.elna b/source/Lexer.elna index a0fa50e..18f0a13 100644 --- a/source/Lexer.elna +++ b/source/Lexer.elna @@ -1,6 +1,6 @@ module; -from FIO import ReadNBytes, StdErr; +from FIO import ReadNBytes; from SYSTEM import ADR, TSIZE; from DynamicStrings import String, InitStringCharStar, KillString; @@ -64,8 +64,8 @@ type ); TransitionAction = proc(PLexer, PLexerToken); Transition = record - Action: TransitionAction; - NextState: TransitionState + action: TransitionAction; + next_state: TransitionState end; TransitionClasses = [22]Transition; @@ -209,25 +209,31 @@ begin i := 129; while i <= 256 do classification[i] := transitionClassOther; - i := i + 1 + INC(i) end end; -proc compare_keyword(Keyword: ARRAY OF CHAR, TokenStart: PLexerBuffer, TokenEnd: PLexerBuffer) -> BOOLEAN; +proc compare_keyword(keyword: ARRAY OF CHAR, token_start: PLexerBuffer, token_end: PLexerBuffer) -> BOOLEAN; var result: BOOLEAN; index: CARDINAL; + keyword_length: CARDINAL; + continue: BOOLEAN; begin index := 0; result := true; + keyword_length := Length(keyword); + continue := (index < keyword_length) & (token_start <> token_end); - while (index < Length(Keyword)) & (TokenStart <> TokenEnd) & result DO - result := (Keyword[index] = TokenStart^) or (Lower(Keyword[index]) = TokenStart^); - INC(TokenStart); - INC(index) + while continue & result do + result := (keyword[index] = token_start^) or (Lower(keyword[index]) = token_start^); + INC(token_start); + INC(index); + continue := (index < keyword_length) & (token_start <> token_end) end; - result := (index = Length(Keyword)) & (TokenStart = TokenEnd) & result; - return result + result := result & (index = Length(keyword)); + + return result & (token_start = token_end) end; (* Reached the end of file. *) @@ -239,29 +245,29 @@ end; (* Add the character to the token currently read and advance to the next character. *) proc transition_action_accumulate(lexer: PLexer, token: PLexerToken); begin - INC(lexer^.Current) + INC(lexer^.current) end; (* The current character is not a part of the token. Finish the token already * read. Don't advance to the next character. *) proc transition_action_finalize(lexer: PLexer, token: PLexerToken); begin - if lexer^.Start^ = ':' then + if lexer^.start^ = ':' then token^.kind := lexerKindColon end; - if lexer^.Start^ = '>' then + if lexer^.start^ = '>' then token^.kind := lexerKindGreaterThan end; - if lexer^.Start^ = '<' then + if lexer^.start^ = '<' then token^.kind := lexerKindLessThan end; - if lexer^.Start^ = '(' then + if lexer^.start^ = '(' then token^.kind := lexerKindLeftParen end; - if lexer^.Start^ = '-' then - token^.kind := lexerKindLeftParen + if lexer^.start^ = '-' then + token^.kind := lexerKindMinus end; - if lexer^.Start^ = '.' then + if lexer^.start^ = '.' then token^.kind := lexerKindDot end end; @@ -269,34 +275,34 @@ end; (* An action for tokens containing multiple characters. *) proc transition_action_composite(lexer: PLexer, token: PLexerToken); begin - if lexer^.Start^ = '<' then - if lexer^.Current^ = '>' then + if lexer^.start^ = '<' then + if lexer^.current^ = '>' then token^.kind := lexerKindNotEqual end; - if lexer^.Current^ = '=' then + if lexer^.current^ = '=' then token^.kind := lexerKindLessEqual end end; - if (lexer^.Start^ = '>') & (lexer^.Current^ = '=') then + if (lexer^.start^ = '>') & (lexer^.current^ = '=') then token^.kind := lexerKindGreaterEqual end; - if (lexer^.Start^ = '.') & (lexer^.Current^ = '.') then + if (lexer^.start^ = '.') & (lexer^.current^ = '.') then token^.kind := lexerKindRange end; - if (lexer^.Start^ = ':') & (lexer^.Current^ = '=') then + if (lexer^.start^ = ':') & (lexer^.current^ = '=') then token^.kind := lexerKindAssignment end; - if (lexer^.Start^ = '-') & (lexer^.Current^ = '>') then + if (lexer^.start^ = '-') & (lexer^.current^ = '>') then token^.kind := lexerKindArrow end; - INC(lexer^.Current) + INC(lexer^.current) end; (* Skip a space. *) proc transition_action_skip(lexer: PLexer, token: PLexerToken); begin - INC(lexer^.Current); - INC(lexer^.Start) + INC(lexer^.current); + INC(lexer^.start) end; (* Delimited string action. *) @@ -304,20 +310,30 @@ proc transition_action_delimited(lexer: PLexer, token: PLexerToken); var text_length: CARDINAL; begin - if lexer^.Start^ = '(' then + if lexer^.start^ = '(' then token^.kind := lexerKindComment end; - if lexer^.Start^ = '"' then + if lexer^.start^ = '"' then + text_length := lexer^.current; + DEC(text_length, lexer^.start); + INC(text_length); + + MemZero(ADR(token^.stringKind), TSIZE(ShortString)); + MemCopy(lexer^.start, text_length, ADR(token^.stringKind)); + token^.kind := lexerKindCharacter end; - if lexer^.Start^ = "'" then - text_length := lexer^.Current - lexer^.Start; + if lexer^.start^ = "'" then + text_length := lexer^.current; + DEC(text_length, lexer^.start); + INC(text_length); + MemZero(ADR(token^.stringKind), TSIZE(ShortString)); - MemCopy(lexer^.Start, text_length, ADR(token^.stringKind)); + MemCopy(lexer^.start, text_length, ADR(token^.stringKind)); token^.kind := lexerKindString end; - INC(lexer^.Current) + INC(lexer^.current) end; (* Finalize keyword or identifier. *) @@ -325,101 +341,102 @@ proc transition_action_key_id(lexer: PLexer, token: PLexerToken); begin token^.kind := lexerKindIdentifier; - token^.identifierKind[1] := lexer^.Current - lexer^.Start; - MemCopy(lexer^.Start, ORD(token^.identifierKind[1]), ADR(token^.identifierKind[2])); + token^.identifierKind[1] := lexer^.current; + DEC(token^.identifierKind[1], lexer^.start); + MemCopy(lexer^.start, ORD(token^.identifierKind[1]), ADR(token^.identifierKind[2])); - if compare_keyword('PROGRAM', lexer^.Start, lexer^.Current) then + if compare_keyword('PROGRAM', lexer^.start, lexer^.current) then token^.kind := lexerKindProgram end; - if compare_keyword('IMPORT', lexer^.Start, lexer^.Current) then + if compare_keyword('IMPORT', lexer^.start, lexer^.current) then token^.kind := lexerKindImport end; - if compare_keyword('CONST', lexer^.Start, lexer^.Current) then + if compare_keyword('CONST', lexer^.start, lexer^.current) then token^.kind := lexerKindConst end; - if compare_keyword('VAR', lexer^.Start, lexer^.Current) then + if compare_keyword('VAR', lexer^.start, lexer^.current) then token^.kind := lexerKindVar end; - if compare_keyword('IF', lexer^.Start, lexer^.Current) then + if compare_keyword('IF', lexer^.start, lexer^.current) then token^.kind := lexerKindIf end; - if compare_keyword('THEN', lexer^.Start, lexer^.Current) then + if compare_keyword('THEN', lexer^.start, lexer^.current) then token^.kind := lexerKindThen end; - if compare_keyword('ELSIF', lexer^.Start, lexer^.Current) then + if compare_keyword('ELSIF', lexer^.start, lexer^.current) then token^.kind := lexerKindElsif end; - if compare_keyword('ELSE', lexer^.Start, lexer^.Current) then + if compare_keyword('ELSE', lexer^.start, lexer^.current) then token^.kind := lexerKindElse end; - if compare_keyword('WHILE', lexer^.Start, lexer^.Current) then + if compare_keyword('WHILE', lexer^.start, lexer^.current) then token^.kind := lexerKindWhile end; - if compare_keyword('DO', lexer^.Start, lexer^.Current) then + if compare_keyword('DO', lexer^.start, lexer^.current) then token^.kind := lexerKindDo end; - if compare_keyword('proc', lexer^.Start, lexer^.Current) then + if compare_keyword('proc', lexer^.start, lexer^.current) then token^.kind := lexerKindProc end; - if compare_keyword('BEGIN', lexer^.Start, lexer^.Current) then + if compare_keyword('BEGIN', lexer^.start, lexer^.current) then token^.kind := lexerKindBegin end; - if compare_keyword('END', lexer^.Start, lexer^.Current) then + if compare_keyword('END', lexer^.start, lexer^.current) then token^.kind := lexerKindEnd end; - if compare_keyword('TYPE', lexer^.Start, lexer^.Current) then + if compare_keyword('TYPE', lexer^.start, lexer^.current) then token^.kind := lexerKindType end; - if compare_keyword('RECORD', lexer^.Start, lexer^.Current) then + if compare_keyword('RECORD', lexer^.start, lexer^.current) then token^.kind := lexerKindRecord end; - if compare_keyword('UNION', lexer^.Start, lexer^.Current) then + if compare_keyword('UNION', lexer^.start, lexer^.current) then token^.kind := lexerKindUnion end; - if compare_keyword('NIL', lexer^.Start, lexer^.Current) then + if compare_keyword('NIL', lexer^.start, lexer^.current) then token^.kind := lexerKindNull end; - if compare_keyword('AND', lexer^.Start, lexer^.Current) then + if compare_keyword('AND', lexer^.start, lexer^.current) then token^.kind := lexerKindAnd end; - if compare_keyword('OR', lexer^.Start, lexer^.Current) then + if compare_keyword('OR', lexer^.start, lexer^.current) then token^.kind := lexerKindOr end; - if compare_keyword('RETURN', lexer^.Start, lexer^.Current) then + if compare_keyword('RETURN', lexer^.start, lexer^.current) then token^.kind := lexerKindReturn end; - if compare_keyword('DEFINITION', lexer^.Start, lexer^.Current) then + if compare_keyword('DEFINITION', lexer^.start, lexer^.current) then token^.kind := lexerKindDefinition end; - if compare_keyword('TO', lexer^.Start, lexer^.Current) then + if compare_keyword('TO', lexer^.start, lexer^.current) then token^.kind := lexerKindTo end; - if compare_keyword('CASE', lexer^.Start, lexer^.Current) then + if compare_keyword('CASE', lexer^.start, lexer^.current) then token^.kind := lexerKindCase end; - if compare_keyword('OF', lexer^.Start, lexer^.Current) then + if compare_keyword('OF', lexer^.start, lexer^.current) then token^.kind := lexerKindOf end; - if compare_keyword('FROM', lexer^.Start, lexer^.Current) then + if compare_keyword('FROM', lexer^.start, lexer^.current) then token^.kind := lexerKindFrom end; - if compare_keyword('MODULE', lexer^.Start, lexer^.Current) then + if compare_keyword('MODULE', lexer^.start, lexer^.current) then token^.kind := lexerKindModule end; - if compare_keyword('IMPLEMENTATION', lexer^.Start, lexer^.Current) then + if compare_keyword('IMPLEMENTATION', lexer^.start, lexer^.current) then token^.kind := lexerKindImplementation end; - if compare_keyword('POINTER', lexer^.Start, lexer^.Current) then + if compare_keyword('POINTER', lexer^.start, lexer^.current) then token^.kind := lexerKindPointer end; - if compare_keyword('ARRAY', lexer^.Start, lexer^.Current) then + if compare_keyword('ARRAY', lexer^.start, lexer^.current) then token^.kind := lexerKindArray end; - if compare_keyword('TRUE', lexer^.Start, lexer^.Current) then + if compare_keyword('TRUE', lexer^.start, lexer^.current) then token^.kind := lexerKindBoolean; token^.booleanKind := true end; - if compare_keyword('FALSE', lexer^.Start, lexer^.Current) then + if compare_keyword('FALSE', lexer^.start, lexer^.current) then token^.kind := lexerKindBoolean; token^.booleanKind := false end @@ -429,49 +446,52 @@ end; * followed by other characters forming a composite token. *) proc transition_action_single(lexer: PLexer, token: PLexerToken); begin - if lexer^.Current^ = '&' then + if lexer^.current^ = '&' then token^.kind := lexerKindAnd end; - if lexer^.Current^ = ';' then + if lexer^.current^ = ';' then token^.kind := lexerKindSemicolon end; - if lexer^.Current^ = ',' then + if lexer^.current^ = ',' then token^.kind := lexerKindComma end; - if lexer^.Current^ = '~' then + if lexer^.current^ = '~' then token^.kind := lexerKindTilde end; - if lexer^.Current^ = ')' then + if lexer^.current^ = ')' then token^.kind := lexerKindRightParen end; - if lexer^.Current^ = '[' then + if lexer^.current^ = '[' then token^.kind := lexerKindLeftSquare end; - if lexer^.Current^ = ']' then + if lexer^.current^ = ']' then token^.kind := lexerKindRightSquare end; - if lexer^.Current^ = '^' then + if lexer^.current^ = '^' then token^.kind := lexerKindHat end; - if lexer^.Current^ = '=' then + if lexer^.current^ = '=' then token^.kind := lexerKindEqual end; - if lexer^.Current^ = '+' then + if lexer^.current^ = '+' then token^.kind := lexerKindPlus end; - if lexer^.Current^ = '/' then + if lexer^.current^ = '*' then + token^.kind := lexerKindAsterisk + end; + if lexer^.current^ = '/' then token^.kind := lexerKindDivision end; - if lexer^.Current^ = '%' then + if lexer^.current^ = '%' then token^.kind := lexerKindRemainder end; - if lexer^.Current^ = '@' then + if lexer^.current^ = '@' then token^.kind := lexerKindAt end; - if lexer^.Current^ = '|' then + if lexer^.current^ = '|' then token^.kind := lexerKindPipe end; - INC(lexer^.Current) + INC(lexer^.current) end; (* Handle an integer literal. *) @@ -483,44 +503,45 @@ var begin token^.kind := lexerKindInteger; - integer_length := lexer^.Current - lexer^.Start; + integer_length := lexer^.current; + DEC(integer_length, lexer^.start); MemZero(ADR(token^.identifierKind), TSIZE(Identifier)); - MemCopy(lexer^.Start, integer_length, ADR(token^.identifierKind[1])); + MemCopy(lexer^.start, integer_length, ADR(token^.identifierKind[1])); buffer := InitStringCharStar(ADR(token^.identifierKind[1])); token^.integerKind := StringToInteger(buffer, 10, found); buffer := KillString(buffer) end; -proc set_default_transition(CurrentState: TransitionState, DefaultAction: TransitionAction, NextState: TransitionState); +proc set_default_transition(current_state: TransitionState, DefaultAction: TransitionAction, next_state: TransitionState); var - DefaultTransition: Transition; + default_transition: Transition; begin - DefaultTransition.Action := DefaultAction; - DefaultTransition.NextState := NextState; + default_transition.action := DefaultAction; + default_transition.next_state := next_state; - transitions[ORD(CurrentState) + 1][ORD(transitionClassInvalid) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassDigit) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassAlpha) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassSpace) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassColon) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassEquals) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassLeftParen) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassRightParen) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassAsterisk) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassUnderscore) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassSingle) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassHex) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassZero) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassX) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassEof) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassDot) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassMinus) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassSingleQuote) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassDoubleQuote) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassGreater) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassLess) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassOther) + 1] := DefaultTransition + transitions[ORD(current_state) + 1][ORD(transitionClassInvalid) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassDigit) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassAlpha) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassSpace) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassColon) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassEquals) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassLeftParen) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassRightParen) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassAsterisk) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassUnderscore) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassSingle) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassHex) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassZero) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassX) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassEof) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassDot) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassMinus) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassSingleQuote) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassDoubleQuote) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassGreater) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassLess) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassOther) + 1] := default_transition end; (* @@ -542,269 +563,278 @@ end; proc initialize_transitions(); begin (* Start state. *) - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassInvalid) + 1].Action := nil; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassInvalid) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassInvalid) + 1].action := nil; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassInvalid) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDigit) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateDecimal; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDigit) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDigit) + 1].next_state := transitionStateDecimal; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAlpha) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAlpha) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAlpha) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSpace) + 1].Action := transition_action_skip; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSpace) + 1].NextState := transitionStateStart; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSpace) + 1].action := transition_action_skip; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSpace) + 1].next_state := transitionStateStart; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassColon) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassColon) + 1].NextState := transitionStateColon; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassColon) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassColon) + 1].next_state := transitionStateColon; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEquals) + 1].Action := transition_action_single; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEquals) + 1].action := transition_action_single; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEquals) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLeftParen) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLeftParen) + 1].NextState := transitionStateLeftParen; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLeftParen) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLeftParen) + 1].next_state := transitionStateLeftParen; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassRightParen) + 1].Action := transition_action_single; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassRightParen) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassRightParen) + 1].action := transition_action_single; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassRightParen) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAsterisk) + 1].Action := transition_action_single; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAsterisk) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAsterisk) + 1].action := transition_action_single; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAsterisk) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassUnderscore) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassUnderscore) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassUnderscore) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassUnderscore) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingle) + 1].Action := transition_action_single; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingle) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingle) + 1].action := transition_action_single; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingle) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassHex) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassHex) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassHex) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassZero) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateLeadingZero; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassZero) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassZero) + 1].next_state := transitionStateLeadingZero; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassX) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassX) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassX) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassX) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEof) + 1].Action := transition_action_eof; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEof) + 1].action := transition_action_eof; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDot) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDot) + 1].NextState := transitionStateDot; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDot) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDot) + 1].next_state := transitionStateDot; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassMinus) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassMinus) + 1].NextState := transitionStateMinus; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassMinus) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassMinus) + 1].next_state := transitionStateMinus; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingleQuote) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingleQuote) + 1].NextState := transitionStateCharacter; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingleQuote) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingleQuote) + 1].next_state := transitionStateCharacter; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDoubleQuote) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDoubleQuote) + 1].NextState := transitionStateString; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDoubleQuote) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDoubleQuote) + 1].next_state := transitionStateString; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassGreater) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassGreater) + 1].NextState := transitionStateGreater; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassGreater) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassGreater) + 1].next_state := transitionStateGreater; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLess) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLess) + 1].NextState := transitionStateLess; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLess) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLess) + 1].next_state := transitionStateLess; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassOther) + 1].Action := nil; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassOther) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassOther) + 1].action := nil; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassOther) + 1].next_state := transitionStateEnd; (* Colon state. *) set_default_transition(transitionStateColon, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateColon) + 1][ORD(transitionClassEquals) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateColon) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateColon) + 1][ORD(transitionClassEquals) + 1].action := transition_action_composite; + transitions[ORD(transitionStateColon) + 1][ORD(transitionClassEquals) + 1].next_state := transitionStateEnd; (* Identifier state. *) set_default_transition(transitionStateIdentifier, transition_action_key_id, transitionStateEnd); - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassDigit) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassDigit) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassDigit) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassAlpha) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassAlpha) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassAlpha) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassUnderscore) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassUnderscore) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassUnderscore) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassUnderscore) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassHex) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassHex) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassHex) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassZero) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassZero) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassZero) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassX) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassX) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassX) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassX) + 1].next_state := transitionStateIdentifier; (* Decimal state. *) set_default_transition(transitionStateDecimal, transition_action_integer, transitionStateEnd); - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassDigit) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateDecimal; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassDigit) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassDigit) + 1].next_state := transitionStateDecimal; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassAlpha) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateDecimalSuffix; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassAlpha) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassAlpha) + 1].next_state := transitionStateDecimalSuffix; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassUnderscore) + 1].Action := nil; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassUnderscore) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassUnderscore) + 1].action := nil; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassUnderscore) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassHex) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateDecimalSuffix; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassHex) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassHex) + 1].next_state := transitionStateDecimalSuffix; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassZero) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateDecimal; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassZero) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassZero) + 1].next_state := transitionStateDecimal; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassX) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassX) + 1].NextState := transitionStateDecimalSuffix; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassX) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassX) + 1].next_state := transitionStateDecimalSuffix; (* Greater state. *) set_default_transition(transitionStateGreater, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateGreater) + 1][ORD(transitionClassEquals) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateGreater) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateGreater) + 1][ORD(transitionClassEquals) + 1].action := transition_action_composite; + transitions[ORD(transitionStateGreater) + 1][ORD(transitionClassEquals) + 1].next_state := transitionStateEnd; (* Minus state. *) set_default_transition(transitionStateMinus, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateMinus) + 1][ORD(transitionClassGreater) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateMinus) + 1][ORD(transitionClassGreater) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateMinus) + 1][ORD(transitionClassGreater) + 1].action := transition_action_composite; + transitions[ORD(transitionStateMinus) + 1][ORD(transitionClassGreater) + 1].next_state := transitionStateEnd; (* Left paren state. *) set_default_transition(transitionStateLeftParen, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateLeftParen) + 1][ORD(transitionClassAsterisk) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateLeftParen) + 1][ORD(transitionClassAsterisk) + 1].NextState := transitionStateComment; + transitions[ORD(transitionStateLeftParen) + 1][ORD(transitionClassAsterisk) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateLeftParen) + 1][ORD(transitionClassAsterisk) + 1].next_state := transitionStateComment; (* Less state. *) set_default_transition(transitionStateLess, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateLess) + 1][ORD(transitionClassEquals) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateLess) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLess) + 1][ORD(transitionClassEquals) + 1].action := transition_action_composite; + transitions[ORD(transitionStateLess) + 1][ORD(transitionClassEquals) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLess) + 1][ORD(transitionClassGreater) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateLess) + 1][ORD(transitionClassGreater) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLess) + 1][ORD(transitionClassGreater) + 1].action := transition_action_composite; + transitions[ORD(transitionStateLess) + 1][ORD(transitionClassGreater) + 1].next_state := transitionStateEnd; (* Hexadecimal after 0x. *) set_default_transition(transitionStateDot, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateDot) + 1][ORD(transitionClassDot) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateDot) + 1][ORD(transitionClassDot) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDot) + 1][ORD(transitionClassDot) + 1].action := transition_action_composite; + transitions[ORD(transitionStateDot) + 1][ORD(transitionClassDot) + 1].next_state := transitionStateEnd; (* Comment. *) set_default_transition(transitionStateComment, transition_action_accumulate, transitionStateComment); - transitions[ORD(transitionStateComment) + 1][ORD(transitionClassAsterisk) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateComment) + 1][ORD(transitionClassAsterisk) + 1].NextState := transitionStateClosingComment; + transitions[ORD(transitionStateComment) + 1][ORD(transitionClassAsterisk) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateComment) + 1][ORD(transitionClassAsterisk) + 1].next_state := transitionStateClosingComment; - transitions[ORD(transitionStateComment) + 1][ORD(transitionClassEof) + 1].Action := nil; - transitions[ORD(transitionStateComment) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateComment) + 1][ORD(transitionClassEof) + 1].action := nil; + transitions[ORD(transitionStateComment) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd; (* Closing comment. *) set_default_transition(transitionStateClosingComment, transition_action_accumulate, transitionStateComment); - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassInvalid) + 1].Action := nil; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassInvalid) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassInvalid) + 1].action := nil; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassInvalid) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassRightParen) + 1].Action := transition_action_delimited; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassRightParen) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassRightParen) + 1].action := transition_action_delimited; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassRightParen) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassAsterisk) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassAsterisk) + 1].NextState := transitionStateClosingComment; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassAsterisk) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassAsterisk) + 1].next_state := transitionStateClosingComment; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassEof) + 1].Action := nil; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassEof) + 1].action := nil; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd; (* Character. *) set_default_transition(transitionStateCharacter, transition_action_accumulate, transitionStateCharacter); - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassInvalid) + 1].Action := nil; - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassInvalid) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassInvalid) + 1].action := nil; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassInvalid) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassEof) + 1].Action := nil; - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassEof) + 1].action := nil; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassSingleQuote) + 1].Action := transition_action_delimited; - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassSingleQuote) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassSingleQuote) + 1].action := transition_action_delimited; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassSingleQuote) + 1].next_state := transitionStateEnd; (* String. *) set_default_transition(transitionStateString, transition_action_accumulate, transitionStateString); - transitions[ORD(transitionStateString) + 1][ORD(transitionClassInvalid) + 1].Action := nil; - transitions[ORD(transitionStateString) + 1][ORD(transitionClassInvalid) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassInvalid) + 1].action := nil; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassInvalid) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateString) + 1][ORD(transitionClassEof) + 1].Action := nil; - transitions[ORD(transitionStateString) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassEof) + 1].action := nil; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateString) + 1][ORD(transitionClassDoubleQuote) + 1].Action := transition_action_delimited; - transitions[ORD(transitionStateString) + 1][ORD(transitionClassDoubleQuote) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassDoubleQuote) + 1].action := transition_action_delimited; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassDoubleQuote) + 1].next_state := transitionStateEnd; (* Leading zero. *) set_default_transition(transitionStateLeadingZero, transition_action_integer, transitionStateEnd); - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassDigit) + 1].Action := nil; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassDigit) + 1].action := nil; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassDigit) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassAlpha) + 1].Action := nil; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassAlpha) + 1].action := nil; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassAlpha) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassUnderscore) + 1].Action := nil; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassUnderscore) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassUnderscore) + 1].action := nil; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassUnderscore) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassHex) + 1].Action := nil; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassHex) + 1].action := nil; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassHex) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassZero) + 1].Action := nil; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassZero) + 1].action := nil; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassZero) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassX) + 1].Action := nil; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassX) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassX) + 1].action := nil; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassX) + 1].next_state := transitionStateEnd; (* Digit with a character suffix. *) set_default_transition(transitionStateDecimalSuffix, transition_action_integer, transitionStateEnd); - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassAlpha) + 1].Action := nil; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassAlpha) + 1].action := nil; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassAlpha) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassDigit) + 1].Action := nil; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassDigit) + 1].action := nil; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassDigit) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassHex) + 1].Action := nil; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassHex) + 1].action := nil; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassHex) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassZero) + 1].Action := nil; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassZero) + 1].action := nil; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassZero) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassX) + 1].Action := nil; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassX) + 1].NextState := transitionStateEnd + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassX) + 1].action := nil; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassX) + 1].next_state := transitionStateEnd end; -proc lexer_initialize(lexer: PLexer, Input: File); +proc lexer_initialize(lexer: PLexer, input: File); begin - lexer^.Input := Input; - lexer^.Length := 0; + lexer^.input := input; + lexer^.length := 0; - ALLOCATE(lexer^.Buffer, CHUNK_SIZE); - MemZero(lexer^.Buffer, CHUNK_SIZE); - lexer^.Size := CHUNK_SIZE + ALLOCATE(lexer^.buffer, CHUNK_SIZE); + MemZero(lexer^.buffer, CHUNK_SIZE); + lexer^.size := CHUNK_SIZE end; proc lexer_current(lexer: PLexer) -> LexerToken; var - CurrentClass: TransitionClass; - CurrentState: TransitionState; - CurrentTransition: Transition; + current_class: TransitionClass; + current_state: TransitionState; + current_transition: Transition; result: LexerToken; + index1: CARDINAL; + index2: CARDINAL; begin - lexer^.Current := lexer^.Start; - CurrentState := transitionStateStart; + lexer^.current := lexer^.start; + current_state := transitionStateStart; - while CurrentState <> transitionStateEnd DO - CurrentClass := classification[ORD(lexer^.Current^) + 1]; + while current_state <> transitionStateEnd DO + index1 := ORD(lexer^.current^); + INC(index1); + current_class := classification[index1]; - CurrentTransition := transitions[ORD(CurrentState) + 1][ORD(CurrentClass) + 1]; - if CurrentTransition.Action <> nil then - CurrentTransition.Action(lexer, ADR(result)) + index1 := ORD(current_state); + INC(index1); + index2 := ORD(current_class); + INC(index2); + + current_transition := transitions[index1][index2]; + if current_transition.action <> nil then + current_transition.action(lexer, ADR(result)) end; - CurrentState := CurrentTransition.NextState + current_state := current_transition.next_state end; return result end; @@ -813,11 +843,11 @@ proc lexer_lex(lexer: PLexer) -> LexerToken; var result: LexerToken; begin - if lexer^.Length = 0 then - lexer^.Length := ReadNBytes(lexer^.Input, CHUNK_SIZE, lexer^.Buffer); - lexer^.Current := lexer^.Buffer + if lexer^.length = 0 then + lexer^.length := ReadNBytes(lexer^.input, CHUNK_SIZE, lexer^.buffer); + lexer^.current := lexer^.buffer end; - lexer^.Start := lexer^.Current; + lexer^.start := lexer^.current; result := lexer_current(lexer); return result @@ -825,7 +855,7 @@ end; proc lexer_destroy(lexer: PLexer); begin - DEALLOCATE(lexer^.Buffer, lexer^.Size) + DEALLOCATE(lexer^.buffer, lexer^.size) end; begin diff --git a/source/Parser.def b/source/Parser.def index 65e58cd..7c135a8 100644 --- a/source/Parser.def +++ b/source/Parser.def @@ -7,21 +7,42 @@ TYPE AstLiteralKind = ( astLiteralKindInteger, astLiteralKindString, - astLiteralKindNull + astLiteralKindNull, + astLiteralKindBoolean ); AstLiteral = RECORD CASE kind: AstLiteralKind OF astLiteralKindInteger: integer: INTEGER | astLiteralKindString: string: ShortString | - astLiteralKindNull: + astLiteralKindNull: | + astLiteralKindBoolean: boolean: BOOLEAN END END; PAstLiteral = POINTER TO AstLiteral; AstUnaryOperator = ( + astUnaryOperatorReference, astUnaryOperatorNot, astUnaryOperatorMinus ); + AstBinaryOperator = ( + astBinaryOperatorSum, + astBinaryOperatorSubtraction, + astBinaryOperatorMultiplication, + astBinaryOperatorDivision, + astBinaryOperatorRemainder, + astBinaryOperatorEquals, + astBinaryOperatorNotEquals, + astBinaryOperatorLess, + astBinaryOperatorGreater, + astBinaryOperatorLessEqual, + astBinaryOperatorGreaterEqual, + astBinaryOperatorDisjunction, + astBinaryOperatorConjunction, + astBinaryOperatorExclusiveDisjunction, + astBinaryOperatorShiftLeft, + astBinaryOperatorShiftRight + ); AstExpressionKind = ( astExpressionKindLiteral, @@ -29,7 +50,9 @@ TYPE astExpressionKindArrayAccess, astExpressionKindDereference, astExpressionKindFieldAccess, - astExpressionKindUnary + astExpressionKindUnary, + astExpressionKindBinary, + astExpressionKindCall ); AstExpression = RECORD CASE kind: AstExpressionKind OF @@ -44,12 +67,49 @@ TYPE field: Identifier | astExpressionKindUnary: unary_operator: AstUnaryOperator; - unary_operand: PAstExpression + unary_operand: PAstExpression | + astExpressionKindBinary: + binary_operator: AstBinaryOperator; + lhs: PAstExpression; + rhs: PAstExpression | + astExpressionKindCall: + callable: PAstExpression; + argument_count: CARDINAL; + arguments: PPAstExpression END END; PAstExpression = POINTER TO AstExpression; PPAstExpression = POINTER TO PAstExpression; + AstStatementKind = ( + astStatementKindIf, + astStatementKindWhile, + astStatementKindAssignment, + astStatementKindReturn, + astStatementKindCall + ); + AstStatement = RECORD + CASE kind: AstStatementKind OF + astStatementKindIf: + if_condition: PAstExpression; + if_branch: AstCompoundStatement | + astStatementKindWhile: + while_condition: PAstExpression; + while_body: AstCompoundStatement | + astStatementKindAssignment: + assignee: PAstExpression; + assignment: PAstExpression | + astStatementKindReturn: returned: PAstExpression | + astStatementKindCall: call: PAstExpression + END + END; + PAstStatement = POINTER TO AstStatement; + PPAstStatement = POINTER TO PAstStatement; + AstCompoundStatement = RECORD + count: CARDINAL; + statements: PPAstStatement + END; + AstImportStatement = RECORD package: Identifier; symbols: PIdentifier @@ -121,5 +181,9 @@ PROCEDURE parse_variable_part(lexer: PLexer): PPAstVariableDeclaration; PROCEDURE parse_constant_part(lexer: PLexer): PPAstConstantDeclaration; PROCEDURE parse_import_part(lexer: PLexer): PPAstImportStatement; PROCEDURE parse_designator(lexer: PLexer): PAstExpression; +PROCEDURE parse_expression(lexer: PLexer): PAstExpression; +PROCEDURE parse_return_statement(lexer: PLexer): PAstStatement; +PROCEDURE parse_assignment_statement(lexer: PLexer; assignee: PAstExpression): PAstStatement; +PROCEDURE parse_call_statement(lexer: PLexer; call: PAstExpression): PAstStatement; END Parser. diff --git a/source/Parser.elna b/source/Parser.elna index f0c552a..f32a728 100644 --- a/source/Parser.elna +++ b/source/Parser.elna @@ -1,11 +1,12 @@ module; +from FIO import ReadNBytes; from SYSTEM import TSIZE; from MemUtils import MemZero; from Storage import ALLOCATE, REALLOCATE; -from Lexer import LexerKind, LexerToken, lexer_current, lexer_lex; +from Lexer import Lexer, LexerKind, LexerToken, lexer_current, lexer_lex; (* Calls lexer_lex() but skips the comments. *) proc transpiler_lex(lexer: PLexer) -> LexerToken; @@ -34,7 +35,9 @@ begin while token.kind <> lexerKindEnd do INC(field_count); - REALLOCATE(field_declarations, TSIZE(AstFieldDeclaration) * (field_count + 1)); + INC(field_count); + REALLOCATE(field_declarations, TSIZE(AstFieldDeclaration) * field_count); + DEC(field_count); current_field := field_declarations; INC(current_field , TSIZE(AstFieldDeclaration) * (field_count - 1)); @@ -136,7 +139,9 @@ begin token := transpiler_lex(lexer); INC(case_count); - REALLOCATE(result^.cases, TSIZE(Identifier) * (case_count + 1)); + INC(case_count); + REALLOCATE(result^.cases, TSIZE(Identifier) * case_count); + DEC(case_count); current_case := result^.cases; INC(current_case, TSIZE(Identifier) * (case_count - 1)); current_case^ := token.identifierKind; @@ -181,7 +186,9 @@ begin while token.kind <> lexerKindRightParen do INC(parameter_count); - REALLOCATE(result^.parameters, TSIZE(PAstTypeExpression) * (parameter_count + 1)); + INC(parameter_count); + REALLOCATE(result^.parameters, TSIZE(PAstTypeExpression) * parameter_count); + DEC(parameter_count); current_parameter := result^.parameters; INC(current_parameter, TSIZE(PAstTypeExpression) * (parameter_count - 1)); @@ -476,7 +483,7 @@ begin literal^.kind := astLiteralKindInteger; literal^.integer := token.integerKind; end; - if token.kind = lexerKindCharacter then + if (token.kind = lexerKindCharacter) or (token.kind = lexerKindString) then NEW(literal); literal^.kind := astLiteralKindString; @@ -487,6 +494,12 @@ begin literal^.kind := astLiteralKindNull; end; + if token.kind = lexerKindBoolean then + NEW(literal); + + literal^.kind := astLiteralKindBoolean; + literal^.boolean := token.booleanKind + end; if literal <> nil then token := transpiler_lex(lexer) end; @@ -527,6 +540,13 @@ begin result^.unary_operator := astUnaryOperatorNot; result^.unary_operand := parse_factor(lexer) end; + if (result = nil) & (next_token.kind = lexerKindLeftParen) then + next_token := transpiler_lex(lexer); + result := parse_expression(lexer); + if result <> nil then + next_token := transpiler_lex(lexer) + end + end; if (result = nil) & (next_token.kind = lexerKindIdentifier) then NEW(result); @@ -544,6 +564,7 @@ var next_token: LexerToken; inner_expression: PAstExpression; designator: PAstExpression; + arguments: PPAstExpression; handled: BOOLEAN; begin designator := parse_factor(lexer); @@ -569,7 +590,7 @@ begin designator^.kind := astExpressionKindArrayAccess; designator^.array := inner_expression; - designator^.index := parse_designator(lexer); + designator^.index := parse_expression(lexer); next_token := transpiler_lex(lexer); handled := true @@ -582,6 +603,38 @@ begin designator^.aggregate := inner_expression; designator^.field := next_token.identifierKind; + next_token := transpiler_lex(lexer); + handled := true + end; + if ~handled & (next_token.kind = lexerKindLeftParen) then + NEW(designator); + next_token := transpiler_lex(lexer); + + designator^.kind := astExpressionKindCall; + designator^.callable := inner_expression; + designator^.argument_count := 0; + designator^.arguments := nil; + + if next_token.kind <> lexerKindRightParen then + ALLOCATE(designator^.arguments, TSIZE(PAstExpression)); + designator^.argument_count := 1; + designator^.arguments^ := parse_expression(lexer); + + next_token := lexer_current(lexer); + + while next_token.kind = lexerKindComma do + next_token := transpiler_lex(lexer); + + designator^.argument_count := designator^.argument_count + 1; + REALLOCATE(designator^.arguments, TSIZE(PAstExpression) * designator^.argument_count); + arguments := designator^.arguments; + INC(arguments, TSIZE(PAstExpression) * (designator^.argument_count - 1)); + arguments^ := parse_expression(lexer); + + next_token := lexer_current(lexer) + end + end; + next_token := transpiler_lex(lexer); handled := true end @@ -590,4 +643,118 @@ begin return designator end; +proc parse_binary_expression(lexer: PLexer, left: PAstExpression, operator: AstBinaryOperator) -> PAstExpression; +var + next_token: LexerToken; + result: PAstExpression; + right: PAstExpression; +begin + next_token := transpiler_lex(lexer); + right := parse_designator(lexer); + result := nil; + + if right <> nil then + NEW(result); + result^.kind := astExpressionKindBinary; + result^.binary_operator := operator; + result^.lhs := left; + result^.rhs := right; + end; + + return result +end; + +proc parse_expression(lexer: PLexer) -> PAstExpression; +var + next_token: LexerToken; + left: PAstExpression; + result: PAstExpression; + written_bytes: CARDINAL; +begin + left := parse_designator(lexer); + result := nil; + next_token := lexer_current(lexer); + + if left <> nil then + if (result = nil) & (next_token.kind = lexerKindNotEqual) then + result := parse_binary_expression(lexer, left, astBinaryOperatorNotEquals) + end; + if (result = nil) & (next_token.kind = lexerKindEqual) then + result := parse_binary_expression(lexer, left, astBinaryOperatorEquals) + end; + if (result = nil) & (next_token.kind = lexerKindGreaterThan) then + result := parse_binary_expression(lexer, left, astBinaryOperatorGreater) + end; + if (result = nil) & (next_token.kind = lexerKindLessThan) then + result := parse_binary_expression(lexer, left, astBinaryOperatorLess) + end; + if (result = nil) & (next_token.kind = lexerKindGreaterEqual) then + result := parse_binary_expression(lexer, left, astBinaryOperatorGreaterEqual) + end; + if (result = nil) & (next_token.kind = lexerKindLessEqual) then + result := parse_binary_expression(lexer, left, astBinaryOperatorLessEqual) + end; + if (result = nil) & (next_token.kind = lexerKindAnd) then + result := parse_binary_expression(lexer, left, astBinaryOperatorConjunction) + end; + if (result = nil) & (next_token.kind = lexerKindOr) then + result := parse_binary_expression(lexer, left, astBinaryOperatorDisjunction) + end; + if (result = nil) & (next_token.kind = lexerKindMinus) then + result := parse_binary_expression(lexer, left, astBinaryOperatorSubtraction) + end; + if (result = nil) & (next_token.kind = lexerKindPlus) then + result := parse_binary_expression(lexer, left, astBinaryOperatorSum) + end; + if (result = nil) & (next_token.kind = lexerKindAsterisk) then + result := parse_binary_expression(lexer, left, astBinaryOperatorMultiplication) + end + end; + if (result = nil) & (left <> nil) then + result := left + end; + + return result +end; + +proc parse_return_statement(lexer: PLexer) -> PAstStatement; +var + token: LexerToken; + result: PAstStatement; +begin + NEW(result); + result^.kind := astStatementKindReturn; + + token := transpiler_lex(lexer); + result^.returned := parse_expression(lexer); + + return result +end; + +proc parse_assignment_statement(lexer: PLexer, assignee: PAstExpression) -> PAstStatement; +var + token: LexerToken; + result: PAstStatement; +begin + NEW(result); + result^.kind := astStatementKindAssignment; + result^.assignee := assignee; + + token := transpiler_lex(lexer); + result^.assignment := parse_expression(lexer); + + return result +end; + +proc parse_call_statement(lexer: PLexer, call: PAstExpression) -> PAstStatement; +var + result: PAstStatement; +begin + NEW(result); + result^.kind := astStatementKindCall; + result^.call := call; + + return result +end; + end. diff --git a/source/Transpiler.elna b/source/Transpiler.elna index f576bea..c63f040 100644 --- a/source/Transpiler.elna +++ b/source/Transpiler.elna @@ -9,14 +9,14 @@ from MemUtils import MemCopy, MemZero; from Common import Identifier, PIdentifier, ShortString; from Lexer import Lexer, LexerToken, lexer_current, lexer_lex, LexerKind; -from Parser import AstTypeExpressionKind, AstExpressionKind, AstLiteralKind, AstUnaryOperator, - AstModule, PAstModule, AstExpression, PAstExpression, PAstLiteral, - PAstConstantDeclaration, PPAstConstantDeclaration, +from Parser import AstTypeExpressionKind, AstExpressionKind, AstLiteralKind, AstUnaryOperator, AstBinaryOperator, + AstModule, PAstModule, AstExpression, PPAstExpression, PAstExpression, PAstLiteral, + PAstConstantDeclaration, PPAstConstantDeclaration, PAstStatement, AstStatementKind, AstTypeDeclaration, PAstTypeDeclaration, PPAstTypeDeclaration, PAstVariableDeclaration, PPAstVariableDeclaration, PAstImportStatement, PPAstImportStatement, PAstTypeExpression, PPAstTypeExpression, AstFieldDeclaration, PAstFieldDeclaration, parse_type_expression, parse_variable_part, parse_type_part, parse_constant_part, parse_import_part, - parse_designator; + parse_designator, parse_expression, parse_return_statement, parse_assignment_statement, parse_call_statement; (* Calls lexer_lex() but skips the comments. *) proc transpiler_lex(lexer: PLexer) -> LexerToken; @@ -42,8 +42,12 @@ end; proc write_current(lexer: PLexer, output: File); var written_bytes: CARDINAL; + count: CARDINAL; begin - written_bytes := WriteNBytes(output, ADDRESS(lexer^.Current - lexer^.Start), lexer^.Start) + count := lexer^.current; + DEC(count, lexer^.start); + + written_bytes := WriteNBytes(output, count, lexer^.start) end; proc transpile_import_statement(context: PTranspilerContext, import_statement: PAstImportStatement); @@ -406,61 +410,6 @@ begin return result end; -proc transpile_unchanged(context: PTranspilerContext, trailing_token: LexerKind); -var - token: LexerToken; - written_bytes: CARDINAL; -begin - token := lexer_current(context^.lexer); - - while (token.kind <> trailing_token) & (token.kind <> lexerKindEnd) do - written_bytes := 0; - if token.kind = lexerKindNull then - WriteString(context^.output, 'NIL '); - written_bytes := 1 - end; - if (token.kind = lexerKindBoolean) & token.booleanKind then - WriteString(context^.output, 'TRUE '); - written_bytes := 1 - end; - if (token.kind = lexerKindBoolean) & (~token.booleanKind) then - WriteString(context^.output, 'FALSE '); - written_bytes := 1 - end; - if token.kind = lexerKindOr then - WriteString(context^.output, 'OR '); - written_bytes := 1 - end; - if token.kind = lexerKindAnd then - WriteString(context^.output, 'AND '); - written_bytes := 1 - end; - if token.kind = lexerKindTilde then - WriteString(context^.output, 'NOT '); - written_bytes := 1 - end; - if written_bytes = 0 then - write_current(context^.lexer, context^.output); - WriteChar(context^.output, ' ') - end; - token := transpiler_lex(context^.lexer) - end -end; - -proc parse_expression(lexer: PLexer) -> PAstExpression; -var - next_token: LexerToken; - result: PAstExpression; - written_bytes: CARDINAL; -begin - result := parse_designator(lexer); - - written_bytes := WriteNBytes(StdErr, ADDRESS(lexer^.Current - lexer^.Start), lexer^.Start); - WriteLine(StdErr); - - return result -end; - proc transpile_unary_operator(context: PTranspilerContext, operator: AstUnaryOperator); begin if operator = astUnaryOperatorMinus then @@ -471,11 +420,50 @@ begin end end; +proc transpile_binary_operator(context: PTranspilerContext, operator: AstBinaryOperator); +begin + if operator = astBinaryOperatorSum then + WriteChar(context^.output, '+') + end; + if operator = astBinaryOperatorSubtraction then + WriteChar(context^.output, '-') + end; + if operator = astBinaryOperatorMultiplication then + WriteChar(context^.output, '*') + end; + if operator = astBinaryOperatorEquals then + WriteChar(context^.output, '=') + end; + if operator = astBinaryOperatorNotEquals then + WriteChar(context^.output, '#') + end; + if operator = astBinaryOperatorLess then + WriteChar(context^.output, '<') + end; + if operator = astBinaryOperatorGreater then + WriteChar(context^.output, '>') + end; + if operator = astBinaryOperatorLessEqual then + WriteString(context^.output, '<=') + end; + if operator = astBinaryOperatorGreaterEqual then + WriteString(context^.output, '>=') + end; + if operator = astBinaryOperatorDisjunction then + WriteString(context^.output, 'OR') + end; + if operator = astBinaryOperatorConjunction then + WriteString(context^.output, 'AND') + end +end; + proc transpile_expression(context: PTranspilerContext, expression: PAstExpression); var literal: PAstLiteral; buffer: [20]CHAR; written_bytes: CARDINAL; + argument_index: CARDINAL; + current_argument: PPAstExpression; begin if expression^.kind = astExpressionKindLiteral then literal := expression^.literal; @@ -486,7 +474,16 @@ begin end; if literal^.kind = astLiteralKindString then WriteString(context^.output, literal^.string) - end + end; + if literal^.kind = astLiteralKindNull then + WriteString(context^.output, 'NIL') + end; + if (literal^.kind = astLiteralKindBoolean) & literal^.boolean then + WriteString(context^.output, 'TRUE') + end; + if (literal^.kind = astLiteralKindBoolean) & (literal^.boolean = false) then + WriteString(context^.output, 'FALSE') + end end; if expression^.kind = astExpressionKindIdentifier then written_bytes := WriteNBytes(context^.output, ORD(expression^.identifier[1]), ADR(expression^.identifier[2])) @@ -509,152 +506,135 @@ begin if expression^.kind = astExpressionKindUnary then transpile_unary_operator(context, expression^.unary_operator); transpile_expression(context, expression^.unary_operand) + end; + if expression^.kind = astExpressionKindBinary then + WriteChar(context^.output, '('); + transpile_expression(context, expression^.lhs); + WriteChar(context^.output, ' '); + transpile_binary_operator(context, expression^.binary_operator); + WriteChar(context^.output, ' '); + transpile_expression(context, expression^.rhs); + WriteChar(context^.output, ')') + end; + if expression^.kind = astExpressionKindCall then + transpile_expression(context, expression^.callable); + WriteChar(context^.output, '('); + + current_argument := expression^.arguments; + if expression^.argument_count > 0 then + transpile_expression(context, current_argument^); + + argument_index := 1; + INC(current_argument, TSIZE(PAstExpression)); + + while argument_index < expression^.argument_count do + WriteString(context^.output, ', '); + + transpile_expression(context, current_argument^); + + INC(current_argument, TSIZE(PAstExpression)); + INC(argument_index) + end + end; + WriteChar(context^.output, ')') end end; -proc transpile_if_statement(context: PTranspilerContext); +proc transpile_if_statement(context: PTranspilerContext) -> PAstStatement; var token: LexerToken; - expression: PAstExpression; - lexer: Lexer; + result: PAstStatement; begin + NEW(result); + result^.kind := astStatementKindIf; WriteString(context^.output, ' IF '); - lexer := context^.lexer^; - token := transpiler_lex(ADR(lexer)); - expression := parse_expression(ADR(lexer)); + token := transpiler_lex(context^.lexer); + result^.if_condition := parse_expression(context^.lexer); - if expression <> nil then - context^.lexer^ := lexer; - transpile_expression(context, expression); - WriteChar(context^.output, ' ') - end; - if expression = nil then - token := transpiler_lex(context^.lexer) - end; - transpile_unchanged(context, lexerKindThen); + transpile_expression(context, result^.if_condition); + token := lexer_current(context^.lexer); - WriteString(context^.output, 'THEN'); + WriteString(context^.output, ' THEN'); WriteLine(context^.output); transpile_statements(context); WriteString(context^.output, ' END'); - token := transpiler_lex(context^.lexer) + token := transpiler_lex(context^.lexer); + + return result end; -proc transpile_while_statement(context: PTranspilerContext); +proc transpile_while_statement(context: PTranspilerContext) -> PAstStatement; var token: LexerToken; + result: PAstStatement; begin + NEW(result); + result^.kind := astStatementKindWhile; WriteString(context^.output, ' WHILE '); - token := transpiler_lex(context^.lexer); - transpile_unchanged(context, lexerKindDo); - WriteString(context^.output, 'DO'); + token := transpiler_lex(context^.lexer); + result^.while_condition := parse_expression(context^.lexer); + + transpile_expression(context, result^.while_condition); + token := lexer_current(context^.lexer); + + WriteString(context^.output, ' DO'); WriteLine(context^.output); transpile_statements(context); WriteString(context^.output, ' END'); - token := transpiler_lex(context^.lexer) + token := transpiler_lex(context^.lexer); + + return result end; -proc transpile_assignment_statement(context: PTranspilerContext); -var - token: LexerToken; +proc transpile_assignment_statement(context: PTranspilerContext, statement: PAstStatement); begin + transpile_expression(context, statement^.assignee); WriteString(context^.output, ' := '); - token := transpiler_lex(context^.lexer); - transpile_unchanged(context, lexerKindSemicolon); + transpile_expression(context, statement^.assignment) end; -proc transpile_call_statement(context: PTranspilerContext); -var - token: LexerToken; -begin - WriteString(context^.output, '('); - token := transpiler_lex(context^.lexer); - - while (token.kind <> lexerKindSemicolon) & (token.kind <> lexerKindEnd) do - write_current(context^.lexer, context^.output); - token := transpiler_lex(context^.lexer) - end -end; - -proc transpile_designator_expression(context: PTranspilerContext); -var - token: LexerToken; -begin - WriteString(context^.output, ' '); - write_current(context^.lexer, context^.output); - token := transpiler_lex(context^.lexer); - - while token.kind = lexerKindLeftSquare do - WriteChar(context^.output, '['); - token := transpiler_lex(context^.lexer); - while token.kind <> lexerKindRightSquare do - write_current(context^.lexer, context^.output); - token := transpiler_lex(context^.lexer) - end; - WriteChar(context^.output, ']'); - token := transpiler_lex(context^.lexer) - end; - if token.kind = lexerKindHat then - WriteChar(context^.output, '^'); - token := transpiler_lex(context^.lexer) - end; - if token.kind = lexerKindDot then - WriteChar(context^.output, '.'); - token := transpiler_lex(context^.lexer); - write_current(context^.lexer, context^.output); - token := transpiler_lex(context^.lexer) - end; - if token.kind = lexerKindHat then - WriteChar(context^.output, '^'); - token := transpiler_lex(context^.lexer) - end; - while token.kind = lexerKindLeftSquare do - WriteChar(context^.output, '['); - token := transpiler_lex(context^.lexer); - while token.kind <> lexerKindRightSquare do - write_current(context^.lexer, context^.output); - token := transpiler_lex(context^.lexer) - end; - WriteChar(context^.output, ']'); - token := transpiler_lex(context^.lexer) - end -end; - -proc transpile_return_statement(context: PTranspilerContext); -var - token: LexerToken; +proc transpile_return_statement(context: PTranspilerContext, statement: PAstStatement); begin WriteString(context^.output, ' RETURN '); - token := transpiler_lex(context^.lexer); - transpile_unchanged(context, lexerKindSemicolon) + + transpile_expression(context, statement^.returned); end; proc transpile_statement(context: PTranspilerContext); var token: LexerToken; + written_bytes: CARDINAL; + statement: PAstStatement; + designator: PAstExpression; begin token := transpiler_lex(context^.lexer); if token.kind = lexerKindIf then - transpile_if_statement(context) + statement := transpile_if_statement(context) end; if token.kind = lexerKindWhile then - transpile_while_statement(context) + statement := transpile_while_statement(context) end; if token.kind = lexerKindReturn then - transpile_return_statement(context) + statement := parse_return_statement(context^.lexer); + transpile_return_statement(context, statement) end; if token.kind = lexerKindIdentifier then - transpile_designator_expression(context); + designator := parse_designator(context^.lexer); token := lexer_current(context^.lexer); if token.kind = lexerKindAssignment then - transpile_assignment_statement(context) + statement := parse_assignment_statement(context^.lexer, designator); + transpile_assignment_statement(context, statement) end; - if token.kind = lexerKindLeftParen then - transpile_call_statement(context) + if token.kind <> lexerKindAssignment then + statement := parse_call_statement(context^.lexer, designator); + transpile_expression(context, designator); + + written_bytes := WriteNBytes(StdErr, 5, context^.lexer^.start); + WriteLine(StdErr); end end end;