MODULE cradle5; (* Adding push and pop to allow multiplication and division and () Adding [64 BITS] Converting to 64 bits (using rax instad of eax Adding bss zone *) IMPORT SYSTEM, Strings, InOut,WholeStr, CharClass, FIO ; CONST TAB = CHR(9); VAR Look : CHAR; ErrorCode : CARDINAL; chaine : ARRAY[0..255] OF CHAR; nomFichier : ARRAY [0..255] OF CHAR; fichier : FIO.File; 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 FIO.WriteString(fichier,s); END Emit; PROCEDURE EmitLn (s : ARRAY OF CHAR ); BEGIN FIO.WriteString(fichier,s); FIO.WriteLine(fichier); END EmitLn; (****************** début du parseur *************) 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 eax, ebx", chaine);*) Strings.Concat(TAB,"pop rbx", chaine); EmitLn(chaine); Strings.Concat(TAB,"add rax, rbx", chaine); EmitLn(chaine); END Add; PROCEDURE Substract; BEGIN Match ('-'); Term; Strings.Concat(TAB,"pop rbx", chaine); EmitLn(chaine); Strings.Concat(TAB,"sub rax, rbx", chaine); EmitLn(chaine); Strings.Concat(TAB,"neg rax", chaine); EmitLn(chaine); END Substract; PROCEDURE Expression; BEGIN Term; WHILE (Look = '+') OR (Look = '-') DO (* EmitLn('MOVE D0,D1'); version 1 *) (* EmitLn('MOVE D0,-(SP)'); version utilisant la pile *) Strings.Concat(TAB,"push rax",chaine); EmitLn(chaine); CASE Look OF '+' : Add; | '-' : Substract; ELSE Expected ("Addop "); END; END; END Expression; (*********************** fin du parseur ***********) PROCEDURE EndCompile; BEGIN Strings.Concat(TAB, "mov rdi,0",chaine); EmitLn(chaine); Strings.Concat(TAB, "mov rax,SYS_EXIT",chaine); EmitLn(chaine); Strings.Concat(TAB,"syscall",chaine); EmitLn(chaine); FIO.Close(fichier) END EndCompile; PROCEDURE Init; VAR OK : BOOLEAN; BEGIN (* création d'un fichier asm *) nomFichier := "cradleasm5.asm"; fichier := FIO.OpenForRandom(nomFichier,TRUE,TRUE ); IF NOT FIO.IsNoError(fichier) THEN InOut.WriteString("Echec de création du fichier asm"); HALT END; ErrorCode := 0; GetChar; EmitLn("[BITS 64]"); EmitLn(""); EmitLn("; begining of the assembly program"); EmitLn(""); EmitLn("%define SYS_EXIT 60"); EmitLn("%define SYS_WRITE 1"); EmitLn("%define STD_IN 0"); EmitLn("%define STD_OUT 1"); EmitLn("%define STD_ERR 2"); EmitLn(""); EmitLn("section .bss"); EmitLn("; nada"); 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 cradle5.