MODULE cradle2; (* deuxième étape du compilateur *) (* ajout des opérations d'addition et de soustraction *) (* les termes sont toujours limités à 1 chiffre *) (* (pas de - unaire !! ) *) (* ::= digit *) (* +/- *) (* une seule opération permise *) IMPORT SYSTEM, Strings, InOut,WholeStr, CharClass, IO ; CONST TAB = CHR(9); VAR Look : CHAR; ErrorCode : CARDINAL; chaine : ARRAY[0..255] OF CHAR; 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 ); 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; 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; PROCEDURE EndCompile; BEGIN Strings.Concat(TAB, "mov rdi,0",chaine); EmitLn(chaine); Strings.Concat(TAB, "mov rax,60",chaine); EmitLn(chaine); Strings.Concat(TAB,"syscall",chaine); EmitLn(chaine); END EndCompile; PROCEDURE Term; VAR c : CHAR; BEGIN GetNum(c); Strings.Concat(TAB,"mov rax,", chaine); Strings.Concat(chaine, Strings.String1(c), chaine); EmitLn(chaine) END Term; PROCEDURE Add; BEGIN Match('+'); Term; Strings.Concat(TAB,"add rax, rbx", chaine); EmitLn(chaine); END Add; PROCEDURE Substract; BEGIN Match ('-'); Term; Strings.Concat(TAB,"sub rax, rbx", chaine); EmitLn(chaine); Strings.Concat(TAB,"neg eax", chaine); EmitLn(chaine); END Substract; PROCEDURE Expression; BEGIN Term; Strings.Concat(TAB,"mov rbx, rax",chaine); EmitLn(chaine); CASE Look OF '+' : Add; | '-' : Substract; ELSE Expected ("Addop "); END; END Expression; PROCEDURE Init; BEGIN (* IO.EchoOff (0, TRUE ) ; *) ErrorCode := 0; GetChar; EmitLn("[BITS 64]"); EmitLn(""); EmitLn("; begining of the assembly program"); EmitLn(""); EmitLn("section .data"); EmitLn(""); EmitLn("section .text"); EmitLn("global _start"); EmitLn(""); EmitLn("_start:"); END Init; BEGIN InOut.WriteString("Début de compilation"); InOut.WriteLn; InOut.WriteString("Entrez le source : "); Init; Expression; EndCompile; END cradle2.