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 TYPE
PLexerBuffer = POINTER TO CHAR; PLexerBuffer = POINTER TO CHAR;
Lexer = RECORD Lexer = RECORD
Input: File; input: File;
Buffer: PLexerBuffer; buffer: PLexerBuffer;
Size: CARDINAL; size: CARDINAL;
Length: CARDINAL; length: CARDINAL;
Start: PLexerBuffer; start: PLexerBuffer;
Current: PLexerBuffer current: PLexerBuffer
END; END;
PLexer = POINTER TO Lexer; PLexer = POINTER TO Lexer;
LexerKind = ( LexerKind = (
@ -60,7 +60,7 @@ TYPE
lexerKindComma, lexerKindComma,
lexerKindPlus, lexerKindPlus,
lexerKindMinus, lexerKindMinus,
lexerKindMultiplication, lexerKindAsterisk,
lexerKindDivision, lexerKindDivision,
lexerKindRemainder, lexerKindRemainder,
lexerKindAssignment, lexerKindAssignment,
@ -90,11 +90,11 @@ TYPE
END; END;
PLexerToken = POINTER TO LexerToken; PLexerToken = POINTER TO LexerToken;
PROCEDURE lexer_initialize(ALexer: PLexer; Input: File); PROCEDURE lexer_initialize(lexer: PLexer; input: File);
PROCEDURE lexer_destroy(ALexer: PLexer); PROCEDURE lexer_destroy(lexer: PLexer);
(* Returns the last read token. *) (* Returns the last read token. *)
PROCEDURE lexer_current(ALexer: PLexer): LexerToken; PROCEDURE lexer_current(lexer: PLexer): LexerToken;
(* Read and return the next token. *) (* Read and return the next token. *)
PROCEDURE lexer_lex(ALexer: PLexer): LexerToken; PROCEDURE lexer_lex(lexer: PLexer): LexerToken;
END Lexer. END Lexer.

View File

@ -1,6 +1,6 @@
IMPLEMENTATION MODULE Lexer; IMPLEMENTATION MODULE Lexer;
FROM FIO IMPORT ReadNBytes, StdErr; FROM FIO IMPORT ReadNBytes;
FROM SYSTEM IMPORT ADR, TSIZE; FROM SYSTEM IMPORT ADR, TSIZE;
FROM DynamicStrings IMPORT String, InitStringCharStar, KillString; FROM DynamicStrings IMPORT String, InitStringCharStar, KillString;
@ -64,8 +64,8 @@ TYPE
); );
TransitionAction = PROCEDURE(PLexer, PLexerToken); TransitionAction = PROCEDURE(PLexer, PLexerToken);
Transition = RECORD Transition = RECORD
Action: TransitionAction; action: TransitionAction;
NextState: TransitionState next_state: TransitionState
END; END;
TransitionClasses = ARRAY[1..22] OF Transition; TransitionClasses = ARRAY[1..22] OF Transition;
@ -209,24 +209,30 @@ BEGIN
i := 129; i := 129;
WHILE i <= 256 DO WHILE i <= 256 DO
classification[i] := transitionClassOther; classification[i] := transitionClassOther;
i := i + 1 INC(i)
END END
END initialize_classification; 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 VAR
result: BOOLEAN; result: BOOLEAN;
index: CARDINAL; index: CARDINAL;
keyword_length: CARDINAL;
continue: BOOLEAN;
BEGIN BEGIN
index := 0; index := 0;
result := TRUE; 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 WHILE continue AND result DO
result := (Keyword[index] = TokenStart^) OR (Lower(Keyword[index]) = TokenStart^); result := (keyword[index] = token_start^) OR (Lower(keyword[index]) = token_start^);
INC(TokenStart); INC(token_start);
INC(index) INC(index);
continue := (index < keyword_length) AND (token_start <> token_end)
END; END;
result := (index = Length(Keyword)) AND (TokenStart = TokenEnd) AND result; result := result AND (index = Length(keyword));
RETURN result
RETURN result AND (token_start = token_end)
END compare_keyword; END compare_keyword;
(* Reached the end of file. *) (* Reached the end of file. *)
PROCEDURE transition_action_eof(lexer: PLexer; token: PLexerToken); 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. *) (* Add the character to the token currently read and advance to the next character. *)
PROCEDURE transition_action_accumulate(lexer: PLexer; token: PLexerToken); PROCEDURE transition_action_accumulate(lexer: PLexer; token: PLexerToken);
BEGIN BEGIN
INC(lexer^.Current) INC(lexer^.current)
END transition_action_accumulate; END transition_action_accumulate;
(* The current character is not a part of the token. Finish the token already (* The current character is not a part of the token. Finish the token already
* read. Don't advance to the next character. *) * read. Don't advance to the next character. *)
PROCEDURE transition_action_finalize(lexer: PLexer; token: PLexerToken); PROCEDURE transition_action_finalize(lexer: PLexer; token: PLexerToken);
BEGIN BEGIN
IF lexer^.Start^ = ':' THEN IF lexer^.start^ = ':' THEN
token^.kind := lexerKindColon token^.kind := lexerKindColon
END; END;
IF lexer^.Start^ = '>' THEN IF lexer^.start^ = '>' THEN
token^.kind := lexerKindGreaterThan token^.kind := lexerKindGreaterThan
END; END;
IF lexer^.Start^ = '<' THEN IF lexer^.start^ = '<' THEN
token^.kind := lexerKindLessThan token^.kind := lexerKindLessThan
END; END;
IF lexer^.Start^ = '(' THEN IF lexer^.start^ = '(' THEN
token^.kind := lexerKindLeftParen token^.kind := lexerKindLeftParen
END; END;
IF lexer^.Start^ = '-' THEN IF lexer^.start^ = '-' THEN
token^.kind := lexerKindLeftParen token^.kind := lexerKindMinus
END; END;
IF lexer^.Start^ = '.' THEN IF lexer^.start^ = '.' THEN
token^.kind := lexerKindDot token^.kind := lexerKindDot
END END
END transition_action_finalize; END transition_action_finalize;
(* An action for tokens containing multiple characters. *) (* An action for tokens containing multiple characters. *)
PROCEDURE transition_action_composite(lexer: PLexer; token: PLexerToken); PROCEDURE transition_action_composite(lexer: PLexer; token: PLexerToken);
BEGIN BEGIN
IF lexer^.Start^ = '<' THEN IF lexer^.start^ = '<' THEN
IF lexer^.Current^ = '>' THEN IF lexer^.current^ = '>' THEN
token^.kind := lexerKindNotEqual token^.kind := lexerKindNotEqual
END; END;
IF lexer^.Current^ = '=' THEN IF lexer^.current^ = '=' THEN
token^.kind := lexerKindLessEqual token^.kind := lexerKindLessEqual
END END
END; END;
IF (lexer^.Start^ = '>') AND (lexer^.Current^ = '=') THEN IF (lexer^.start^ = '>') AND (lexer^.current^ = '=') THEN
token^.kind := lexerKindGreaterEqual token^.kind := lexerKindGreaterEqual
END; END;
IF (lexer^.Start^ = '.') AND (lexer^.Current^ = '.') THEN IF (lexer^.start^ = '.') AND (lexer^.current^ = '.') THEN
token^.kind := lexerKindRange token^.kind := lexerKindRange
END; END;
IF (lexer^.Start^ = ':') AND (lexer^.Current^ = '=') THEN IF (lexer^.start^ = ':') AND (lexer^.current^ = '=') THEN
token^.kind := lexerKindAssignment token^.kind := lexerKindAssignment
END; END;
IF (lexer^.Start^ = '-') AND (lexer^.Current^ = '>') THEN IF (lexer^.start^ = '-') AND (lexer^.current^ = '>') THEN
token^.kind := lexerKindArrow token^.kind := lexerKindArrow
END; END;
INC(lexer^.Current) INC(lexer^.current)
END transition_action_composite; END transition_action_composite;
(* Skip a space. *) (* Skip a space. *)
PROCEDURE transition_action_skip(lexer: PLexer; token: PLexerToken); PROCEDURE transition_action_skip(lexer: PLexer; token: PLexerToken);
BEGIN BEGIN
INC(lexer^.Current); INC(lexer^.current);
INC(lexer^.Start) INC(lexer^.start)
END transition_action_skip; END transition_action_skip;
(* Delimited string action. *) (* Delimited string action. *)
PROCEDURE transition_action_delimited(lexer: PLexer; token: PLexerToken); PROCEDURE transition_action_delimited(lexer: PLexer; token: PLexerToken);
VAR VAR
text_length: CARDINAL; text_length: CARDINAL;
BEGIN BEGIN
IF lexer^.Start^ = '(' THEN IF lexer^.start^ = '(' THEN
token^.kind := lexerKindComment token^.kind := lexerKindComment
END; 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 token^.kind := lexerKindCharacter
END; END;
IF lexer^.Start^ = "'" THEN IF lexer^.start^ = "'" THEN
text_length := lexer^.Current - lexer^.Start; text_length := lexer^.current;
DEC(text_length, lexer^.start);
INC(text_length);
MemZero(ADR(token^.stringKind), TSIZE(ShortString)); 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 token^.kind := lexerKindString
END; END;
INC(lexer^.Current) INC(lexer^.current)
END transition_action_delimited; END transition_action_delimited;
(* Finalize keyword OR identifier. *) (* Finalize keyword OR identifier. *)
PROCEDURE transition_action_key_id(lexer: PLexer; token: PLexerToken); PROCEDURE transition_action_key_id(lexer: PLexer; token: PLexerToken);
BEGIN BEGIN
token^.kind := lexerKindIdentifier; token^.kind := lexerKindIdentifier;
token^.identifierKind[1] := lexer^.Current - lexer^.Start; token^.identifierKind[1] := lexer^.current;
MemCopy(lexer^.Start, ORD(token^.identifierKind[1]), ADR(token^.identifierKind[2])); 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 token^.kind := lexerKindProgram
END; END;
IF compare_keyword('IMPORT', lexer^.Start, lexer^.Current) THEN IF compare_keyword('IMPORT', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindImport token^.kind := lexerKindImport
END; END;
IF compare_keyword('CONST', lexer^.Start, lexer^.Current) THEN IF compare_keyword('CONST', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindConst token^.kind := lexerKindConst
END; END;
IF compare_keyword('VAR', lexer^.Start, lexer^.Current) THEN IF compare_keyword('VAR', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindVar token^.kind := lexerKindVar
END; END;
IF compare_keyword('IF', lexer^.Start, lexer^.Current) THEN IF compare_keyword('IF', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindIf token^.kind := lexerKindIf
END; END;
IF compare_keyword('THEN', lexer^.Start, lexer^.Current) THEN IF compare_keyword('THEN', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindThen token^.kind := lexerKindThen
END; END;
IF compare_keyword('ELSIF', lexer^.Start, lexer^.Current) THEN IF compare_keyword('ELSIF', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindElsif token^.kind := lexerKindElsif
END; END;
IF compare_keyword('ELSE', lexer^.Start, lexer^.Current) THEN IF compare_keyword('ELSE', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindElse token^.kind := lexerKindElse
END; END;
IF compare_keyword('WHILE', lexer^.Start, lexer^.Current) THEN IF compare_keyword('WHILE', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindWhile token^.kind := lexerKindWhile
END; END;
IF compare_keyword('DO', lexer^.Start, lexer^.Current) THEN IF compare_keyword('DO', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindDo token^.kind := lexerKindDo
END; END;
IF compare_keyword('proc', lexer^.Start, lexer^.Current) THEN IF compare_keyword('proc', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindProc token^.kind := lexerKindProc
END; END;
IF compare_keyword('BEGIN', lexer^.Start, lexer^.Current) THEN IF compare_keyword('BEGIN', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindBegin token^.kind := lexerKindBegin
END; END;
IF compare_keyword('END', lexer^.Start, lexer^.Current) THEN IF compare_keyword('END', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindEnd token^.kind := lexerKindEnd
END; END;
IF compare_keyword('TYPE', lexer^.Start, lexer^.Current) THEN IF compare_keyword('TYPE', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindType token^.kind := lexerKindType
END; END;
IF compare_keyword('RECORD', lexer^.Start, lexer^.Current) THEN IF compare_keyword('RECORD', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindRecord token^.kind := lexerKindRecord
END; END;
IF compare_keyword('UNION', lexer^.Start, lexer^.Current) THEN IF compare_keyword('UNION', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindUnion token^.kind := lexerKindUnion
END; END;
IF compare_keyword('NIL', lexer^.Start, lexer^.Current) THEN IF compare_keyword('NIL', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindNull token^.kind := lexerKindNull
END; END;
IF compare_keyword('AND', lexer^.Start, lexer^.Current) THEN IF compare_keyword('AND', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindAnd token^.kind := lexerKindAnd
END; END;
IF compare_keyword('OR', lexer^.Start, lexer^.Current) THEN IF compare_keyword('OR', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindOr token^.kind := lexerKindOr
END; END;
IF compare_keyword('RETURN', lexer^.Start, lexer^.Current) THEN IF compare_keyword('RETURN', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindReturn token^.kind := lexerKindReturn
END; END;
IF compare_keyword('DEFINITION', lexer^.Start, lexer^.Current) THEN IF compare_keyword('DEFINITION', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindDefinition token^.kind := lexerKindDefinition
END; END;
IF compare_keyword('TO', lexer^.Start, lexer^.Current) THEN IF compare_keyword('TO', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindTo token^.kind := lexerKindTo
END; END;
IF compare_keyword('CASE', lexer^.Start, lexer^.Current) THEN IF compare_keyword('CASE', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindCase token^.kind := lexerKindCase
END; END;
IF compare_keyword('OF', lexer^.Start, lexer^.Current) THEN IF compare_keyword('OF', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindOf token^.kind := lexerKindOf
END; END;
IF compare_keyword('FROM', lexer^.Start, lexer^.Current) THEN IF compare_keyword('FROM', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindFrom token^.kind := lexerKindFrom
END; END;
IF compare_keyword('MODULE', lexer^.Start, lexer^.Current) THEN IF compare_keyword('MODULE', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindModule token^.kind := lexerKindModule
END; END;
IF compare_keyword('IMPLEMENTATION', lexer^.Start, lexer^.Current) THEN IF compare_keyword('IMPLEMENTATION', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindImplementation token^.kind := lexerKindImplementation
END; END;
IF compare_keyword('POINTER', lexer^.Start, lexer^.Current) THEN IF compare_keyword('POINTER', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindPointer token^.kind := lexerKindPointer
END; END;
IF compare_keyword('ARRAY', lexer^.Start, lexer^.Current) THEN IF compare_keyword('ARRAY', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindArray token^.kind := lexerKindArray
END; END;
IF compare_keyword('TRUE', lexer^.Start, lexer^.Current) THEN IF compare_keyword('TRUE', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindBoolean; token^.kind := lexerKindBoolean;
token^.booleanKind := TRUE token^.booleanKind := TRUE
END; END;
IF compare_keyword('FALSE', lexer^.Start, lexer^.Current) THEN IF compare_keyword('FALSE', lexer^.start, lexer^.current) THEN
token^.kind := lexerKindBoolean; token^.kind := lexerKindBoolean;
token^.booleanKind := FALSE token^.booleanKind := FALSE
END END
@ -420,49 +437,52 @@ END transition_action_key_id;
* followed by other characters forming a composite token. *) * followed by other characters forming a composite token. *)
PROCEDURE transition_action_single(lexer: PLexer; token: PLexerToken); PROCEDURE transition_action_single(lexer: PLexer; token: PLexerToken);
BEGIN BEGIN
IF lexer^.Current^ = '&' THEN IF lexer^.current^ = '&' THEN
token^.kind := lexerKindAnd token^.kind := lexerKindAnd
END; END;
IF lexer^.Current^ = ';' THEN IF lexer^.current^ = ';' THEN
token^.kind := lexerKindSemicolon token^.kind := lexerKindSemicolon
END; END;
IF lexer^.Current^ = ',' THEN IF lexer^.current^ = ',' THEN
token^.kind := lexerKindComma token^.kind := lexerKindComma
END; END;
IF lexer^.Current^ = '~' THEN IF lexer^.current^ = '~' THEN
token^.kind := lexerKindTilde token^.kind := lexerKindTilde
END; END;
IF lexer^.Current^ = ')' THEN IF lexer^.current^ = ')' THEN
token^.kind := lexerKindRightParen token^.kind := lexerKindRightParen
END; END;
IF lexer^.Current^ = '[' THEN IF lexer^.current^ = '[' THEN
token^.kind := lexerKindLeftSquare token^.kind := lexerKindLeftSquare
END; END;
IF lexer^.Current^ = ']' THEN IF lexer^.current^ = ']' THEN
token^.kind := lexerKindRightSquare token^.kind := lexerKindRightSquare
END; END;
IF lexer^.Current^ = '^' THEN IF lexer^.current^ = '^' THEN
token^.kind := lexerKindHat token^.kind := lexerKindHat
END; END;
IF lexer^.Current^ = '=' THEN IF lexer^.current^ = '=' THEN
token^.kind := lexerKindEqual token^.kind := lexerKindEqual
END; END;
IF lexer^.Current^ = '+' THEN IF lexer^.current^ = '+' THEN
token^.kind := lexerKindPlus token^.kind := lexerKindPlus
END; END;
IF lexer^.Current^ = '/' THEN IF lexer^.current^ = '*' THEN
token^.kind := lexerKindAsterisk
END;
IF lexer^.current^ = '/' THEN
token^.kind := lexerKindDivision token^.kind := lexerKindDivision
END; END;
IF lexer^.Current^ = '%' THEN IF lexer^.current^ = '%' THEN
token^.kind := lexerKindRemainder token^.kind := lexerKindRemainder
END; END;
IF lexer^.Current^ = '@' THEN IF lexer^.current^ = '@' THEN
token^.kind := lexerKindAt token^.kind := lexerKindAt
END; END;
IF lexer^.Current^ = '|' THEN IF lexer^.current^ = '|' THEN
token^.kind := lexerKindPipe token^.kind := lexerKindPipe
END; END;
INC(lexer^.Current) INC(lexer^.current)
END transition_action_single; END transition_action_single;
(* Handle an integer literal. *) (* Handle an integer literal. *)
PROCEDURE transition_action_integer(lexer: PLexer; token: PLexerToken); PROCEDURE transition_action_integer(lexer: PLexer; token: PLexerToken);
@ -473,43 +493,44 @@ VAR
BEGIN BEGIN
token^.kind := lexerKindInteger; token^.kind := lexerKindInteger;
integer_length := lexer^.Current - lexer^.Start; integer_length := lexer^.current;
DEC(integer_length, lexer^.start);
MemZero(ADR(token^.identifierKind), TSIZE(Identifier)); 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])); buffer := InitStringCharStar(ADR(token^.identifierKind[1]));
token^.integerKind := StringToInteger(buffer, 10, found); token^.integerKind := StringToInteger(buffer, 10, found);
buffer := KillString(buffer) buffer := KillString(buffer)
END transition_action_integer; 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 VAR
DefaultTransition: Transition; default_transition: Transition;
BEGIN BEGIN
DefaultTransition.Action := DefaultAction; default_transition.action := DefaultAction;
DefaultTransition.NextState := NextState; default_transition.next_state := next_state;
transitions[ORD(CurrentState) + 1][ORD(transitionClassInvalid) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassInvalid) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassDigit) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassDigit) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassAlpha) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassAlpha) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassSpace) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassSpace) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassColon) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassColon) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassEquals) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassEquals) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassLeftParen) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassLeftParen) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassRightParen) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassRightParen) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassAsterisk) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassAsterisk) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassUnderscore) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassUnderscore) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassSingle) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassSingle) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassHex) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassHex) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassZero) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassZero) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassX) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassX) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassEof) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassEof) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassDot) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassDot) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassMinus) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassMinus) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassSingleQuote) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassSingleQuote) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassDoubleQuote) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassDoubleQuote) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassGreater) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassGreater) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassLess) + 1] := DefaultTransition; transitions[ORD(current_state) + 1][ORD(transitionClassLess) + 1] := default_transition;
transitions[ORD(CurrentState) + 1][ORD(transitionClassOther) + 1] := DefaultTransition transitions[ORD(current_state) + 1][ORD(transitionClassOther) + 1] := default_transition
END set_default_transition; END set_default_transition;
(* (*
* The transition table describes transitions from one state to another, given * The transition table describes transitions from one state to another, given
@ -530,267 +551,276 @@ END set_default_transition;
PROCEDURE initialize_transitions(); PROCEDURE initialize_transitions();
BEGIN BEGIN
(* Start state. *) (* Start state. *)
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassInvalid) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDigit) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateDecimal;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAlpha) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateIdentifier;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSpace) + 1].Action := transition_action_skip; 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].next_state := transitionStateStart;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassColon) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateColon;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEquals) + 1].Action := transition_action_single; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLeftParen) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateLeftParen;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassRightParen) + 1].Action := transition_action_single; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAsterisk) + 1].Action := transition_action_single; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassUnderscore) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateIdentifier;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingle) + 1].Action := transition_action_single; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassHex) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateIdentifier;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassZero) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateLeadingZero;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassX) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateIdentifier;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEof) + 1].Action := transition_action_eof; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDot) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateDot;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassMinus) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateMinus;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingleQuote) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateCharacter;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDoubleQuote) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateString;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassGreater) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateGreater;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLess) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateLess;
transitions[ORD(transitionStateStart) + 1][ORD(transitionClassOther) + 1].Action := NIL; 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].next_state := transitionStateEnd;
(* Colon state. *) (* Colon state. *)
set_default_transition(transitionStateColon, transition_action_finalize, transitionStateEnd); 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].action := transition_action_composite;
transitions[ORD(transitionStateColon) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; transitions[ORD(transitionStateColon) + 1][ORD(transitionClassEquals) + 1].next_state := transitionStateEnd;
(* Identifier state. *) (* Identifier state. *)
set_default_transition(transitionStateIdentifier, transition_action_key_id, transitionStateEnd); 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].action := transition_action_accumulate;
transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateIdentifier; 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].action := transition_action_accumulate;
transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateIdentifier; 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].action := transition_action_accumulate;
transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassUnderscore) + 1].NextState := transitionStateIdentifier; 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].action := transition_action_accumulate;
transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateIdentifier; 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].action := transition_action_accumulate;
transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateIdentifier; 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].action := transition_action_accumulate;
transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassX) + 1].NextState := transitionStateIdentifier; transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassX) + 1].next_state := transitionStateIdentifier;
(* Decimal state. *) (* Decimal state. *)
set_default_transition(transitionStateDecimal, transition_action_integer, transitionStateEnd); 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].action := transition_action_accumulate;
transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateDecimal; 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].action := transition_action_accumulate;
transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateDecimalSuffix; 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].action := NIL;
transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassUnderscore) + 1].NextState := transitionStateEnd; 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].action := transition_action_accumulate;
transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateDecimalSuffix; 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].action := transition_action_accumulate;
transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateDecimal; 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].action := transition_action_accumulate;
transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassX) + 1].NextState := transitionStateDecimalSuffix; transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassX) + 1].next_state := transitionStateDecimalSuffix;
(* Greater state. *) (* Greater state. *)
set_default_transition(transitionStateGreater, transition_action_finalize, transitionStateEnd); 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].action := transition_action_composite;
transitions[ORD(transitionStateGreater) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; transitions[ORD(transitionStateGreater) + 1][ORD(transitionClassEquals) + 1].next_state := transitionStateEnd;
(* Minus state. *) (* Minus state. *)
set_default_transition(transitionStateMinus, transition_action_finalize, transitionStateEnd); 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].action := transition_action_composite;
transitions[ORD(transitionStateMinus) + 1][ORD(transitionClassGreater) + 1].NextState := transitionStateEnd; transitions[ORD(transitionStateMinus) + 1][ORD(transitionClassGreater) + 1].next_state := transitionStateEnd;
(* Left paren state. *) (* Left paren state. *)
set_default_transition(transitionStateLeftParen, transition_action_finalize, transitionStateEnd); 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].action := transition_action_accumulate;
transitions[ORD(transitionStateLeftParen) + 1][ORD(transitionClassAsterisk) + 1].NextState := transitionStateComment; transitions[ORD(transitionStateLeftParen) + 1][ORD(transitionClassAsterisk) + 1].next_state := transitionStateComment;
(* Less state. *) (* Less state. *)
set_default_transition(transitionStateLess, transition_action_finalize, transitionStateEnd); 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].action := transition_action_composite;
transitions[ORD(transitionStateLess) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; 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].action := transition_action_composite;
transitions[ORD(transitionStateLess) + 1][ORD(transitionClassGreater) + 1].NextState := transitionStateEnd; transitions[ORD(transitionStateLess) + 1][ORD(transitionClassGreater) + 1].next_state := transitionStateEnd;
(* Hexadecimal after 0x. *) (* Hexadecimal after 0x. *)
set_default_transition(transitionStateDot, transition_action_finalize, transitionStateEnd); 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].action := transition_action_composite;
transitions[ORD(transitionStateDot) + 1][ORD(transitionClassDot) + 1].NextState := transitionStateEnd; transitions[ORD(transitionStateDot) + 1][ORD(transitionClassDot) + 1].next_state := transitionStateEnd;
(* Comment. *) (* Comment. *)
set_default_transition(transitionStateComment, transition_action_accumulate, transitionStateComment); 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].action := transition_action_accumulate;
transitions[ORD(transitionStateComment) + 1][ORD(transitionClassAsterisk) + 1].NextState := transitionStateClosingComment; 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].action := NIL;
transitions[ORD(transitionStateComment) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; transitions[ORD(transitionStateComment) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd;
(* Closing comment. *) (* Closing comment. *)
set_default_transition(transitionStateClosingComment, transition_action_accumulate, transitionStateComment); set_default_transition(transitionStateClosingComment, transition_action_accumulate, transitionStateComment);
transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassInvalid) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassRightParen) + 1].Action := transition_action_delimited; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassAsterisk) + 1].Action := transition_action_accumulate; 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].next_state := transitionStateClosingComment;
transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassEof) + 1].Action := NIL; 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].next_state := transitionStateEnd;
(* Character. *) (* Character. *)
set_default_transition(transitionStateCharacter, transition_action_accumulate, transitionStateCharacter); set_default_transition(transitionStateCharacter, transition_action_accumulate, transitionStateCharacter);
transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassInvalid) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassEof) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassSingleQuote) + 1].Action := transition_action_delimited; 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].next_state := transitionStateEnd;
(* String. *) (* String. *)
set_default_transition(transitionStateString, transition_action_accumulate, transitionStateString); set_default_transition(transitionStateString, transition_action_accumulate, transitionStateString);
transitions[ORD(transitionStateString) + 1][ORD(transitionClassInvalid) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateString) + 1][ORD(transitionClassEof) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateString) + 1][ORD(transitionClassDoubleQuote) + 1].Action := transition_action_delimited; 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].next_state := transitionStateEnd;
(* Leading zero. *) (* Leading zero. *)
set_default_transition(transitionStateLeadingZero, transition_action_integer, transitionStateEnd); set_default_transition(transitionStateLeadingZero, transition_action_integer, transitionStateEnd);
transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassDigit) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassAlpha) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassUnderscore) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassHex) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassZero) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassX) + 1].Action := NIL; 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].next_state := transitionStateEnd;
(* Digit with a character suffix. *) (* Digit with a character suffix. *)
set_default_transition(transitionStateDecimalSuffix, transition_action_integer, transitionStateEnd); set_default_transition(transitionStateDecimalSuffix, transition_action_integer, transitionStateEnd);
transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassAlpha) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassDigit) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassHex) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassZero) + 1].Action := NIL; 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].next_state := transitionStateEnd;
transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassX) + 1].Action := NIL; 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].next_state := transitionStateEnd
END initialize_transitions; END initialize_transitions;
PROCEDURE lexer_initialize(lexer: PLexer; Input: File); PROCEDURE lexer_initialize(lexer: PLexer; input: File);
BEGIN BEGIN
lexer^.Input := Input; lexer^.input := input;
lexer^.Length := 0; lexer^.length := 0;
ALLOCATE(lexer^.Buffer, CHUNK_SIZE); ALLOCATE(lexer^.buffer, CHUNK_SIZE);
MemZero(lexer^.Buffer, CHUNK_SIZE); MemZero(lexer^.buffer, CHUNK_SIZE);
lexer^.Size := CHUNK_SIZE lexer^.size := CHUNK_SIZE
END lexer_initialize; END lexer_initialize;
PROCEDURE lexer_current(lexer: PLexer): LexerToken; PROCEDURE lexer_current(lexer: PLexer): LexerToken;
VAR VAR
CurrentClass: TransitionClass; current_class: TransitionClass;
CurrentState: TransitionState; current_state: TransitionState;
CurrentTransition: Transition; current_transition: Transition;
result: LexerToken; result: LexerToken;
index1: CARDINAL;
index2: CARDINAL;
BEGIN BEGIN
lexer^.Current := lexer^.Start; lexer^.current := lexer^.start;
CurrentState := transitionStateStart; current_state := transitionStateStart;
WHILE CurrentState <> transitionStateEnd DO WHILE current_state <> transitionStateEnd DO
CurrentClass := classification[ORD(lexer^.Current^) + 1]; index1 := ORD(lexer^.current^);
INC(index1);
current_class := classification[index1];
CurrentTransition := transitions[ORD(CurrentState) + 1][ORD(CurrentClass) + 1]; index1 := ORD(current_state);
IF CurrentTransition.Action <> NIL THEN INC(index1);
CurrentTransition.Action(lexer, ADR(result)) index2 := ORD(current_class);
INC(index2);
current_transition := transitions[index1][index2];
IF current_transition.action <> NIL THEN
current_transition.action(lexer, ADR(result))
END; END;
CurrentState := CurrentTransition.NextState current_state := current_transition.next_state
END; END;
RETURN result RETURN result
END lexer_current; END lexer_current;
@ -798,18 +828,18 @@ PROCEDURE lexer_lex(lexer: PLexer): LexerToken;
VAR VAR
result: LexerToken; result: LexerToken;
BEGIN BEGIN
IF lexer^.Length = 0 THEN IF lexer^.length = 0 THEN
lexer^.Length := ReadNBytes(lexer^.Input, CHUNK_SIZE, lexer^.Buffer); lexer^.length := ReadNBytes(lexer^.input, CHUNK_SIZE, lexer^.buffer);
lexer^.Current := lexer^.Buffer lexer^.current := lexer^.buffer
END; END;
lexer^.Start := lexer^.Current; lexer^.start := lexer^.current;
result := lexer_current(lexer); result := lexer_current(lexer);
RETURN result RETURN result
END lexer_lex; END lexer_lex;
PROCEDURE lexer_destroy(lexer: PLexer); PROCEDURE lexer_destroy(lexer: PLexer);
BEGIN BEGIN
DEALLOCATE(lexer^.Buffer, lexer^.Size) DEALLOCATE(lexer^.buffer, lexer^.size)
END lexer_destroy; END lexer_destroy;
BEGIN BEGIN
initialize_classification(); initialize_classification();

