public static CanonizedExp Combine(CanonizedExp b1, CanonizedExp b2, Func <TreeExp, TreeExp, TreeExp> f) { CanonizedExp c = Compose(b1, b2.Body); return(new CanonizedExp(c.Body, f(c.Exp, b2.Exp))); }
public static List <TreeStm> ToStm(CanonizedExp b1, CanonizedExp b2, Func <TreeExp, TreeExp, TreeStm> f) { CanonizedExp c = Compose(b1, b2.Body); List <TreeStm> res = new List <TreeStm>(c.Body); res.Add(f(c.Exp, b2.Exp)); return(res); }
private CanonizedExp CanonExpression(TreeExp exp) { switch (exp) { case ExpCall call: { CanonizedExp cfunc = CanonNoTopCall(call.Function); List <CanonizedExp> cargs = new List <CanonizedExp>(); foreach (var arg in call.Args) { cargs.Add(CanonNoTopCall(arg)); } return(CanonizedExp.Combine(cfunc, cargs, (a, b) => new ExpCall(a, b))); } case ExpConst constant: { return(new CanonizedExp(constant)); } case ExpName name: { return(new CanonizedExp(name)); } case ExpTemp temp: { return(new CanonizedExp(temp)); } case ExpParam para: { return(new CanonizedExp(para)); } case ExpMem mem: { return(CanonNoTopCall(mem.Address).MapExp((a) => new ExpMem(a))); } case ExpBinOp binop: { return(CanonizedExp.Combine(CanonNoTopCall(binop.Left), CanonNoTopCall(binop.Right), (l, r) => new ExpBinOp(binop.Operator, l, r))); } case ExpESeq eseq: { CanonizedExp b1 = new CanonizedExp(CanonStm(eseq.Stm), new ExpConst(0)); CanonizedExp cres = CanonNoTopCall(eseq.Exp); return(CanonizedExp.Combine(b1, cres, (nop, e) => e)); } default: throw new Exception("Shiiiit"); } }
CanonizedExp CanonNoTopCall(TreeExp e) { CanonizedExp ce = CanonExpression(e); if (ce.Exp is ExpCall) { TreeExp call = ce.Exp; TreeExp t = new ExpTemp(new Temp()); List <TreeStm> stms = new List <TreeStm>(ce.Body); stms.Add(new StmMove(t, call)); ce = new CanonizedExp(stms, t); } return(ce); }
// cfunc, cargs, (a ,b) => new ExpCall(a, b) public static CanonizedExp Combine(CanonizedExp b1, List <CanonizedExp> clist, Func <TreeExp, List <TreeExp>, TreeExp> f) { List <CanonizedExp> clistRev = new List <CanonizedExp>(clist); clistRev.Reverse(); List <TreeExp> joined = new List <TreeExp>(); List <TreeStm> stms = new List <TreeStm>(); foreach (CanonizedExp ce in clistRev) { CanonizedExp ca = Compose(ce, stms); stms = ca.Body; joined.Insert(0, ca.Exp); } CanonizedExp c = Compose(b1, stms); return(new CanonizedExp(c.Body, f(c.Exp, joined))); }
private static CanonizedExp Compose(CanonizedExp c, List <TreeStm> stms) { if (!stms.Any()) { return(c); } List <TreeStm> newstms = new List <TreeStm>(); newstms.AddRange(c.Body); if (Commute(stms, c.Exp)) { newstms.AddRange(stms); return(new CanonizedExp(newstms, c.Exp)); } else { TreeExp t = new ExpTemp(new Temp()); newstms.Add(new StmMove(t, c.Exp)); newstms.AddRange(stms); return(new CanonizedExp(newstms, t)); } }
private List <TreeStm> CanonStm(TreeStm s) { switch (s) { case StmMove move: { if (move.Dest is ExpMem mem) { TreeExp addr = ((ExpMem)move.Dest).Address; CanonExpression(addr); return(CanonizedExp.ToStm(CanonNoTopCall(addr), CanonNoTopCall(move.Source), (eaddr, esrc) => new StmMove(new ExpMem(eaddr), esrc))); } else if (move.Dest is ExpTemp) { return(CanonExpression(move.Source).ToStm(esrc => new StmMove(move.Dest, esrc))); } else if (move.Dest is ExpParam) { return(CanonExpression(move.Source).ToStm(esrc => new StmMove(move.Dest, esrc))); } else if (move.Dest is ExpESeq dst) { return(CanonStm(new StmSeq(new List <TreeStm> { dst.Stm, new StmMove(dst.Exp, move.Source) }))); } else { throw new Exception("Left-hand side of MOVE must be TEMP, PARAM, MEM or ESEQ."); } } case StmJump jump: { return(CanonNoTopCall(jump.Dest).ToStm(e => new StmJump(e, jump.PossibleTargets))); } case StmCJump cjump: { return(CanonizedExp.ToStm(CanonNoTopCall(cjump.Left), CanonNoTopCall(cjump.Right), (l, r) => new StmCJump(cjump.Rel, l, r, cjump.LabelTrue, cjump.LabelFalse))); } case StmSeq seq: { List <TreeStm> cstms = new List <TreeStm>(); foreach (var stat in seq.Stms) { cstms.AddRange(CanonStm(stat)); } return(cstms); } case StmLabel label: { List <TreeStm> stms = new List <TreeStm>(); stms.Add(label); return(stms); } default: throw new Exception("Ya know, did not match any Statement."); } }