Package AGEvalSwipl

Source Code of AGEvalSwipl.AbstractGenerator

package AGEvalSwipl;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map.Entry;
import java.util.Vector;

import jpl.Term;
import jpl.Variable;
import AGEval.AGEvaluator;
import AGEval.Function;
import AGEval.InvalidGrammarException;
import AGEvalSwipl.AGEvaluatorSwipl.Schedule;
import aleGrammar.ALEParser;
import aleGrammar.AleFrontend;
import aleGrammar.ALEParser.ExtendedClass;

//Given Backend implementation and abstract schedule, generate output
//based on original Generator, but changes loop handling
public class AbstractGenerator implements GeneratorI {

  public final boolean debug = true;
 
  private final Backend backend;
  public AbstractGenerator (Backend backend_) {
    backend = backend_;
  }
 
 
  //@Deprecated
  /*
  public static Vertex lookupAttribute(String lhsRaw, AGEval.Class cls) throws InvalidGrammarException {
    String lhs = lhsRaw.replace("$$", "").replace("$-", "").replace("$i", "");
    return lhs.split("@").length == 2 ?
        (lhs.split("@")[0].equals("self") ? cls.findVertexByExtName(lhs.split("@")[1])           
         : cls.getChildByName(lhs.split("@")[0]).findVertexByExtName(lhs.split("@")[1]))
        : cls.findVertexByExtName(lhs);         
  }
  */
 
  public static ALEParser.ExtendedVertex extendedGet(ALEParser ast, AGEval.IFace cls, String prop) throws InvalidGrammarException {
    String uProp = prop.toLowerCase();
   
    for (Entry<String, ALEParser.ExtendedVertex> e : ast.extendedClasses.get(cls).extendedVertices.entrySet())
      if (e.getKey().toLowerCase().equals(uProp)) return e.getValue();   

    AGEval.IFace iface = cls.getInterface();
    if (iface == cls || iface == null) throw new InvalidGrammarException("Extended get on interface fail: " + cls.getName() + " for " + prop);   
    else
      for (Entry<String, ALEParser.ExtendedVertex> e : ast.extendedClasses.get(iface).extendedVertices.entrySet())
        if (e.getKey().toLowerCase().equals(uProp)) return e.getValue();   
   
    throw new InvalidGrammarException("Extended get on class fail: " + cls.getName() + " for " + prop)
  }
 
  public static AGEval.IFace lookupChildGeneral(AGEval.Class cls, String child) throws InvalidGrammarException {
    AGEval.IFace res = cls.getChildByName(child);
    if (res != null) return res;
    else {
      for (Entry<String, AGEval.IFace> e: cls.getChildMappings().entrySet()) {
        if (e.getKey().toLowerCase().equals(child)) {
          if (e.getValue() != null) return e.getValue();
          else throw new InvalidGrammarException("Looked up null child: " + cls.getName() + "'s " + child);         
        }
      }
    }
    throw new InvalidGrammarException("Cannot find child " + child + " of " + cls.getName());
   
  }
 
