From 731e9c700a3bb53c70efad7658f3d7bc531dc663 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Tue, 27 May 2025 07:52:51 +0200 Subject: [PATCH] Transpile type section --- source/Lexer.def | 4 +- source/Lexer.elna | 8 +- source/Transpiler.elna | 165 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 171 insertions(+), 6 deletions(-) diff --git a/source/Lexer.def b/source/Lexer.def index 23bc7f3..a6ba01f 100644 --- a/source/Lexer.def +++ b/source/Lexer.def @@ -71,8 +71,8 @@ TYPE lexerKindCharacter, lexerKindString, lexerKindFrom, - lexerKindExclamation, - lexerKindArrow, + lexerKindPointer, + lexerKindArray, lexerKindTrait, lexerKindProgram, lexerKindModule, diff --git a/source/Lexer.elna b/source/Lexer.elna index 4f09fc3..4de2760 100644 --- a/source/Lexer.elna +++ b/source/Lexer.elna @@ -6,6 +6,7 @@ FROM SYSTEM IMPORT ADR; FROM Storage IMPORT DEALLOCATE, ALLOCATE; FROM Strings IMPORT Length; FROM MemUtils IMPORT MemZero; +FROM StrCase IMPORT Lower; CONST ChunkSize = 65536; @@ -210,7 +211,7 @@ BEGIN Result := TRUE; WHILE (Index < Length(Keyword)) AND (TokenStart <> TokenEnd) AND Result DO - Result := Keyword[Index] = TokenStart^; + Result := (Keyword[Index] = TokenStart^) OR (Lower(Keyword[Index]) = TokenStart^); INC(TokenStart); INC(Index) END; @@ -344,6 +345,10 @@ BEGIN AToken^.Kind := lexerKindModule ELSIF CompareKeyword('IMPLEMENTATION', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindImplementation + ELSIF CompareKeyword('POINTER', ALexer^.Start, ALexer^.Current) THEN + AToken^.Kind := lexerKindPointer + ELSIF CompareKeyword('ARRAY', ALexer^.Start, ALexer^.Current) THEN + AToken^.Kind := lexerKindArray ELSIF CompareKeyword('TRUE', ALexer^.Start, ALexer^.Current) THEN AToken^.Kind := lexerKindBoolean; AToken^.booleanKind := TRUE @@ -685,7 +690,6 @@ VAR Result: LexerToken; BEGIN ALexer^.Current := ALexer^.Start; - Result.Kind := lexerKindTrait; CurrentState := transitionStateStart; WHILE CurrentState <> transitionStateEnd DO diff --git a/source/Transpiler.elna b/source/Transpiler.elna index 25dfe52..28dd9d1 100644 --- a/source/Transpiler.elna +++ b/source/Transpiler.elna @@ -7,9 +7,10 @@ FROM Terminal IMPORT Write, WriteLn, WriteString; FROM Lexer IMPORT Lexer, LexerToken, LexerCurrent, LexerLex, LexerKind; TYPE - TranspilerContext = RECORD - END; PTranspilerContext = POINTER TO TranspilerContext; + TranspilerContext = RECORD + Indentation: CARDINAL + END; (* Calls LexerLex() but skips the comments. *) PROCEDURE TranspilerLex(ALexer: PLexer): LexerToken; @@ -138,6 +139,7 @@ BEGIN Token := TranspilerLex(ALexer); TranspileImportPart(AContext, ALexer); TranspileConstantPart(AContext, ALexer); + TranspileTypePart(AContext, ALexer); Token := LexerCurrent(ALexer); WHILE Token.Kind <> lexerKindEof DO @@ -148,6 +150,165 @@ BEGIN END END TranspileModule; +PROCEDURE TranspileTypeFields(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + Token := TranspilerLex(ALexer); + + WHILE Token.Kind <> lexerKindEnd DO + WriteString(' '); + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + Token := TranspilerLex(ALexer); + WriteString(': '); + TranspileTypeExpression(AContext, ALexer); + Token := TranspilerLex(ALexer); + + IF Token.Kind = lexerKindSemicolon THEN + Token := TranspilerLex(ALexer); + WriteSemicolon() + ELSE + WriteLn() + END + END +END TranspileTypeFields; + +PROCEDURE TranspileRecordType(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; +BEGIN + WriteString('RECORD'); + WriteLn(); + TranspileTypeFields(AContext, ALexer); + WriteString(' END') +END TranspileRecordType; + +PROCEDURE TranspilePointerType(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + WriteString('POINTER TO '); + Token := TranspilerLex(ALexer); + TranspileTypeExpression(AContext, ALexer) +END TranspilePointerType; + +PROCEDURE TranspileArrayType(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; +BEGIN +END TranspileArrayType; + +PROCEDURE TranspileEnumerationType(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + WriteString('('); + WriteLn(); + WriteString(' '); + + Token := TranspilerLex(ALexer); + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + + Token := TranspilerLex(ALexer); + + WHILE Token.Kind = lexerKindComma DO + Write(','); + WriteLn(); + WriteString(' '); + Token := TranspilerLex(ALexer); + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + + Token := TranspilerLex(ALexer) + END; + WriteLn(); + WriteString(' )') +END TranspileEnumerationType; + +PROCEDURE TranspileUnionType(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; +END TranspileUnionType; + +PROCEDURE TranspileProcedureType(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + Token := TranspilerLex(ALexer); + WriteString('PROCEDURE('); + + Token := TranspilerLex(ALexer); + + WHILE Token.Kind <> lexerKindRightParen DO + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + + Token := TranspilerLex(ALexer); + IF Token.Kind = lexerKindComma THEN + Token := TranspilerLex(ALexer); + WriteString(', ') + END + END; + Write(')') +END TranspileProcedureType; + +PROCEDURE TranspileTypeExpression(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + Token := TranspilerLex(ALexer); + IF Token.Kind = lexerKindRecord THEN + TranspileRecordType(AContext, ALexer) + ELSIF Token.Kind = lexerKindLeftParen THEN + TranspileEnumerationType(AContext, ALexer) + ELSIF Token.Kind = lexerKindArray THEN + TranspileArrayType(AContext, ALexer) + ELSIF Token.Kind = lexerKindPointer THEN + TranspilePointerType(AContext, ALexer) + ELSIF Token.Kind = lexerKindProc THEN + TranspileProcedureType(AContext, ALexer) + ELSE + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start) + END +END TranspileTypeExpression; + +PROCEDURE TranspileTypeDeclaration(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; + WrittenBytes: CARDINAL; +BEGIN + WriteString(' '); + Token := LexerCurrent(ALexer); + WrittenBytes := WriteNBytes(StdOut, ADDRESS(ALexer^.Current - ALexer^.Start), ALexer^.Start); + + Token := TranspilerLex(ALexer); + WriteString(' = '); + TranspileTypeExpression(AContext, ALexer); + Token := TranspilerLex(ALexer); + WriteSemicolon(); +END TranspileTypeDeclaration; + +PROCEDURE TranspileTypePart(AContext: PTranspilerContext; ALexer: PLexer); +VAR + Token: LexerToken; +BEGIN + Token := LexerCurrent(ALexer); + + IF Token.Kind = lexerKindType THEN + WriteString('TYPE'); + WriteLn(); + Token := TranspilerLex(ALexer); + + WHILE Token.Kind = lexerKindIdentifier DO + TranspileTypeDeclaration(AContext, ALexer); + Token := TranspilerLex(ALexer) + END + END +END TranspileTypePart; + PROCEDURE Transpile(ALexer: PLexer); VAR Token: LexerToken;