diff --git a/source/Lexer.def b/source/Lexer.def index ce6fd01..bd3fbcf 100644 --- a/source/Lexer.def +++ b/source/Lexer.def @@ -7,12 +7,12 @@ FROM Common IMPORT Identifier, ShortString; TYPE PLexerBuffer = POINTER TO CHAR; Lexer = RECORD - Input: File; - Buffer: PLexerBuffer; - Size: CARDINAL; - Length: CARDINAL; - Start: PLexerBuffer; - Current: PLexerBuffer + input: File; + buffer: PLexerBuffer; + size: CARDINAL; + length: CARDINAL; + start: PLexerBuffer; + current: PLexerBuffer END; PLexer = POINTER TO Lexer; LexerKind = ( @@ -90,11 +90,11 @@ TYPE END; PLexerToken = POINTER TO LexerToken; -PROCEDURE lexer_initialize(ALexer: PLexer; Input: File); -PROCEDURE lexer_destroy(ALexer: PLexer); +PROCEDURE lexer_initialize(lexer: PLexer; input: File); +PROCEDURE lexer_destroy(lexer: PLexer); (* Returns the last read token. *) -PROCEDURE lexer_current(ALexer: PLexer): LexerToken; +PROCEDURE lexer_current(lexer: PLexer): LexerToken; (* Read and return the next token. *) -PROCEDURE lexer_lex(ALexer: PLexer): LexerToken; +PROCEDURE lexer_lex(lexer: PLexer): LexerToken; END Lexer. diff --git a/source/Lexer.mod b/source/Lexer.mod index 4d8ca20..6c50a84 100644 --- a/source/Lexer.mod +++ b/source/Lexer.mod @@ -64,8 +64,8 @@ TYPE ); TransitionAction = PROCEDURE(PLexer, PLexerToken); Transition = RECORD - Action: TransitionAction; - NextState: TransitionState + action: TransitionAction; + next_state: TransitionState END; TransitionClasses = ARRAY[1..22] OF Transition; @@ -209,24 +209,30 @@ BEGIN i := 129; WHILE i <= 256 DO classification[i] := transitionClassOther; - i := i + 1 + INC(i) END END initialize_classification; -PROCEDURE compare_keyword(Keyword: ARRAY OF CHAR; TokenStart: PLexerBuffer; TokenEnd: PLexerBuffer): BOOLEAN; +PROCEDURE compare_keyword(keyword: ARRAY OF CHAR; token_start: PLexerBuffer; token_end: PLexerBuffer): BOOLEAN; VAR result: BOOLEAN; index: CARDINAL; + keyword_length: CARDINAL; + continue: BOOLEAN; BEGIN index := 0; result := TRUE; + keyword_length := Length(keyword); + continue := (index < keyword_length) AND (token_start <> token_end); - WHILE (index < Length(Keyword)) AND (TokenStart <> TokenEnd) AND result DO - result := (Keyword[index] = TokenStart^) OR (Lower(Keyword[index]) = TokenStart^); - INC(TokenStart); - INC(index) + WHILE continue AND result DO + result := (keyword[index] = token_start^) OR (Lower(keyword[index]) = token_start^); + INC(token_start); + INC(index); + continue := (index < keyword_length) AND (token_start <> token_end) END; - result := (index = Length(Keyword)) AND (TokenStart = TokenEnd) AND result; - RETURN result + result := result AND (index = Length(keyword)); + + RETURN result AND (token_start = token_end) END compare_keyword; (* Reached the end of file. *) PROCEDURE transition_action_eof(lexer: PLexer; token: PLexerToken); @@ -236,182 +242,193 @@ END transition_action_eof; (* Add the character to the token currently read and advance to the next character. *) PROCEDURE transition_action_accumulate(lexer: PLexer; token: PLexerToken); BEGIN - INC(lexer^.Current) + INC(lexer^.current) END transition_action_accumulate; (* The current character is not a part of the token. Finish the token already * read. Don't advance to the next character. *) PROCEDURE transition_action_finalize(lexer: PLexer; token: PLexerToken); BEGIN - IF lexer^.Start^ = ':' THEN + IF lexer^.start^ = ':' THEN token^.kind := lexerKindColon END; - IF lexer^.Start^ = '>' THEN + IF lexer^.start^ = '>' THEN token^.kind := lexerKindGreaterThan END; - IF lexer^.Start^ = '<' THEN + IF lexer^.start^ = '<' THEN token^.kind := lexerKindLessThan END; - IF lexer^.Start^ = '(' THEN + IF lexer^.start^ = '(' THEN token^.kind := lexerKindLeftParen END; - IF lexer^.Start^ = '-' THEN + IF lexer^.start^ = '-' THEN token^.kind := lexerKindLeftParen END; - IF lexer^.Start^ = '.' THEN + IF lexer^.start^ = '.' THEN token^.kind := lexerKindDot END END transition_action_finalize; (* An action for tokens containing multiple characters. *) PROCEDURE transition_action_composite(lexer: PLexer; token: PLexerToken); BEGIN - IF lexer^.Start^ = '<' THEN - IF lexer^.Current^ = '>' THEN + IF lexer^.start^ = '<' THEN + IF lexer^.current^ = '>' THEN token^.kind := lexerKindNotEqual END; - IF lexer^.Current^ = '=' THEN + IF lexer^.current^ = '=' THEN token^.kind := lexerKindLessEqual END END; - IF (lexer^.Start^ = '>') AND (lexer^.Current^ = '=') THEN + IF (lexer^.start^ = '>') AND (lexer^.current^ = '=') THEN token^.kind := lexerKindGreaterEqual END; - IF (lexer^.Start^ = '.') AND (lexer^.Current^ = '.') THEN + IF (lexer^.start^ = '.') AND (lexer^.current^ = '.') THEN token^.kind := lexerKindRange END; - IF (lexer^.Start^ = ':') AND (lexer^.Current^ = '=') THEN + IF (lexer^.start^ = ':') AND (lexer^.current^ = '=') THEN token^.kind := lexerKindAssignment END; - IF (lexer^.Start^ = '-') AND (lexer^.Current^ = '>') THEN + IF (lexer^.start^ = '-') AND (lexer^.current^ = '>') THEN token^.kind := lexerKindArrow END; - INC(lexer^.Current) + INC(lexer^.current) END transition_action_composite; (* Skip a space. *) PROCEDURE transition_action_skip(lexer: PLexer; token: PLexerToken); BEGIN - INC(lexer^.Current); - INC(lexer^.Start) + INC(lexer^.current); + INC(lexer^.start) END transition_action_skip; (* Delimited string action. *) PROCEDURE transition_action_delimited(lexer: PLexer; token: PLexerToken); VAR text_length: CARDINAL; BEGIN - IF lexer^.Start^ = '(' THEN + IF lexer^.start^ = '(' THEN token^.kind := lexerKindComment END; - IF lexer^.Start^ = '"' THEN + IF lexer^.start^ = '"' THEN + text_length := lexer^.current; + DEC(text_length, lexer^.start); + INC(text_length); + + MemZero(ADR(token^.stringKind), TSIZE(ShortString)); + MemCopy(lexer^.start, text_length, ADR(token^.stringKind)); + token^.kind := lexerKindCharacter END; - IF lexer^.Start^ = "'" THEN - text_length := lexer^.Current - lexer^.Start; + IF lexer^.start^ = "'" THEN + text_length := lexer^.current; + DEC(text_length, lexer^.start); + INC(text_length); + MemZero(ADR(token^.stringKind), TSIZE(ShortString)); - MemCopy(lexer^.Start, text_length, ADR(token^.stringKind)); + MemCopy(lexer^.start, text_length, ADR(token^.stringKind)); token^.kind := lexerKindString END; - INC(lexer^.Current) + INC(lexer^.current) END transition_action_delimited; (* Finalize keyword OR identifier. *) PROCEDURE transition_action_key_id(lexer: PLexer; token: PLexerToken); BEGIN token^.kind := lexerKindIdentifier; - token^.identifierKind[1] := lexer^.Current - lexer^.Start; - MemCopy(lexer^.Start, ORD(token^.identifierKind[1]), ADR(token^.identifierKind[2])); + token^.identifierKind[1] := lexer^.current; + DEC(token^.identifierKind[1], lexer^.start); + MemCopy(lexer^.start, ORD(token^.identifierKind[1]), ADR(token^.identifierKind[2])); - IF compare_keyword('PROGRAM', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('PROGRAM', lexer^.start, lexer^.current) THEN token^.kind := lexerKindProgram END; - IF compare_keyword('IMPORT', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('IMPORT', lexer^.start, lexer^.current) THEN token^.kind := lexerKindImport END; - IF compare_keyword('CONST', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('CONST', lexer^.start, lexer^.current) THEN token^.kind := lexerKindConst END; - IF compare_keyword('VAR', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('VAR', lexer^.start, lexer^.current) THEN token^.kind := lexerKindVar END; - IF compare_keyword('IF', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('IF', lexer^.start, lexer^.current) THEN token^.kind := lexerKindIf END; - IF compare_keyword('THEN', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('THEN', lexer^.start, lexer^.current) THEN token^.kind := lexerKindThen END; - IF compare_keyword('ELSIF', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('ELSIF', lexer^.start, lexer^.current) THEN token^.kind := lexerKindElsif END; - IF compare_keyword('ELSE', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('ELSE', lexer^.start, lexer^.current) THEN token^.kind := lexerKindElse END; - IF compare_keyword('WHILE', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('WHILE', lexer^.start, lexer^.current) THEN token^.kind := lexerKindWhile END; - IF compare_keyword('DO', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('DO', lexer^.start, lexer^.current) THEN token^.kind := lexerKindDo END; - IF compare_keyword('proc', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('proc', lexer^.start, lexer^.current) THEN token^.kind := lexerKindProc END; - IF compare_keyword('BEGIN', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('BEGIN', lexer^.start, lexer^.current) THEN token^.kind := lexerKindBegin END; - IF compare_keyword('END', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('END', lexer^.start, lexer^.current) THEN token^.kind := lexerKindEnd END; - IF compare_keyword('TYPE', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('TYPE', lexer^.start, lexer^.current) THEN token^.kind := lexerKindType END; - IF compare_keyword('RECORD', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('RECORD', lexer^.start, lexer^.current) THEN token^.kind := lexerKindRecord END; - IF compare_keyword('UNION', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('UNION', lexer^.start, lexer^.current) THEN token^.kind := lexerKindUnion END; - IF compare_keyword('NIL', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('NIL', lexer^.start, lexer^.current) THEN token^.kind := lexerKindNull END; - IF compare_keyword('AND', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('AND', lexer^.start, lexer^.current) THEN token^.kind := lexerKindAnd END; - IF compare_keyword('OR', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('OR', lexer^.start, lexer^.current) THEN token^.kind := lexerKindOr END; - IF compare_keyword('RETURN', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('RETURN', lexer^.start, lexer^.current) THEN token^.kind := lexerKindReturn END; - IF compare_keyword('DEFINITION', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('DEFINITION', lexer^.start, lexer^.current) THEN token^.kind := lexerKindDefinition END; - IF compare_keyword('TO', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('TO', lexer^.start, lexer^.current) THEN token^.kind := lexerKindTo END; - IF compare_keyword('CASE', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('CASE', lexer^.start, lexer^.current) THEN token^.kind := lexerKindCase END; - IF compare_keyword('OF', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('OF', lexer^.start, lexer^.current) THEN token^.kind := lexerKindOf END; - IF compare_keyword('FROM', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('FROM', lexer^.start, lexer^.current) THEN token^.kind := lexerKindFrom END; - IF compare_keyword('MODULE', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('MODULE', lexer^.start, lexer^.current) THEN token^.kind := lexerKindModule END; - IF compare_keyword('IMPLEMENTATION', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('IMPLEMENTATION', lexer^.start, lexer^.current) THEN token^.kind := lexerKindImplementation END; - IF compare_keyword('POINTER', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('POINTER', lexer^.start, lexer^.current) THEN token^.kind := lexerKindPointer END; - IF compare_keyword('ARRAY', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('ARRAY', lexer^.start, lexer^.current) THEN token^.kind := lexerKindArray END; - IF compare_keyword('TRUE', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('TRUE', lexer^.start, lexer^.current) THEN token^.kind := lexerKindBoolean; token^.booleanKind := TRUE END; - IF compare_keyword('FALSE', lexer^.Start, lexer^.Current) THEN + IF compare_keyword('FALSE', lexer^.start, lexer^.current) THEN token^.kind := lexerKindBoolean; token^.booleanKind := FALSE END @@ -420,49 +437,49 @@ END transition_action_key_id; * followed by other characters forming a composite token. *) PROCEDURE transition_action_single(lexer: PLexer; token: PLexerToken); BEGIN - IF lexer^.Current^ = '&' THEN + IF lexer^.current^ = '&' THEN token^.kind := lexerKindAnd END; - IF lexer^.Current^ = ';' THEN + IF lexer^.current^ = ';' THEN token^.kind := lexerKindSemicolon END; - IF lexer^.Current^ = ',' THEN + IF lexer^.current^ = ',' THEN token^.kind := lexerKindComma END; - IF lexer^.Current^ = '~' THEN + IF lexer^.current^ = '~' THEN token^.kind := lexerKindTilde END; - IF lexer^.Current^ = ')' THEN + IF lexer^.current^ = ')' THEN token^.kind := lexerKindRightParen END; - IF lexer^.Current^ = '[' THEN + IF lexer^.current^ = '[' THEN token^.kind := lexerKindLeftSquare END; - IF lexer^.Current^ = ']' THEN + IF lexer^.current^ = ']' THEN token^.kind := lexerKindRightSquare END; - IF lexer^.Current^ = '^' THEN + IF lexer^.current^ = '^' THEN token^.kind := lexerKindHat END; - IF lexer^.Current^ = '=' THEN + IF lexer^.current^ = '=' THEN token^.kind := lexerKindEqual END; - IF lexer^.Current^ = '+' THEN + IF lexer^.current^ = '+' THEN token^.kind := lexerKindPlus END; - IF lexer^.Current^ = '/' THEN + IF lexer^.current^ = '/' THEN token^.kind := lexerKindDivision END; - IF lexer^.Current^ = '%' THEN + IF lexer^.current^ = '%' THEN token^.kind := lexerKindRemainder END; - IF lexer^.Current^ = '@' THEN + IF lexer^.current^ = '@' THEN token^.kind := lexerKindAt END; - IF lexer^.Current^ = '|' THEN + IF lexer^.current^ = '|' THEN token^.kind := lexerKindPipe END; - INC(lexer^.Current) + INC(lexer^.current) END transition_action_single; (* Handle an integer literal. *) PROCEDURE transition_action_integer(lexer: PLexer; token: PLexerToken); @@ -473,43 +490,44 @@ VAR BEGIN token^.kind := lexerKindInteger; - integer_length := lexer^.Current - lexer^.Start; + integer_length := lexer^.current; + DEC(integer_length, lexer^.start); MemZero(ADR(token^.identifierKind), TSIZE(Identifier)); - MemCopy(lexer^.Start, integer_length, ADR(token^.identifierKind[1])); + MemCopy(lexer^.start, integer_length, ADR(token^.identifierKind[1])); buffer := InitStringCharStar(ADR(token^.identifierKind[1])); token^.integerKind := StringToInteger(buffer, 10, found); buffer := KillString(buffer) END transition_action_integer; -PROCEDURE set_default_transition(CurrentState: TransitionState; DefaultAction: TransitionAction; NextState: TransitionState); +PROCEDURE set_default_transition(current_state: TransitionState; DefaultAction: TransitionAction; next_state: TransitionState); VAR - DefaultTransition: Transition; + default_transition: Transition; BEGIN - DefaultTransition.Action := DefaultAction; - DefaultTransition.NextState := NextState; + default_transition.action := DefaultAction; + default_transition.next_state := next_state; - transitions[ORD(CurrentState) + 1][ORD(transitionClassInvalid) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassDigit) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassAlpha) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassSpace) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassColon) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassEquals) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassLeftParen) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassRightParen) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassAsterisk) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassUnderscore) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassSingle) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassHex) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassZero) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassX) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassEof) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassDot) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassMinus) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassSingleQuote) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassDoubleQuote) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassGreater) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassLess) + 1] := DefaultTransition; - transitions[ORD(CurrentState) + 1][ORD(transitionClassOther) + 1] := DefaultTransition + transitions[ORD(current_state) + 1][ORD(transitionClassInvalid) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassDigit) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassAlpha) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassSpace) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassColon) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassEquals) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassLeftParen) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassRightParen) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassAsterisk) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassUnderscore) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassSingle) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassHex) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassZero) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassX) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassEof) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassDot) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassMinus) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassSingleQuote) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassDoubleQuote) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassGreater) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassLess) + 1] := default_transition; + transitions[ORD(current_state) + 1][ORD(transitionClassOther) + 1] := default_transition END set_default_transition; (* * The transition table describes transitions from one state to another, given @@ -530,267 +548,276 @@ END set_default_transition; PROCEDURE initialize_transitions(); BEGIN (* Start state. *) - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassInvalid) + 1].Action := NIL; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassInvalid) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassInvalid) + 1].action := NIL; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassInvalid) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDigit) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateDecimal; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDigit) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDigit) + 1].next_state := transitionStateDecimal; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAlpha) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAlpha) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAlpha) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSpace) + 1].Action := transition_action_skip; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSpace) + 1].NextState := transitionStateStart; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSpace) + 1].action := transition_action_skip; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSpace) + 1].next_state := transitionStateStart; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassColon) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassColon) + 1].NextState := transitionStateColon; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassColon) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassColon) + 1].next_state := transitionStateColon; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEquals) + 1].Action := transition_action_single; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEquals) + 1].action := transition_action_single; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEquals) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLeftParen) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLeftParen) + 1].NextState := transitionStateLeftParen; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLeftParen) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLeftParen) + 1].next_state := transitionStateLeftParen; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassRightParen) + 1].Action := transition_action_single; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassRightParen) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassRightParen) + 1].action := transition_action_single; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassRightParen) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAsterisk) + 1].Action := transition_action_single; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAsterisk) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAsterisk) + 1].action := transition_action_single; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassAsterisk) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassUnderscore) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassUnderscore) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassUnderscore) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassUnderscore) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingle) + 1].Action := transition_action_single; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingle) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingle) + 1].action := transition_action_single; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingle) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassHex) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassHex) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassHex) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassZero) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateLeadingZero; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassZero) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassZero) + 1].next_state := transitionStateLeadingZero; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassX) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassX) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassX) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassX) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEof) + 1].Action := transition_action_eof; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEof) + 1].action := transition_action_eof; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDot) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDot) + 1].NextState := transitionStateDot; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDot) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDot) + 1].next_state := transitionStateDot; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassMinus) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassMinus) + 1].NextState := transitionStateMinus; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassMinus) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassMinus) + 1].next_state := transitionStateMinus; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingleQuote) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingleQuote) + 1].NextState := transitionStateCharacter; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingleQuote) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassSingleQuote) + 1].next_state := transitionStateCharacter; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDoubleQuote) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDoubleQuote) + 1].NextState := transitionStateString; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDoubleQuote) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassDoubleQuote) + 1].next_state := transitionStateString; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassGreater) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassGreater) + 1].NextState := transitionStateGreater; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassGreater) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassGreater) + 1].next_state := transitionStateGreater; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLess) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLess) + 1].NextState := transitionStateLess; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLess) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassLess) + 1].next_state := transitionStateLess; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassOther) + 1].Action := NIL; - transitions[ORD(transitionStateStart) + 1][ORD(transitionClassOther) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassOther) + 1].action := NIL; + transitions[ORD(transitionStateStart) + 1][ORD(transitionClassOther) + 1].next_state := transitionStateEnd; (* Colon state. *) set_default_transition(transitionStateColon, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateColon) + 1][ORD(transitionClassEquals) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateColon) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateColon) + 1][ORD(transitionClassEquals) + 1].action := transition_action_composite; + transitions[ORD(transitionStateColon) + 1][ORD(transitionClassEquals) + 1].next_state := transitionStateEnd; (* Identifier state. *) set_default_transition(transitionStateIdentifier, transition_action_key_id, transitionStateEnd); - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassDigit) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassDigit) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassDigit) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassAlpha) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassAlpha) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassAlpha) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassUnderscore) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassUnderscore) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassUnderscore) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassUnderscore) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassHex) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassHex) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassHex) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassZero) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassZero) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassZero) + 1].next_state := transitionStateIdentifier; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassX) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassX) + 1].NextState := transitionStateIdentifier; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassX) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateIdentifier) + 1][ORD(transitionClassX) + 1].next_state := transitionStateIdentifier; (* Decimal state. *) set_default_transition(transitionStateDecimal, transition_action_integer, transitionStateEnd); - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassDigit) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateDecimal; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassDigit) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassDigit) + 1].next_state := transitionStateDecimal; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassAlpha) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateDecimalSuffix; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassAlpha) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassAlpha) + 1].next_state := transitionStateDecimalSuffix; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassUnderscore) + 1].Action := NIL; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassUnderscore) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassUnderscore) + 1].action := NIL; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassUnderscore) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassHex) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateDecimalSuffix; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassHex) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassHex) + 1].next_state := transitionStateDecimalSuffix; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassZero) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateDecimal; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassZero) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassZero) + 1].next_state := transitionStateDecimal; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassX) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassX) + 1].NextState := transitionStateDecimalSuffix; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassX) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateDecimal) + 1][ORD(transitionClassX) + 1].next_state := transitionStateDecimalSuffix; (* Greater state. *) set_default_transition(transitionStateGreater, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateGreater) + 1][ORD(transitionClassEquals) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateGreater) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateGreater) + 1][ORD(transitionClassEquals) + 1].action := transition_action_composite; + transitions[ORD(transitionStateGreater) + 1][ORD(transitionClassEquals) + 1].next_state := transitionStateEnd; (* Minus state. *) set_default_transition(transitionStateMinus, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateMinus) + 1][ORD(transitionClassGreater) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateMinus) + 1][ORD(transitionClassGreater) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateMinus) + 1][ORD(transitionClassGreater) + 1].action := transition_action_composite; + transitions[ORD(transitionStateMinus) + 1][ORD(transitionClassGreater) + 1].next_state := transitionStateEnd; (* Left paren state. *) set_default_transition(transitionStateLeftParen, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateLeftParen) + 1][ORD(transitionClassAsterisk) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateLeftParen) + 1][ORD(transitionClassAsterisk) + 1].NextState := transitionStateComment; + transitions[ORD(transitionStateLeftParen) + 1][ORD(transitionClassAsterisk) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateLeftParen) + 1][ORD(transitionClassAsterisk) + 1].next_state := transitionStateComment; (* Less state. *) set_default_transition(transitionStateLess, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateLess) + 1][ORD(transitionClassEquals) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateLess) + 1][ORD(transitionClassEquals) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLess) + 1][ORD(transitionClassEquals) + 1].action := transition_action_composite; + transitions[ORD(transitionStateLess) + 1][ORD(transitionClassEquals) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLess) + 1][ORD(transitionClassGreater) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateLess) + 1][ORD(transitionClassGreater) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLess) + 1][ORD(transitionClassGreater) + 1].action := transition_action_composite; + transitions[ORD(transitionStateLess) + 1][ORD(transitionClassGreater) + 1].next_state := transitionStateEnd; (* Hexadecimal after 0x. *) set_default_transition(transitionStateDot, transition_action_finalize, transitionStateEnd); - transitions[ORD(transitionStateDot) + 1][ORD(transitionClassDot) + 1].Action := transition_action_composite; - transitions[ORD(transitionStateDot) + 1][ORD(transitionClassDot) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDot) + 1][ORD(transitionClassDot) + 1].action := transition_action_composite; + transitions[ORD(transitionStateDot) + 1][ORD(transitionClassDot) + 1].next_state := transitionStateEnd; (* Comment. *) set_default_transition(transitionStateComment, transition_action_accumulate, transitionStateComment); - transitions[ORD(transitionStateComment) + 1][ORD(transitionClassAsterisk) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateComment) + 1][ORD(transitionClassAsterisk) + 1].NextState := transitionStateClosingComment; + transitions[ORD(transitionStateComment) + 1][ORD(transitionClassAsterisk) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateComment) + 1][ORD(transitionClassAsterisk) + 1].next_state := transitionStateClosingComment; - transitions[ORD(transitionStateComment) + 1][ORD(transitionClassEof) + 1].Action := NIL; - transitions[ORD(transitionStateComment) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateComment) + 1][ORD(transitionClassEof) + 1].action := NIL; + transitions[ORD(transitionStateComment) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd; (* Closing comment. *) set_default_transition(transitionStateClosingComment, transition_action_accumulate, transitionStateComment); - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassInvalid) + 1].Action := NIL; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassInvalid) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassInvalid) + 1].action := NIL; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassInvalid) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassRightParen) + 1].Action := transition_action_delimited; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassRightParen) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassRightParen) + 1].action := transition_action_delimited; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassRightParen) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassAsterisk) + 1].Action := transition_action_accumulate; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassAsterisk) + 1].NextState := transitionStateClosingComment; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassAsterisk) + 1].action := transition_action_accumulate; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassAsterisk) + 1].next_state := transitionStateClosingComment; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassEof) + 1].Action := NIL; - transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassEof) + 1].action := NIL; + transitions[ORD(transitionStateClosingComment) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd; (* Character. *) set_default_transition(transitionStateCharacter, transition_action_accumulate, transitionStateCharacter); - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassInvalid) + 1].Action := NIL; - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassInvalid) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassInvalid) + 1].action := NIL; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassInvalid) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassEof) + 1].Action := NIL; - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassEof) + 1].action := NIL; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassSingleQuote) + 1].Action := transition_action_delimited; - transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassSingleQuote) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassSingleQuote) + 1].action := transition_action_delimited; + transitions[ORD(transitionStateCharacter) + 1][ORD(transitionClassSingleQuote) + 1].next_state := transitionStateEnd; (* String. *) set_default_transition(transitionStateString, transition_action_accumulate, transitionStateString); - transitions[ORD(transitionStateString) + 1][ORD(transitionClassInvalid) + 1].Action := NIL; - transitions[ORD(transitionStateString) + 1][ORD(transitionClassInvalid) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassInvalid) + 1].action := NIL; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassInvalid) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateString) + 1][ORD(transitionClassEof) + 1].Action := NIL; - transitions[ORD(transitionStateString) + 1][ORD(transitionClassEof) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassEof) + 1].action := NIL; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassEof) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateString) + 1][ORD(transitionClassDoubleQuote) + 1].Action := transition_action_delimited; - transitions[ORD(transitionStateString) + 1][ORD(transitionClassDoubleQuote) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassDoubleQuote) + 1].action := transition_action_delimited; + transitions[ORD(transitionStateString) + 1][ORD(transitionClassDoubleQuote) + 1].next_state := transitionStateEnd; (* Leading zero. *) set_default_transition(transitionStateLeadingZero, transition_action_integer, transitionStateEnd); - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassDigit) + 1].Action := NIL; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassDigit) + 1].action := NIL; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassDigit) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassAlpha) + 1].Action := NIL; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassAlpha) + 1].action := NIL; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassAlpha) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassUnderscore) + 1].Action := NIL; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassUnderscore) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassUnderscore) + 1].action := NIL; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassUnderscore) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassHex) + 1].Action := NIL; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassHex) + 1].action := NIL; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassHex) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassZero) + 1].Action := NIL; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassZero) + 1].action := NIL; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassZero) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassX) + 1].Action := NIL; - transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassX) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassX) + 1].action := NIL; + transitions[ORD(transitionStateLeadingZero) + 1][ORD(transitionClassX) + 1].next_state := transitionStateEnd; (* Digit with a character suffix. *) set_default_transition(transitionStateDecimalSuffix, transition_action_integer, transitionStateEnd); - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassAlpha) + 1].Action := NIL; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassAlpha) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassAlpha) + 1].action := NIL; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassAlpha) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassDigit) + 1].Action := NIL; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassDigit) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassDigit) + 1].action := NIL; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassDigit) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassHex) + 1].Action := NIL; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassHex) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassHex) + 1].action := NIL; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassHex) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassZero) + 1].Action := NIL; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassZero) + 1].NextState := transitionStateEnd; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassZero) + 1].action := NIL; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassZero) + 1].next_state := transitionStateEnd; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassX) + 1].Action := NIL; - transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassX) + 1].NextState := transitionStateEnd + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassX) + 1].action := NIL; + transitions[ORD(transitionStateDecimalSuffix) + 1][ORD(transitionClassX) + 1].next_state := transitionStateEnd END initialize_transitions; -PROCEDURE lexer_initialize(lexer: PLexer; Input: File); +PROCEDURE lexer_initialize(lexer: PLexer; input: File); BEGIN - lexer^.Input := Input; - lexer^.Length := 0; + lexer^.input := input; + lexer^.length := 0; - ALLOCATE(lexer^.Buffer, CHUNK_SIZE); - MemZero(lexer^.Buffer, CHUNK_SIZE); - lexer^.Size := CHUNK_SIZE + ALLOCATE(lexer^.buffer, CHUNK_SIZE); + MemZero(lexer^.buffer, CHUNK_SIZE); + lexer^.size := CHUNK_SIZE END lexer_initialize; PROCEDURE lexer_current(lexer: PLexer): LexerToken; VAR - CurrentClass: TransitionClass; - CurrentState: TransitionState; - CurrentTransition: Transition; + current_class: TransitionClass; + current_state: TransitionState; + current_transition: Transition; result: LexerToken; + index1: CARDINAL; + index2: CARDINAL; BEGIN - lexer^.Current := lexer^.Start; - CurrentState := transitionStateStart; + lexer^.current := lexer^.start; + current_state := transitionStateStart; - WHILE CurrentState <> transitionStateEnd DO - CurrentClass := classification[ORD(lexer^.Current^) + 1]; + WHILE current_state <> transitionStateEnd DO + index1 := ORD(lexer^.current^); + INC(index1); + current_class := classification[index1]; - CurrentTransition := transitions[ORD(CurrentState) + 1][ORD(CurrentClass) + 1]; - IF CurrentTransition.Action <> NIL THEN - CurrentTransition.Action(lexer, ADR(result)) + index1 := ORD(current_state); + INC(index1); + index2 := ORD(current_class); + INC(index2); + + current_transition := transitions[index1][index2]; + IF current_transition.action <> NIL THEN + current_transition.action(lexer, ADR(result)) END; - CurrentState := CurrentTransition.NextState + current_state := current_transition.next_state END; RETURN result END lexer_current; @@ -798,18 +825,18 @@ PROCEDURE lexer_lex(lexer: PLexer): LexerToken; VAR result: LexerToken; BEGIN - IF lexer^.Length = 0 THEN - lexer^.Length := ReadNBytes(lexer^.Input, CHUNK_SIZE, lexer^.Buffer); - lexer^.Current := lexer^.Buffer + IF lexer^.length = 0 THEN + lexer^.length := ReadNBytes(lexer^.input, CHUNK_SIZE, lexer^.buffer); + lexer^.current := lexer^.buffer END; - lexer^.Start := lexer^.Current; + lexer^.start := lexer^.current; result := lexer_current(lexer); RETURN result END lexer_lex; PROCEDURE lexer_destroy(lexer: PLexer); BEGIN - DEALLOCATE(lexer^.Buffer, lexer^.Size) + DEALLOCATE(lexer^.buffer, lexer^.size) END lexer_destroy; BEGIN initialize_classification(); diff --git a/source/Parser.def b/source/Parser.def index 65e58cd..a763bcb 100644 --- a/source/Parser.def +++ b/source/Parser.def @@ -7,21 +7,42 @@ TYPE AstLiteralKind = ( astLiteralKindInteger, astLiteralKindString, - astLiteralKindNull + astLiteralKindNull, + astLiteralKindBoolean ); AstLiteral = RECORD CASE kind: AstLiteralKind OF astLiteralKindInteger: integer: INTEGER | astLiteralKindString: string: ShortString | - astLiteralKindNull: + astLiteralKindNull: | + astLiteralKindBoolean: boolean: BOOLEAN END END; PAstLiteral = POINTER TO AstLiteral; AstUnaryOperator = ( + astUnaryOperatorReference, astUnaryOperatorNot, astUnaryOperatorMinus ); + AstBinaryOperator = ( + astBinaryOperatorSum, + astBinaryOperatorSubtraction, + astBinaryOperatorMultiplication, + astBinaryOperatorDivision, + astBinaryOperatorRemainder, + astBinaryOperatorEquals, + astBinaryOperatorNotEquals, + astBinaryOperatorLess, + astBinaryOperatorGreater, + astBinaryOperatorLessEqual, + astBinaryOperatorGreaterEqual, + astBinaryOperatorDisjunction, + astBinaryOperatorConjunction, + astBinaryOperatorExclusiveDisjunction, + astBinaryOperatorShiftLeft, + astBinaryOperatorShiftRight + ); AstExpressionKind = ( astExpressionKindLiteral, @@ -29,7 +50,9 @@ TYPE astExpressionKindArrayAccess, astExpressionKindDereference, astExpressionKindFieldAccess, - astExpressionKindUnary + astExpressionKindUnary, + astExpressionKindBinary, + astExpressionKindCall ); AstExpression = RECORD CASE kind: AstExpressionKind OF @@ -44,7 +67,15 @@ TYPE field: Identifier | astExpressionKindUnary: unary_operator: AstUnaryOperator; - unary_operand: PAstExpression + unary_operand: PAstExpression | + astExpressionKindBinary: + binary_operator: AstBinaryOperator; + lhs: PAstExpression; + rhs: PAstExpression | + astExpressionKindCall: + callable: PAstExpression; + argument_count: CARDINAL; + arguments: PPAstExpression END END; PAstExpression = POINTER TO AstExpression; @@ -121,5 +152,6 @@ PROCEDURE parse_variable_part(lexer: PLexer): PPAstVariableDeclaration; PROCEDURE parse_constant_part(lexer: PLexer): PPAstConstantDeclaration; PROCEDURE parse_import_part(lexer: PLexer): PPAstImportStatement; PROCEDURE parse_designator(lexer: PLexer): PAstExpression; +PROCEDURE parse_expression(lexer: PLexer): PAstExpression; END Parser. diff --git a/source/Parser.mod b/source/Parser.mod index 22c5f3b..dc051dc 100644 --- a/source/Parser.mod +++ b/source/Parser.mod @@ -5,7 +5,7 @@ FROM SYSTEM IMPORT TSIZE; FROM MemUtils IMPORT MemZero; FROM Storage IMPORT ALLOCATE, REALLOCATE; -FROM Lexer IMPORT LexerKind, LexerToken, lexer_current, lexer_lex; +FROM Lexer IMPORT Lexer, LexerKind, LexerToken, lexer_current, lexer_lex; (* Calls lexer_lex() but skips the comments. *) PROCEDURE transpiler_lex(lexer: PLexer): LexerToken; @@ -174,7 +174,9 @@ BEGIN WHILE token.kind <> lexerKindRightParen DO INC(parameter_count); - REALLOCATE(result^.parameters, TSIZE(PAstTypeExpression) * (parameter_count + 1)); + INC(parameter_count); + REALLOCATE(result^.parameters, TSIZE(PAstTypeExpression) * parameter_count); + DEC(parameter_count); current_parameter := result^.parameters; INC(current_parameter, TSIZE(PAstTypeExpression) * (parameter_count - 1)); @@ -459,7 +461,7 @@ BEGIN literal^.kind := astLiteralKindInteger; literal^.integer := token.integerKind; END; - IF token.kind = lexerKindCharacter THEN + IF (token.kind = lexerKindCharacter) OR (token.kind = lexerKindString) THEN NEW(literal); literal^.kind := astLiteralKindString; @@ -470,6 +472,12 @@ BEGIN literal^.kind := astLiteralKindNull; END; + IF token.kind = lexerKindBoolean THEN + NEW(literal); + + literal^.kind := astLiteralKindBoolean; + literal^.boolean := token.booleanKind + END; IF literal <> NIL THEN token := transpiler_lex(lexer) END; @@ -509,6 +517,13 @@ BEGIN result^.unary_operator := astUnaryOperatorNot; result^.unary_operand := parse_factor(lexer) END; + IF (result = NIL) AND (next_token.kind = lexerKindLeftParen) THEN + next_token := transpiler_lex(lexer); + result := parse_expression(lexer); + IF result <> NIL THEN + next_token := transpiler_lex(lexer) + END + END; IF (result = NIL) AND (next_token.kind = lexerKindIdentifier) THEN NEW(result); @@ -525,6 +540,7 @@ VAR next_token: LexerToken; inner_expression: PAstExpression; designator: PAstExpression; + arguments: PPAstExpression; handled: BOOLEAN; BEGIN designator := parse_factor(lexer); @@ -563,6 +579,38 @@ BEGIN designator^.aggregate := inner_expression; designator^.field := next_token.identifierKind; + next_token := transpiler_lex(lexer); + handled := TRUE + END; + IF ~handled AND (next_token.kind = lexerKindLeftParen) THEN + NEW(designator); + next_token := transpiler_lex(lexer); + + designator^.kind := astExpressionKindCall; + designator^.callable := inner_expression; + designator^.argument_count := 0; + designator^.arguments := NIL; + + IF next_token.kind <> lexerKindRightParen THEN + ALLOCATE(designator^.arguments, TSIZE(PAstExpression)); + designator^.argument_count := 1; + designator^.arguments^ := parse_designator(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_designator(lexer); + + next_token := lexer_current(lexer) + END + END; + next_token := transpiler_lex(lexer); handled := TRUE END @@ -570,4 +618,75 @@ BEGIN RETURN designator END parse_designator; +PROCEDURE parse_binary_expression(lexer: PLexer; left: PAstExpression; operator: AstBinaryOperator): PAstExpression; +VAR + next_token: LexerToken; + result: PAstExpression; + right: PAstExpression; +BEGIN + next_token := transpiler_lex(lexer); + right := parse_designator(lexer); + result := NIL; + + IF right <> NIL THEN + NEW(result); + result^.kind := astExpressionKindBinary; + result^.binary_operator := operator; + result^.lhs := left; + result^.rhs := right; + END; + + RETURN result +END parse_binary_expression; +PROCEDURE parse_expression(lexer: PLexer): PAstExpression; +VAR + next_token: LexerToken; + left: PAstExpression; + result: PAstExpression; + saved: Lexer; +BEGIN + left := parse_designator(lexer); + saved := 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 + END; + IF (result = NIL) AND (left <> NIL) THEN + result := left; + lexer^ := saved + END; + + RETURN result +END parse_expression; END Parser. diff --git a/source/Transpiler.mod b/source/Transpiler.mod index f81fdc0..d78359d 100644 --- a/source/Transpiler.mod +++ b/source/Transpiler.mod @@ -9,14 +9,14 @@ FROM MemUtils IMPORT MemCopy, MemZero; FROM Common IMPORT Identifier, PIdentifier, ShortString; FROM Lexer IMPORT Lexer, LexerToken, lexer_current, lexer_lex, LexerKind; -FROM Parser IMPORT AstTypeExpressionKind, AstExpressionKind, AstLiteralKind, AstUnaryOperator, - AstModule, PAstModule, AstExpression, PAstExpression, PAstLiteral, +FROM Parser IMPORT AstTypeExpressionKind, AstExpressionKind, AstLiteralKind, AstUnaryOperator, AstBinaryOperator, + AstModule, PAstModule, AstExpression, PPAstExpression, PAstExpression, PAstLiteral, PAstConstantDeclaration, PPAstConstantDeclaration, AstTypeDeclaration, PAstTypeDeclaration, PPAstTypeDeclaration, PAstVariableDeclaration, PPAstVariableDeclaration, PAstImportStatement, PPAstImportStatement, PAstTypeExpression, PPAstTypeExpression, AstFieldDeclaration, PAstFieldDeclaration, parse_type_expression, parse_variable_part, parse_type_part, parse_constant_part, parse_import_part, - parse_designator; + parse_designator, parse_expression; (* Calls lexer_lex() but skips the comments. *) PROCEDURE transpiler_lex(lexer: PLexer): LexerToken; @@ -40,8 +40,12 @@ END write_semicolon; PROCEDURE write_current(lexer: PLexer; output: File); VAR written_bytes: CARDINAL; + count: CARDINAL; BEGIN - written_bytes := WriteNBytes(output, ADDRESS(lexer^.Current - lexer^.Start), lexer^.Start) + count := lexer^.current; + DEC(count, lexer^.start); + + written_bytes := WriteNBytes(output, count, lexer^.start) END write_current; PROCEDURE transpile_import_statement(context: PTranspilerContext; import_statement: PAstImportStatement); VAR @@ -385,59 +389,6 @@ BEGIN RETURN result END transpile_procedure_heading; -PROCEDURE transpile_unchanged(context: PTranspilerContext; trailing_token: LexerKind); -VAR - token: LexerToken; - written_bytes: CARDINAL; -BEGIN - token := lexer_current(context^.lexer); - - WHILE (token.kind <> trailing_token) AND (token.kind <> lexerKindEnd) DO - written_bytes := 0; - IF token.kind = lexerKindNull THEN - WriteString(context^.output, 'NIL '); - written_bytes := 1 - END; - IF (token.kind = lexerKindBoolean) AND token.booleanKind THEN - WriteString(context^.output, 'TRUE '); - written_bytes := 1 - END; - IF (token.kind = lexerKindBoolean) AND (~token.booleanKind) THEN - WriteString(context^.output, 'FALSE '); - written_bytes := 1 - END; - IF token.kind = lexerKindOr THEN - WriteString(context^.output, 'OR '); - written_bytes := 1 - END; - IF token.kind = lexerKindAnd THEN - WriteString(context^.output, 'AND '); - written_bytes := 1 - END; - IF token.kind = lexerKindTilde THEN - WriteString(context^.output, 'NOT '); - written_bytes := 1 - END; - IF written_bytes = 0 THEN - write_current(context^.lexer, context^.output); - WriteChar(context^.output, ' ') - END; - token := transpiler_lex(context^.lexer) - END -END transpile_unchanged; -PROCEDURE parse_expression(lexer: PLexer): PAstExpression; -VAR - next_token: LexerToken; - result: PAstExpression; - written_bytes: CARDINAL; -BEGIN - result := parse_designator(lexer); - - written_bytes := WriteNBytes(StdErr, ADDRESS(lexer^.Current - lexer^.Start), lexer^.Start); - WriteLine(StdErr); - - RETURN result -END parse_expression; PROCEDURE transpile_unary_operator(context: PTranspilerContext; operator: AstUnaryOperator); BEGIN IF operator = astUnaryOperatorMinus THEN @@ -447,11 +398,49 @@ BEGIN WriteChar(context^.output, '~') END END transpile_unary_operator; +PROCEDURE transpile_binary_operator(context: PTranspilerContext; operator: AstBinaryOperator); +BEGIN + IF operator = astBinaryOperatorSum THEN + WriteChar(context^.output, '+') + END; + IF operator = astBinaryOperatorSubtraction THEN + WriteChar(context^.output, '-') + END; + IF operator = astBinaryOperatorMultiplication THEN + WriteChar(context^.output, '*') + END; + IF operator = astBinaryOperatorEquals THEN + WriteChar(context^.output, '=') + END; + IF operator = astBinaryOperatorNotEquals THEN + WriteChar(context^.output, '#') + END; + IF operator = astBinaryOperatorLess THEN + WriteChar(context^.output, '<') + END; + IF operator = astBinaryOperatorGreater THEN + WriteChar(context^.output, '>') + END; + IF operator = astBinaryOperatorLessEqual THEN + WriteString(context^.output, '<=') + END; + IF operator = astBinaryOperatorGreaterEqual THEN + WriteString(context^.output, '>=') + END; + IF operator = astBinaryOperatorDisjunction THEN + WriteString(context^.output, 'OR') + END; + IF operator = astBinaryOperatorConjunction THEN + WriteString(context^.output, 'AND') + END +END transpile_binary_operator; PROCEDURE transpile_expression(context: PTranspilerContext; expression: PAstExpression); VAR literal: PAstLiteral; buffer: ARRAY[1..20] OF CHAR; written_bytes: CARDINAL; + argument_index: CARDINAL; + current_argument: PPAstExpression; BEGIN IF expression^.kind = astExpressionKindLiteral THEN literal := expression^.literal; @@ -462,7 +451,16 @@ BEGIN END; IF literal^.kind = astLiteralKindString THEN WriteString(context^.output, literal^.string) - END + END; + IF literal^.kind = astLiteralKindNull THEN + WriteString(context^.output, 'NIL') + END; + IF (literal^.kind = astLiteralKindBoolean) AND literal^.boolean THEN + WriteString(context^.output, 'TRUE') + END; + IF (literal^.kind = astLiteralKindBoolean) AND (literal^.boolean = FALSE) THEN + WriteString(context^.output, 'FALSE') + END END; IF expression^.kind = astExpressionKindIdentifier THEN written_bytes := WriteNBytes(context^.output, ORD(expression^.identifier[1]), ADR(expression^.identifier[2])) @@ -485,31 +483,53 @@ BEGIN IF expression^.kind = astExpressionKindUnary THEN transpile_unary_operator(context, expression^.unary_operator); transpile_expression(context, expression^.unary_operand) + END; + IF expression^.kind = astExpressionKindBinary THEN + WriteChar(context^.output, '('); + transpile_expression(context, expression^.lhs); + WriteChar(context^.output, ' '); + transpile_binary_operator(context, expression^.binary_operator); + WriteChar(context^.output, ' '); + transpile_expression(context, expression^.rhs); + WriteChar(context^.output, ')') + END; + IF expression^.kind = astExpressionKindCall THEN + transpile_expression(context, expression^.callable); + WriteChar(context^.output, '('); + + current_argument := expression^.arguments; + IF expression^.argument_count > 0 THEN + transpile_expression(context, current_argument^); + + argument_index := 1; + INC(current_argument, TSIZE(PAstExpression)); + + WHILE argument_index < expression^.argument_count DO + WriteString(context^.output, ', '); + + transpile_expression(context, current_argument^); + + INC(current_argument, TSIZE(PAstExpression)); + INC(argument_index) + END + END; + WriteChar(context^.output, ')') END END transpile_expression; PROCEDURE transpile_if_statement(context: PTranspilerContext); VAR token: LexerToken; - expression: PAstExpression; - lexer: Lexer; + condition: PAstExpression; BEGIN WriteString(context^.output, ' IF '); - lexer := context^.lexer^; - token := transpiler_lex(ADR(lexer)); - expression := parse_expression(ADR(lexer)); + token := transpiler_lex(context^.lexer); + condition := parse_expression(context^.lexer); - IF expression <> NIL THEN - context^.lexer^ := lexer; - transpile_expression(context, expression); - WriteChar(context^.output, ' ') - END; - IF expression = NIL THEN - token := transpiler_lex(context^.lexer) - END; - transpile_unchanged(context, lexerKindThen); + transpile_expression(context, condition); + token := lexer_current(context^.lexer); - WriteString(context^.output, 'THEN'); + WriteString(context^.output, ' THEN'); WriteLine(context^.output); transpile_statements(context); WriteString(context^.output, ' END'); @@ -518,12 +538,17 @@ END transpile_if_statement; PROCEDURE transpile_while_statement(context: PTranspilerContext); VAR token: LexerToken; + condition: PAstExpression; BEGIN WriteString(context^.output, ' WHILE '); - token := transpiler_lex(context^.lexer); - transpile_unchanged(context, lexerKindDo); - WriteString(context^.output, 'DO'); + token := transpiler_lex(context^.lexer); + condition := parse_expression(context^.lexer); + + transpile_expression(context, condition); + token := lexer_current(context^.lexer); + + WriteString(context^.output, ' DO'); WriteLine(context^.output); transpile_statements(context); WriteString(context^.output, ' END'); @@ -532,10 +557,14 @@ END transpile_while_statement; PROCEDURE transpile_assignment_statement(context: PTranspilerContext); VAR token: LexerToken; + assignment: PAstExpression; BEGIN WriteString(context^.output, ' := '); + token := transpiler_lex(context^.lexer); - transpile_unchanged(context, lexerKindSemicolon); + assignment := parse_expression(context^.lexer); + + transpile_expression(context, assignment) END transpile_assignment_statement; PROCEDURE transpile_call_statement(context: PTranspilerContext); VAR @@ -595,14 +624,17 @@ END transpile_designator_expression; PROCEDURE transpile_return_statement(context: PTranspilerContext); VAR token: LexerToken; + return_expression: PAstExpression; BEGIN WriteString(context^.output, ' RETURN '); token := transpiler_lex(context^.lexer); - transpile_unchanged(context, lexerKindSemicolon) + return_expression := parse_expression(context^.lexer); + transpile_expression(context, return_expression) END transpile_return_statement; PROCEDURE transpile_statement(context: PTranspilerContext); VAR token: LexerToken; + written_bytes: CARDINAL; BEGIN token := transpiler_lex(context^.lexer); @@ -620,7 +652,13 @@ BEGIN token := lexer_current(context^.lexer); IF token.kind = lexerKindAssignment THEN - transpile_assignment_statement(context) + transpile_assignment_statement(context); + token := lexer_current(context^.lexer); + + IF (token.kind <> lexerKindSemicolon) AND (token.kind <> lexerKindEnd) THEN + written_bytes := WriteNBytes(StdErr, 10, context^.lexer^.start); + WriteLine(StdErr) + END END; IF token.kind = lexerKindLeftParen THEN transpile_call_statement(context)