⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 translate.java

📁 编译原理大作业---tiger编译器 包括semant,translate,mipsframe,regalloc等所有phase 懂的人自会知道
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
      if (Vargs.size()!=0) {         el=new Tree.ExpList(((Exp)Vargs.elementAt(0)).unEx(), null);         Tree.ExpList temp1=null, temp2=null;         Tree.Exp temp=null;         temp1 = el;         for (int i=1;i<Vargs.size();i++) {            temp=((Exp)Vargs.elementAt(i)).unEx();            temp2=new Tree.ExpList(temp,null);            temp1.tail=temp2;            temp1=temp1.tail;         }      }      // controlla se e' una funzione di libreria o esterna...      // e in base a questo cambia la lista degli argomenti (args)      // aggiungendo lo static_link o meno.      // lista degli argomenti      Tree.ExpList args;      // salva la label della funzione      Temp.Label labf=levf.frame.name;      Hashtable h=frame.funz_ext;      // se la funzione non e' di libreria (non esiste gia')      if ((h.get(labf.toString())) == null) {         Tree.TEMP static_link = new Tree.TEMP(frame.FP());         // calcola lo static link         Tree.Exp sl=trovaFrame(levf,curr,static_link);         // aggiunge in testa alla lista dei parametri lo static link         args = new Tree.ExpList(sl,el);      }      // altrimenti (se e' una funzione di libreria ... )      else { args = el; }      // codice finale: bisogna distinguere se si restituisce un VOID oppure no      if (isVoid) return new Nx(                            new Tree.EXP(                               new Tree.CALL(new Tree.NAME(levf.frame.name), args)));      else return new Ex(new Tree.CALL(new Tree.NAME(levf.frame.name), args));   }   // ----- recordExp -----   public Exp recordExp(Vector fields) {   // crea il registro per il puntatore al record   Temp.Temp r = new Temp.Temp();   Tree.TEMP recordp = new Tree.TEMP(r);   // chiama la funzione esterna "allocRecord(size)" che restituisce   // il puntatore all'area di memoria allocata (size*wordsize byte)   Tree.MOVE extCall= new Tree.MOVE(                         recordp,                         frame.externalCall(                            "allocRecord",                            new Tree.ExpList(                               new Tree.CONST(fields.size()*frame.wordSize()),                               null)));   // codice per l'inizializzazione dei campi del record   Tree.Stm single_init;   Tree.Stm total_init=null;   if (fields.size()!=0) {      // passo base      total_init = new Tree.MOVE(new Tree.MEM(recordp), ((Exp)fields.elementAt(0)).unEx());      // iterazione      for (int i=1;i<fields.size();i++) {         single_init = new Tree.MOVE(                          new Tree.MEM(                             new Tree.BINOP(                                Tree.BINOP.PLUS,                                recordp,                                new Tree.CONST(i*frame.wordSize()))),                          ((Exp)fields.elementAt(i)).unEx());         total_init  = new Tree.SEQ(total_init,single_init);         } // for   } // if    // controlla se non ha campi, in tal caso restituisce CONST(-1)    // (non si puo' usare 0 perche' altrimenti si confonde con nilExp)    if(fields.isEmpty()) return new Ex(new Tree.CONST(-1));    // completa l'albero (costruisce un ESEQ...)    return new Ex(new Tree.ESEQ(new Tree.SEQ(extCall, total_init), recordp));    }    // ----- arrayExp -----    public Exp arrayExp(Exp size, Exp init) {    // crea il registro per il puntatore all'array    Temp.Temp r = new Temp.Temp();    Tree.TEMP arrayp = new Tree.TEMP(r);    // calcola lo spazio da allocare ((size + 1) * wordSize)    Tree.Exp quantita = intOp(                           Tree.BINOP.MUL,                           intOp(                              Tree.BINOP.PLUS,                              size,                              intExp(1)),                           intExp(frame.wordSize())).unEx();    // chiamata a funzione esterna "initArray(size,init)" che    // restituisce il puntatore all'area ampia size*wordsize    Tree.Exp routineExt = frame.externalCall(                             "initArray",                             new Tree.ExpList(                                quantita,                                new Tree.ExpList(size.unEx(), null)));        // Codice intermedio totale        // initArray alloca la memoria e restituisce il puntatore        // al primo campo del vettore. Quindi si riempie il primo campo        // con il valore "size".        // Infine viene restituito il registro contente il puntatore all'array.        return new Ex(                  new Tree.ESEQ(                     new Tree.SEQ(                        new Tree.MOVE(arrayp, routineExt),                        new Tree.MOVE(                           new Tree.MEM(arrayp),                           size.unEx())),                     arrayp));    }    // ----- seqExp -----    /*     viene semplicemente costruita una sequenza di "pezzi" di albero gia' passati    come parametri (attraverso il Vector pezzi).    restituisce un Nx o un Ex a seconda del tipo dell'ultima exp    (che fornisce il valore a tutta la sequenza).    */    public Exp seqExp(Vector pezzi, boolean isVoid) {       Tree.Stm albero_totale = null;       // se la sequenza e' vuota...       // crea un pezzo di albero fittizio in cui creiamo una nuova etichetta       // e ci saltiamo ...       if (pezzi.isEmpty()) {          Temp.Label lab = new Temp.Label();           return new Nx(new Tree.SEQ(new Tree.JUMP(lab),new Tree.LABEL(lab)));       }       // controlla prima se la sequenza e' composta da una sola exp       // in tal caso restituisce direttamente l'exp totale...       if (pezzi.size() == 1 ) {          if (isVoid) { return new Nx(((Exp)pezzi.elementAt(0)).unNx()); }          else { return new Ex(((Exp)pezzi.elementAt(0)).unEx()); }       }       // costruisce l'albero fino all'ultimo elemento...       for (int i=0;i<pezzi.size() -1;i++) {          if (i==0) albero_totale = (((Exp)pezzi.elementAt(0)).unNx());          else albero_totale = new Tree.SEQ(albero_totale,((Exp)pezzi.elementAt(i)).unNx());       }       // appende l'ultimo elemento (che da' il valore alla sequenza) in base a isVoid...       if (isVoid) {          return new Nx(new Tree.SEQ(albero_totale,((Exp)pezzi.lastElement()).unNx()));       }       else {          return new Ex(new Tree.ESEQ(albero_totale,((Exp)pezzi.lastElement()).unEx()));       }    }    // ----- letExp -----    /*     Questo metodo crea un ESEQ dove     gli stm sono la seq di dichiarazioni (parametro decs)     e l'exp e' il corpo della let (parametro body)    */    public Exp letExp(Vector decs, Exp body) {       // inizializza decs_tree con un "salto a vuoto" per evitare       // di mettere null su ESEQ alla fine nel caso in cui il vettore sia vuoto...       // cioe' se non ci sono dichiarazioni (...che uso assurdo della let!)       Temp.Label lab = new Temp.Label();       Tree.Stm decs_tree = new Tree.SEQ(new Tree.JUMP(lab),new Tree.LABEL(lab));       // crea la SEQ di dichiarazioni...       for(int i=0;i<decs.size();i++) {          if (i==0) decs_tree = ((Exp)decs.elementAt(0)).unNx();          else { decs_tree=new Tree.SEQ(decs_tree,((Exp)decs.elementAt(i)).unNx()); }       }       // attacca la sequenza e il body...       return new Ex(new Tree.ESEQ(decs_tree,body.unEx()));    }    // ----- transProg -----    /*     il main viene gestito come una funzione     il procFrag del main viene inserito nella lista principale dei frags    */    public Exp transProg(Exp prg, Level level,boolean isVoid) {       if (isVoid) {          prg = new Nx(                   new Tree.SEQ(                      new Tree.LABEL(level.frame.name),                      prg.unNx()));       }       else {          if (debflag==1) System.out.println("\n> Registro di restituisce del frame Main, Main.RV(): " + level.frame.RV());          prg = new Nx(                   new Tree.SEQ(                      new Tree.LABEL(level.frame.name),                      new Tree.MOVE(                         new Tree.TEMP(level.frame.RV()),                      prg.unEx())));       }       // inserisce il ProcFrag nella lista principale frags       insFrag(new ProcFrag(prg.unNx(),level.frame));       return prg;    }    /*********************************     *         DICHIARAZIONI         *     *********************************/    // ----- varDec -----    public Exp varDec(Access acc, Level level, Exp init) {       return assignExp(simpleVar(acc,level),init);    }    // ----- functionDec -----    /*     Di questo metodo esistono due versioni, una crea un pezzo     di albero fittizio (per completare l'albero del Codice Intermedio)     l'altra crea il prologo e l'epilogo (tramite il metodo     procEntryExit1) e inserisce nella lista dei frags un ProcFrag     contenente il codice intermedio del corpo con epilogo e prologo.    */    public Exp functionDec() {       return new Nx(new Tree.EXP(new Tree.CONST(0)));    }    public void functionDec(Level level, Exp body, boolean isProc) {       procEntryExit1(level,body,isProc);    }    // ----- typeDec -----    public Exp typeDec() {       return new Nx(new Tree.EXP(new Tree.CONST(0)));    }    // *********************************    // *           SUPPORTO            *    // *********************************    // ----- getResult -----    // restituisce la lista di Data/Proc Frag.    public Frag getResult() { return frags; }    // ----- procEntryExit1 ----    public void procEntryExit1(Level level,Exp body,boolean isProc) {       Tree.Stm body_con_prologo_ed_epilogo;       Tree.Stm stmbody;       if (isProc) {          stmbody = new Tree.SEQ(                       new Tree.LABEL(level.frame.name),                       body.unNx());       }       else {          stmbody = new Tree.SEQ(                       new Tree.LABEL(level.frame.name),                       new Tree.MOVE(                          new Tree.TEMP(frame.RV()),                          body.unEx()));       }       // lancia procEntryExit di frame       body_con_prologo_ed_epilogo = level.frame.procEntryExit1(stmbody);       // inserisce il ProcFrag nella lista principale frags       insFrag(new ProcFrag(body_con_prologo_ed_epilogo,level.frame));    }    // ----- insFrag ----    // inserisce un frag in "frags"    public void insFrag(Frag f) {       if (frags==null) frags = f;       else if (frags.next==null) frags.next = f;            else frags.next.insertFrag(f);    }    // ----- trovaFrame -----    /*     questo metodo trova l'inizio dello stack frame in cui la variabile     e' allocata, usando i livelli, partendo dal frame corrente (frame.FP()),     e risalendo mano mano un livello per volta.     curr.frame.formals.head rappresenta lo static link.     NOTA: questo metodo viene utilizzato sia da simpleVar che da callExp.    */    public Tree.Exp trovaFrame(Level home, Level curr, Tree.Exp fp) {       if (home==curr) return fp;       else return trovaFrame(home, curr.parent, curr.frame.formals.head.exp(fp));    }    // ----- nullInstr -----    // inserisce codice fittizio nel caso si abbia un "null" in Semant.    public Exp nullInstr() {       Temp.Label l = new Temp.Label();       return new Nx(                 new Tree.SEQ(                    new Tree.JUMP(l),                    new Tree.LABEL(l)));    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -