jacksplwxy

现代编译原理——第六章:中间树 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 ; }
复制代码

 

posted on 2018-12-02 11:49  jacksplwxy  阅读(814)  评论(0编辑  收藏  举报

导航