MODULE PL0c3; (************************************************************) (* PL0 compiler in GNU Modula-2 *) (* using only ISO Libraries to void mixing *) (* generates an asm file to be interpreted by PLO executable*) (* Eric Streit May 2026 *) (************************************************************) (* program structure *) (* read a file with the text program *) (* syntax analysis followed by semantic analysis *) (* and code generation *) FROM IOResult IMPORT ReadResults, ReadResult; FROM TextIO IMPORT ReadRestLine, SkipLine, ReadToken, WriteLn, WriteString, ReadChar; FROM SeqFile IMPORT OpenRead, OpenWrite, OpenResults, Close, ChanId, read, write; IMPORT STextIO, SWholeIO, Strings; VAR theChanId : ChanId; theResult : OpenResults; theChar : CHAR; theLineNumber : CARDINAL; theFileName : ARRAY[0..128] OF CHAR; thelength : CARDINAL; BEGIN STextIO.WriteString("PL0 compiler from Wirth book 'Algorithms and Data Structures'"); STextIO.WriteLn; STextIO.WriteString("Eric Streit "); STextIO.WriteLn; STextIO.WriteLn; (* adding the file name input *) theFileName := ""; STextIO.WriteString("Enter the file name (ENTER to leave)(with an ending '.' to add automatcally the extension) : "); STextIO.ReadString(theFileName); (* STextIO.WriteString(theFileName); *) thelength := Strings.Length(theFileName); IF thelength = 0 THEN STextIO.WriteString("Leaving .... bye ! "); STextIO.WriteLn; HALT ELSE (* adding extension if the name ends by . )*) IF theFileName[thelength-1] = "." THEN (* adding extension if enough space*) IF thelength < 125 THEN Strings.Concat(theFileName, "pl0", theFileName); ELSE STextIO.WriteString("File name too long"); STextIO.WriteLn; STextIO.WriteString("Halting"); HALT; END; END; END; STextIO.WriteString(theFileName); STextIO.WriteLn; theLineNumber := 1; OpenRead(theChanId, "test1.pl0", read, theResult); IF theResult = noSuchFile THEN STextIO.WriteString("Sorry, this file doesn't exist ; halting"); STextIO.WriteLn; ELSE IF theResult=opened THEN (* file is open*) STextIO.WriteString("file opened!"); STextIO.WriteLn; STextIO.WriteLn; (* reading a char*) ReadChar(theChanId, theChar); (* testing the result *) (* if OK we continue *) WHILE ReadResult(theChanId) <> endOfInput DO (* testing end of line *) IF ReadResult(theChanId) = endOfLine THEN INC(theLineNumber); (* we have to 'skip' the endOfLine ... so strange *) SkipLine(theChanId); END; (* printing the char*) STextIO.WriteChar(theChar); (* reading next char *) ReadChar(theChanId, theChar); END; Close(theChanId); ELSE STextIO.WriteString("Error"); STextIO.WriteLn; END; END; END PL0c3.