| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- 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,"mul 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 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");
- (* on met le résultat dans rax, puis transfert and rdi pour avoir le code de sortie *)
- Strings.Concat(TAB, "mov rdi, rax", 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.
|