View File

@ -7,21 +7,42 @@ TYPE
AstLiteralKind = ( AstLiteralKind = (
astLiteralKindInteger, astLiteralKindInteger,
astLiteralKindString, astLiteralKindString,
astLiteralKindNull astLiteralKindNull,
astLiteralKindBoolean
); );
AstLiteral = RECORD AstLiteral = RECORD
CASE kind: AstLiteralKind OF CASE kind: AstLiteralKind OF
astLiteralKindInteger: integer: INTEGER | astLiteralKindInteger: integer: INTEGER |
astLiteralKindString: string: ShortString | astLiteralKindString: string: ShortString |
astLiteralKindNull: astLiteralKindNull: |
astLiteralKindBoolean: boolean: BOOLEAN
END END
END; END;
PAstLiteral = POINTER TO AstLiteral; PAstLiteral = POINTER TO AstLiteral;
AstUnaryOperator = ( AstUnaryOperator = (
astUnaryOperatorReference,
astUnaryOperatorNot, astUnaryOperatorNot,
astUnaryOperatorMinus astUnaryOperatorMinus
); );
AstBinaryOperator = (
astBinaryOperatorSum,
astBinaryOperatorSubtraction,
astBinaryOperatorMultiplication,
astBinaryOperatorDivision,
astBinaryOperatorRemainder,
astBinaryOperatorEquals,
astBinaryOperatorNotEquals,
astBinaryOperatorLess,
astBinaryOperatorGreater,
astBinaryOperatorLessEqual,
astBinaryOperatorGreaterEqual,
astBinaryOperatorDisjunction,
astBinaryOperatorConjunction,
astBinaryOperatorExclusiveDisjunction,
astBinaryOperatorShiftLeft,
astBinaryOperatorShiftRight
);
AstExpressionKind = ( AstExpressionKind = (
astExpressionKindLiteral, astExpressionKindLiteral,
@ -29,7 +50,9 @@ TYPE
astExpressionKindArrayAccess, astExpressionKindArrayAccess,
astExpressionKindDereference, astExpressionKindDereference,
astExpressionKindFieldAccess, astExpressionKindFieldAccess,
astExpressionKindUnary astExpressionKindUnary,
astExpressionKindBinary,
astExpressionKindCall
); );
AstExpression = RECORD AstExpression = RECORD
CASE kind: AstExpressionKind OF CASE kind: AstExpressionKind OF
@ -44,12 +67,49 @@ TYPE
field: Identifier | field: Identifier |
astExpressionKindUnary: astExpressionKindUnary:
unary_operator: AstUnaryOperator; 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
END; END;
PAstExpression = POINTER TO AstExpression; PAstExpression = POINTER TO AstExpression;
PPAstExpression = POINTER TO PAstExpression; 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 AstImportStatement = RECORD
package: Identifier; package: Identifier;
symbols: PIdentifier symbols: PIdentifier
@ -121,5 +181,9 @@ PROCEDURE parse_variable_part(lexer: PLexer): PPAstVariableDeclaration;
PROCEDURE parse_constant_part(lexer: PLexer): PPAstConstantDeclaration; PROCEDURE parse_constant_part(lexer: PLexer): PPAstConstantDeclaration;
PROCEDURE parse_import_part(lexer: PLexer): PPAstImportStatement; PROCEDURE parse_import_part(lexer: PLexer): PPAstImportStatement;
PROCEDURE parse_designator(lexer: PLexer): PAstExpression; 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. END Parser.

