Parse call expressions

This commit is contained in:
2025-06-07 23:50:33 +02:00
parent c9c9b217a2
commit 6cfeb46dbf
5 changed files with 674 additions and 435 deletions

View File

@ -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.

View File

@ -1,6 +1,6 @@
IMPLEMENTATION MODULE Lexer;
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 = PROCEDURE(PLexer, PLexerToken);
Transition = RECORD
Action: TransitionAction;
NextState: TransitionState
action: TransitionAction;
next_state: TransitionState
END;
TransitionClasses = ARRAY[1..22] OF Transition;
@ -209,24 +209,30 @@ BEGIN
i := 129;
WHILE i <= 256 DO
classification[i] := transitionClassOther;
i := i + 1
INC(i)
END
END initialize_classification;
PROCEDURE compare_keyword(Keyword: ARRAY OF CHAR; TokenStart: PLexerBuffer; TokenEnd: PLexerBuffer): BOOLEAN;
PROCEDURE 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) AND (token_start <> token_end);
WHILE (index < Length(Keyword)) AND (TokenStart <> TokenEnd) AND result DO
result := (Keyword[index] = TokenStart^) OR (Lower(Keyword[index]) = TokenStart^);
INC(TokenStart);
INC(index)
WHILE continue AND result DO
result := (keyword[index] = token_start^) OR (Lower(keyword[index]) = token_start^);
INC(token_start);
INC(index);
continue := (index < keyword_length) AND (token_start <> token_end)
END;
result := (index = Length(Keyword)) AND (TokenStart = TokenEnd) AND result;
RETURN result
result := result AND (index = Length(keyword));
RETURN result AND (token_start = token_end)
END compare_keyword;
(* Reached the end of file. *)
PROCEDURE transition_action_eof(lexer: PLexer; token: PLexerToken);
@ -236,182 +242,193 @@ END transition_action_eof;
(* Add the character to the token currently read and advance to the next character. *)
PROCEDURE transition_action_accumulate(lexer: PLexer; token: PLexerToken);
BEGIN
INC(lexer^.Current)
INC(lexer^.current)
END transition_action_accumulate;
(* The current character is not a part of the token. Finish the token already
* read. Don't advance to the next character. *)
PROCEDURE 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 transition_action_finalize;
(* An action for tokens containing multiple characters. *)
PROCEDURE 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^ = '>') AND (lexer^.Current^ = '=') THEN
IF (lexer^.start^ = '>') AND (lexer^.current^ = '=') THEN
token^.kind := lexerKindGreaterEqual
END;
IF (lexer^.Start^ = '.') AND (lexer^.Current^ = '.') THEN
IF (lexer^.start^ = '.') AND (lexer^.current^ = '.') THEN
token^.kind := lexerKindRange
END;
IF (lexer^.Start^ = ':') AND (lexer^.Current^ = '=') THEN
IF (lexer^.start^ = ':') AND (lexer^.current^ = '=') THEN
token^.kind := lexerKindAssignment
END;
IF (lexer^.Start^ = '-') AND (lexer^.Current^ = '>') THEN
IF (lexer^.start^ = '-') AND (lexer^.current^ = '>') THEN
token^.kind := lexerKindArrow
END;
INC(lexer^.Current)
INC(lexer^.current)
END transition_action_composite;
(* Skip a space. *)
PROCEDURE transition_action_skip(lexer: PLexer; token: PLexerToken);
BEGIN
INC(lexer^.Current);
INC(lexer^.Start)
INC(lexer^.current);
INC(lexer^.start)
END transition_action_skip;
(* Delimited string action. *)
PROCEDURE 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 transition_action_delimited;
(* Finalize keyword OR identifier. *)
PROCEDURE 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
@ -420,49 +437,52 @@ END transition_action_key_id;
* followed by other characters forming a composite token. *)
PROCEDURE 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 transition_action_single;
(* Handle an integer literal. *)
PROCEDURE transition_action_integer(lexer: PLexer; token: PLexerToken);
@ -473,43 +493,44 @@ 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 transition_action_integer;
PROCEDURE set_default_transition(CurrentState: TransitionState; DefaultAction: TransitionAction; NextState: TransitionState);
PROCEDURE 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 set_default_transition;
(*
* The transition table describes transitions from one state to another, given
@ -530,267 +551,276 @@ END set_default_transition;
PROCEDURE 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 initialize_transitions;
PROCEDURE lexer_initialize(lexer: PLexer; Input: File);
PROCEDURE 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 lexer_initialize;
PROCEDURE 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 lexer_current;
@ -798,18 +828,18 @@ PROCEDURE 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
END lexer_lex;
PROCEDURE lexer_destroy(lexer: PLexer);
BEGIN
DEALLOCATE(lexer^.Buffer, lexer^.Size)
DEALLOCATE(lexer^.buffer, lexer^.size)
END lexer_destroy;
BEGIN
initialize_classification();

View File

@ -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.

View File

@ -1,11 +1,12 @@
IMPLEMENTATION MODULE Parser;
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. *)
PROCEDURE transpiler_lex(lexer: PLexer): LexerToken;
@ -33,7 +34,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));
@ -131,7 +134,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;
@ -174,7 +179,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));
@ -459,7 +466,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;
@ -470,6 +477,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;
@ -509,6 +522,13 @@ BEGIN
result^.unary_operator := astUnaryOperatorNot;
result^.unary_operand := parse_factor(lexer)
END;
IF (result = NIL) AND (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) AND (next_token.kind = lexerKindIdentifier) THEN
NEW(result);
@ -525,6 +545,7 @@ VAR
next_token: LexerToken;
inner_expression: PAstExpression;
designator: PAstExpression;
arguments: PPAstExpression;
handled: BOOLEAN;
BEGIN
designator := parse_factor(lexer);
@ -550,7 +571,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
@ -563,6 +584,38 @@ BEGIN
designator^.aggregate := inner_expression;
designator^.field := next_token.identifierKind;
next_token := transpiler_lex(lexer);
handled := TRUE
END;
IF ~handled AND (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
@ -570,4 +623,113 @@ BEGIN
RETURN designator
END parse_designator;
PROCEDURE 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 parse_binary_expression;
PROCEDURE 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) AND (next_token.kind = lexerKindNotEqual) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorNotEquals)
END;
IF (result = NIL) AND (next_token.kind = lexerKindEqual) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorEquals)
END;
IF (result = NIL) AND (next_token.kind = lexerKindGreaterThan) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorGreater)
END;
IF (result = NIL) AND (next_token.kind = lexerKindLessThan) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorLess)
END;
IF (result = NIL) AND (next_token.kind = lexerKindGreaterEqual) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorGreaterEqual)
END;
IF (result = NIL) AND (next_token.kind = lexerKindLessEqual) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorLessEqual)
END;
IF (result = NIL) AND (next_token.kind = lexerKindAnd) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorConjunction)
END;
IF (result = NIL) AND (next_token.kind = lexerKindOr) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorDisjunction)
END;
IF (result = NIL) AND (next_token.kind = lexerKindMinus) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorSubtraction)
END;
IF (result = NIL) AND (next_token.kind = lexerKindPlus) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorSum)
END;
IF (result = NIL) AND (next_token.kind = lexerKindAsterisk) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorMultiplication)
END
END;
IF (result = NIL) AND (left <> NIL) THEN
result := left
END;
RETURN result
END parse_expression;
PROCEDURE 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 parse_return_statement;
PROCEDURE 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 parse_assignment_statement;
PROCEDURE parse_call_statement(lexer: PLexer; call: PAstExpression): PAstStatement;
VAR
result: PAstStatement;
BEGIN
NEW(result);
result^.kind := astStatementKindCall;
result^.call := call;
RETURN result
END parse_call_statement;
END Parser.

