From c87c0501af14213d76fe816771a0db4e72fb7c0e Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 29 May 2025 14:59:22 +0200 Subject: [PATCH] Make procedure name after the end --- source/Lexer.def | 3 +- source/Lexer.elna | 22 +++---------- source/Transpiler.elna | 73 +++++++++++++++++------------------------- 3 files changed, 36 insertions(+), 62 deletions(-) diff --git a/source/Lexer.def b/source/Lexer.def index a6ba01f..b6648f5 100644 --- a/source/Lexer.def +++ b/source/Lexer.def @@ -80,7 +80,8 @@ TYPE ); LexerToken = RECORD CASE Kind: LexerKind OF - lexerKindBoolean: booleanKind: BOOLEAN + lexerKindBoolean: booleanKind: BOOLEAN | + lexerKindIdentifier: identifierKind: ARRAY[1..256] OF CHAR END END; PLexerToken = POINTER TO LexerToken; diff --git a/source/Lexer.elna b/source/Lexer.elna index 5cfae9d..42b79cf 100644 --- a/source/Lexer.elna +++ b/source/Lexer.elna @@ -5,7 +5,7 @@ FROM SYSTEM IMPORT ADR; FROM Storage IMPORT DEALLOCATE, ALLOCATE; FROM Strings IMPORT Length; -FROM MemUtils IMPORT MemZero; +FROM MemUtils IMPORT MemCopy, MemZero; FROM StrCase IMPORT Lower; CONST @@ -201,7 +201,6 @@ BEGIN Classification[127] := transitionClassSingle; (* ~ *) Classification[128] := transitionClassInvalid (* DEL *) END InitializeClassification; - PROCEDURE CompareKeyword(Keyword: ARRAY OF CHAR; TokenStart: PLexerBuffer; TokenEnd: PLexerBuffer): BOOLEAN; VAR Result: BOOLEAN; @@ -218,19 +217,16 @@ BEGIN Result := (Index = Length(Keyword)) AND (TokenStart = TokenEnd) AND Result; RETURN Result END CompareKeyword; - (* Reached the end of file. *) PROCEDURE TransitionActionEof(ALexer: PLexer; AToken: PLexerToken); BEGIN AToken^.Kind := lexerKindEof END TransitionActionEof; - (* Add the character to the token currently read and advance to the next character. *) PROCEDURE TransitionActionAccumulate(ALexer: PLexer; AToken: PLexerToken); BEGIN INC(ALexer^.Current) END TransitionActionAccumulate; - (* The current character is not a part of the token. Finish the token already * read. Don't advance to the next character. *) PROCEDURE TransitionActionFinalize(ALexer: PLexer; AToken: PLexerToken); @@ -254,7 +250,6 @@ BEGIN AToken^.Kind := lexerKindDot END END TransitionActionFinalize; - (* An action for tokens containing multiple characters. *) PROCEDURE TransitionActionComposite(ALexer: PLexer; AToken: PLexerToken); BEGIN @@ -277,14 +272,12 @@ BEGIN END; INC(ALexer^.Current) END TransitionActionComposite; - (* Skip a space. *) PROCEDURE TransitionActionSkip(ALexer: PLexer; AToken: PLexerToken); BEGIN INC(ALexer^.Current); INC(ALexer^.Start) END TransitionActionSkip; - (* Delimited string action. *) PROCEDURE TransitionActionDelimited(ALexer: PLexer; AToken: PLexerToken); BEGIN @@ -299,12 +292,14 @@ BEGIN END; INC(ALexer^.Current) END TransitionActionDelimited; - (* Finalize keyword or identifier. *) PROCEDURE TransitionActionKeyId(ALexer: PLexer; AToken: PLexerToken); BEGIN AToken^.Kind := lexerKindIdentifier; + AToken^.identifierKind[1] := ALexer^.Current - ALexer^.Start; + MemCopy(ALexer^.Start, ORD(AToken^.identifierKind[1]), ADR(AToken^.identifierKind[2])); + IF CompareKeyword('PROGRAM', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindProgram END; @@ -401,7 +396,6 @@ BEGIN AToken^.booleanKind := FALSE 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); @@ -450,13 +444,11 @@ BEGIN END; INC(ALexer^.Current) END TransitionActionSingle; - (* Handle an integer literal. *) PROCEDURE TransitionActionInteger(ALexer: PLexer; AToken: PLexerToken); BEGIN AToken^.Kind := lexerKindInteger END TransitionActionInteger; - PROCEDURE SetDefaultTransition(CurrentState: TransitionState; DefaultAction: TransitionAction; NextState: TransitionState); VAR DefaultTransition: Transition; @@ -487,7 +479,6 @@ BEGIN Transitions[ORD(CurrentState)][ORD(transitionClassLess)] := DefaultTransition; Transitions[ORD(CurrentState)][ORD(transitionClassOther)] := DefaultTransition END SetDefaultTransition; - (* * The transition table describes transitions from one state to another, given * a symbol (character class). @@ -741,7 +732,6 @@ BEGIN Transitions[ORD(transitionStateDecimalSuffix)][ORD(transitionClassX)].Action := NIL; Transitions[ORD(transitionStateDecimalSuffix)][ORD(transitionClassX)].NextState := transitionStateEnd END InitializeTransitions; - PROCEDURE LexerInitialize(ALexer: PLexer; Input: File); BEGIN ALexer^.Input := Input; @@ -751,7 +741,6 @@ BEGIN MemZero(ALexer^.Buffer, ChunkSize); ALexer^.Size := ChunkSize END LexerInitialize; - PROCEDURE LexerCurrent(ALexer: PLexer): LexerToken; VAR CurrentClass: TransitionClass; @@ -773,7 +762,6 @@ BEGIN END; RETURN Result END LexerCurrent; - PROCEDURE LexerLex(ALexer: PLexer): LexerToken; VAR Result: LexerToken; @@ -787,12 +775,10 @@ BEGIN Result := LexerCurrent(ALexer); RETURN Result END LexerLex; - PROCEDURE LexerDestroy(ALexer: PLexer); BEGIN DEALLOCATE(ALexer^.Buffer, ALexer^.Size) END LexerDestroy; - BEGIN InitializeClassification(); InitializeTransitions() diff --git a/source/Transpiler.elna b/source/Transpiler.elna index 1f50d43..b0edbc3 100644 --- a/source/Transpiler.elna +++ b/source/Transpiler.elna @@ -25,14 +25,12 @@ BEGIN RETURN Result END TranspilerLex; - (* Write a semicolon followed by a newline. *) PROCEDURE WriteSemicolon(); BEGIN WriteString(';'); WriteLn() END WriteSemicolon; - PROCEDURE TranspileImport(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -59,7 +57,6 @@ BEGIN WriteSemicolon(); Token := TranspilerLex(ALexer) END TranspileImport; - PROCEDURE TranspileImportPart(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -72,7 +69,6 @@ BEGIN END; WriteLn() END TranspileImportPart; - PROCEDURE TranspileConstant(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -91,7 +87,6 @@ BEGIN Token := TranspilerLex(ALexer); WriteSemicolon() END TranspileConstant; - PROCEDURE TranspileConstantPart(AContext: PTranspilerContext; ALexer: PLexer): BOOLEAN; VAR Token: LexerToken; @@ -112,7 +107,6 @@ BEGIN END; RETURN Result END TranspileConstantPart; - PROCEDURE TranspileModule(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -149,16 +143,19 @@ BEGIN WriteLn() END; TranspileProcedurePart(AContext, ALexer); + TranspileStatementPart(AContext, ALexer); - Token := LexerCurrent(ALexer); - WHILE Token.Kind <> lexerKindEof DO - WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); - WriteLn(); + WriteString('END '); - Token := TranspilerLex(ALexer) - END + Token := TranspilerLex(ALexer); + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + + Token := TranspilerLex(ALexer); + Write('.'); + + Token := TranspilerLex(ALexer); + WriteLn() END TranspileModule; - PROCEDURE TranspileTypeFields(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -181,7 +178,6 @@ BEGIN WriteLn() END END TranspileTypeFields; - PROCEDURE TranspileRecordType(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -191,7 +187,6 @@ BEGIN TranspileTypeFields(AContext, ALexer); WriteString(' END') END TranspileRecordType; - PROCEDURE TranspilePointerType(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -204,7 +199,6 @@ BEGIN END; TranspileTypeExpression(AContext, ALexer) END TranspilePointerType; - PROCEDURE TranspileArrayType(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -228,7 +222,6 @@ BEGIN WriteString(' OF '); TranspileTypeExpression(AContext, ALexer) END TranspileArrayType; - PROCEDURE TranspileEnumerationType(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -255,12 +248,10 @@ BEGIN WriteLn(); WriteString(' )') END TranspileEnumerationType; - PROCEDURE TranspileUnionType(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; END TranspileUnionType; - PROCEDURE TranspileProcedureType(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -282,7 +273,6 @@ BEGIN END; Write(')') END TranspileProcedureType; - PROCEDURE TranspileTypeExpression(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -308,7 +298,6 @@ BEGIN WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start) END END TranspileTypeExpression; - PROCEDURE TranspileTypeDeclaration(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -324,7 +313,6 @@ BEGIN Token := TranspilerLex(ALexer); WriteSemicolon(); END TranspileTypeDeclaration; - PROCEDURE TranspileTypePart(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -343,7 +331,6 @@ BEGIN WriteLn() END END TranspileTypePart; - PROCEDURE TranspileVariableDeclaration(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -359,7 +346,6 @@ BEGIN Token := TranspilerLex(ALexer); WriteSemicolon() END TranspileVariableDeclaration; - PROCEDURE TranspileVariablePart(AContext: PTranspilerContext; ALexer: PLexer): BOOLEAN; VAR Token: LexerToken; @@ -380,15 +366,15 @@ BEGIN END; RETURN Result END TranspileVariablePart; - -PROCEDURE TranspileProcedureHeading(AContext: PTranspilerContext; ALexer: PLexer); +PROCEDURE TranspileProcedureHeading(AContext: PTranspilerContext; ALexer: PLexer): LexerToken; VAR Token: LexerToken; + Result: LexerToken; WrittenBytes: CARDINAL; BEGIN WriteString('PROCEDURE '); - Token := TranspilerLex(ALexer); + Result := TranspilerLex(ALexer); WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); Token := TranspilerLex(ALexer); @@ -420,9 +406,10 @@ BEGIN Token := TranspilerLex(ALexer) END; Token := TranspilerLex(ALexer); - WriteSemicolon() -END TranspileProcedureHeading; + WriteSemicolon(); + RETURN Result +END TranspileProcedureHeading; PROCEDURE TranspileIfStatement(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -442,7 +429,6 @@ BEGIN WriteString(' END'); Token := TranspilerLex(ALexer) END TranspileIfStatement; - PROCEDURE TranspileWhileStatement(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -462,7 +448,6 @@ BEGIN WriteString(' END'); Token := TranspilerLex(ALexer) END TranspileWhileStatement; - PROCEDURE TranspileAssignmentStatement(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -477,7 +462,6 @@ BEGIN Token := TranspilerLex(ALexer) END END TranspileAssignmentStatement; - PROCEDURE TranspileCallStatement(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -491,7 +475,6 @@ BEGIN Token := TranspilerLex(ALexer) END END TranspileCallStatement; - PROCEDURE TranspileReturnStatement(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -502,7 +485,6 @@ BEGIN WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); Token := TranspilerLex(ALexer) END TranspileReturnStatement; - PROCEDURE TranspileStatement(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -548,6 +530,16 @@ BEGIN Write('^'); Token := TranspilerLex(ALexer) END; + 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 = lexerKindAssignment THEN TranspileAssignmentStatement(AContext, ALexer) @@ -557,7 +549,6 @@ BEGIN END END END TranspileStatement; - PROCEDURE TranspileStatements(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -574,7 +565,6 @@ BEGIN WriteLn() END END TranspileStatements; - PROCEDURE TranspileStatementPart(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -586,25 +576,24 @@ BEGIN TranspileStatements(AContext, ALexer) END END TranspileStatementPart; - PROCEDURE TranspileProcedureDeclaration(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; SeenPart: BOOLEAN; WrittenBytes: CARDINAL; BEGIN - TranspileProcedureHeading(AContext, ALexer); + Token := 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); + WrittenBytes := WriteNBytes(StdOut, ORD(Token.identifierKind[1]), ADR(Token.identifierKind[2])); + Token := TranspilerLex(ALexer); WriteSemicolon(); Token := TranspilerLex(ALexer) END TranspileProcedureDeclaration; - PROCEDURE TranspileProcedurePart(AContext: PTranspilerContext; ALexer: PLexer); VAR Token: LexerToken; @@ -617,7 +606,6 @@ BEGIN WriteLn() END END TranspileProcedurePart; - PROCEDURE Transpile(ALexer: PLexer); VAR Token: LexerToken; @@ -626,5 +614,4 @@ VAR BEGIN TranspileModule(ADR(Context), ALexer) END Transpile; - END Transpiler.