Parse call expressions
This commit is contained in:
@ -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.
|
||||||
|
552
source/Lexer.mod
552
source/Lexer.mod
@ -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();
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user