View File

@ -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. *)
PROCEDURE transpiler_lex(lexer: PLexer): LexerToken;
@ -40,8 +40,12 @@ END write_semicolon;
PROCEDURE 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 write_current;
PROCEDURE transpile_import_statement(context: PTranspilerContext; import_statement: PAstImportStatement);
VAR
@ -385,59 +389,6 @@ BEGIN
RETURN result
END transpile_procedure_heading;
PROCEDURE transpile_unchanged(context: PTranspilerContext; trailing_token: LexerKind);
VAR
token: LexerToken;
written_bytes: CARDINAL;
BEGIN
token := lexer_current(context^.lexer);
WHILE (token.kind <> trailing_token) AND (token.kind <> lexerKindEnd) DO
written_bytes := 0;
IF token.kind = lexerKindNull THEN
WriteString(context^.output, 'NIL ');
written_bytes := 1
END;
IF (token.kind = lexerKindBoolean) AND token.booleanKind THEN
WriteString(context^.output, 'TRUE ');
written_bytes := 1
END;
IF (token.kind = lexerKindBoolean) AND (~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 transpile_unchanged;
PROCEDURE 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 parse_expression;
PROCEDURE transpile_unary_operator(context: PTranspilerContext; operator: AstUnaryOperator);
BEGIN
IF operator = astUnaryOperatorMinus THEN
@ -447,11 +398,49 @@ BEGIN
WriteChar(context^.output, '~')
END
END transpile_unary_operator;
PROCEDURE 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 transpile_binary_operator;
PROCEDURE transpile_expression(context: PTranspilerContext; expression: PAstExpression);
VAR
literal: PAstLiteral;
buffer: ARRAY[1..20] OF CHAR;
written_bytes: CARDINAL;
argument_index: CARDINAL;
current_argument: PPAstExpression;
BEGIN
IF expression^.kind = astExpressionKindLiteral THEN
literal := expression^.literal;
@ -462,7 +451,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) AND literal^.boolean THEN
WriteString(context^.output, 'TRUE')
END;
IF (literal^.kind = astLiteralKindBoolean) AND (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]))
@ -485,145 +483,130 @@ 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 transpile_expression;
PROCEDURE transpile_if_statement(context: PTranspilerContext);
PROCEDURE 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 transpile_if_statement;
PROCEDURE transpile_while_statement(context: PTranspilerContext);
PROCEDURE 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 transpile_while_statement;
PROCEDURE transpile_assignment_statement(context: PTranspilerContext);
VAR
token: LexerToken;
PROCEDURE 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 transpile_assignment_statement;
PROCEDURE transpile_call_statement(context: PTranspilerContext);
VAR
token: LexerToken;
BEGIN
WriteString(context^.output, '(');
token := transpiler_lex(context^.lexer);
WHILE (token.kind <> lexerKindSemicolon) AND (token.kind <> lexerKindEnd) DO
write_current(context^.lexer, context^.output);
token := transpiler_lex(context^.lexer)
END
END transpile_call_statement;
PROCEDURE 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 transpile_designator_expression;
PROCEDURE transpile_return_statement(context: PTranspilerContext);
VAR
token: LexerToken;
PROCEDURE 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 transpile_return_statement;
PROCEDURE 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 transpile_statement;