示例#1
0
 /**
  * This method produces a new Abstraction which is the result of adding captured variables as new
  * arguments and bind it in current ns. It returns the name of the bound funciton.
  *
  * @param a
  * @param captured
  * @return a String object denoting the name given to this function
  * @throws SymbolException
  */
 private String lift(Abstraction a, Set captured) throws SymbolException {
   Abstraction abs = a;
   if (!captured.isEmpty()) {
     /* recreate abstraction adding captured variables */
     abs = new Abstraction();
     /* bind captured variables */
     Iterator it = captured.iterator();
     while (it.hasNext()) {
       LocalBinding lb = (LocalBinding) it.next();
       LocalBinding nlb = new LocalBinding(lb.getName());
       abs.bind(nlb);
     }
     /* rebind old variables */
     it = a.getBindings().values().iterator();
     while (it.hasNext()) {
       LocalBinding lb = (LocalBinding) it.next();
       LocalBinding nlb = new LocalBinding(lb.getName());
       abs.bind(nlb);
     }
     /* restore body */
     abs.setBody(a.getBody());
   }
   /*
    * bind new abstraction in ns if a is an anonymous abstraction - no class
    * name - then it is renamed lambdaXXX and bound in namespace. Else, it is
    * given a new name and a reference to this new name is stored in substMap.
    */
   String newname = "lambda" + counter++;
   ns.bind(newname, abs);
   abs.setClassName(ns.getName() + "." + newname);
   return newname;
 }
示例#2
0
 /**
  * This method produces an Expression from an arbitrary Abstraction object which is applied to a
  * list of Variables referencing captured bindings.
  *
  * @param a an Abstraction object to partially apply
  * @param captured
  * @return
  */
 private Expression applyLifted(String s, Set captured) {
   if (captured.isEmpty()) return new Variable(s);
   Application app = new Application();
   app.setFunction(new Variable(s));
   /* bind captured variables */
   Iterator it = captured.iterator();
   while (it.hasNext()) {
     LocalBinding lb = (LocalBinding) it.next();
     app.addArgument(new Variable(lb.getName()));
   }
   return app;
 }
示例#3
0
 /**
  * Returns an Abstraction object resulting from lifting the given expression with captured
  * variable set. if <code>f
  * x y</code> is an expression with <code>y</code> a captured variable, then it is transformed
  * into <code>lambdaXXX
  * = \ y -> f x y</code> which can later be used to replace the original expression with <code>
  * lambdaXXX y</code>.
  *
  * @param e
  * @param captured
  * @return a String object
  * @throws SymbolException
  */
 private String lift(Expression e, Set captured) throws SymbolException {
   if (e instanceof Abstraction) return lift((Abstraction) e, captured);
   Abstraction abs = new Abstraction();
   /* bind captured variables */
   Iterator it = captured.iterator();
   while (it.hasNext()) {
     LocalBinding lb = (LocalBinding) it.next();
     LocalBinding nlb = new LocalBinding(lb.getName());
     abs.bind(nlb);
   }
   /* restore body */
   abs.setBody(e);
   String newname = "lambda" + counter++;
   ns.bind(newname, abs);
   return newname;
 }
示例#4
0
  /** @see jaskell.compiler.JaskellVisitor#visit(Alternative) */
  public Object visit(Alternative a) {
    try {
      Type tex = (Type) a.getExpression().visit(this);
      log.finer("In alternative, type of expression " + a.getExpression() + " is " + tex);

      /* set type of bound variable */
      LocalBinding lb = a.getBinding();
      if (lb != null) lb.setType(tex);
      /* visit type of alternatives */
      Iterator it = a.getChoices();
      Type ptype = tex;
      Type btype = null;
      while (it.hasNext()) {
        Map.Entry entry = (Map.Entry) it.next();
        /* checkt type of pattern */
        Type pt = (Type) ((Pattern) entry.getKey()).visit(this);
        if (ptype == null) ptype = pt;
        else ptype = tu.unify(pt, ptype, typeVariablesMap);
        log.finer("In alternative, unifying pattern type " + pt + " to " + ptype);
        Expression expr = (Expression) entry.getValue();
        /* check type of body */
        Type bt = (Type) expr.visit(this);
        //                      /* apply substitution with type variables from pattern */
        //                      TypeSubstitution ts = new TypeSubstitution(typeVariablesMap);
        //                      expr.visit(ts);
        if (btype == null) btype = bt;
        else btype = tu.unify(bt, btype, typeVariablesMap);
        log.finer("In alternative, unifying body type " + bt + " to " + btype);
      }
      /* visit default choice */
      Type deft = (Type) a.getWildcard().visit(this);
      a.setType(btype);
      return btype;
    } catch (TypeError te) {
      if (te.getLineCol() == null) te.setLineCol(a.getTag("source"));
      throw te;
    }
  }
示例#5
0
 /** @see jaskell.compiler.JaskellVisitor#visit(Abstraction) */
 public Object visit(Abstraction a) {
   try {
     Type t = a.getType();
     if (t != null) return subst.substitute(t);
     log.finest("Visiting abstraction : " + a);
     Expression body = a.getBody();
     /* duplicate bindings map to assign types to variables */
     pushContext(a.getBindings());
     /* create fresh type variables as type for each bound
      * variable */
     Iterator it = namesMap.values().iterator();
     LinkedList tl = new LinkedList();
     while (it.hasNext()) {
       LocalBinding name = (LocalBinding) it.next();
       Type vt = TypeFactory.freshBinding();
       name.setType(vt);
       tl.add(vt);
     }
     Type tv = TypeFactory.freshBinding();
     /* create type with all variables for function */
     Type ft = Types.fun(tl, tv);
     log.finer("In abstraction, setting type to " + ft);
     a.setType(ft);
     /* analyze body */
     Type bt = (Type) body.visit(this);
     /* unify return type of function with type of body */
     Type ret = tu.unify(PrimitiveType.getReturnType(ft), bt, typeVariablesMap);
     TyvarSubstitution tys = new TyvarSubstitution(typeVariablesMap);
     tys.visit(a);
     log.finer("Done abstraction, setting type from " + ft + " to " + a.getType());
     popContext();
     return a.getType();
   } catch (TypeError te) {
     if (te.getLineCol() == null) te.setLineCol(a.getTag("source"));
     throw te;
   }
 }
示例#6
0
 /** @see jaskell.compiler.JaskellVisitor#visit(LocalBinding) */
 public Object visit(LocalBinding a) {
   return a.getType();
 }