00001: package clogs.transform;
00002:
00003: import clogs.ast.*;
00004: import clogs.util.List;
00005: import clogs.util.Optional;
00006:
00007: public class EliminateHighLevelControl extends Phase
00008: {
00009: public List<ExtDecl> transform (List<ExtDecl> edecls)
00010: {
00011: List<ExtDecl> result = List.nil ();
00012:
00013: for (ExtDecl edecl : edecls) {
00014: if (edecl instanceof Decl) {
00015: result = result.snoc (edecl);
00016:
00017: } else if (edecl instanceof FunDef) {
00018: FunDef fundef = (FunDef) edecl;
00019: result = result.snoc (new FunDef (fundef.type, fundef.name, fundef.params, transformBody (fundef.body)));
00020:
00021: } else {
00022: throw new RuntimeException ("Missing ExtDecl case: " + edecl.getClass ().getName ());
00023: }
00024: }
00025:
00026: return result;
00027: }
00028:
00029:
00030: static StatCompound transformBody (StatCompound statC) {
00031: List<Stat> statsNew = List.nil ();
00032: for (Stat stat : statC.stats) {
00033: statsNew = statsNew.concat (transformStat (stat));
00034: }
00035: return new StatCompound (statC.decls, statsNew);
00036: }
00037:
00038:
00039: static List<Stat> transformStat (Stat stat)
00040: {
00041: List<Stat> result = List.nil ();
00042:
00043: if (stat instanceof StatCompound) {
00044: StatCompound statC = (StatCompound) stat;
00045: result = result.snoc (transformBody (statC).addLabels (statC.labels));
00046:
00047: } else if (stat instanceof StatExp) {
00048: result = result.snoc (stat);
00049:
00050: } else if (stat instanceof StatGoto) {
00051: result = result.snoc (stat);
00052:
00053: } else if (stat instanceof StatIf) {
00054: // if (exp) statT else statF
00055: // -->
00056: // if (exp)
00057: // goto l1;
00058: // else
00059: // goto l2;
00060: // l1:
00061: // skip;
00062: // statT
00063: // goto l3;
00064: // l2:
00065: // skip;
00066: // statF
00067: // goto l3;
00068: // l3:
00069: // skip
00070: StatIf statI = (StatIf) stat;
00071: String l1 = Fresh.getLabel ("true");
00072: String l2 = Fresh.getLabel ("false");
00073: String l3 = Fresh.getLabel ("end_if");
00074: result = result.snoc (new StatIf (statI.exp, new StatGoto (l1), new StatGoto (l2)).addLabels (statI.labels));
00075: result = result.snoc (new StatSkip ().addLabel (l1));
00076: result = result.concat (transformStat (statI.statT));
00077: result = result.snoc (new StatGoto (l3));
00078: result = result.snoc (new StatSkip ().addLabel (l2));
00079: result = result.concat (transformStat (statI.statF));
00080: result = result.snoc (new StatGoto (l3));
00081: result = result.snoc (new StatSkip ().addLabel (l3));
00082:
00083: } else if (stat instanceof StatReturn) {
00084: result = result.snoc (stat);
00085:
00086: } else if (stat instanceof StatSkip) {
00087: result = result.snoc (stat);
00088:
00089: } else if (stat instanceof StatWhile) {
00090: // while (exp) stat
00091: // -->
00092: // goto l2;
00093: // l1:
00094: // skip;
00095: // stat
00096: // l2:
00097: // if (exp)
00098: // goto l1
00099: // else
00100: // goto l3;
00101: // l3:
00102: // skip;
00103: StatWhile statW = (StatWhile) stat;
00104: String l1 = Fresh.getLabel ("body_while");
00105: String l2 = Fresh.getLabel ("test_while");
00106: String l3 = Fresh.getLabel ("end_while");
00107: result = result.snoc (new StatGoto (l2).addLabels (statW.labels));
00108: result = result.snoc (new StatSkip ().addLabel (l1));
00109: result = result.concat (transformStat (statW.stat));
00110: result = result.snoc (new StatIf (statW.exp, new StatGoto (l1), new StatGoto (l3)).addLabel (l2));
00111: result = result.snoc (new StatSkip ().addLabel (l3));
00112:
00113: } else {
00114: throw new RuntimeException ("Missing Stat case: " + stat.getClass ().getName ());
00115: }
00116:
00117: return result;
00118: }
00119: }
00120:
00121:
|