View File

@ -1,11 +1,12 @@
IMPLEMENTATION MODULE Parser; IMPLEMENTATION MODULE Parser;
FROM FIO IMPORT ReadNBytes;
FROM SYSTEM IMPORT TSIZE; FROM SYSTEM IMPORT TSIZE;
FROM MemUtils IMPORT MemZero; FROM MemUtils IMPORT MemZero;
FROM Storage IMPORT ALLOCATE, REALLOCATE; 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. *) (* Calls lexer_lex() but skips the comments. *)
PROCEDURE transpiler_lex(lexer: PLexer): LexerToken; PROCEDURE transpiler_lex(lexer: PLexer): LexerToken;
@ -33,7 +34,9 @@ BEGIN
WHILE token.kind <> lexerKindEnd DO WHILE token.kind <> lexerKindEnd DO
INC(field_count); 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; current_field := field_declarations;
INC(current_field , TSIZE(AstFieldDeclaration) * (field_count - 1)); INC(current_field , TSIZE(AstFieldDeclaration) * (field_count - 1));
@ -131,7 +134,9 @@ BEGIN
token := transpiler_lex(lexer); token := transpiler_lex(lexer);
INC(case_count); 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; current_case := result^.cases;
INC(current_case, TSIZE(Identifier) * (case_count - 1)); INC(current_case, TSIZE(Identifier) * (case_count - 1));
current_case^ := token.identifierKind; current_case^ := token.identifierKind;
@ -174,7 +179,9 @@ BEGIN
WHILE token.kind <> lexerKindRightParen DO WHILE token.kind <> lexerKindRightParen DO
INC(parameter_count); 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; current_parameter := result^.parameters;
INC(current_parameter, TSIZE(PAstTypeExpression) * (parameter_count - 1)); INC(current_parameter, TSIZE(PAstTypeExpression) * (parameter_count - 1));
@ -459,7 +466,7 @@ BEGIN
literal^.kind := astLiteralKindInteger; literal^.kind := astLiteralKindInteger;
literal^.integer := token.integerKind; literal^.integer := token.integerKind;
END; END;
IF token.kind = lexerKindCharacter THEN IF (token.kind = lexerKindCharacter) OR (token.kind = lexerKindString) THEN
NEW(literal); NEW(literal);
literal^.kind := astLiteralKindString; literal^.kind := astLiteralKindString;
@ -470,6 +477,12 @@ BEGIN
literal^.kind := astLiteralKindNull; literal^.kind := astLiteralKindNull;
END; END;
IF token.kind = lexerKindBoolean THEN
NEW(literal);
literal^.kind := astLiteralKindBoolean;
literal^.boolean := token.booleanKind
END;
IF literal <> NIL THEN IF literal <> NIL THEN
token := transpiler_lex(lexer) token := transpiler_lex(lexer)
END; END;
@ -509,6 +522,13 @@ BEGIN
result^.unary_operator := astUnaryOperatorNot; result^.unary_operator := astUnaryOperatorNot;
result^.unary_operand := parse_factor(lexer) result^.unary_operand := parse_factor(lexer)
END; 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 IF (result = NIL) AND (next_token.kind = lexerKindIdentifier) THEN
NEW(result); NEW(result);
@ -525,6 +545,7 @@ VAR
next_token: LexerToken; next_token: LexerToken;
inner_expression: PAstExpression; inner_expression: PAstExpression;
designator: PAstExpression; designator: PAstExpression;
arguments: PPAstExpression;
handled: BOOLEAN; handled: BOOLEAN;
BEGIN BEGIN
designator := parse_factor(lexer); designator := parse_factor(lexer);
@ -550,7 +571,7 @@ BEGIN
designator^.kind := astExpressionKindArrayAccess; designator^.kind := astExpressionKindArrayAccess;
designator^.array := inner_expression; designator^.array := inner_expression;
designator^.index := parse_designator(lexer); designator^.index := parse_expression(lexer);
next_token := transpiler_lex(lexer); next_token := transpiler_lex(lexer);
handled := TRUE handled := TRUE
@ -563,6 +584,38 @@ BEGIN
designator^.aggregate := inner_expression; designator^.aggregate := inner_expression;
designator^.field := next_token.identifierKind; 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); next_token := transpiler_lex(lexer);
handled := TRUE handled := TRUE
END END
@ -570,4 +623,113 @@ BEGIN
RETURN designator RETURN designator
END parse_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. END Parser.

