• 现代编译原理--第六章(中间树 IR Tree 含源码)


      (转载请表明出处   http://www.cnblogs.com/BlackWalnut/p/4559717.html )

          这一章,就虎书而言,理论知识点是及其少的,就介绍了为什么要有一个中间表示树。看下面这张图就能理解为什么了。

      由以上可以知道,中间表达式树可以看成是一种简化过的汇编语言组成的树。在这个阶段,我们已经抛弃了所有的变量名称和函数名称,使用标号以及变量以及临时变量(temp_newtemp)来代替来代替。,而且所有的变量都存储在frame中,也就是说,我们是使用frame来分割代码的,一个frame就代表了一个函数。

      这章的代码量却是挺多的。在写代码之前,如果不懂整个代码的布局,是很难了解书上那写代码是对应那些功能,以及书上没有给出的代码,我应该这么完善。那么,我就我自己的理解来说一下到目前为止(翻译成中间表示树以后,编译器的前端就算基本完成了),整个代码的布局是什么样。

      首先我们从外部读取tiger语言编写的源代码,经过由flex和bison生成的lex.yy.cpp  tiger.tab.cpp tiger.tab.h的处理(词法分析,语法分析),生成了抽象语法树,这个语法树的数据结构是在absyn,table,symbol这些文件中定义的。然后我们要抽象语法树转化为中间表示树,这个转化过程都是由 semant 文件中的函数完成(语义分析)。semant主要完成了两个任务:对类型检测(类型检测)以及生成中间表达树(中间表达树)。类型检测过程中使用到了evn,table,symbol,type中定义的一些东西。而转化为中间表示树使用了translate文件中的函数,之所以使用这translate文件 ,是为了将树的具体构建过程和语义分析过程分离,这样如果想要用另一种方式表示中间表示树,可以不动原来semant的代码。因为在semant定义的函数只能看到以Tr_开头的函数,而看不到关于树的任何信息。一棵中间表示树是由frame(F开头),tree(T开头)两部文件分组成的,并且这两部分只被translate使用。

      值得注意的是,前一章我们介绍的活动记录的时候提到,一个活动记录里面包含局部变量,临时变量,寄存器,静态链等信息。但是在frame里面,我们没有记录临时变量。临时变量的信息是在中间表示树中记录的(就是调用temp_newtemp),并且在生成frame的时候,我们也并不是真的取内存中分配一块地址然后记录他的位置,我们只是记录一个变量的相对位移。对于寄存器来说,frame中可以申请无数个寄存器。但是在最终翻译成汇编的时候,我们会根据实际寄存器的数量,将没有办法得到的寄存器的变量放入内存中。而temp_newlabel则是生成各种标签,因为汇编语言中是可以直接goto到一个标签位置的。

      也就是说,frame中记录在任何目标机器上都要用到的信息,这个信息是一个理想化的信息,在最终翻译成代码的时候,还有根据机器的不同来进行调整。

      也要注意到,中间代码多是面向汇编的,所以在translate中将抽象与法树对应的语句和表达式(还是高级语言)转换成中间语法树的节点(面向汇编)。

      知道了以上信息,剩下的就是根据具体的要求来写相应的代码了。可以看出,tiger作者给出的代码框架还是很值得学习的。

         好了,一下就是一部分关键代码。

      

    /*
     * tree.h - Definitions for intermediate representation (IR) trees.
     *
     */
    #ifndef TREE_H_
    #define TREE_H_
    
    typedef struct T_stm_ *T_stm;
    typedef struct T_exp_ *T_exp;
    typedef struct T_expList_ *T_expList;
    struct T_expList_ {T_exp head; T_expList tail;};
    typedef struct T_stmList_ *T_stmList;
    struct T_stmList_ {T_stm head; T_stmList tail;};
    
    typedef enum {T_plus, T_minus, T_mul, T_div,
        T_and, T_or, T_lshift, T_rshift, T_arshift, T_xor} T_binOp ;
    
    typedef enum  {T_eq, T_ne, T_lt, T_gt, T_le, T_ge,
        T_ult, T_ule, T_ugt, T_uge} T_relOp;
    
    struct T_stm_ {enum {T_SEQ, T_LABEL, T_JUMP, T_CJUMP, T_MOVE,
        T_EXP} kind;
    union {struct {T_stm left, right;} SEQ;
    Temp_label LABEL;
    struct {T_exp exp; Temp_labelList jumps;} JUMP;
    struct {T_relOp op; T_exp left, right;
    Temp_label trues, falses;} CJUMP;
    struct {T_exp dst, src;} MOVE;
    T_exp EXP;
    } u;
    };
    
    struct T_exp_ {enum {T_BINOP, T_MEM, T_TEMP, T_ESEQ, T_NAME,
        T_CONST, T_CALL} kind;
    union {struct {T_binOp op; T_exp left, right;} BINOP;
    T_exp MEM;
    Temp_temp TEMP;
    struct {T_stm stm; T_exp exp;} ESEQ;
    Temp_label NAME;
    int CONST;
    struct {T_exp fun; T_expList args;} CALL;
    } u;
    };
    
    T_expList T_ExpList (T_exp head, T_expList tail);
    T_stmList T_StmList (T_stm head, T_stmList tail);
    
    T_stm T_Seq(T_stm left, T_stm right);
    T_stm T_Label(Temp_label);
    T_stm T_Jump(T_exp exp, Temp_labelList labels);
    T_stm T_Cjump(T_relOp op, T_exp left, T_exp right, 
                  Temp_label trues, Temp_label falses);
    T_stm T_Move(T_exp, T_exp);
    T_stm T_Exp(T_exp);
    
    T_exp T_Binop(T_binOp, T_exp, T_exp);
    T_exp T_Mem(T_exp);
    T_exp T_Temp(Temp_temp);
    T_exp T_Eseq(T_stm, T_exp);
    T_exp T_Name(Temp_label);
    T_exp T_Const(int);
    T_exp T_Call(T_exp, T_expList);
    
    T_relOp T_notRel(T_relOp);  /* a op b    ==     not(a notRel(op) b)  */
    T_relOp T_commute(T_relOp); /* a op b    ==    b commute(op) a       */
    
    
    
    #endif
    #include <stdio.h>
    #include "util.h"
    #include "symbol.h"
    #include "temp.h"
    #include "tree.h"
    
    T_expList T_ExpList(T_exp head, T_expList tail)
    {T_expList p = (T_expList) checked_malloc (sizeof *p);
     p->head=head; p->tail=tail;
     return p;
    }
    
    T_stmList T_StmList(T_stm head, T_stmList tail)
    {T_stmList p = (T_stmList) checked_malloc (sizeof *p);
     p->head=head; p->tail=tail;
     return p;
    }
     
    T_stm T_Seq(T_stm left, T_stm right)
    {T_stm p = (T_stm) checked_malloc(sizeof *p);
      p->kind= T_stm_::T_SEQ;
     p->u.SEQ.left=left;
     p->u.SEQ.right=right;
     return p;
    }
    
    T_stm T_Label(Temp_label label)
    {T_stm p = (T_stm) checked_malloc(sizeof *p);
     p->kind= T_stm_::T_LABEL;
     p->u.LABEL=label;
     return p;
    }
     
    T_stm T_Jump(T_exp exp, Temp_labelList labels)
    {T_stm p = (T_stm) checked_malloc(sizeof *p);
     p->kind= T_stm_::T_JUMP;
     p->u.JUMP.exp=exp;
     p->u.JUMP.jumps=labels;
     return p;
    }
    
    T_stm T_Cjump(T_relOp op, T_exp left, T_exp right, 
              Temp_label trues, Temp_label falses)
    {T_stm p = (T_stm) checked_malloc(sizeof *p);
     p->kind= T_stm_::T_CJUMP;
     p->u.CJUMP.op=op; p->u.CJUMP.left=left; p->u.CJUMP.right=right;
     p->u.CJUMP.trues=trues;
     p->u.CJUMP.falses=falses;
     return p;
    }
     
    T_stm T_Move(T_exp dst, T_exp src)
    {T_stm p = (T_stm) checked_malloc(sizeof *p);
     p->kind= T_stm_::T_MOVE;
     p->u.MOVE.dst=dst;
     p->u.MOVE.src=src;
     return p;
    }
     
    T_stm T_Exp(T_exp exp)
    {T_stm p = (T_stm) checked_malloc(sizeof *p);
     p->kind= T_stm_::T_EXP;
     p->u.EXP=exp;
     return p;
    }
     
    T_exp T_Binop(T_binOp op, T_exp left, T_exp right)
    {T_exp p = (T_exp) checked_malloc(sizeof *p);
     p->kind= T_exp_::T_BINOP;
     p->u.BINOP.op=op;
     p->u.BINOP.left=left;
     p->u.BINOP.right=right;
     return p;
    }
     
    T_exp T_Mem(T_exp exp)
    {T_exp p = (T_exp) checked_malloc(sizeof *p);
     p->kind= T_exp_::T_MEM;
     p->u.MEM=exp;
     return p;
    }
     
    T_exp T_Temp(Temp_temp temp)
    {T_exp p = (T_exp) checked_malloc(sizeof *p);
     p->kind= T_exp_::T_TEMP;
     p->u.TEMP=temp;
     return p;
    }
     
    T_exp T_Eseq(T_stm stm, T_exp exp)
    {T_exp p = (T_exp) checked_malloc(sizeof *p);
     p->kind= T_exp_::T_ESEQ;
     p->u.ESEQ.stm=stm;
     p->u.ESEQ.exp=exp;
     return p;
    }
     
    T_exp T_Name(Temp_label name)
    {T_exp p = (T_exp) checked_malloc(sizeof *p);
     p->kind= T_exp_::T_NAME;
     p->u.NAME=name;
     return p;
    }
     
    T_exp T_Const(int consti)
    {T_exp p = (T_exp) checked_malloc(sizeof *p);
     p->kind= T_exp_::T_CONST;
     p->u.CONST=consti;
     return p;
    }
     
    T_exp T_Call(T_exp fun, T_expList args)
    {T_exp p = (T_exp) checked_malloc(sizeof *p);
     p->kind= T_exp_::T_CALL;
     p->u.CALL.fun=fun;
     p->u.CALL.args=args;
     return p;
    }
    
    T_relOp T_notRel(T_relOp r)
    {
     switch(r)
       {case T_eq: return T_ne;
        case T_ne: return T_eq;
        case T_lt: return T_ge;
        case T_ge: return T_lt;
        case T_gt: return T_le;
        case T_le: return T_gt;
        case T_ult: return T_uge;
        case T_uge: return T_ult;
        case T_ule: return T_ugt ;
        case T_ugt: return T_ule;
      }
     assert(0); 
    }
    
    T_relOp T_commute(T_relOp r)
    {switch(r) {
        case T_eq: return T_eq;
        case T_ne: return T_ne;
        case T_lt: return T_gt;
        case T_ge: return T_le;
        case T_gt: return T_lt ;
        case T_le: return T_ge;
        case T_ult: return T_ugt;
        case T_uge: return T_ule;
        case T_ule: return T_uge ;
        case T_ugt: return T_ult;
       }
     assert(0); 
    }
    #ifndef TRANSLATE_H_
    #define TRANSLATE_H_
    
    #include "frame.h"
    #include "absyn.h"
    //frame œ‡πÿ
    
    typedef struct Tr_level_      * Tr_level ;    
    typedef struct Tr_accesslist_ * Tr_accesslist ;
    typedef struct Tr_access_     * Tr_access ;  
    struct  Tr_accesslist_  { Tr_access  head ;  Tr_accesslist tial ; };
    struct  Tr_level_       { Tr_level parent ;  F_frame frame; };  //≤„µƒ◊˜”√ «Œ™¡À±£¥Êæ≤è¡¥
    struct  Tr_access_      { Tr_level level  ;  F_access access ; };//º«¬º¡À“ª∏ˆ≤„∫Õ≤„÷–µƒŒª÷√ ’‚—˘ ∑Ω±„“ª∏ˆ«∂Ã◊≤„»•≤È—Ø“˝”√µƒÕ‚≤ø±‰¡ø À¸ «E_varEntry÷–µƒ“ª∏ˆ±‰¡ø
    
    
    //frame œ‡πÿ
    Tr_accesslist Tr_Accesslist(Tr_access head , Tr_accesslist tial) ;
    Tr_access Tr_Access(Tr_level level , F_access access ) ;
    Tr_level Tr_outermorst() ;
    Tr_level Tr_newLevel(Tr_level parent , Temp_label name , U_boolList formals ) ;
    Tr_accesslist Tr_formals(Tr_level level) ;
    Tr_access Tr_allocLocal(Tr_level level , bool escape ) ;
    void     Tr_ClearAcces(Tr_accesslist list) ; //Ω´list Õ∑≈ µ´ « ≤ª Õ∑≈∆‰÷–µƒhead
    
    
    
    // IR Tree œ‡πÿ
    #define  GetExpEx  Tr_exp_::Tr_ex
    #define  GetExpNx  Tr_exp_::Tr_nx 
    #define  GetExpCx  Tr_exp_::Tr_cx 
    
    typedef struct Tr_exp_* Tr_exp ;
    typedef struct Tr_expList_ * Tr_expList ;
    typedef struct patchList_ * patchList ;
    
    struct Cx { patchList trues ; patchList falses ; T_stm stm ; };
    struct patchList_ { Temp_label *head ; patchList tail ; };
    
    struct Tr_exp_
    {
        enum{Tr_ex , Tr_nx , Tr_cx } kind;
        union
        {
            T_exp ex ;
            T_stm nx ;
            Cx    cx ;
        }u;
    };
    
    struct Tr_expList_
    {
        Tr_exp head ;
        Tr_expList tail ;
    };
    
    //IR Treeœ‡πÿ 
    Tr_exp Tr_Ex(T_exp exp ) ;
    Tr_exp Tr_Nx(T_stm stm ) ;
    Tr_exp Tr_Cx(patchList trues , patchList falses , T_stm stm ) ;
    
    T_exp  Tr_unEx(Tr_exp exp) ;
    T_stm  Tr_unNx(Tr_exp exp) ;
    Cx     Tr_unCx(Tr_exp exp) ;
    
    patchList PatchList(Temp_label *head , patchList patchlist ) ;
    void doPatch(patchList patchlist , Temp_label label) ;
    Tr_expList Tr_ExpList(Tr_exp head , Tr_expList tail) ;
    
    Tr_exp  Tr_nilExp() ;
    Tr_exp  Tr_intExp(int i) ;
    Tr_exp  Tr_stringExp(string str) ;
    
    Tr_exp  Tr_simpleVar(Tr_access acc , Tr_level level );
    Tr_exp  Tr_subscriptVar(Tr_exp base, Tr_exp index);
    Tr_exp  Tr_fieldVar(Tr_exp base, int offset);
    
    Tr_exp  Tr_binopExp(Tr_exp left , Tr_exp right ,A_oper oper );
    Tr_exp  Tr_relopExp(Tr_exp left , Tr_exp right , A_oper oper) ;
    
    Tr_exp Tr_ifExp( Tr_exp test , Tr_exp then , Tr_exp elses ) ;
    Tr_exp Tr_recordExp( Tr_expList explist , int num) ;
    Tr_exp Tr_arryExp(Tr_exp index , Tr_exp init) ;
    Tr_exp Tr_seqExp(Tr_expList explist) ;
    Tr_exp Tr_assignExp(Tr_exp exp1 , Tr_exp exp2) ;
    
    Tr_exp Tr_whileExp(  Tr_exp test , Tr_exp body , bool isbreak) ;
    Tr_exp Tr_forExp(Tr_access acc , Tr_exp hi , Tr_exp low , Tr_exp body) ;
    Tr_exp Tr_breakExp() ;
    Tr_exp Tr_letExp(Tr_expList declist , Tr_exp exp ) ;
    
    Tr_exp Tr_callExp(Temp_label label ,Tr_level funleve , Tr_level  level ,Tr_expList explist ) ;
    Tr_exp Tr_StaticLink(Tr_level now, Tr_level def);
    
    
    Tr_exp Tr_varDec(Tr_access acc , Tr_exp init) ;
    Tr_exp Tr_typeDec();
    Tr_exp Tr_funDec(Tr_expList bodylist) ;
    
    void Tr_procEntryExit(Tr_level level , Tr_exp body , Tr_accesslist formals) ;
    
    F_fragList Tr_getResult() ;
    
    #endif
    #include "translate.h"
    #include "util.h"
    #include "env.h"
    #include <stdio.h>
    #include <stdlib.h>
    Tr_access Tr_allocLocal(Tr_level level , bool escape )
    {
      F_access acc ;
      acc = F_allocLoacl(level->frame  , escape) ;
      return Tr_Access(level , acc) ;
    }
    
    Tr_access Tr_Access(Tr_level level , F_access access )
    {
        Tr_access acc = (Tr_access)checked_malloc(sizeof(*acc));
        acc->level = level;
        acc->access = access;
        return acc;
    }
    
    Tr_accesslist Tr_Accesslist(Tr_access head , Tr_accesslist tial)
    {
        Tr_accesslist tmp = (Tr_accesslist)checked_malloc(sizeof(*tmp));
        tmp->head = head ;
        tmp->tial = tial ;
        return tmp ;
    }
    Tr_level Tr_newLevel(Tr_level parent , Temp_label name , U_boolList formals )
    {
        Tr_level level = (Tr_level)checked_malloc(sizeof(*level));
        level->parent = parent ;
        level->frame = F_newframe(name , U_BoolList(true , formals) ) ; // ’‚¿Ôº”µƒtrue¥˙±Ì¡Àæ≤è¡¥
        return level ;
    }
    
    
    Tr_accesslist Tr_formals(Tr_level level)
    {
        F_accesslist f_acc = level->frame->formals ;
        f_acc = f_acc->tail ;//µ⁄“ª∏ˆ¥˙±Ì¡Àæ≤è¡¥ À˘“‘“™ÃÙ≥ˆ¿¥
        Tr_accesslist tmp = NULL ;
        while(f_acc)
        {
             tmp = Tr_Accesslist(Tr_Access(level , f_acc->head), tmp) ;
             f_acc = f_acc->tail ;
        }
        return tmp ;
    }
    
    Tr_level Tr_outermorst()
    {
        static Tr_level tmp = NULL ;
        if (!tmp)
        {
            tmp = (Tr_level)checked_malloc(sizeof(*tmp));
            U_boolList b = U_BoolList(true , NULL) ;
            tmp->frame = F_newframe(Temp_newlabel() , b)  ;
            tmp->parent = NULL ;
        }
        return tmp ;
    
    }
    
    void Tr_ClearAcces(Tr_accesslist list)
    {
        Tr_accesslist tmp ;
        tmp = list ;
        while(list)
        {
            list = list->tial ;
            tmp->head =  NULL ;
            tmp->tial =  NULL ;
            free(tmp) ;
            tmp = list ;
        }
    }
    
    Tr_exp Tr_Ex(T_exp exp )
    {
        Tr_exp tmp = (Tr_exp)checked_malloc(sizeof(*tmp));
        tmp->kind = GetExpEx ;
        tmp->u.ex = exp ;
        return tmp ;
    }
    
    Tr_exp Tr_Nx(T_stm stm )
    {
        Tr_exp tmp = (Tr_exp)checked_malloc(sizeof(*tmp));
        tmp->kind = GetExpNx ;
        tmp->u.nx = stm ;
        return tmp ;
    }
    
    Tr_exp Tr_Cx(patchList trues , patchList falses , T_stm stm )
    {
        Tr_exp tmp = (Tr_exp)checked_malloc(sizeof(*tmp));
        tmp->kind = GetExpCx ;
        tmp->u.cx.falses = falses ;
        tmp->u.cx.trues = trues ;
        tmp->u.cx.stm = stm ;
        return tmp ;
    }
    T_stm  Tr_unNx(Tr_exp exp)
    {
        switch (exp->kind)
        {
        case  GetExpEx:
            return T_Exp(exp->u.ex);
        case  GetExpCx:
            return T_Exp(Tr_unEx(exp));
        case  GetExpNx:
            return exp->u.nx;
        }
        assert(0);
    }
    Cx  Tr_unCx(Tr_exp exp)
    {
        switch (exp->kind)
        {
        case GetExpCx :
            return exp->u.cx;
        case GetExpEx:
            {
                T_stm stm = T_Cjump(T_ne, exp->u.ex, T_Const(0), NULL ,  NULL);
                Cx cx; 
                cx.stm = stm;
                cx.falses = PatchList(&stm->u.CJUMP.falses, NULL);
                cx.trues = PatchList(&stm->u.CJUMP.trues, NULL);
                return cx;
            }
        }
        assert(0);
    }
    T_exp  Tr_unEx(Tr_exp exp)
    {
        switch(exp->kind)
        {
        case GetExpEx :
         return exp->u.ex ;
        case GetExpCx :
            {
              Temp_temp tmp = Temp_newtemp() ;
              Temp_label t = Temp_newlabel() , f = Temp_newlabel() ;
              doPatch(exp->u.cx.falses , f) ;
              doPatch(exp->u.cx.trues , t) ;
              return T_Eseq(T_Move(T_Temp(tmp) , T_Const(1)),
                      T_Eseq( exp->u.cx.stm ,
                       T_Eseq( T_Label(f) ,
                        T_Eseq(T_Move(T_Temp(tmp) , T_Const(0)) ,
                         T_Eseq(T_Label(t) ,
                          T_Temp(tmp)))))) ;
    
            }
        case GetExpNx :
            {
              return T_Eseq(exp->u.nx, T_Const(0));// Œ™ ≤√¥“™∑µªÿ0 ’‚∏ˆnx≤ª «Œfi÷µ”Ôæ‰√¥
            }
        }
        assert(0);
    }
    
    void doPatch(  patchList patchlist , Temp_label lable)
    {
        for ( ;  patchlist ; patchlist = patchlist->tail)
        {
            (*patchlist->head) = lable ;
        }
    }
    
    patchList PatchList(Temp_label *head , patchList patchlist ) 
    {
        patchList tmp = (patchList)checked_malloc(sizeof(*tmp));
        tmp->head = head ;
        tmp->tail = patchlist ;
        return tmp ;
    }
    
    Tr_expList Tr_ExpList(Tr_exp head , Tr_expList tail)
    {
        Tr_expList tmp = (Tr_expList)checked_malloc(sizeof(*tmp)) ;
        tmp->head = head ;
        tmp->tail = tail ;
        return tmp ;
    }
    
    Tr_exp Tr_nilExp()
    {
        static Temp_temp temp =  NULL  ;
            if ( !temp )
            {
               temp = Temp_newtemp() ;
               T_stm alloc = T_Move(T_Temp(temp),
                   T_Call(T_Name(Temp_namedlabel("initRecord")), T_ExpList(T_Const(0), NULL)));
               return Tr_Ex(T_Eseq(alloc, T_Temp(temp)));
            }
    
         return Tr_Ex(T_Temp(temp)) ;
    }
    
    Tr_exp Tr_intExp(int i)
    {
        return  Tr_Ex(T_Const(i)) ;
    }
    
    static F_fragList stringFragList = NULL;
    Tr_exp Tr_stringExp(string s) 
    { 
        Temp_label slabel = Temp_newlabel();
        F_frag fragment = F_StringFrag(slabel, s);
        stringFragList = F_FragList(fragment, stringFragList);
        return Tr_Ex(T_Name(slabel));
    }
    
    Tr_exp Tr_simpleVar(Tr_access acc, Tr_level level)
    {
        T_exp tmp = T_Temp(F_FP());
        while ( level && level != acc->level->parent )
        {
            tmp = T_Mem(T_Binop(T_plus, T_Const(level->frame->formals->head->u.offset), tmp));
            level = level->parent;
        }
        
        return  Tr_Ex(F_Exp(acc->access, tmp));
    }
    
    Tr_exp Tr_subscriptVar(Tr_exp base, Tr_exp index )
    {
        return Tr_Ex(T_Mem(T_Binop(T_plus, Tr_unEx(base), T_Binop(T_mul, Tr_unEx(index), T_Const(F_wordSize)))));
    }
    
    Tr_exp Tr_fieldVar(Tr_exp base, int offset)
    {
        return Tr_Ex(T_Mem(T_Binop(T_plus, Tr_unEx(base), T_Const(offset * F_wordSize))));
    }
    
    Tr_exp Tr_binopExp(Tr_exp left , Tr_exp right ,A_oper oper )
    {
        T_binOp op ;
        switch(oper)
        {
        case A_plusOp   :
            {
                op = T_binOp::T_plus ;
                break ;
            }
        case A_minusOp  :
            {
                op = T_binOp::T_minus ;
                break ;
            }
        case A_timesOp  :
            {
                op = T_binOp::T_mul ;
                break ;
            }
        case A_divideOp :
            {
                op = T_binOp::T_div ;
                break ;
            }
        default :
            {
                return NULL ;
            }
        }
       return Tr_Ex(T_Binop(op , Tr_unEx(left) , Tr_unEx(right))) ;
    }
    Tr_exp  Tr_relopExp(Tr_exp left , Tr_exp right , A_oper oper) 
    {
        T_relOp op ;
        switch(oper)
        {
         case A_ltOp :
             {
                 op = T_relOp::T_lt ;
                 break ;
             }
         case A_leOp :
             {
                 op = T_relOp::T_le ;
                 break ;
             }
         case A_gtOp :
             {
                 op = T_relOp::T_gt ;
                 break ;
             }
         case A_geOp :
             {
                  op = T_relOp::T_ge ;
                 break ;
             }
         case A_eqOp :
             {
                 op = T_relOp::T_eq ;
                 break ;
             }
         case A_neqOp :
             {
                 op = T_relOp::T_ne ;
                 break ;
             }
         default :
             return NULL ;
        }
        T_stm stm = T_Cjump(op ,Tr_unEx(left) , Tr_unEx(right) , NULL , NULL );
        patchList trues =  PatchList(&stm->u.CJUMP.trues , NULL) ;
        patchList falses =  PatchList(&stm->u.CJUMP.falses , NULL) ;
        return  Tr_Cx(trues , falses , stm) ;
    }
    
    Tr_exp Tr_ifExp( Tr_exp test , Tr_exp then , Tr_exp elses ) 
    {
    
       Cx ctest  = Tr_unCx(test) ;
       T_stm reslutstm , thenstm , elsestm  ;
       reslutstm = thenstm = elsestm = NULL ;
       Temp_label t = Temp_newlabel() ;
       Temp_label f = Temp_newlabel() ;
       Temp_temp v = Temp_newtemp() ; 
        doPatch(ctest.falses , f) ;
        doPatch(ctest.trues , t ) ; 
            switch(then->kind)
            {
            case GetExpEx :
                {
                    thenstm = T_Seq(ctest.stm , T_Seq(T_Label(t) , T_Move(T_Temp(v) , Tr_unEx(then)))) ;
                    break ;
                }
            case GetExpNx :
                {
                    thenstm = T_Seq(ctest.stm ,T_Seq(T_Label(t) , then->u.nx)) ;
                    break ;
                }
            case GetExpCx :
                {
                    
                    thenstm = T_Seq(ctest.stm , T_Seq(T_Label(t) , Tr_unNx(then))) ;
                    break ;
                }
            }
    
       if (elses)
       {
           switch(elses->kind)
           {
           case GetExpEx:
               {
                   elsestm = T_Move(T_Temp(v), Tr_unEx(elses)) ;
                   break ;
               }
           case GetExpNx :
               {
                   elsestm = elses->u.nx ;
                   break ;
               }
           case GetExpCx :
               {
                  elsestm = Tr_unNx(elses) ;
                  break ;
               }
           }
       }
       if (elsestm)
       {
           Temp_label jump = Temp_newlabel() ;
           
           return Tr_Nx(T_Seq(
               T_Seq( thenstm , T_Seq(T_Jump( T_Name(jump) , Temp_LabelList(jump , NULL)) ,T_Seq(T_Label(f) ,elsestm))) ,
               T_Label(jump))) ;
       }
            return Tr_Nx( T_Seq(thenstm , T_Label(f))) ; 
    }
    
    Tr_exp Tr_recordExp( Tr_expList explist , int num)  //’‚¿Ô¥´Ω¯¿¥µƒexplist ∫Õ’Ê «µƒexplist «œ‡∑¥µƒ
    {
       T_stm stm ;
       Temp_temp t = Temp_newtemp();
       T_exp callfun = T_Call(T_Name(Temp_namedlabel("initRecord")) ,T_ExpList(T_Const(num*F_wordSize) , NULL)) ;
    
       stm = T_Move(T_Mem(T_Binop(T_plus , T_Temp(t) , T_Const((num - 1)*F_wordSize))), Tr_unEx(explist->head)) ;
       num-- ;
       explist = explist->tail ;
       while(explist)
       {
         stm = T_Seq(T_Move(T_Mem(T_Binop(T_plus, T_Temp(t) , T_Const((num -1 ) * F_wordSize))), Tr_unEx(explist->head)),stm) ;
         explist = explist->tail ;
         num-- ;
       }
       stm = T_Seq(T_Move(T_Temp(t) , callfun) , stm) ;
       return Tr_Ex( T_Eseq( stm , T_Temp(t))) ;
    }
    
    
    Tr_exp Tr_arryExp(Tr_exp index , Tr_exp init)
    {
        Temp_temp t = Temp_newtemp() ;
        T_exp callfun = T_Call(T_Name(Temp_namedlabel("initArray")) ,T_ExpList( Tr_unEx(index),T_ExpList(Tr_unEx(init) ,NULL))) ;
        return  Tr_Nx( T_Move( T_Temp(t) , callfun) );
    }
     
    Tr_exp Tr_seqExp(Tr_expList explist)
    {
        if (!explist)
        {
            return NULL ;
        }
        T_stm stm = Tr_unNx(explist->head) ;
        explist = explist->tail ;
        while(explist)
        {
            stm = T_Seq( Tr_unNx(explist->head) , stm) ;
            explist = explist->tail ;
        }
        return Tr_Nx(stm) ;
    }
    
    Tr_exp Tr_assignExp(Tr_exp exp1 , Tr_exp exp2)
    {
        return Tr_Nx(T_Move(T_Mem( Tr_unEx(exp1)) , T_Mem(Tr_unEx(exp2))))  ;
    }
    
    Tr_exp Tr_letExp(Tr_expList declist , Tr_exp exp )
    {
        if (!declist)
        {
            return NULL ;
        }
        T_stm stm = Tr_unNx(declist->head) ;
        declist = declist->tail ;
        while(declist)
        {
            stm = T_Seq(Tr_unNx(declist->head) , stm) ;
            declist = declist->tail ;
        }
        if (exp)
        {
            stm = T_Seq(stm , Tr_unNx(exp)) ;
        }
        return Tr_Nx(stm);
    }
    
    Tr_exp Tr_whileExp(Tr_exp test , Tr_exp body , bool isbreak)
    {
      
        Cx ctest = Tr_unCx(test) ;
        Temp_label t = Temp_newlabel() ;
        Temp_label done = Temp_namedlabel("done") ;
        doPatch(ctest.falses , done) ;
        doPatch(ctest.trues , t) ;
        T_stm  stm ;
        Temp_label testlabel = Temp_newlabel();
        
        stm = T_Seq(T_Label(t) , T_Seq(Tr_unNx(body) ,T_Jump(T_Name(testlabel),Temp_LabelList(testlabel,NULL)))) ;
        stm = T_Seq( T_Label(testlabel) , T_Seq(ctest.stm ,T_Seq(stm , T_Label(done)))) ;
        return Tr_Nx(stm);
    }
    
    Tr_exp Tr_breakExp()
    {
        Temp_label done = Temp_namedlabel("done") ;
        return Tr_Nx(T_Jump(T_Name(done) , Temp_LabelList(done , NULL))) ;
    }
    
    Tr_exp Tr_forExp(Tr_access acc , Tr_exp hi , Tr_exp low , Tr_exp body)
    {
        T_exp tmp = T_Temp(F_FP());
         //tmp = T_Mem(T_Binop(T_plus ,tmp , T_Const(acc->level->frame->formals->head->u.offset))) ;
          T_exp memt =  F_Exp(acc->access , tmp) ;
        T_stm stm = T_Move(memt , Tr_unEx(low)) ;
        Temp_temp h = Temp_newtemp() ;
        T_stm limit = T_Move(T_Temp(h) , Tr_unEx(hi)) ;
        Cx cx ;
        cx.stm =  T_Cjump(T_lt ,memt ,T_Temp(h) , NULL , NULL) ;
        cx.falses = PatchList(&cx.stm->u.CJUMP.falses , NULL) ;
        cx.trues = PatchList(&cx.stm->u.CJUMP.trues , NULL) ;
        T_stm finalbody = T_Seq(T_Move(memt , T_Binop(T_plus , memt , T_Const(1))) , Tr_unNx(body)) ;
        
        Tr_exp tmpwhile = Tr_whileExp(Tr_Cx(cx.trues , cx.falses , cx.stm) , Tr_Nx(finalbody) , false) ;
        return  Tr_Nx(T_Seq( stm , T_Seq( limit , Tr_unNx(tmpwhile)))) ;
    }
     Tr_exp Tr_StaticLink(Tr_level now, Tr_level def)
     {
        T_exp addr = T_Temp(F_FP());
        while(now && (now != def->parent)) 
        { 
            F_access sl = F_formals(now->frame)->head;
            addr = F_Exp(sl, addr);
            now = now->parent;
        }
        return Tr_Ex(addr);
    }
    Tr_exp Tr_callExp(Temp_label label ,Tr_level funleve , Tr_level  level ,Tr_expList explist ) 
    {
        T_expList tmplist = NULL;
        while(explist)
        {
            tmplist = T_ExpList( Tr_unEx(explist->head) , tmplist) ;
            explist = explist->tail ;
        }
        tmplist = T_ExpList(Tr_unEx(Tr_StaticLink(funleve , level)) , tmplist) ;
        T_exp callfun = T_Call(T_Name(label) ,tmplist) ;
        return Tr_Ex(callfun) ;
    }
    Tr_exp Tr_callExp(E_enventry entry , Tr_level level , Tr_expList explist  ) 
    {
        
         T_expList tmplist = NULL;
         while(explist)
         {
             tmplist = T_ExpList( Tr_unEx(explist->head) , tmplist) ;
             explist = explist->tail ;
         }
         tmplist = T_ExpList(Tr_unEx(Tr_StaticLink(entry->u.fun.level , level)) , tmplist) ;
        T_exp callfun = T_Call(T_Name(entry->u.fun.label) ,tmplist) ;
        return Tr_Ex(callfun) ;
    }
    
    Tr_exp Tr_varDec(Tr_access acc , Tr_exp init)
    {
        T_exp tmp = T_Temp(F_FP());
        T_exp memt =  F_Exp(acc->access , tmp) ;
        return Tr_Nx(T_Move(memt , Tr_unEx(init)))  ;
    }
    
    Tr_exp Tr_typeDec()
    {
         return Tr_Ex(T_Const(0)) ;
    }
    
    Tr_exp Tr_funDec(Tr_expList bodylist)
    {
        T_stm stm ;
        stm = T_Move(T_Temp(F_RV()) , Tr_unEx(bodylist->head)) ;
        bodylist = bodylist->tail ;
        while (bodylist)
        {
          stm = T_Seq(T_Move(T_Temp(F_RV()) , Tr_unEx(bodylist->head)) , stm);
        }
        return Tr_Nx(stm) ;
    }
    #ifndef SENMANT_H_
    #define SENMANT_H_
    #include "types.h"
    #include "translate.h"
    #include "absyn.h"
    struct expty { Tr_exp exp ; Ty_ty ty; };
    expty expTy(Tr_exp exp , Ty_ty ty) ;
    expty  transVar(S_table venv , S_table tenv , A_var var , Tr_level level) ;
    expty  transExp(S_table venv , S_table tenv , A_exp exp , Tr_level level  ) ; //∑µªÿ÷µ÷–µƒtyty“ª∂® «◊ÓµÕ≤„µƒ¿‡–Õ
    Tr_exp   transDec(S_table venv , S_table tenv , A_dec dec , Tr_level level ) ;
    Ty_ty  transTy( S_table tenv , A_ty ty) ;
    //ƒ⁄÷√±Í æ∑˚ºÏ≤‚ int string ÷ª”√‘⁄œÚ÷µª∑æ≥ ‰»Î÷µµƒ ±∫Ú≤≈ºÏ≤‚  ¿‡–Õª∑æ≥‘⁄ tranTy÷–“—æ≠ºÏ≤‚
    bool  innerIdentifiers( S_symbol sym);
    #endif
    #include "semant.h"
    #include <assert.h>
    #include "env.h"
    
    expty expTy(Tr_exp exp , Ty_ty ty)
    {
        expty e ;
        e.exp = exp ; e.ty = ty ;
        return e ;
    }
    
    expty  transExp(S_table venv , S_table tenv , A_exp exp  , Tr_level level )  // done  «Œ™¡ÀºÏ≤‚break «∑Ò‘⁄’˝»∑µƒŒª÷√
    {
        static bool done  = false ;
      if (exp == NULL )
      {
          assert(0);
      }
       switch(exp->kind)
       {
       case  A_varExp :
               return transVar(venv , tenv , exp->u.var , level ) ;
       case  A_nilExp :
              return expTy( Tr_nilExp() ,Ty_Nil());
       case  A_intExp :  // ’‚¿Ôµƒint «Àµµƒ’˚–Õ≥£¡ø ∂¯≤ª «int¿‡–Õ
              return expTy( Tr_intExp(exp->u.intt) , Ty_Int()) ;
       case  A_stringExp ://’‚¿Ôµƒstring  «Àµµƒ◊÷∑˚¥Æ≥£¡ø ∂¯≤ª «string¿‡–Õ
              return expTy( Tr_stringExp(exp->u.stringg) , Ty_String()) ;
       case  A_callExp :
              {
                  E_enventry tmp = (E_enventry)S_look(venv, exp->u.call.func) ;
                  if (tmp == NULL)
                  {
                      assert(0) ;
                  }
                  Ty_tyList tylist  = tmp->u.fun.formals ;
                  A_expList explist = exp->u.call.args ;
                  Tr_expList trexplist = NULL ;
                  while (tylist != NULL && explist != NULL)
                  {
                      expty exptyp = transExp(venv , tenv , explist->head , level) ;
                     
                      if (exptyp.ty->kind == Ty_ty_::Ty_nil)
                      {
                          continue ;
                      }
                       if (!isTyequTy(tylist->head , exptyp.ty))
                       {
                           assert(0) ;
                       }
                        trexplist = Tr_ExpList(exptyp.exp , trexplist) ;
                      tylist = tylist->tail ;  explist = explist->tail ;
                  }
                  if (tylist != NULL || explist != NULL )
                  {
                      assert(0);
                  }
    
                  return expTy(Tr_callExp(tmp->u.fun.label , tmp->u.fun.level , level , trexplist) , actrulyTy(tmp->u.fun.result)) ; 
              }
       case  A_opExp :
              {
                  expty tmpleft = transExp(venv , tenv, exp->u.op.left , level ) ;
                  expty tmpright = transExp(venv , tenv, exp->u.op.right , level ) ;
                  switch(exp->u.op.oper)
                  {
                  case A_plusOp   : 
                  case A_minusOp  : 
                  case A_timesOp  : 
                  case A_divideOp : 
                      {
    
                          if (tmpleft.ty->kind != Ty_ty_::Ty_int)
                              assert(0);
                          if (tmpright.ty->kind != Ty_ty_::Ty_int)
                              assert(0);   
                           return expTy(Tr_binopExp(tmpleft.exp , tmpright.exp ,exp->u.op.oper) , Ty_Int()) ; 
                      }
                  case A_ltOp     : 
                  case A_leOp     : 
                  case A_gtOp     : 
                  case A_geOp     : 
                         {
                             if (tmpleft.ty->kind != Ty_ty_::Ty_int)
                                 assert(0);
                             if (tmpright.ty->kind != Ty_ty_::Ty_int)
                                 assert(0);   
                             return expTy(Tr_relopExp(tmpleft.exp , tmpright.exp , exp->u.op.oper) , Ty_Int()) ;
                         }
                  case A_eqOp :
                  case A_neqOp: 
                         {
                             if (tmpleft.ty->kind == Ty_ty_::Ty_int
                                 && tmpright.ty->kind == Ty_ty_::Ty_int)
                                 return expTy(Tr_relopExp(tmpleft.exp , tmpright.exp , exp->u.op.oper)  , Ty_Int()) ;
                             if (tmpleft.ty->kind == tmpright.ty->kind)
                             {
                                 if (tmpleft.ty->kind == Ty_ty_::Ty_record || tmpleft.ty->kind == Ty_ty_::Ty_array)
                                 {
                                     if ( tmpleft.ty == tmpright.ty )
                                     {
                                         return expTy(Tr_relopExp(tmpleft.exp , tmpright.exp , exp->u.op.oper) , Ty_Int()) ;
                                     }
                                 }
                             }
                             assert(0);
                         }
                  }
                  assert(0);
              }
       case  A_recordExp :
              {
                  Ty_ty tmpty = (Ty_ty)S_look(tenv , exp->u.record.typ) ;
                   tmpty = actrulyTy(tmpty) ;
                   if (tmpty == NULL )
                   {
                       assert(0) ;
                   }
                  if (tmpty->kind != Ty_ty_::Ty_record )
                  {
                      assert(0) ;
                  }
                  A_efieldList tmpefield = exp->u.record.fields ;
                  Ty_fieldList tmpfieldlist = tmpty->u.record ;
                  Tr_expList trexplist = NULL ;
                  int num = 0 ;
                  while(tmpefield && tmpfieldlist)
                  {    
                       expty tmp = transExp(venv , tenv , tmpefield->head->exp , level) ;
                      if (tmpefield->head->name != tmpfieldlist->head->name )
                      {
                          assert(0) ;
                      }
                      if (!isTyequTy(tmp.ty ,tmpfieldlist->head->ty))
                      {
                          assert(0) ;
                      }
                      trexplist = Tr_ExpList(tmp.exp , trexplist) ;
                      tmpefield = tmpefield->tail ; tmpfieldlist = tmpfieldlist->tail ; 
                      num ++;
                  }
                  if (tmpfieldlist!= NULL || tmpefield != NULL )
                  {
                      assert(0) ;
                  }
                  expty tmp = expTy(Tr_recordExp(trexplist,num),tmpty));
    Tr_FreeExplist(trexplist) ; // 只释放链表结构 不释放内容(hand)
    return tmp ; } case A_seqExp : { A_expList explist = exp->u.seq ; Tr_expList trexplist = NULL ; if (explist) { while(explist->tail) { trexplist = Tr_ExpList(transExp( venv , tenv , explist->head , level).exp , trexplist) ; explist = explist->tail ; } } else { return expTy( Tr_seqExp(trexplist) , Ty_Void()); } expty tmp = transExp(venv , tenv , explist->head , level) ; trexplist = Tr_ExpList(tmp.exp , trexplist) ;
    Tr_FreeExplist(trexplist) ; //只释放链表结构 不是放内容(hand)
    return expTy(Tr_seqExp(trexplist) , tmp.ty); } case A_assignExp : { expty tmpV = transVar(venv , tenv , exp->u.assign.var , level) ; expty tmpE = transExp(venv , tenv , exp->u.assign.exp , level); if (tmpE.ty->kind != tmpV.ty->kind) { assert(0); } return expTy(Tr_assignExp(tmpV .exp , tmpE.exp) , Ty_Void()); } case A_ifExp : { expty tmptest = transExp(venv ,tenv , exp->u.iff.test , level) ; if(tmptest.ty->kind != Ty_ty_::Ty_int) { assert(0); } expty tmpthen = transExp(venv , tenv , exp->u.iff.then , level ) ; if (exp->u.iff.elsee != NULL) { expty tmpelse = transExp(venv , tenv , exp->u.iff.elsee , level) ; if ( tmpthen.ty != tmpelse.ty ) { assert(0); } return expTy( Tr_ifExp(tmptest.exp , tmpthen.exp , tmpelse.exp) , tmpelse.ty); } if (tmpthen.ty->kind != Ty_ty_::Ty_void) { assert(0); } return expTy(Tr_ifExp(tmptest.exp , tmpthen.exp , NULL) , Ty_Void()); } case A_whileExp : { expty test = transExp(venv , tenv , exp->u.whilee.test , level ); if (test.ty->kind != Ty_ty_::Ty_int) { assert(0) ; } expty body = transExp(venv , tenv , exp->u.whilee.body , level ); if ( done ) { // Àµ√˜’‚¿Ô√Ê”–break done = false ; } /* if (body.ty->kind != Ty_ty_::Ty_void) { assert(0); }*/ return expTy(Tr_whileExp(test.exp , body.exp , false) , Ty_Void()); } case A_forExp : { expty tmplo = transExp(venv , tenv , exp->u.forr.lo , level ); expty tmphi = transExp(venv , tenv , exp->u.forr.hi ,level ); S_beginScope(venv); Tr_access acc; acc = Tr_allocLocal(level , exp->u.forr.escape); // forŒ™ ≤√¥“™”–Ô“›£ø£ø£ø£ø£ø S_enter(venv , exp->u.forr.var , E_VarEntry( acc ,Ty_Int())); expty tmpbody = transExp(venv , tenv, exp->u.forr.body , level); if (tmplo.ty->kind != Ty_ty_::Ty_int || tmphi.ty->kind != Ty_ty_::Ty_int ) { assert(0); } S_endScope(venv); return expTy(Tr_forExp(acc, tmphi.exp , tmplo.exp , tmpbody.exp) , Ty_Void()); } case A_breakExp : { done = true ; return expTy(Tr_breakExp() , Ty_Void()); } case A_letExp : { S_beginScope(venv); S_beginScope(tenv); A_decList declist = exp->u.let.decs ; Tr_expList trexplist = NULL ; while(declist != NULL) { trexplist = Tr_ExpList(transDec(venv , tenv , declist->head , level) , trexplist) ; declist = declist->tail; } expty tmp ; if (exp->u.let.body) { tmp = transExp(venv , tenv , exp->u.let.body , level); tmp = expTy(Tr_letExp(trexplist , tmp.exp) , tmp.ty) ; } else { tmp = expTy(Tr_letExp(trexplist , NULL) , Ty_Void()) ; }
    Tr_FreeExplist(trexplist) ;//只释放链表结构,不是放链表内容(hand) S_endScope(venv); S_endScope(tenv);
    return tmp ; } case A_arrayExp : { Ty_ty ty = (Ty_ty)S_look(tenv , exp->u.array.typ); ty = actrulyTy(ty); if (ty == NULL || ty->kind != Ty_ty_::Ty_array) { assert(0); } expty tynum = transExp(venv , tenv , exp->u.array.size , level ); if (tynum.ty->kind != Ty_ty_::Ty_int) { assert(0); } expty tyinit = transExp(venv , tenv, exp->u.array.init , level ) ; if (tyinit.ty != ty->u.array ) { assert(0) ; } return expTy(Tr_arryExp(tynum.exp, tyinit.exp) , ty); } } assert(0); } expty transVar(S_table venv , S_table tenv , A_var var , Tr_level level) { switch(var->kind) { case A_simpleVar : { E_enventry tmp = (E_enventry) S_look(venv , var->u.simple) ; if (tmp != NULL && tmp->kind == E_enventry_::E_varEntry) { return expTy(Tr_simpleVar(tmp->u.var.access , level), actrulyTy(tmp->u.var.ty)) ; } assert(0) ; } case A_fieldVar : { expty tmpty = transVar(venv , tenv , var->u.field.var , level) ; if (tmpty.ty->kind != Ty_ty_::Ty_record) { assert(0); } Ty_fieldList fieldList = tmpty.ty->u.record ; int num = 0; while( fieldList ) { if ( fieldList->head->name == var->u.field.sym ) { return expTy(Tr_fieldVar(tmpty.exp ,num) , actrulyTy(fieldList->head->ty)) ; } num ++ ; fieldList = fieldList->tail ; } assert(0); } case A_subscriptVar : { expty tmp = transVar(venv , tenv , var->u.subscript.var , level) ; if (tmp.ty->kind != Ty_ty_::Ty_array ) { assert(0) ; } expty tmpexp = transExp(venv , tenv , var->u.subscript.exp , level ) ; if (tmpexp.ty->kind != Ty_ty_::Ty_int) { assert(0) ; } return expTy(Tr_subscriptVar(tmp.exp ,tmpexp.exp) , tmp.ty) ; } } assert(0) ; } Tr_exp transDec(S_table venv , S_table tenv , A_dec dec , Tr_level level) { switch(dec->kind) { case A_functionDec : { A_fundecList tmpfun = dec->u.function ; Tr_level newlevel ; Tr_access acce ; U_boolList boollist = NULL ; Ty_ty reslut = NULL ; while(tmpfun) { A_fieldList tmpfeldList = tmpfun->head->params ; Ty_tyList tylist = NULL ; while(tmpfeldList) { Ty_ty ty = (Ty_ty)S_look(tenv,tmpfeldList->head->typ); if (ty == NULL ) { assert(0) ; } tylist = Ty_TyList(ty , tylist) ; tmpfeldList = tmpfeldList->tail ; boollist = U_BoolList(true , boollist) ; } if (innerIdentifiers(tmpfun->head->name)) { assert(0) ; } //¿‡À∆”⁄…˘√˜“ª∏ˆ∫Ø ˝ ªπ√ª”–∂®“ÂÀ¸ newlevel = Tr_newLevel(level ,Temp_newlabel() ,boollist); reslut = (Ty_ty)S_look(tenv ,tmpfun->head->result) ; if (reslut == NULL ) { reslut = Ty_Void() ; } S_enter(venv , tmpfun->head->name , E_FunEntry( newlevel, newlevel->frame->name , tylist , reslut)) ; tmpfun = tmpfun->tail ; U_ClearBoolList(boollist) ; // “ÚŒ™÷ª «”√¡Àbool ≤¢√ª”–±£¥ÊÀ¸ À˘“‘ªπ“™ Õ∑≈“ªœ¬ boollist = NULL ; } tmpfun = dec->u.function ; E_enventry funEntry; Tr_accesslist tr_acceselist , tmpacclist ; Tr_expList trexplist = NULL ; while(tmpfun) { S_beginScope(venv) ; funEntry = (E_enventry) S_look(venv , tmpfun->head->name) ; tmpacclist = tr_acceselist = Tr_formals(funEntry->u.fun.level) ; A_fieldList tmpfeldList = tmpfun->head->params ; // ’‚¿Ô“™øº¬«µΩparamsµƒ…˙≥…∑Ω Ω »Áπ˚∫Õtr_accesslist≤ª“ª÷¬“™∏ƒ“ªœ¬ while(tmpfeldList) { Ty_ty ty = (Ty_ty)S_look(tenv,tmpfeldList->head->typ); if (innerIdentifiers(tmpfeldList->head->name)) { assert(0); } S_enter(venv ,tmpfeldList->head->name, E_VarEntry(tmpacclist->head,ty)) ; tmpfeldList = tmpfeldList->tail ; tmpacclist = tmpacclist->tial ; } expty tmp = transExp(venv , tenv , tmpfun->head->body , newlevel) ; trexplist = Tr_ExpList(tmp.exp , trexplist) ; if (tmp.ty != actrulyTy(funEntry->u.fun.result)) { assert(0) ; } Tr_ClearAcces(tr_acceselist) ; //÷ª π”√¡Àhead tail≤ø∑÷«Â¿Ì∏…æª S_endScope(venv) ; tmpfun = tmpfun->tail ; } return Tr_funDec(trexplist) ; } case A_typeDec : { A_nametyList namelist = dec->u.type ; while(namelist) { if (innerIdentifiers(namelist->head->name)) { assert(0) ; } // ¥¶¿Ìµ›πÈ ¿‡À∆”⁄ …˘√˜“ª∏ˆ¿‡–Õ µ´ «ªπ√ª”–∂®“ÂÀ¸ S_enter(tenv , namelist->head->name ,Ty_Name(namelist->head->name , NULL)) ; namelist = namelist->tail ; } namelist = dec->u.type ; while(namelist) { // ¥¶¿Ìµ›πÈ Ty_ty tmp1 = transTy(tenv , namelist->head->ty ) ; Ty_ty tmp2 = (Ty_ty)S_look(tenv , namelist->head->name) ; if ( tmp1->kind == Ty_ty_::Ty_int || tmp1->kind == Ty_ty_::Ty_string || tmp1->kind == Ty_ty_::Ty_nil || tmp1->kind == Ty_ty_::Ty_void) { //ƒ⁄÷√¿‡–Õ π”√µƒ «Õ¨“ª«¯”Úƒ⁄¥Ê Œ™¡À±£≥÷ø…“‘æ≠––÷∏’僱»ΩœæÕ÷±Ω”»∑∂® «∑ÒŒ™Õ¨“ª∏ˆ¿‡–Õ ƒ«√¥æÕ“™÷±Ω”∞—∞Û∂®∏¯ªª¡À tmp2 = (Ty_ty)S_changeBind(tenv , namelist->head->name , tmp1); tmp2 = (Ty_ty)freeTy(tmp2) ; } else { //»Áπ˚≤ª «’‚Àƒ÷÷ƒ⁄÷√¿‡–Õ “™œ˙ªŸ tyCpy(tmp2 , tmp1) ; tmp1 = (Ty_ty)freeTy(tmp1) ; } namelist = namelist->tail ; } namelist = dec->u.type; while(namelist) { // ¥¶¿Ì —≠ª∑µ›πÈ ¿˝»Á type a = b type b = a Ty_ty tmp = (Ty_ty)S_look(tenv , namelist->head->name) ; if (!actrulyTy(tmp)) { assert(0) ; } namelist = namelist->tail ; } return Tr_typeDec(); } case A_varDec : { if(dec->u.var.init == NULL) { assert(0) ; } expty tmp = transExp(venv , tenv , dec->u.var.init , level ) ; if( (dec->u.var.typ != NULL) ) { if ( actrulyTy((Ty_ty)S_look(tenv ,dec->u.var.typ)) != tmp.ty) { assert(0) ; } } if (innerIdentifiers(dec->u.var.var)) { assert(0) ; } Tr_access acc = Tr_allocLocal(level , dec->u.var.escape) ; S_enter(venv , dec->u.var.var ,E_VarEntry( acc ,tmp.ty)) ; return Tr_varDec(acc , tmp.exp); } } assert(0) ; } Ty_ty transTy(S_table tenv , A_ty ty) { switch(ty->kind) { case A_nameTy : { if (S_Symbol("int") == ty->u.name) { return Ty_Int(); } if (S_Symbol("string") == ty->u.name) { return Ty_String(); } Ty_ty tmp = (Ty_ty)S_look(tenv , ty->u.name) ; if ( tmp == NULL ) { assert(0) ; } return Ty_Name(ty->u.name , tmp) ; } case A_recordTy : { A_fieldList tmpfeldList = ty->u.record ; Ty_fieldList tyfdlist = NULL ; while(tmpfeldList) { Ty_ty tmp = (Ty_ty)S_look(tenv , tmpfeldList->head->typ) ; if ( tmp == NULL ) { assert(0) ; } if (innerIdentifiers(tmpfeldList->head->name)) { assert(0); } tyfdlist = Ty_FieldList(Ty_Field( tmpfeldList->head->name , tmp) , tyfdlist) ; tmpfeldList = tmpfeldList->tail ; } return Ty_Record(tyfdlist); } case A_arrayTy : { Ty_ty tmp = (Ty_ty)S_look(tenv , ty->u.array); if ( tmp == NULL ) { assert(0); } return Ty_Array(tmp) ; } } assert(0) ; } bool innerIdentifiers( S_symbol sym) { if (sym == S_Symbol("int") || sym == S_Symbol("string") ) { return true ; } return false ; }
  • 相关阅读:
    快速指引(CDH6.3.2)
    gRpc 跨语言调用(NetCore 与 Spring Boot)
    Windows 极简利器
    Jenkins 于Docker 中源配置
    Kettle 问题
    在 Ubuntu 下直接将二进制文件制作成 rpm 包
    麒麟常见问题
    基于jssip的简单封装
    带有handleEvent的eventEmitter
    js集锦
  • 原文地址:https://www.cnblogs.com/BlackWalnut/p/4559717.html
Copyright © 2020-2023  润新知