MODULE cradle1; (* première phase du compilateur avec génération du code de sortie propre en amd64 *) (* on entre une valeur entière et il donne la valeur dans son code de sortie *) (* à examiner avec : echo $? *) (* gère les erreurs de saisie *) (* par contre permet la saisie de plusieurs caractères... ce qui n'est pas correct *) (* ::= digit *) IMPORT SYSTEM, Strings, InOut,WholeStr, CharClass, IO ; CONST TAB = CHR(9); VAR Look : CHAR; ErrorCode : CARDINAL; PROCEDURE GetChar; BEGIN InOut.Read(Look) END GetChar; PROCEDURE Error (s : ARRAY OF CHAR); BEGIN InOut.WriteLn; InOut.Write(CHR(8)); InOut.Write(TAB); InOut.WriteString("Error : "); InOut.WriteString(s); InOut.Write("."); END Error; PROCEDURE Abort (s : ARRAY OF CHAR); BEGIN Error(s); HALT END Abort; PROCEDURE Expected (s : ARRAY OF CHAR); VAR chaine : ARRAY [0..255] OF CHAR; BEGIN Strings.Concat(s, " Expected ",chaine); Abort (chaine) END Expected; PROCEDURE Match ( x : CHAR ); VAR chaine : ARRAY [0..255] OF CHAR; BEGIN IF Look = x THEN GetChar ELSE Strings.Concat("''",Strings.String1(x),chaine); Strings.Concat(chaine, "''", chaine); Expected(chaine) END; END Match; PROCEDURE IsAlpha (c : CHAR ) : BOOLEAN; BEGIN RETURN CharClass.IsUpper(CAP(c)) END IsAlpha; PROCEDURE IsDigit (c : CHAR) : BOOLEAN; BEGIN RETURN CharClass.IsNumeric(c) END IsDigit; PROCEDURE GetName (VAR s : ARRAY OF CHAR); BEGIN IF NOT IsAlpha(Look) THEN ErrorCode := 1; Expected('Name'); END; Strings.Assign(Strings.String1(CAP(Look)),s); GetChar; END GetName; PROCEDURE GetNum (VAR c : CHAR); BEGIN IF NOT IsDigit(Look) THEN ErrorCode := 1; Expected('Integer'); END; c := Look; (* GetChar; commented out as we only authorize one digit num *) END GetNum; PROCEDURE Emit (s : ARRAY OF CHAR); BEGIN InOut.WriteString(s); END Emit; PROCEDURE EmitLn (s : ARRAY OF CHAR ); BEGIN InOut.WriteString(s); InOut.WriteLn; END EmitLn; (************* début du parser ***************) (* ::= digit *) PROCEDURE Expression; VAR chaine : ARRAY[0..255] OF CHAR; c : CHAR; BEGIN GetNum(c); Strings.Concat(TAB,"mov rbx, ", chaine); Strings.Concat(chaine, Strings.String1(c), chaine); EmitLn(chaine); (* on met le résultat dans rbx, puis transfert and rdi pour avoir le code de sortie *) Strings.Concat(TAB,"mov rdi, rbx", chaine); EmitLn(chaine) END Expression; (************ fin du parser ******************) PROCEDURE EndCompile; VAR chaine : ARRAY[0..255] OF CHAR; BEGIN (*Strings.Concat(TAB, "mov rdi,",chaine); Strings.Concat(chaine, Strings.String1(Look) , chaine); EmitLn(chaine);*) Strings.Concat(TAB, "mov rax,60",chaine); EmitLn(chaine); Strings.Concat(TAB,"syscall",chaine); EmitLn(chaine); END EndCompile; PROCEDURE Init; BEGIN ErrorCode := 0; GetChar; EmitLn("[BITS 64]"); EmitLn(""); EmitLn(" "); EmitLn("; begining of the assembly program"); EmitLn(" "); EmitLn("section .data"); EmitLn(" "); EmitLn("section .text"); EmitLn("global _start"); EmitLn(" "); EmitLn("_start:"); EmitLn(""); END Init; BEGIN InOut.WriteString("Début de compilation"); InOut.WriteLn; InOut.WriteString("Entrez le source : "); Init; Expression; EndCompile; END cradle1.