View File

@ -9,14 +9,14 @@ FROM MemUtils IMPORT MemCopy, MemZero;
FROM Common IMPORT Identifier, PIdentifier, ShortString; FROM Common IMPORT Identifier, PIdentifier, ShortString;
FROM Lexer IMPORT Lexer, LexerToken, lexer_current, lexer_lex, LexerKind; FROM Lexer IMPORT Lexer, LexerToken, lexer_current, lexer_lex, LexerKind;
FROM Parser IMPORT AstTypeExpressionKind, AstExpressionKind, AstLiteralKind, AstUnaryOperator, FROM Parser IMPORT AstTypeExpressionKind, AstExpressionKind, AstLiteralKind, AstUnaryOperator, AstBinaryOperator,
AstModule, PAstModule, AstExpression, PAstExpression, PAstLiteral, AstModule, PAstModule, AstExpression, PPAstExpression, PAstExpression, PAstLiteral,
PAstConstantDeclaration, PPAstConstantDeclaration, PAstConstantDeclaration, PPAstConstantDeclaration, PAstStatement, AstStatementKind,
AstTypeDeclaration, PAstTypeDeclaration, PPAstTypeDeclaration, AstTypeDeclaration, PAstTypeDeclaration, PPAstTypeDeclaration,
PAstVariableDeclaration, PPAstVariableDeclaration, PAstImportStatement, PPAstImportStatement, PAstVariableDeclaration, PPAstVariableDeclaration, PAstImportStatement, PPAstImportStatement,
PAstTypeExpression, PPAstTypeExpression, AstFieldDeclaration, PAstFieldDeclaration, PAstTypeExpression, PPAstTypeExpression, AstFieldDeclaration, PAstFieldDeclaration,
parse_type_expression, parse_variable_part, parse_type_part, parse_constant_part, parse_import_part, 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. *) (* Calls lexer_lex() but skips the comments. *)
PROCEDURE transpiler_lex(lexer: PLexer): LexerToken; PROCEDURE transpiler_lex(lexer: PLexer): LexerToken;
@ -40,8 +40,12 @@ END write_semicolon;
PROCEDURE write_current(lexer: PLexer; output: File); PROCEDURE write_current(lexer: PLexer; output: File);
VAR VAR
written_bytes: CARDINAL; written_bytes: CARDINAL;
count: CARDINAL;
BEGIN 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; END write_current;
PROCEDURE transpile_import_statement(context: PTranspilerContext; import_statement: PAstImportStatement); PROCEDURE transpile_import_statement(context: PTranspilerContext; import_statement: PAstImportStatement);
VAR VAR
@ -385,59 +389,6 @@ BEGIN
RETURN result RETURN result
END transpile_procedure_heading; 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); PROCEDURE transpile_unary_operator(context: PTranspilerContext; operator: AstUnaryOperator);
BEGIN BEGIN
IF operator = astUnaryOperatorMinus THEN IF operator = astUnaryOperatorMinus THEN
@ -447,11 +398,49 @@ BEGIN
WriteChar(context^.output, '~') WriteChar(context^.output, '~')
END END
END transpile_unary_operator; 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); PROCEDURE transpile_expression(context: PTranspilerContext; expression: PAstExpression);
VAR VAR
literal: PAstLiteral; literal: PAstLiteral;
buffer: ARRAY[1..20] OF CHAR; buffer: ARRAY[1..20] OF CHAR;
written_bytes: CARDINAL; written_bytes: CARDINAL;
argument_index: CARDINAL;
current_argument: PPAstExpression;
BEGIN BEGIN
IF expression^.kind = astExpressionKindLiteral THEN IF expression^.kind = astExpressionKindLiteral THEN
literal := expression^.literal; literal := expression^.literal;
@ -462,7 +451,16 @@ BEGIN
END; END;
IF literal^.kind = astLiteralKindString THEN IF literal^.kind = astLiteralKindString THEN
WriteString(context^.output, literal^.string) 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; END;
IF expression^.kind = astExpressionKindIdentifier THEN IF expression^.kind = astExpressionKindIdentifier THEN
written_bytes := WriteNBytes(context^.output, ORD(expression^.identifier[1]), ADR(expression^.identifier[2])) written_bytes := WriteNBytes(context^.output, ORD(expression^.identifier[1]), ADR(expression^.identifier[2]))
@ -485,145 +483,130 @@ BEGIN
IF expression^.kind = astExpressionKindUnary THEN IF expression^.kind = astExpressionKindUnary THEN
transpile_unary_operator(context, expression^.unary_operator); transpile_unary_operator(context, expression^.unary_operator);
transpile_expression(context, expression^.unary_operand) 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
END transpile_expression; END transpile_expression;
PROCEDURE transpile_if_statement(context: PTranspilerContext); PROCEDURE transpile_if_statement(context: PTranspilerContext): PAstStatement;
VAR VAR
token: LexerToken; token: LexerToken;
expression: PAstExpression; result: PAstStatement;
lexer: Lexer;
BEGIN BEGIN
NEW(result);
result^.kind := astStatementKindIf;
WriteString(context^.output, ' IF '); WriteString(context^.output, ' IF ');
lexer := context^.lexer^; token := transpiler_lex(context^.lexer);
token := transpiler_lex(ADR(lexer)); result^.if_condition := parse_expression(context^.lexer);
expression := parse_expression(ADR(lexer));
IF expression <> NIL THEN transpile_expression(context, result^.if_condition);
context^.lexer^ := lexer; token := lexer_current(context^.lexer);
transpile_expression(context, expression);
WriteChar(context^.output, ' ')
END;
IF expression = NIL THEN
token := transpiler_lex(context^.lexer)
END;
transpile_unchanged(context, lexerKindThen);
WriteString(context^.output, 'THEN'); WriteString(context^.output, ' THEN');
WriteLine(context^.output); WriteLine(context^.output);
transpile_statements(context); transpile_statements(context);
WriteString(context^.output, ' END'); WriteString(context^.output, ' END');
token := transpiler_lex(context^.lexer) token := transpiler_lex(context^.lexer);
RETURN result
END transpile_if_statement; END transpile_if_statement;
PROCEDURE transpile_while_statement(context: PTranspilerContext); PROCEDURE transpile_while_statement(context: PTranspilerContext): PAstStatement;
VAR VAR
token: LexerToken; token: LexerToken;
result: PAstStatement;
BEGIN BEGIN
NEW(result);
result^.kind := astStatementKindWhile;
WriteString(context^.output, ' WHILE '); 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); WriteLine(context^.output);
transpile_statements(context); transpile_statements(context);
WriteString(context^.output, ' END'); WriteString(context^.output, ' END');
token := transpiler_lex(context^.lexer) token := transpiler_lex(context^.lexer);
RETURN result
END transpile_while_statement; END transpile_while_statement;
PROCEDURE transpile_assignment_statement(context: PTranspilerContext); PROCEDURE transpile_assignment_statement(context: PTranspilerContext; statement: PAstStatement);
VAR
token: LexerToken;
BEGIN BEGIN
transpile_expression(context, statement^.assignee);
WriteString(context^.output, ' := '); WriteString(context^.output, ' := ');
token := transpiler_lex(context^.lexer); transpile_expression(context, statement^.assignment)
transpile_unchanged(context, lexerKindSemicolon);
END transpile_assignment_statement; END transpile_assignment_statement;
PROCEDURE transpile_call_statement(context: PTranspilerContext); PROCEDURE transpile_return_statement(context: PTranspilerContext; statement: PAstStatement);
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;
BEGIN BEGIN
WriteString(context^.output, ' RETURN '); WriteString(context^.output, ' RETURN ');
token := transpiler_lex(context^.lexer);
transpile_unchanged(context, lexerKindSemicolon) transpile_expression(context, statement^.returned);
END transpile_return_statement; END transpile_return_statement;
PROCEDURE transpile_statement(context: PTranspilerContext); PROCEDURE transpile_statement(context: PTranspilerContext);
VAR VAR
token: LexerToken; token: LexerToken;
written_bytes: CARDINAL;
statement: PAstStatement;
designator: PAstExpression;
BEGIN BEGIN
token := transpiler_lex(context^.lexer); token := transpiler_lex(context^.lexer);
IF token.kind = lexerKindIf THEN IF token.kind = lexerKindIf THEN
transpile_if_statement(context) statement := transpile_if_statement(context)
END; END;
IF token.kind = lexerKindWhile THEN IF token.kind = lexerKindWhile THEN
transpile_while_statement(context) statement := transpile_while_statement(context)
END; END;
IF token.kind = lexerKindReturn THEN IF token.kind = lexerKindReturn THEN
transpile_return_statement(context) statement := parse_return_statement(context^.lexer);
transpile_return_statement(context, statement)
END; END;
IF token.kind = lexerKindIdentifier THEN IF token.kind = lexerKindIdentifier THEN
transpile_designator_expression(context); designator := parse_designator(context^.lexer);
token := lexer_current(context^.lexer); token := lexer_current(context^.lexer);
IF token.kind = lexerKindAssignment THEN IF token.kind = lexerKindAssignment THEN
transpile_assignment_statement(context) statement := parse_assignment_statement(context^.lexer, designator);
transpile_assignment_statement(context, statement)
END; END;
IF token.kind = lexerKindLeftParen THEN IF token.kind <> lexerKindAssignment THEN
transpile_call_statement(context) statement := parse_call_statement(context^.lexer, designator);
transpile_expression(context, designator);
written_bytes := WriteNBytes(StdErr, 5, context^.lexer^.start);
WriteLine(StdErr);
END END
END END
END transpile_statement; END transpile_statement;