|
|
@@ -0,0 +1,317 @@
|
|
|
+MODULE cradle8;
|
|
|
+
|
|
|
+(* Ajout de UNARY MINUS/PLUS *)
|
|
|
+(* simple and easy version *)
|
|
|
+
|
|
|
+(* <factor> ::= [+|-]digit | (<expression>) *)
|
|
|
+(* <expression> ::= <term> [<addop> <term>]* *)
|
|
|
+(* <term> ::= <factor> [ <mulop> <factor ]* *)
|
|
|
+
|
|
|
+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 IsAddop(c: CHAR): BOOLEAN;
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ RETURN (c = "+") OR (c = "-")
|
|
|
+END IsAddop;
|
|
|
+
|
|
|
+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;
|
|
|
+
|
|
|
+(******************************************************)
|
|
|
+(* le parser commence ici *********************)
|
|
|
+(******************************************************)
|
|
|
+
|
|
|
+(* <factor> ::= [+|-]digit | (<expression>) *)
|
|
|
+(* <expression> ::= <term> [<addop> <term>]* *)
|
|
|
+(* <term> ::= <factor> [ <mulop> <factor ]* *)
|
|
|
+(* adding unary sign, + and - *)
|
|
|
+
|
|
|
+PROCEDURE Expression; FORWARD;
|
|
|
+
|
|
|
+PROCEDURE Factor;
|
|
|
+(* Parse and Translate a Math Factor *)
|
|
|
+(* in cradle5, it was Term *)
|
|
|
+
|
|
|
+VAR
|
|
|
+ c : CHAR;
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ IF Look = '(' THEN
|
|
|
+ (* (expression) *)
|
|
|
+ Match('(');
|
|
|
+ Expression;
|
|
|
+ Match(')');
|
|
|
+ ELSE
|
|
|
+ (* digit *)
|
|
|
+ (* EmitLn('MOVE #' + GetNum + ',D0')*)
|
|
|
+ GetNum(c);
|
|
|
+ Strings.Concat(TAB,"mov rax,", chaine);
|
|
|
+ Strings.Concat(chaine, Strings.String1(c), chaine);
|
|
|
+ EmitLn(chaine)
|
|
|
+ END
|
|
|
+END Factor;
|
|
|
+
|
|
|
+
|
|
|
+PROCEDURE Multiply;
|
|
|
+(* Recognize and Translate a Multiply *)
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ Match('*');
|
|
|
+ Factor;
|
|
|
+ (*EmitLn('MULS (SP)+,D0');*)
|
|
|
+ Strings.Concat(TAB,"pop rbx", chaine);
|
|
|
+ EmitLn(chaine);
|
|
|
+ Strings.Concat(TAB,"imul rax, rbx", chaine);
|
|
|
+ EmitLn(chaine);
|
|
|
+END Multiply;
|
|
|
+
|
|
|
+
|
|
|
+PROCEDURE Divide;
|
|
|
+(* Recognize and Translate a Divide *)
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ Match('/');
|
|
|
+ Factor;
|
|
|
+ (*EmitLn('MOVE (SP)+,D1');*)
|
|
|
+ (*EmitLn('DIVS D1,D0');*)
|
|
|
+ Strings.Concat(TAB,"pop rbx", chaine);
|
|
|
+ EmitLn(chaine);
|
|
|
+ Strings.Concat(TAB,"div rax, rbx", chaine);
|
|
|
+ EmitLn(chaine);
|
|
|
+END Divide;
|
|
|
+
|
|
|
+
|
|
|
+PROCEDURE Term;
|
|
|
+(* Parse and Translate a Math Term*)
|
|
|
+
|
|
|
+VAR
|
|
|
+ c : CHAR;
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ Factor;
|
|
|
+ WHILE (Look = '*') OR (Look = '/') DO
|
|
|
+ (*EmitLn('MOVE D0,-(SP)');*)
|
|
|
+ Strings.Concat(TAB,"push rax",chaine);
|
|
|
+ EmitLn(chaine);
|
|
|
+ CASE Look OF
|
|
|
+ '*': Multiply; |
|
|
|
+ '/': Divide;
|
|
|
+ ELSE
|
|
|
+ Expected('Mulop');
|
|
|
+ END;
|
|
|
+ END;
|
|
|
+END Term;
|
|
|
+
|
|
|
+PROCEDURE Add;
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ Match('+');
|
|
|
+ Term;
|
|
|
+ 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;
|
|
|
+(* Parse and Translate an Expression*)
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ IF IsAddop (Look) THEN
|
|
|
+ Strings.Concat(TAB,"xor rax, rax",chaine);
|
|
|
+ EmitLn(chaine);
|
|
|
+ ELSE
|
|
|
+ Term;
|
|
|
+ END;
|
|
|
+ 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 parser ************)
|
|
|
+
|
|
|
+PROCEDURE Init;
|
|
|
+
|
|
|
+VAR
|
|
|
+ OK : BOOLEAN;
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ (* création d'un fichier asm *)
|
|
|
+ nomFichier := "cradleasm8.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("; sys calls");
|
|
|
+ EmitLn("%define SYS_EXIT 60");
|
|
|
+ EmitLn("%define SYS_WRITE 1");
|
|
|
+ EmitLn("");
|
|
|
+ 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;
|
|
|
+
|
|
|
+PROCEDURE EndCompile;
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ EmitLn("");
|
|
|
+ EmitLn("; end of program");
|
|
|
+ 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;
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ InOut.WriteString("Début de compilation");
|
|
|
+ InOut.WriteLn;
|
|
|
+ InOut.WriteString("Entrez le source : ");
|
|
|
+ Init;
|
|
|
+ Expression;
|
|
|
+ EndCompile;
|
|
|
+END cradle8.
|