  public static ALEParser.ExtendedVertex lookupAttributeExtended(String lhsRaw, AGEval.Class cls, ALEParser ast) throws InvalidGrammarException {
    String lhs = lhsRaw.toLowerCase().replace("$$", "").replace("$-", "").replace("$i", "").replace("_init", "").replace("_last", "").replace("_step", "");
    String rhsRaw = AGEvaluatorSwipl.attribName(lhs);
    String node;
    String prop;
    if (lhs.split("_").length == 2) { //child_prop or self@child_prop
      node = AGEvaluatorSwipl.attribName(lhsRaw).split("_")[0];
      prop = lhsRaw.split("_")[1];
    } else {
      node = AGEvaluatorSwipl.attribBase(lhs);
      prop = rhsRaw;
    }
    try {
      return extendedGet(ast, node.equals("self") ? cls : lookupChildGeneral(cls, node), prop);
    } catch (InvalidGrammarException e) {
      throw new InvalidGrammarException("Bad lookupAttributeExtended: " + lhsRaw + " in class/interface " + cls.getName() + "\n" + e.getMessage());
    }
   
  }

 
  public HashMap<String, String> genExprPrinter(AGEvaluator aleg, HashMap<AGEval.Class, ArrayList<ALEParser.Cond>> conds, Schedule sched) throws InvalidGrammarException {
    HashMap<String, String> exprPrinter = new HashMap<String, String>();
    for (AGEval.Class cls : aleg.classes) {
      for (Function f : cls.getFunctions()) {
        String printArgs = "";
        for (String src : f.getStringSrcs())
          printArgs += backend.logStmtVar(2, 8, src.toString(), sched._ast, cls, src, backend.rhsToVal(src, cls, sched._ast));
        String printer = "";
        printer += backend.logStmtVar(2, 4, f.getName(), sched._ast, cls, f.myDest, backend.rhsToVal(f.myDest, cls, sched._ast));
        exprPrinter.put(f.getName().toLowerCase(), printer + printArgs);
      }
    }
         
    for (ALEParser.Assignment asgn : sched._ast.assignments) {
      if (!"".equals(asgn.loopVar)) {
        AGEval.Class cls = asgn._class;
        String lhsRaw = asgn._sink;
        String lhs = lhsRaw.toLowerCase();
           boolean isParentAttrib = !lhsRaw.contains("@") || lhsRaw.split("@")[0].equals("self");
        ////////
        if (asgn.isReduction) {
          //init
          String whoInit = cls.getName().toLowerCase() + "_" + lhsRaw.toLowerCase().replace("@", "_") + "_init";
          String initVar = isParentAttrib ? (lhsRaw + "_init") : ("self@" + AGEvaluatorSwipl.attribBase(lhsRaw) + "_" + AGEvaluatorSwipl.attribName(lhsRaw) + "_init");
          exprPrinter.put(whoInit,
              backend.logStmtVar(
                  0, 6, "init " + asgn._sink, sched._ast, cls, initVar,
                  backend.rhsToVal(initVar, cls, sched._ast)));
          //last
          //String dupeLhs = backend.lhsToAddress((isParentAttrib ? AGEvaluatorSwipl.attribName(lhs) : (lhs.replace("@","_") + "_last")), cls, sched._ast);
          String dupe = isParentAttrib ? AGEvaluatorSwipl.attribName(lhs) : (lhs.replace("@","_") + "_last");
          exprPrinter.put(whoInit,
              exprPrinter.get(whoInit+ backend.logStmtVar(0, 4, "last init " + dupe, sched._ast, cls, dupe, backend.rhsToVal(dupe, cls, sched._ast)));
        }
        if (asgn._sink.contains("[-1]")) {
          String whoInit = cls.getName().toLowerCase() + "_" + lhsRaw.toLowerCase().replace("@", "_").replace("[-1]", "") + "_init";
          exprPrinter.put(whoInit, backend.logStmtVar(6, 9, "init " + lhsRaw, sched._ast, cls, lhsRaw, backend.rhsToVal(lhsRaw, cls, sched._ast)));
        } else {
          String whoStep = cls.getName().toLowerCase() + "_" + lhsRaw.toLowerCase().replace("@", "_") + "_step";
          exprPrinter.put(whoStep, backend.logStmtVar(6, 9, "step " + lhsRaw, sched._ast, cls, lhsRaw, backend.rhsToVal(lhsRaw, cls, sched._ast)));
        }
        if (asgn.isReduction) {
          String printVar = (isParentAttrib ? AGEvaluatorSwipl.attribName(lhs) : (lhs.replace("@","_"))) + "_last";
          exprPrinter.put(cls.getName().toLowerCase() + "_" + lhsRaw.toLowerCase().replace("@", "_") + "_last",
              backend.logStmtVar(0, 6, "last " + lhs, sched._ast, cls, printVar, backend.rhsToVal(printVar, cls, sched._ast)));

        }
      }
    }
   
    //NOTE: conds handled with exprToCall's invocation of addNestedConditionals
   
      return exprPrinter;
  }
 
 
  public String nestedTernary(ALEParser.Case c, String lhs, AGEval.Class cls, Schedule sched) throws InvalidGrammarException {
    String res = "";
    if (!c.isElse) {   
      res += bindExpr(c.openBody, c.indexedVariables, cls, false, false, backend.toAcc(lhs, cls), sched);
      res += " ? ";
    } else {
      //res += " : ";
    }

    for (ALEParser.Assignment asgn : c.assignments) {
      if (asgn._sink.equals(lhs)) {
        res += "(" + bindExpr(asgn._indexedBody, asgn._variables, cls, false, false, backend.toAcc(lhs, cls), sched) + ")";
        return res + (c.isElse ? "" : ":");
      }
    }

    //not directly available, try from conds
    //FIXME only use cond that (recursively) covers lhs (should be exactly 1 -- verify?)
    for (ALEParser.Cond cnd : c.conditionals) {
      res += nestedTernary(cnd, lhs, cls, sched);
    }

    return res + (c.isElse ? "" : ":");
  }
   
  //navigate cases until got assignment
  public String nestedTernary(ALEParser.Cond c, String lhs, AGEval.Class cls, Schedule sched) throws InvalidGrammarException {
    String res = "(";
    res += nestedTernary(c.testCase, lhs, cls, sched);
    for (ALEParser.Case cs : c.elseifs) res += nestedTernary(cs, lhs, cls, sched);
    res += nestedTernary(c.elseCase, lhs, cls, sched);
    return res + ")";
  }

 
  public String nestedTernaryLoopStep(ALEParser.Case c, String lhsRaw, AGEval.Class cls, Schedule sched) throws InvalidGrammarException {
      String res = "";
      if (!c.isElse) {   
        res += bindExpr(c.openBody, c.indexedVariables, cls, true, false, backend.toAcc(lhsRaw, cls), sched);
        res += " ? ";
      } else {
      //  res += " : ";
      }
     
      for (ALEParser.Assignment asgn : c.assignments) {
        if (asgn._sink.equals(lhsRaw)) {
          return res += asgnLoopExpr(cls, asgn, lhsRaw, false, sched+ (c.isElse ? "" : ":");
        }
      }
     
      for (ALEParser.Cond cnd : c.conditionals) {
        res += nestedTernaryLoopStep(cnd, lhsRaw, cls, sched);
      }
     
      return res  + (c.isElse ? "" : ":");
    }
   
    public String nestedTernaryLoopStep(ALEParser.Cond c, String lhsRaw, AGEval.Class cls, Schedule sched) throws InvalidGrammarException {
      String res = "(";
      res += nestedTernaryLoopStep(c.testCase, lhsRaw, cls, sched);
      for (ALEParser.Case cs : c.elseifs) res += nestedTernaryLoopStep(cs, lhsRaw, cls, sched);
      res += nestedTernaryLoopStep(c.elseCase, lhsRaw, cls, sched);
      return res + ")";
    }
   
  public String nestedTernaryLoopInit(ALEParser.Case c, String lhsRaw, AGEval.Class cls, Schedule sched) throws InvalidGrammarException {
      String res = "";
      if (!c.isElse) {   
        //cppGen.checkInitable(sched.reductions, cls, c.indexedVariables, lhsRaw);
        res += bindExpr(c.openBody, c.indexedVariables, cls, true, true, backend.toAcc(lhsRaw, cls), sched);
        res += " ? ";
      } else {
        //res += " : ";
      }
     
      for (ALEParser.Assignment asgn : c.assignments) {
        if (asgn._sink.equals(lhsRaw)) {
          return res += asgnLoopExpr(cls, asgn, lhsRaw, true, sched) + (c.isElse ? "" : ":");
        }
      }
     
      for (ALEParser.Cond cnd : c.conditionals) {
        res += nestedTernaryLoopInit(cnd, lhsRaw, cls, sched);
      }
     
      return res + (c.isElse ? "" : ":");
    }
   
    public String nestedTernaryLoopInit(ALEParser.Cond c, String lhsRaw, AGEval.Class cls, Schedule sched) throws InvalidGrammarException {
      String res = "(";
      res += nestedTernaryLoopInit(c.testCase, lhsRaw, cls, sched);
      for (ALEParser.Case cs : c.elseifs) res += nestedTernaryLoopInit(cs, lhsRaw, cls, sched);
      res += nestedTernaryLoopInit(c.elseCase, lhsRaw, cls, sched);
      return res + ")";
    }
   
//  public static String bindExpr(String openBody, HashMap<String,String> indexedVariables, AGEval.Class cls) throws InvalidGrammarException {
  public String bindExpr(String openBody, HashMap<String,String> indexedVariables, AGEval.Class cls, boolean allowStep, boolean replaceStep, String acc, Schedule sched) throws InvalidGrammarException {   
    String res = backend.replaceTypeVals(openBody, sched._ast);
    for (Entry<String, String> e : indexedVariables.entrySet()) {
//      res = res.replaceAll(e.getValue() + " ", rhsToVal(e.getKey(), cls) + " ");
//      res = res.replaceAll(e.getValue() + "$", rhsToVal(e.getKey(), cls) + " ");
      if (!allowStep && (e.getKey().equals("$-") || e.getKey().contains("$i") || e.getKey().contains("$$"))) {
        throw new InvalidGrammarException("reduction variables ($ identifiers) must be in loop steps, error binding expression "
            + openBody + " with " + e.getKey() + " == " + e.getValue());
      }
      if (e.getKey().contains("$-")) {
        if (replaceStep) {
          //init
          throw new InvalidGrammarException("$acc must be in loop steps, error binding expression "
              + openBody + " with " + e.getKey() + " == " + e.getValue());
        } else {
          //step
          res = res.replaceAll(e.getValue() + " ", backend.rhsToVal(e.getKey(), cls, sched._ast) + " ");
          res = res.replaceAll(e.getValue() + ",", backend.rhsToVal(e.getKey(), cls, sched._ast) + ",");
          res = res.replaceAll(e.getValue() + "\\)", backend.rhsToVal(e.getKey(), cls, sched._ast+ ")");           
          res = res.replaceAll(e.getValue() + "$", backend.rhsToVal(e.getKey(), cls, sched._ast+ " ");           
        }
      } else if (e.getKey().contains("$i")) {   
        if (replaceStep) {
          //FIXME init $i => final
          res = res.replaceAll(e.getValue() + " ", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ " ");
          res = res.replaceAll(e.getValue() + ",", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ ",");
          res = res.replaceAll(e.getValue() + "\\)", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ ")");
          res = res.replaceAll(e.getValue() + "$", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ " ");
          //FIXME data structure generation must provide (in case using more lax check than just isReduct...)
        } else {
          //step $i => child
          res = res.replaceAll(e.getValue() + " ", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ " ");
          res = res.replaceAll(e.getValue() + ",", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ ",");
          res = res.replaceAll(e.getValue() + "\\)", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ ")");           
          res = res.replaceAll(e.getValue() + "$", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ " ");           
        }
      } else {
        res = res.replaceAll(e.getValue() + " ", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ " ");
        res = res.replaceAll(e.getValue() + ",", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ ",");
        res = res.replaceAll(e.getValue() + "\\)", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ ")");
        res = res.replaceAll(e.getValue() + "$", backend.rhsToVal(e.getKey(), cls, sched._ast).replace("$", "\\$"+ " ");
      }     
    }
    return res;
  }
 
 
  public String asgnLoopExpr (AGEval.Class cls, ALEParser.Assignment asgn, String lhsRaw, boolean isInit, Schedule sched) throws InvalidGrammarException {
    String res = "";
    if (asgn.isReduction) {
      res += "(" +
        bindExpr(
          isInit ? asgn.startBody : asgn.stepBody,
          isInit ? asgn.startVariables : asgn.stepVariables,
          cls, true, isInit, backend.toAcc(lhsRaw, cls), sched) + ")";
    } else {
      //if (sched.reductions.accessedAsLast.get(cls).contains(lhsRaw)) CppGenerator.checkInitable(sched.reductions, cls, asgn._variables, lhsRaw);     
      res += "(" + bindExpr(asgn._indexedBody, asgn._variables, cls, true, isInit, backend.toAcc(lhsRaw, cls), sched) + ")";
    }
   
    return res;
  }
 
  public void addAssign(String lhsRaw, AGEval.Class cls, AGEvaluatorSwipl.Schedule sched, boolean isReduction,
      ALEParser.Assignment maybeAsgn, ALEParser.Cond maybeCond, HashMap<String, String> exprToCall) throws InvalidGrammarException
      boolean isParentAttrib = !lhsRaw.contains("@") || lhsRaw.split("@")[0].equals("self");
      String lhs = lhsRaw.toLowerCase();
      if (isReduction) {
        //init
        String whoInit = cls.getName().toLowerCase() + "_" + lhsRaw.toLowerCase().replace("@", "_") + "_init";
        String initLhs = backend.lhsToAddress(isParentAttrib ? (lhsRaw + "_init") : ("self@" + AGEvaluatorSwipl.attribBase(lhsRaw) + "_" + AGEvaluatorSwipl.attribName(lhsRaw) + "_init"), cls, sched._ast);
        exprToCall.put(
            whoInit,
            backend.asgnE(initLhs, (maybeCond == null ? asgnLoopExpr(cls, maybeAsgn, lhsRaw, true, sched)
                : nestedTernaryLoopInit(maybeCond, lhsRaw, cls, sched))));
        //last
        String dupeLhs = backend.lhsToAddress((isParentAttrib ? AGEvaluatorSwipl.attribName(lhs) : (lhs.replace("@","_") + "_last")), cls, sched._ast);                 
        exprToCall.put(whoInit, exprToCall.get(whoInit) +
            ";\n"
            + backend.asgnE(dupeLhs,
                backend.rhsToVal(isParentAttrib ? (lhsRaw + "_init") : ("self@" + AGEvaluatorSwipl.attribBase(lhsRaw) + "_" + AGEvaluatorSwipl.attribName(lhsRaw) + "_init"), cls, sched._ast)));

      }
      if (lhsRaw.contains("[-1]")) {
        String whoInit = cls.getName().toLowerCase() + "_" + lhsRaw.toLowerCase().replace("@", "_").replace("[-1]","") + "_init";
        String initLhs = backend.lhsToAddress(isParentAttrib ? (lhsRaw + "_init") : ("self@" + AGEvaluatorSwipl.attribBase(lhsRaw) + "_" + AGEvaluatorSwipl.attribName(lhsRaw).replace("[-1]","") + "_init"), cls, sched._ast);       
        exprToCall.put(
            whoInit,
            backend.asgnE(initLhs, (maybeCond == null ? asgnLoopExpr(cls, maybeAsgn, lhsRaw, true, sched)
                : nestedTernaryLoopInit(maybeCond, lhsRaw, cls, sched))));
      } else {
        String whoStep = cls.getName().toLowerCase() + "_" + lhsRaw.toLowerCase().replace("@", "_") + "_step";
        exprToCall.put(whoStep,
            backend.asgnE(backend.lhsToAddress(lhsRaw, cls, sched._ast), (maybeCond == null ? asgnLoopExpr(cls, maybeAsgn, lhsRaw, false, sched)
                : nestedTernaryLoopStep(maybeCond, lhsRaw, cls, sched))));
      }
      if (isReduction) {
        String dupeLhs = backend.lhsToAddress((isParentAttrib ? AGEvaluatorSwipl.attribName(lhs) : (lhs.replace("@","_"))) + "_last", cls, sched._ast);                 
        exprToCall.put(cls.getName().toLowerCase() + "_" + lhsRaw.toLowerCase().replace("@", "_") + "_last",
            "      " + backend.asgnE(dupeLhs, backend.rhsToVal(lhsRaw, cls, sched._ast)));

      }
  }
 
  public HashMap<String, String> genExprToCall(AGEvaluator aleg, HashMap<AGEval.Class, ArrayList<ALEParser.Cond>> conds, Schedule sched, HashMap<String, String> exprPrinter) throws InvalidGrammarException {
    HashMap<String, String> exprToCall = new HashMap<String, String>();
    for (AGEval.Class cls : aleg.classes) {
      for (Function f : cls.getFunctions()) {
        String lhs = backend.lhsToAddress(f.myDest, cls, sched._ast);
        String rhs = f.getName() + "(";
        boolean isFirst = true;
        for (String src : f.getStringSrcs()) {
          if (isFirst) isFirst = false;
          else rhs += ", ";
          rhs += backend.rhsToVal(src, cls, sched._ast);
        }
        rhs += ")";
        exprToCall.put(f.getName().toLowerCase(), backend.asgnE(lhs, rhs));
      }
    }
    for (ALEParser.Assignment asgn : sched._ast.assignments) {
      if (!"".equals(asgn.loopVar)) {
        addAssign(asgn._sink, asgn._class, sched, asgn.isReduction, asgn, null, exprToCall);
      }
    }
    addNestedConditionals(exprToCall, exprPrinter, conds, aleg, sched);
    return exprToCall;
  }
 
  public static void gatherVariables(ALEParser.Case c, HashSet<String> nonReductSinks, HashSet<String> reductSinks) {
      for (ALEParser.Assignment asgn : c.assignments) {
        if (asgn.isReduction) reductSinks.add(asgn._sink);
        else nonReductSinks.add(asgn._sink);
      }
      for (ALEParser.Cond cnd : c.conditionals) {
        gatherVariables(cnd, nonReductSinks, reductSinks);
      }
    }
    public static void gatherVariables(ALEParser.Cond c, HashSet<String> nonReductSinks, HashSet<String> reductSinks) {
      gatherVariables(c.testCase, nonReductSinks, reductSinks);
      for (ALEParser.Case cs : c.elseifs) gatherVariables(cs, nonReductSinks, reductSinks);
      gatherVariables(c.elseCase, nonReductSinks, reductSinks);
    }
   

 
  public void addNestedConditionals (
      HashMap<String, String> exprToCall,
      HashMap<String, String> exprPrinter,
      HashMap<AGEval.Class, ArrayList<ALEParser.Cond>> conds,
      AGEvaluator aleg,
      Schedule sched) throws InvalidGrammarException {     
    if (conds == null) return;     
    for (AGEval.Class cls : aleg.classes) {
      if (conds.containsKey(cls)) {
        for (ALEParser.Cond cnd  : conds.get(cls)) {
          HashSet<String> nonReductSinks = new HashSet<String>();       
          HashSet<String> reductSinks = new HashSet<String>();
          gatherVariables(cnd, nonReductSinks, reductSinks);
          HashSet<String> sinks = new HashSet<String>();
          sinks.addAll(nonReductSinks);
          sinks.addAll(reductSinks);
          for (String lhsRaw : sinks) {
            String lhs = lhsRaw.toLowerCase();
            String loop = sched._ast.extendedClasses.get(cls).idToLoop.get(lhs);
            if (loop == null) {
              System.err.println("- loop cnd asgn, class " + cls.getName() + ": lhs " + lhs);
              for (String opt : sched._ast.extendedClasses.get(cls).idToLoop.keySet()) {
                System.err.println("  option: " + opt);
              }
              throw new InvalidGrammarException("could not find enclosing loop");
            }                 

            boolean inLoop = !"".equals(sched._ast.extendedClasses.get(cls).idToLoop.get(lhs));
            String fname = cls.getName().toLowerCase() + "_" + lhs.replace("@", "_");
            String assign = backend.lhsToAddress(lhsRaw, cls, sched._ast);
            if (!inLoop) {                  
              String rhs = nestedTernary(cnd, lhsRaw, cls, sched);
              exprToCall.put(fname, backend.asgnE(assign, rhs));
              exprPrinter.put(fname, backend.logStmtVar(0, 0, fname, sched._ast, cls,  lhs, backend.rhsToVal(lhs, cls, sched._ast)));
            } else {
              boolean isReduction = reductSinks.contains(lhsRaw);
              addAssign(lhsRaw, cls, sched, isReduction, null, cnd, exprToCall);             
              exprPrinter.put(fname+"_step",
                  backend.logStmtVar(0, 0, fname + "_step", sched._ast, cls, lhs, backend.rhsToVal(lhs, cls, sched._ast)));
            }
            if (reductSinks.contains(lhsRaw)) {
              String iLhs = "self@"
                + (AGEvaluatorSwipl.attribBase(lhsRaw).equals("self") ? "": (AGEvaluatorSwipl.attribBase(lhsRaw)+"_"))
                + AGEvaluatorSwipl.attribName(lhsRaw) + "_init";               
              exprPrinter.put(fname+"_init",
                  backend.logStmtVar(0, 0, fname + "_init", sched._ast, cls, iLhs, backend.rhsToVal(iLhs, cls, sched._ast)));             
            }
          }
        }
      }
    }
  }
 
 
  // Each HashMap returned from this method is equivalent to one pass in generated visitors
  public HashMap<AGEval.Class, String> visit (
      AGEvaluator aleg,
      LoopRecoverer ir,
      HashMap<String, AGEval.Class> classMap,
      HashMap<String, String> exprToCall,
      HashMap<String, String> exprPrinter,
      int visitNum,
      //Term pass,
      HashMap<AGEval.Class, ArrayList<String>> childOrders,
      Schedule sched) throws InvalidGrammarException {
    //System.err.println("Visit.");

    HashMap<AGEval.Class, String>  visit = new HashMap<AGEval.Class, String> (aleg.classes.size());
    for (AGEval.Class cls : aleg.classes) {
      visit.put(cls, backend.visitHeader(cls, visitNum, sched._ast)); //e.g., function vbox0 {
    }
   
    for (Entry<AGEval.Class, Vector<LoopRecoverer.SingleVisitClean>> e : ir.visitsClean.entrySet()) {
      AGEval.Class cls = e.getKey();
      if (e.getValue().size() > visitNum) {
        LoopRecoverer.SingleVisitClean v  = e.getValue().get(visitNum);
        for (LoopRecoverer.Block block : v.blocks) {
          switch (block.blockType) {
            case UNKNOWN:
              for (String a : block.assignments)
                System.err.println("  " + a);
              throw new InvalidGrammarException("Unknown block type");
            case LOOP:   
              openLoopClean(cls, block.maybeLoopVar, sched, block, exprToCall, exprPrinter, visit);             
              for (String lhs : block.assignments) {
                if (lhs.contains("_recur")) {                                   
                  String childName = lhs.split("_")[0].replace("unrolln", "");                 
                  //System.err.println("Recur child name: "+ childName);                 
                  if (childrenContains(sched._ast.extendedClasses.get(cls).multiChildren.keySet(), childName)) {
                    visit.put(cls, visit.get(cls) + backend.childrenRecur(cls, childName, visitNum, sched._ast));
                    visit.put(cls, visit.get(cls) + backend.logStmt(6, 2, "resume loop visit " + cls.getName(), "" + visitNum));
                  } else {
                    throw new InvalidGrammarException(cls.getName() + "::" + lhs + ": Cannot do a single child recursion (" + lhs + ") within a loop (" + block.maybeLoopVar + ")");                   
                  }
                } else {
                  if (lhs.contains("_step1") || lhs.contains("_step2")) continue;
                  visitStatement(cls, sched, visit, lhs, true, exprToCall, exprPrinter);
                }
              }
              closeLoopClean(cls, block.maybeLoopVar, sched, block, exprToCall, exprPrinter, visit);
              break;
            case STATEMENT:
              for (String lhs : block.assignments) {
                if (lhs.contains("_recur")) {
                  String childName = lhs.split("_")[0].replace("unrolln", "");
                  if (childrenContains(sched._ast.extendedClasses.get(cls).multiChildren.keySet(), childName)) {
                    throw new InvalidGrammarException(cls.getName() + "::" + lhs + ": Cannot do an array recursion (" + lhs + ") outside of a loop");
                  } else {
                    visit.put(cls, visit.get(cls) + "  " + backend.childRecur(cls, childName, visitNum));
                    visit.put(cls, visit.get(cls) + backend.logStmt(2, 2, "resume visit " + cls.getName(), "" + visitNum));
                  }

                } else {
                  visitStatement(cls, sched, visit, lhs, false, exprToCall, exprPrinter);
                }
              }
             
          }
          //block or not?
        }
      }
    }
/*   
    //HashMap<AGEval.Class, ArrayList<String>> openLoopVars = new HashMap<AGEval.Class, ArrayList<String>>();   
    int childI = 0;
    for (Term act : pass.toTermArray()) {
      if (act.isInteger()) {
        visitRecursion(sched, visitNum, childOrders, act, childI, openLoopVars, visit, exprToCall, exprPrinter);
        //System.err.println("Calling visit recursion on " + act.toString());
        childI++;
      } else {
        visitAction(sched, act, openLoopVars, visit, exprToCall, exprPrinter);
        //System.err.println("Calling visit action on " + act.toString());
      }
    }
*/   
    //System.err.println("(pass: " + pass + ")\n==\n");
    // Add the footer to each visit
    for (AGEval.Class cls : aleg.classes) {
      visit.put(cls, visit.get(cls) + backend.visitFooter(cls, visitNum, sched._ast));     
    }
    return visit;
  }
 
  public String visits(
      AGEvaluator aleg,
      LoopRecoverer ir,
      Hashtable<Variable, Term> binding, HashMap<AGEval.Class, ArrayList<String>> childOrder,
      HashMap<String, AGEval.Class> classMap,
      HashMap<String, String> exprToCall,
      HashMap<String, String> exprPrinter,
      Schedule sched) throws InvalidGrammarException {
    String res = "";
    int numVisits = binding.get("P").toTermArray().length;
    ArrayList<HashMap<AGEval.Class, String> > visits = new ArrayList<HashMap<AGEval.Class, String> > (numVisits);     
    ArrayList<String> directions = new ArrayList<String>(numVisits);
    int visitI = 0;          
    for (Term visit : binding.get("P").toTermArray()) {
      //System.out.println("Pass: " + visit);
      //(Visit, Direction, Previous, Assume, VisitO); car/cdr for each nesting
      String stencil = visit.arg(2).arg(1).toString();
      directions.add(stencil);
      visits.add(visit(aleg, ir, classMap, exprToCall, exprPrinter, visitI, /*visit.arg(2).arg(2).arg(2).arg(2),*/ childOrder, sched));
      visitI++;
    }

    //res += "\nStencil order: ";
    //for (String dir : directions) res += dir + " ";
    //res += "\n";
    for (HashMap<AGEval.Class, String>  pass : visits) {
      res += "///// pass /////\n";
      for (String visit : pass.values()) {
        res += visit;
      }
    }
   
    return res;
  }
 
 
  public boolean isPhantom(String f, ExtendedClass cls2) {
    String cleanF = f.replace("_step","").replace("_init","").replace("_last","");   
    String[] parts = cleanF.split("_");
    String nodeF;
    String attribF;
      if (parts.length == 2) {
        nodeF = "self";
        attribF = parts[1];
      } else {
        nodeF = parts[parts.length - 2];
        attribF = parts[parts.length - 1];
      }
    String cmp = nodeF + "@" + attribF;
    if (cls2.phantomAttributes.contains(cmp)) {
//      System.err.println("skip phantom F: " + f);
      return true;
    } else {
//      System.err.println("do F: " + f);
      return false;
    }   
  }
 
 
 
  public void openLoopClean (AGEval.Class cls, String loopVar,
      AGEvaluatorSwipl.Schedule sched,
      LoopRecoverer.Block block,
      HashMap<String, String> exprToCall, HashMap<String, String> exprPrinter,
      HashMap<AGEval.Class, String>  soFar) throws InvalidGrammarException {
 
    ExtendedClass cls2 = sched._ast.extendedClasses.get(cls);
     
    String res = "\n";
    for (String s : block.assignments) {
      if (!s.contains("_stepn")) continue;     
      String sClean = cls.getName().toLowerCase() + "_" + s.replace("_stepn", "_init");
      if (!exprToCall.containsKey(sClean)) continue; //FIXME what case is this?
      if (isPhantom(sClean, cls2)) continue;

      res += "  " + exprToCall.get(sClean).replace("\n", "\n  ") + ";\n";
      String log = exprPrinter.get(sClean);
      if (debug && log != null)
        res += "  " + log.replace("\n", "\n  ");
      else
        System.err.println("Missing log: " + sClean);       
    }   
    res += backend.openChildLoop(cls, loopVar, sched._ast)
    soFar.put(cls, soFar.get(cls) + res);
  }
 
  public void closeLoopClean (AGEval.Class cls, String loopVar,
      AGEvaluatorSwipl.Schedule sched,
      LoopRecoverer.Block block,     
      HashMap<String, String> exprToCall, HashMap<String, String> exprPrinter,
      HashMap<AGEval.Class, String>  soFar) throws InvalidGrammarException {
   
    ExtendedClass cls2 = sched._ast.extendedClasses.get(cls);
     

    String transfer = backend.openLastChild(cls, loopVar);   
    boolean hasAnyToCopy = false;
    for (String s : block.assignments) {
      if (!s.contains("_stepn")) continue;     
      String sClean = cls.getName().toLowerCase() + "_" + s.replace("_stepn", "_init");
      if (isPhantom(sClean, cls2)) {
        System.err.println("Phantom: " + sClean);
        continue;
      }
      if (handledTransfer(cls, sched, sClean, exprToCall, exprPrinter)) continue;
/*
      if (!exprToCall.containsKey(sClean)) { //transfer?
        System.err.println("Non transfer: " + sClean);
        for (String k : exprToCall.keySet()) System.err.println("  " + k);
        continue; //FIXME what case is this?
      }
*/     
      String cleanF = s.replace("_stepn", "").replace("_", "@");   
      //System.err.println("Checking for closure open var " + cleanF);
      //for (String s : schedule2.reductions.accessedAsLast.get(cls)) System.err.println("  " + s);
      if (sched.reductions.accessedAsLast.get(cls).contains(cleanF)) { //set: x, child@y, ...
        String base = AGEvaluatorSwipl.attribBase(cleanF);
        if (base.equals("self")) continue;
        hasAnyToCopy = true;     
        String attrib = cleanF.split("@")[1];
        String lastAttrib = (base + "_" + attrib + "_last").toLowerCase();
        String lastLhs = "self@" + lastAttrib;
        transfer  += "        " + backend.asgnS(backend.lhsToAddress(lastLhs, cls, sched._ast), backend.rhsToVal(cleanF, cls, sched._ast));
        transfer  += backend.logStmtVar(8,4,cleanF, sched._ast, cls, lastLhs, backend.rhsToVal(lastLhs, cls, sched._ast));
      }
    } 
    transfer  += backend.closeLastChild();
     
    String mainBody = "";
      for (String s : block.assignments) {
        if (!s.contains("_stepn")) continue;
        String f = s.replace("_stepn", "_last");
      if (!isPhantom(cls.getName().toLowerCase() + "_" + f, cls2)) {
        if (exprToCall.containsKey(f + "_last")) {
          hasAnyToCopy = true;
          mainBody += exprToCall.get(f + "_last") + ";\n";
        }
      }
    }
    String res = (hasAnyToCopy ? transfer : "") + mainBody + backend.closeChildLoop() + "\n"
    soFar.put(cls, soFar.get(cls) + res);
  }
 
 
 
  public static boolean childrenContains(Collection<String> rawCollection, String entry) {
    String entryClean = entry.toLowerCase();
    for (String s : rawCollection) {
      if (s.toLowerCase().equals(entryClean)) return true;
    }
    return false;
  }
 

  //true if transfer (externally defined)
  //false if not transfer (internally defined)
  //exn if not transfer and not handler
  public static Boolean handledTransfer
  (AGEval.Class cls, Schedule sched,  String exprName, HashMap<String, String> exprToCall, HashMap<String, String> exprPrinter)
  throws InvalidGrammarException {
   
    if (exprToCall.get(exprName) == null || exprPrinter.get(exprName) == null) {
      if (exprName.split("_").length == 4) { //loop
        String lhs = exprName.replace("_step", "");
        if (!sched.reductions.allClassWrites.get(cls).contains(lhs)) { //FIXME shouldn't be not !?
          //System.err.println("Check: " + lhs);
          for (String w : sched.reductions.allClassWrites.get(cls)) {
            String cmp = cls.getName().toLowerCase() + "_" + w.replace("@", "_");
            if (lhs.equals(cmp)) throw new InvalidGrammarException("Missing statement handler for write: " + cls.getName()+"::"+exprName);
          }
          return true;
       
      } else {
        if (AGEvaluatorSwipl.chainLoops) {         
          //might be a self loop
          /////// FIXME
          if (exprToCall.get(exprName+"_last") != null && exprPrinter.get(exprName+"_last") != null) return false;
          if (!sched.reductions.allClassWrites.get(cls).contains(exprName)) {
            //System.err.println("Check: " + lhs);
            for (String w : sched.reductions.allClassWrites.get(cls)) {  //FIXME shouldn't be not !?
              String cmp = cls.getName().toLowerCase() + "_" + w.replace("@", "_");
              if (exprName.equals(cmp)) throw new InvalidGrammarException("Missing statement handler for write: " + cls.getName()+"::"+exprName);
            }
            return true;
         
          ///////                 
         
          throw new InvalidGrammarException("Missing statement handler: " + cls.getName()+"::"+exprName);
        } else {
          System.err.println("Missing statement handler: " + cls.getName()+"::"+exprName);
        }
      } 
    }
    return false;
  }
   
public void visitStatement (AGEval.Class cls, Schedule sched,  HashMap<AGEval.Class, String>  visit, String exprNameRaw,
    boolean inLoop,
    HashMap<String, String> exprToCall, HashMap<String, String> exprPrinter) throws InvalidGrammarException {
  String exprName =
      cls.getName().toLowerCase() + "_"
          + (exprNameRaw.contains("_stepn") ?
              (exprNameRaw.replace("_stepn", "_step"))
              : exprNameRaw.replace("@", "_"));
 
 
  if (visit.get(cls) == null) System.err.println("failed to get cls on Vertex " + exprName + ", " + cls.getName());
  else if (visit.get(cls).equals("null"))
    System.err.println("Got null str on cls of Vertex " + exprName + ", " + cls.getName())
 
  //skip transfer calls (needed for scheduling, but assigned externally)
  if (handledTransfer(cls, sched, exprName, exprToCall, exprPrinter)) return;
 
  /*
  if (exprToCall.get(exprName) == null || exprPrinter.get(exprName) == null) {
    System.err.println(cls.getName() + ": failed to get expr (" + exprName + ") -- " + (exprToCall.get(exprName) == null ? "expr" : "printer"));
    System.err.println("Calls: ");
    for (String k : exprToCall.keySet()) System.err.print("  " + k);
    System.err.println("\nPrints: ");
    for (String k : exprPrinter.keySet()) System.err.print("  " + k);
    System.err.println();
  }
  */
 
  String padding = inLoop ? "      " : "  ";
  ExtendedClass cls2 = sched._ast.extendedClasses.get(cls);
 
  //FIXME skip nullaries
  if (exprToCall.containsKey(exprName)) {
    boolean isP = isPhantom(exprName, cls2);
    String p = debug && !isP ? exprPrinter.get(exprName) : "";
    if (p == null) {
      System.err.println("Missing printer: " + cls.getName()+"::"+exprName);
      p="";
    }
    //System.err.println("putting: " + exprToCall.get(exprName));
    //System.err.println("print: " + p);
    String extra = isP ? "" : exprToCall.get(exprName).replace("\n", "\n      ");
    visit.put(cls, visit.get(cls) + padding + extra + ";\n" + p);
  }
}
 
  public String visitDispatchers(int visits, AGEvaluator aleg, Vector<HashSet<AGEval.Class>> buSubInorderBuIns, Vector<HashSet<AGEval.Class>> buSubInorderBus) {
    String res = "";
    for (int i = 0; i < visits; i++) res += backend.visitDispatcher(i, aleg, buSubInorderBuIns.get(i), buSubInorderBus.get(i));
    return res;
 
 
 
  public String functionHeaders (ALEParser g) throws InvalidGrammarException {
    //sort lifted expressions by class
    HashMap<AGEval.Class, ArrayList<ALEParser.Assignment>> assignments = new HashMap<AGEval.Class, ArrayList<ALEParser.Assignment>>();
    for (ALEParser.Assignment asgn : g.assignments) {
      if (!assignments.containsKey(asgn._class)) assignments.put(asgn._class, new ArrayList<ALEParser.Assignment>());
      if (!asgn.isReduction) assignments.get(asgn._class).add(asgn);
    }
    String res = "";
    for (ArrayList<ALEParser.Assignment> cAssigns : assignments.values() ) {
      for (ALEParser.Assignment assign : cAssigns) res += backend.functionHeader(assign, g);
    }
    return res;
 
   
 
  public Schedule synthesizeAll(String alePath, String outputDir, String resourceDir, boolean verbose, boolean isFixedChildOrder, boolean isExhaustive, int maxLen, boolean stripFloats) throws Exception {
   
    System.err.println("all");
   
    File variants = (new File(outputDir + File.separator + "variants"));
    if (variants != null && variants.isDirectory()) {
      for (File d : variants.listFiles()) {
        for (File f : d.listFiles()) f.delete();
        d.delete();
      }
      variants.delete();
    }

    ///////////////////////////////////////////////////////////////
   
    AleFrontend grammar = new AleFrontend(alePath, AGEvaluatorSwipl.chainLoops, stripFloats);
    grammar.initFtl(!AGEvaluatorSwipl.chainLoops); //play with old alegen core
   
    AGEvaluatorSwipl ages = new AGEvaluatorSwipl(grammar.alegEval, grammar.ast, verbose);   
    String prologGrammar = ages.alegAstToSwiplAst();
   
    File prettyGrammar = new File(alePath);
        String baseName = prettyGrammar.getName().split("\\.")[0];
    String prologGrammarPath = outputDir + File.separator + baseName + ".pl";
    AGEvaluatorSwipl.writeFile(prologGrammarPath, prologGrammar);
    if (verbose) System.out.println("=== PL GRAMMAR: === \n " + prologGrammar);
    ages.runGrammar(resourceDir, prologGrammarPath);
   
    Schedule sched = ages.generateVisits(isFixedChildOrder, isExhaustive, false, maxLen, grammar.alegEval, grammar.ast);   
   
    HashMap<String, String> exprPrinter = genExprPrinter(sched._aleg, grammar.ast.condsTop, sched);
    HashMap<String, String> exprToCall = genExprToCall(sched._aleg, grammar.ast.condsTop, sched, exprPrinter);

    ////////////////////////////////////////////////////////////////
       
    Hashtable<Variable, Term> binding = null;
    int round = 0;   
    (new File(outputDir + File.separator + "variants")).mkdir();
   
    String fHeaders = functionHeaders(grammar.ast);
   
    long queryTime = -System.currentTimeMillis();
    System.err.println("Start time: " + queryTime + "ms");
   
    long timeSinceLastQuery = -System.currentTimeMillis();
    int found = 0;
    int cumQTime = 0;
    while (sched.hasNext()) {
      found++;
      binding = sched.moveNext();   
     
      //if (!sched.isAllParallel()) continue;
     
      long qTime = timeSinceLastQuery + System.currentTimeMillis();
      cumQTime += qTime;
      String seq = "";
      for (Term visit : sched.binding.get("P").toTermArray()) {
        seq += " " + visit.arg(2).arg(1).toString().replace("tdLtrU", "inorder");
      }
      System.err.println("sched: " + seq);
      System.err.println("find time: " + qTime + "ms");
      System.err.println("Running average: " + (cumQTime / found) + "ms/query (over " + found + " queries)");

      long compeTime = -System.currentTimeMillis();
     
      (new File(outputDir + File.separator + "variants/variant" + round)).mkdir();
      backend.generateParseFiles(grammar.ast, sched, outputDir + File.separator + "variants/variant" + round + File.separator, verbose, fHeaders);
     
      LoopRecoverer ir = new LoopRecoverer(sched);
     
      String visitOut =
        backend.preVisits(grammar.alegEval, sched)
        + visits(sched._aleg, ir, binding, sched.computeVisitOrders(), sched.classMap, exprToCall, exprPrinter, sched)
        + backend.postVisits(grammar.alegEval, sched);
      String visitDispatches = visitDispatchers(sched.numVisits(), grammar.alegEval, sched.buSubInorderBuIn, sched.buSubInorderBus);
     
      backend.output(baseName, visitOut, visitDispatches, outputDir + File.separator + "variants/variant" + round + File.separator, true, verbose, grammar.ast, sched, fHeaders, binding, grammar.alegEval);
      AGEvaluatorSwipl.writeFile(outputDir + File.separator + "variants/variant" + round + File.separator + "schedule", seq);
      round++;
      //if (!isExhaustive) {
      //  System.err.println("(breaking early: not exhaustive");
      //  break;
      //}
      System.err.println("Code gen time: " + (compeTime + System.currentTimeMillis()) + " ms");
      timeSinceLastQuery = -System.currentTimeMillis();
     
    }
    //return;
   
    System.err.println("Total time: " + (queryTime + System.currentTimeMillis()) + "ms");

    return sched;
   
   
  }
 
  public Schedule synthesize(String alePath, String outputDir, String resourceDir, boolean verbose, boolean isFixedChildOrder, boolean isExhaustive, int maxLen, boolean stripFloats) throws Exception {
   
    AleFrontend grammar = new AleFrontend(alePath, AGEvaluatorSwipl.chainLoops, stripFloats);
    grammar.initFtl(!AGEvaluatorSwipl.chainLoops); //play with old alegen core
   
    AGEvaluatorSwipl ages = new AGEvaluatorSwipl(grammar.alegEval, grammar.ast, verbose);   
    String prologGrammar = ages.alegAstToSwiplAst();
   
    File prettyGrammar = new File(alePath);
        String baseName = prettyGrammar.getName().split("\\.")[0];
    String prologGrammarPath = outputDir + File.separator + baseName + ".pl";
    AGEvaluatorSwipl.writeFile(prologGrammarPath, prologGrammar);
    if (verbose) System.out.println("=== PL GRAMMAR: === \n " + prologGrammar);
    ages.runGrammar(resourceDir, prologGrammarPath);
   
   
    long totalTime = -System.currentTimeMillis();
   
   
    Schedule sched = ages.generateVisits(isFixedChildOrder, isExhaustive, true, maxLen, grammar.alegEval, grammar.ast);   

   
    ////////////////////////////////////////////////////////////////
     
    Hashtable<Variable, Term> binding = null;
    //int vlen =  0;
   
    if (true) {
      while (sched.hasNext()) {
       

        binding = sched.moveNext();       
        String seq = "";
        //int len = 0;
        for (Term visit : sched.binding.get("P").toTermArray()) {
          //len++;
          seq += " " + visit.arg(2).arg(1).toString().replace("tdLtrU", "inorder");
        }
        System.err.println("sched: " + seq);
        //if (sched.isAllParallel()) break;
        break;
      }
      //return;     
    } //else {
//
//      while (sched.hasNext()) {
//        Hashtable<Variable, Term> nextBinding = sched.moveNext();
//        int nextLen = sched.binding.get("P").toTermArray().length;
//        if (binding == null || nextLen < vlen) {
//          binding = nextBinding;
//          vlen = nextLen;
//        }
//        if (!sched.isAllParallel()) continue;
//        //break;
//      }
//    }
   
    System.err.println("Total time: " + ((totalTime + System.currentTimeMillis())/1000.0) + "s");

    String schedPath = outputDir +File.separator + baseName +".sched";
    AGEvaluatorSwipl.writeFile(schedPath, sched.printBinding());
    AGEvaluatorSwipl.writeFile(schedPath +"Summary", sched.printBindingShort());
   
    String mapPath = outputDir + File.separator + baseName + ".json";
    AGEvaluatorSwipl.writeFile(mapPath, new JSON(sched._ast).getJSON("  ", "  "));

    String fHeaders = functionHeaders(grammar.ast);
   
    backend.generateParseFiles(grammar.ast, sched, outputDir, verbose, fHeaders);
   
    LoopRecoverer ir = new LoopRecoverer(sched);
   
   
    HashMap<String, String> exprPrinter = genExprPrinter(sched._aleg, grammar.ast.condsTop, sched);
    HashMap<String, String> exprToCall = genExprToCall(sched._aleg, grammar.ast.condsTop, sched, exprPrinter);
   
    String visitOut =
      backend.preVisits(grammar.alegEval, sched)
      + visits(sched._aleg, ir, binding, sched.computeVisitOrders(), sched.classMap, exprToCall, exprPrinter, sched)
      + backend.postVisits(grammar.alegEval, sched);
    String visitDispatches = visitDispatchers(sched.numVisits(), grammar.alegEval, sched.buSubInorderBuIn, sched.buSubInorderBus);
   
    backend.output(baseName, visitOut, visitDispatches, outputDir, true, verbose, grammar.ast, sched, fHeaders, binding, grammar.alegEval);
   
    return sched;
  }
 
  public static void main(String[] args) throws Exception {
   
    //=========================
    //String testName = "tdtdpost.ale";
    String testName = "../Examples/spiraldemo2.ftl";
    //String testName = "../Examples/horvbox.ale";
    //String testName ="crosschain3.ale";
    //String testName = "../../csssemantics/ftl/tablesideal.ftl.eric";
    boolean useCpp = false; //false => HTML5
    //=========================

    if (args.length != 3) {
      System.err.println("Expected 3 args:");
      System.err.println("  0: resourceDir (..-swipl/AGEvalSwipl)");
      System.err.println("  1: outputDir (..-ftl/)");
      System.err.println("  2: inputDir (..-swipl/Tests/");     
    }
   
    AGEvaluatorSwipl.Schedule sched;
    long loadTime = -System.currentTimeMillis();
    sched = AGEvaluatorSwipl.getSchedules(args[0] + File.separator,  args[2] + File.separator, testName,  args[1] + File.separator, false, true, false, true, 20, false);
    if (!sched.hasNext()) {
      System.err.println("  " + testName + ": no soln");
      throw new Exception("blah");
    }
    sched.moveNext();
    loadTime += System.currentTimeMillis();
   
    LoopRecoverer ir = new LoopRecoverer(sched);
    System.out.println("====Raw===");
    System.out.println(ir.toStringRaw());
    System.out.println("====Reconstructed===");
    System.out.println(ir.toStringClean());
   
    Backend backend = useCpp ? new CppGenerator() : new Html5Generator() ;
    AbstractGenerator irGen = new AbstractGenerator(backend);

    HashMap<String, String> exprPrinter = irGen.genExprPrinter(sched._aleg, sched._ast.condsTop, sched);
    HashMap<String, String> exprToCall = irGen.genExprToCall(sched._aleg, sched._ast.condsTop, sched, exprPrinter);
   
   
    String visitOut =
        backend.preVisits(sched._aleg, sched)
        + irGen.visits(sched._aleg, ir, sched.binding, sched.computeVisitOrders(), sched.classMap, exprToCall, exprPrinter, sched)
        + backend.postVisits(sched._aleg, sched);
    String visitDispatches = irGen.visitDispatchers(sched.numVisits(), sched._aleg, sched.buSubInorderBuIn, sched.buSubInorderBus);

    System.out.println("=======VisitOut=====\n" + visitOut);
    System.out.println("=======VisitDispatches=====\n" + visitDispatches);
    System.out.println("Schedule time: " + loadTime + "ms");
  }
}
TOP

Related Classes of AGEvalSwipl.AbstractGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.