+ | trans_exp env vartypes (A.Marked(marked_exp)) =
+ trans_exp env vartypes (Mark.data marked_exp)
+ | trans_exp env vartypes (A.FuncCall(func, stms)) =
+ T.CALL(func,
+ List.map
+ (fn exp => (trans_exp env vartypes exp, Temp.sts (Type.size (typeof' vartypes exp))))
+ stms,
+ Temp.sts (Type.size (AstUtils.Function.returntype (Symbol.look' funcs func))))
+ | trans_exp env vartypes (A.Member (exp, id)) =
+ let
+ val apk = T.BINOP (T.ADD, trans_exp env vartypes exp, T.CONST (Word32.fromInt (offset_s id (typeof' vartypes exp))))
+ val tipo = type_s id (typeof' vartypes exp)
+ in
+ if Type.issmall tipo
+ then T.MEMORY(apk, Temp.sts (Type.size tipo))
+ else apk
+ end
+ | trans_exp env vartypes (A.DerefMember (exp, id)) =
+ trans_exp env vartypes (A.Member (A.Dereference (exp), id))
+ | trans_exp env vartypes (A.Dereference(exp)) =
+ if (Type.issmall (deref (typeof' vartypes exp)))
+ then T.MEMORY(trans_exp env vartypes exp, Temp.sts (Type.size (deref (typeof' vartypes exp))))
+ else trans_exp env vartypes exp
+ | trans_exp env vartypes (A.ArrIndex(exp1, exp2)) =
+ let
+ val asubk = T.BINOP(T.ADD, trans_exp env vartypes exp1,
+ T.BINOP(T.MUL, trans_exp env vartypes exp2,
+ T.CONST(Word32.fromInt(sizeof (deref (typeof' vartypes exp1))))))
+ val tipo = deref (typeof' vartypes exp1)
+ val d =
+ if not (Flag.isset Flags.safe)
+ then asubk
+ else T.COND (T.BINOP
+ (T.BE,
+ T.MEMORY (T.BINOP (
+ T.SUB,
+ trans_exp env vartypes exp1,
+ T.CONST 0w8), Temp.Long),
+ trans_exp env vartypes exp2),
+ T.NULLPTR,
+ asubk)
+ in
+ if Type.issmall tipo
+ then T.MEMORY(d, Temp.sts (Type.size tipo))
+ else d
+ end
+ | trans_exp env vartypes (A.New(tipo)) =
+ let
+ val t1 = T.TEMP (Temp.new "result" Temp.Quad)
+ in
+ T.STMVAR (
+ [T.MOVE (t1, T.ALLOC (T.CONST (Word32.fromInt(sizeof tipo)))),
+ T.EFFECT (T.MEMORY (t1, Temp.Long))],
+ t1)
+ end
+ | trans_exp env vartypes (A.NewArr(tipo, exp)) =
+ let
+ val size = T.BINOP(T.MUL, trans_exp env vartypes exp, T.CONST(Word32.fromInt(sizeof tipo)))
+ val t1 = T.TEMP (Temp.new "allocated address" Temp.Quad)
+ val ts = T.TEMP (Temp.new "size" Temp.Long)
+ in
+ if not (Flag.isset Flags.safe)
+ then T.STMVAR ([T.MOVE (t1, T.ALLOC size),
+ T.EFFECT (T.COND (T.BINOP (T.EQ, trans_exp env vartypes exp, T.CONST 0w0), T.CONST 0w0, T.MEMORY (t1, Temp.Long)))],
+ t1)
+ else T.COND (T.BINOP(T.EQ, size, T.CONST 0w0),
+ T.NULLPTR,
+ T.STMVAR (
+ [T.MOVE(t1,
+ T.COND(
+ T.BINOP(T.LT, size, T.CONST 0w0),
+ T.NULLPTR,
+ T.ALLOC (T.BINOP (T.ADD, size, T.CONST 0w8)))
+ ),
+ T.MOVE(T.MEMORY (t1, Temp.Long), trans_exp env vartypes exp)],
+ T.BINOP(T.ADD, t1, T.CONST 0w8)))
+ end
+ | trans_exp env vartypes (A.Null) = T.NULLPTR
+ | trans_exp env vartypes (A.Conditional(c,e1,e2)) = T.COND(trans_exp env vartypes c, trans_exp env vartypes e1, trans_exp env vartypes e2)