diff --git a/source/Lexer.elna b/source/Lexer.elna index 582c6b1..5cfae9d 100644 --- a/source/Lexer.elna +++ b/source/Lexer.elna @@ -215,7 +215,8 @@ BEGIN INC(TokenStart); INC(Index) END; - RETURN (Index = Length(Keyword)) AND (TokenStart = TokenEnd) AND Result + Result := (Index = Length(Keyword)) AND (TokenStart = TokenEnd) AND Result; + RETURN Result END CompareKeyword; (* Reached the end of file. *) @@ -236,15 +237,20 @@ PROCEDURE TransitionActionFinalize(ALexer: PLexer; AToken: PLexerToken); BEGIN IF ALexer^.Start^ = ':' THEN AToken^.Kind := lexerKindColon - ELSIF ALexer^.Start^ = '>' THEN + END; + IF ALexer^.Start^ = '>' THEN AToken^.Kind := lexerKindGreaterThan - ELSIF ALexer^.Start^ = '<' THEN + END; + IF ALexer^.Start^ = '<' THEN AToken^.Kind := lexerKindLessThan - ELSIF ALexer^.Start^ = '(' THEN + END; + IF ALexer^.Start^ = '(' THEN AToken^.Kind := lexerKindLeftParen - ELSIF ALexer^.Start^ = '-' THEN + END; + IF ALexer^.Start^ = '-' THEN AToken^.Kind := lexerKindLeftParen - ELSIF ALexer^.Start^ = '.' THEN + END; + IF ALexer^.Start^ = '.' THEN AToken^.Kind := lexerKindDot END END TransitionActionFinalize; @@ -255,14 +261,18 @@ BEGIN IF ALexer^.Start^ = '<' THEN IF ALexer^.Current^ = '>' THEN AToken^.Kind := lexerKindNotEqual - ELSIF ALexer^.Current^ = '=' THEN + END; + IF ALexer^.Current^ = '=' THEN AToken^.Kind := lexerKindLessEqual END - ELSIF (ALexer^.Start^ = '>') AND (ALexer^.Current^ = '=') THEN + END; + IF (ALexer^.Start^ = '>') AND (ALexer^.Current^ = '=') THEN AToken^.Kind := lexerKindGreaterEqual - ELSIF (ALexer^.Start^ = '.') AND (ALexer^.Current^ = '.') THEN + END; + IF (ALexer^.Start^ = '.') AND (ALexer^.Current^ = '.') THEN AToken^.Kind := lexerKindRange - ELSIF (ALexer^.Start^ = ':') AND (ALexer^.Current^ = '=') THEN + END; + IF (ALexer^.Start^ = ':') AND (ALexer^.Current^ = '=') THEN AToken^.Kind := lexerKindAssignment END; INC(ALexer^.Current) @@ -275,14 +285,16 @@ BEGIN INC(ALexer^.Start) END TransitionActionSkip; -(* 0x04. Delimited string action. *) +(* Delimited string action. *) PROCEDURE TransitionActionDelimited(ALexer: PLexer; AToken: PLexerToken); BEGIN IF ALexer^.Start^ = '(' THEN AToken^.Kind := lexerKindComment - ELSIF ALexer^.Start^ = '"' THEN + END; + IF ALexer^.Start^ = '"' THEN AToken^.Kind := lexerKindCharacter - ELSIF ALexer^.Start^ = "'" THEN + END; + IF ALexer^.Start^ = "'" THEN AToken^.Kind := lexerKindString END; INC(ALexer^.Current) @@ -291,93 +303,150 @@ END TransitionActionDelimited; (* Finalize keyword or identifier. *) PROCEDURE TransitionActionKeyId(ALexer: PLexer; AToken: PLexerToken); BEGIN + AToken^.Kind := lexerKindIdentifier; + IF CompareKeyword('PROGRAM', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindProgram - ELSIF CompareKeyword('IMPORT', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('IMPORT', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindImport - ELSIF CompareKeyword('CONST', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('CONST', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindConst - ELSIF CompareKeyword('VAR', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('VAR', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindVar - ELSIF CompareKeyword('IF', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('IF', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindIf - ELSIF CompareKeyword('THEN', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('THEN', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindThen - ELSIF CompareKeyword('ELSIF', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('ELSIF', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindElsif - ELSIF CompareKeyword('ELSE', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('ELSE', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindElse - ELSIF CompareKeyword('WHILE', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('WHILE', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindWhile - ELSIF CompareKeyword('DO', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('DO', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindDo - ELSIF CompareKeyword('PROCEDURE', ALexer^.Start, ALexer^.Current) OR CompareKeyword('proc', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('proc', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindProc - ELSIF CompareKeyword('BEGIN', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('BEGIN', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindBegin - ELSIF CompareKeyword('END', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('END', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindEnd - ELSIF CompareKeyword('TYPE', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('TYPE', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindType - ELSIF CompareKeyword('RECORD', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('RECORD', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindRecord - ELSIF CompareKeyword('UNION', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('UNION', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindUnion - ELSIF CompareKeyword('NIL', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('NIL', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindNull - ELSIF CompareKeyword('AND', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('AND', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindAnd - ELSIF CompareKeyword('OR', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('OR', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindOr - ELSIF CompareKeyword('RETURN', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('RETURN', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindReturn - ELSIF CompareKeyword('DEFINITION', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('DEFINITION', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindDefinition - ELSIF CompareKeyword('TO', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('TO', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindTo - ELSIF CompareKeyword('CASE', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('CASE', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindCase - ELSIF CompareKeyword('OF', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('OF', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindOf - ELSIF CompareKeyword('FROM', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('FROM', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindFrom - ELSIF CompareKeyword('MODULE', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('MODULE', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindModule - ELSIF CompareKeyword('IMPLEMENTATION', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('IMPLEMENTATION', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindImplementation - ELSIF CompareKeyword('POINTER', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('POINTER', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindPointer - ELSIF CompareKeyword('ARRAY', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('ARRAY', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindArray - ELSIF CompareKeyword('TRUE', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('TRUE', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindBoolean; AToken^.booleanKind := TRUE - ELSIF CompareKeyword('FALSE', ALexer^.Start, ALexer^.Current) THEN + END; + IF CompareKeyword('FALSE', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindBoolean; AToken^.booleanKind := FALSE - ELSE - AToken^.Kind := lexerKindIdentifier - END; + END END TransitionActionKeyId; (* Action for tokens containing only one character. The character cannot be * followed by other characters forming a composite token. *) PROCEDURE TransitionActionSingle(ALexer: PLexer; AToken: PLexerToken); BEGIN - CASE ALexer^.Current^ OF - '&': AToken^.Kind := lexerKindAnd | - ';': AToken^.Kind := lexerKindSemicolon | - ',': AToken^.Kind := lexerKindComma | - ')': AToken^.Kind := lexerKindRightParen | - '[': AToken^.Kind := lexerKindLeftSquare | - ']': AToken^.Kind := lexerKindRightSquare | - '^': AToken^.Kind := lexerKindHat | - '=': AToken^.Kind := lexerKindEqual | - '+': AToken^.Kind := lexerKindPlus | - '/': AToken^.Kind := lexerKindDivision | - '%': AToken^.Kind := lexerKindRemainder | - '@': AToken^.Kind := lexerKindAt | - '|': AToken^.Kind := lexerKindPipe + IF ALexer^.Current^ = '&' THEN + AToken^.Kind := lexerKindAnd + END; + IF ALexer^.Current^ = ';' THEN + AToken^.Kind := lexerKindSemicolon + END; + IF ALexer^.Current^ = ',' THEN + AToken^.Kind := lexerKindComma + END; + IF ALexer^.Current^ = ',' THEN + AToken^.Kind := lexerKindComma + END; + IF ALexer^.Current^ = ')' THEN + AToken^.Kind := lexerKindRightParen + END; + IF ALexer^.Current^ = '[' THEN + AToken^.Kind := lexerKindLeftSquare + END; + IF ALexer^.Current^ = ']' THEN + AToken^.Kind := lexerKindRightSquare + END; + IF ALexer^.Current^ = '^' THEN + AToken^.Kind := lexerKindHat + END; + IF ALexer^.Current^ = '=' THEN + AToken^.Kind := lexerKindEqual + END; + IF ALexer^.Current^ = '+' THEN + AToken^.Kind := lexerKindPlus + END; + IF ALexer^.Current^ = '/' THEN + AToken^.Kind := lexerKindDivision + END; + IF ALexer^.Current^ = '%' THEN + AToken^.Kind := lexerKindRemainder + END; + IF ALexer^.Current^ = '@' THEN + AToken^.Kind := lexerKindAt + END; + IF ALexer^.Current^ = '|' THEN + AToken^.Kind := lexerKindPipe END; INC(ALexer^.Current) END TransitionActionSingle; @@ -389,7 +458,8 @@ BEGIN END TransitionActionInteger; PROCEDURE SetDefaultTransition(CurrentState: TransitionState; DefaultAction: TransitionAction; NextState: TransitionState); -VAR DefaultTransition: Transition; +VAR + DefaultTransition: Transition; BEGIN DefaultTransition.Action := DefaultAction; DefaultTransition.NextState := NextState; @@ -415,7 +485,7 @@ BEGIN Transitions[ORD(CurrentState)][ORD(transitionClassDoubleQuote)] := DefaultTransition; Transitions[ORD(CurrentState)][ORD(transitionClassGreater)] := DefaultTransition; Transitions[ORD(CurrentState)][ORD(transitionClassLess)] := DefaultTransition; - Transitions[ORD(CurrentState)][ORD(transitionClassOther)] := DefaultTransition; + Transitions[ORD(CurrentState)][ORD(transitionClassOther)] := DefaultTransition END SetDefaultTransition; (* @@ -705,6 +775,8 @@ BEGIN END LexerCurrent; PROCEDURE LexerLex(ALexer: PLexer): LexerToken; +VAR + Result: LexerToken; BEGIN IF ALexer^.Length = 0 THEN ALexer^.Length := ReadNBytes(ALexer^.Input, ChunkSize, ALexer^.Buffer); @@ -712,7 +784,8 @@ BEGIN END; ALexer^.Start := ALexer^.Current; - RETURN LexerCurrent(ALexer) + Result := LexerCurrent(ALexer); + RETURN Result END LexerLex; PROCEDURE LexerDestroy(ALexer: PLexer); diff --git a/source/Transpiler.elna b/source/Transpiler.elna index 72262e7..1f50d43 100644 --- a/source/Transpiler.elna +++ b/source/Transpiler.elna @@ -92,13 +92,15 @@ BEGIN WriteSemicolon() END TranspileConstant; -PROCEDURE TranspileConstantPart(AContext: PTranspilerContext; ALexer: PLexer); +PROCEDURE TranspileConstantPart(AContext: PTranspilerContext; ALexer: PLexer): BOOLEAN; VAR Token: LexerToken; + Result: BOOLEAN; BEGIN Token := LexerCurrent(ALexer); + Result := Token.Kind = lexerKindConst; - IF Token.Kind = lexerKindConst THEN + IF Result THEN WriteString('CONST'); WriteLn(); Token := TranspilerLex(ALexer); @@ -106,9 +108,9 @@ BEGIN WHILE Token.Kind = lexerKindIdentifier DO TranspileConstant(AContext, ALexer); Token := TranspilerLex(ALexer) - END; - WriteLn() - END + END + END; + RETURN Result END TranspileConstantPart; PROCEDURE TranspileModule(AContext: PTranspilerContext; ALexer: PLexer); @@ -120,8 +122,9 @@ BEGIN IF Token.Kind = lexerKindDefinition THEN WriteString('DEFINITION '); - Token := TranspilerLex(ALexer); - ELSIF Token.Kind = lexerKindImplementation THEN + Token := TranspilerLex(ALexer) + END; + IF Token.Kind = lexerKindImplementation THEN WriteString('IMPLEMENTATION '); Token := TranspilerLex(ALexer) END; @@ -138,9 +141,13 @@ BEGIN (* Write the module body. *) Token := TranspilerLex(ALexer); TranspileImportPart(AContext, ALexer); - TranspileConstantPart(AContext, ALexer); + IF TranspileConstantPart(AContext, ALexer) THEN + WriteLn() + END; TranspileTypePart(AContext, ALexer); - TranspileVariablePart(AContext, ALexer); + IF TranspileVariablePart(AContext, ALexer) THEN + WriteLn() + END; TranspileProcedurePart(AContext, ALexer); Token := LexerCurrent(ALexer); @@ -169,10 +176,9 @@ BEGIN IF Token.Kind = lexerKindSemicolon THEN Token := TranspilerLex(ALexer); - WriteSemicolon() - ELSE - WriteLn() - END + Write(';') + END; + WriteLn() END END TranspileTypeFields; @@ -285,15 +291,20 @@ BEGIN Token := TranspilerLex(ALexer); IF Token.Kind = lexerKindRecord THEN TranspileRecordType(AContext, ALexer) - ELSIF Token.Kind = lexerKindLeftParen THEN + END; + IF Token.Kind = lexerKindLeftParen THEN TranspileEnumerationType(AContext, ALexer) - ELSIF Token.Kind = lexerKindArray THEN + END; + IF Token.Kind = lexerKindArray THEN TranspileArrayType(AContext, ALexer) - ELSIF (Token.Kind = lexerKindPointer) OR (Token.Kind = lexerKindHat) THEN + END; + IF (Token.Kind = lexerKindPointer) OR (Token.Kind = lexerKindHat) THEN TranspilePointerType(AContext, ALexer) - ELSIF Token.Kind = lexerKindProc THEN + END; + IF Token.Kind = lexerKindProc THEN TranspileProcedureType(AContext, ALexer) - ELSE + END; + IF Token.Kind = lexerKindIdentifier THEN WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start) END END TranspileTypeExpression; @@ -349,13 +360,15 @@ BEGIN WriteSemicolon() END TranspileVariableDeclaration; -PROCEDURE TranspileVariablePart(AContext: PTranspilerContext; ALexer: PLexer); +PROCEDURE TranspileVariablePart(AContext: PTranspilerContext; ALexer: PLexer): BOOLEAN; VAR Token: LexerToken; + Result: BOOLEAN; BEGIN Token := LexerCurrent(ALexer); + Result := Token.Kind = lexerKindVar; - IF Token.Kind = lexerKindVar THEN + IF Result THEN WriteString('VAR'); WriteLn(); Token := TranspilerLex(ALexer); @@ -363,12 +376,12 @@ BEGIN WHILE Token.Kind = lexerKindIdentifier DO TranspileVariableDeclaration(AContext, ALexer); Token := TranspilerLex(ALexer) - END; - WriteLn() - END + END + END; + RETURN Result END TranspileVariablePart; -PROCEDURE TranspileProcedureDeclaration(AContext: PTranspilerContext; ALexer: PLexer); +PROCEDURE TranspileProcedureHeading(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; WrittenBytes: CARDINAL; @@ -388,8 +401,7 @@ BEGIN Token := TranspilerLex(ALexer); WriteString(': '); - Token := TranspilerLex(ALexer); - WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + TranspileTypeExpression(AContext, ALexer); Token := TranspilerLex(ALexer); IF Token.Kind = lexerKindSemicolon THEN @@ -409,6 +421,188 @@ BEGIN END; Token := TranspilerLex(ALexer); WriteSemicolon() +END TranspileProcedureHeading; + +PROCEDURE TranspileIfStatement(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + WriteString(' IF '); + Token := TranspilerLex(ALexer); + + WHILE Token.Kind <> lexerKindThen DO + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + Write(' '); + Token := TranspilerLex(ALexer) + END; + WriteString('THEN'); + WriteLn(); + TranspileStatements(AContext, ALexer); + WriteString(' END'); + Token := TranspilerLex(ALexer) +END TranspileIfStatement; + +PROCEDURE TranspileWhileStatement(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + WriteString(' WHILE '); + Token := TranspilerLex(ALexer); + + WHILE Token.Kind <> lexerKindDo DO + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + Write(' '); + Token := TranspilerLex(ALexer) + END; + WriteString('DO'); + WriteLn(); + TranspileStatements(AContext, ALexer); + WriteString(' END'); + Token := TranspilerLex(ALexer) +END TranspileWhileStatement; + +PROCEDURE TranspileAssignmentStatement(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + WriteString(' := '); + Token := TranspilerLex(ALexer); + + WHILE (Token.Kind <> lexerKindSemicolon) AND (Token.Kind <> lexerKindEnd) DO + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + Write(' '); + Token := TranspilerLex(ALexer) + END +END TranspileAssignmentStatement; + +PROCEDURE TranspileCallStatement(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + WriteString('('); + Token := TranspilerLex(ALexer); + + WHILE (Token.Kind <> lexerKindSemicolon) AND (Token.Kind <> lexerKindEnd) DO + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + Token := TranspilerLex(ALexer) + END +END TranspileCallStatement; + +PROCEDURE TranspileReturnStatement(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + WriteString(' RETURN '); + Token := TranspilerLex(ALexer); + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + Token := TranspilerLex(ALexer) +END TranspileReturnStatement; + +PROCEDURE TranspileStatement(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + Token := TranspilerLex(ALexer); + + IF Token.Kind = lexerKindIf THEN + TranspileIfStatement(AContext, ALexer) + END; + IF Token.Kind = lexerKindWhile THEN + TranspileWhileStatement(AContext, ALexer) + END; + IF Token.Kind = lexerKindReturn THEN + TranspileReturnStatement(AContext, ALexer) + END; + IF Token.Kind = lexerKindIdentifier THEN + WriteString(' '); + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + Token := TranspilerLex(ALexer); + + WHILE Token.Kind = lexerKindLeftSquare DO + Write('['); + Token := TranspilerLex(ALexer); + WHILE Token.Kind <> lexerKindRightSquare DO + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + Token := TranspilerLex(ALexer) + END; + Write(']'); + Token := TranspilerLex(ALexer); + END; + IF Token.Kind = lexerKindHat THEN + Write('^'); + Token := TranspilerLex(ALexer) + END; + IF Token.Kind = lexerKindDot THEN + Write('.'); + Token := TranspilerLex(ALexer); + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + Token := TranspilerLex(ALexer); + END; + IF Token.Kind = lexerKindHat THEN + Write('^'); + Token := TranspilerLex(ALexer) + END; + + IF Token.Kind = lexerKindAssignment THEN + TranspileAssignmentStatement(AContext, ALexer) + END; + IF Token.Kind = lexerKindLeftParen THEN + TranspileCallStatement(AContext, ALexer) + END + END +END TranspileStatement; + +PROCEDURE TranspileStatements(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; +BEGIN + Token := LexerCurrent(ALexer); + + WHILE Token.Kind <> lexerKindEnd DO + TranspileStatement(AContext, ALexer); + Token := LexerCurrent(ALexer); + + IF Token.Kind = lexerKindSemicolon THEN + Write(';') + END; + WriteLn() + END +END TranspileStatements; + +PROCEDURE TranspileStatementPart(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; +BEGIN + Token := LexerCurrent(ALexer); + IF Token.Kind = lexerKindBegin THEN + WriteString('BEGIN'); + WriteLn(); + TranspileStatements(AContext, ALexer) + END +END TranspileStatementPart; + +PROCEDURE TranspileProcedureDeclaration(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + SeenPart: BOOLEAN; + WrittenBytes: CARDINAL; +BEGIN + TranspileProcedureHeading(AContext, ALexer); + SeenPart := TranspileConstantPart(AContext, ALexer); + SeenPart := TranspileVariablePart(AContext, ALexer); + TranspileStatementPart(AContext, ALexer); + WriteString('END '); + Token := TranspilerLex(ALexer); + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + Token := TranspilerLex(ALexer); + WriteSemicolon(); + Token := TranspilerLex(ALexer) END TranspileProcedureDeclaration; PROCEDURE TranspileProcedurePart(AContext: PTranspilerContext; ALexer: PLexer); @@ -417,8 +611,10 @@ VAR BEGIN Token := LexerCurrent(ALexer); - IF Token.Kind = lexerKindProc THEN - TranspileProcedureDeclaration(AContext, ALexer) + WHILE Token.Kind = lexerKindProc DO + TranspileProcedureDeclaration(AContext, ALexer); + Token := LexerCurrent(ALexer); + WriteLn() END END TranspileProcedurePart;