Package kiss.lang.expression

Source Code of kiss.lang.expression.Loop

package kiss.lang.expression;

import clojure.lang.IPersistentMap;
import clojure.lang.IPersistentSet;
import clojure.lang.Symbol;
import kiss.lang.Environment;
import kiss.lang.Expression;
import kiss.lang.Type;
import kiss.lang.impl.RecurResult;

/**
* A let expression, creates a local lexical binding
*
* @author Mike
*/
public class Loop extends Expression {

  private final Symbol[] syms;
  private final Expression[] initials;
  private final Expression body;

  public Loop(Symbol[] syms, Expression[] initials, Expression body) {
    this.syms=syms;
    this.initials=initials;
    this.body=body;
  }

  public static Loop create(Symbol[] syms, Expression[] initials, Expression body) {
    return new Loop(syms,initials,body);
  }
 
  public Loop update(Symbol[] syms, Expression[] initials, Expression body) {
    Expression[] nis =this.initials;
    for (int i=0; i<initials.length; i++) {
      if (nis[i]!=initials[i]) {
        nis=initials;
        break;
      }
    }
    if ((this.syms==syms)&&(this.body==body)&&(this.initials==nis)) return this;
    return create(syms, nis,body);
  }
 
  @Override
  public Expression optimise() {
    Expression b=body.optimise();
    Expression[] is=initials.clone();
    for (int i=0; i<is.length; i++) {
      is[i]=is[i].optimise();
    }
   
    return update(syms,is,b);
  }
 
  @Override
  public Type getType() {
    return body.getType();
  }
 
  @Override
  public boolean isPure() {
    if (!body.isPure()) return false;
    for (Expression i:initials) {
      if (!i.isPure()) return false;
    }
    return true;
  }
 
  @Override
  public Environment compute(Environment d, IPersistentMap bindings) {
    int n=syms.length;
    for (int i=0; i<n; i++) {
      d=initials[i].compute(d, bindings);
      if (d.isExiting()) return d;
      Object result=d.getResult();
      bindings=bindings.assoc(syms[i], result);
    }
    while (true) {
      d=body.compute(d, bindings);
      Object ro=d.getResult();
      if (!(ro instanceof RecurResult)) {
        return d;
      }
     
      RecurResult rr=(RecurResult) ro;
      for (int i=0; i<n; i++) {
        bindings=bindings.assoc(syms[i], rr.values[i]);
      }
    }   
  }
 
  @Override
  public Expression specialise(Type type) {
    Expression newBody=body.specialise(type);
    return update(syms,initials,newBody);
  }
   
  @Override
  public Expression substitute(IPersistentMap bindings) {
    Expression[] nis=initials.clone();
    for (int i=0; i<initials.length; i++) {
      nis[i]=initials[i].substitute(bindings);
      bindings=bindings.without(syms[i]);
    }
    Expression nbody=body.substitute(bindings);
    if (nbody==null) return null;
   
    return update(syms,nis,nbody);
  }
 
  @Override
  public IPersistentSet accumulateFreeSymbols(IPersistentSet s) {
    s=body.accumulateFreeSymbols(s);
    s=s.disjoin(syms);
    for (Expression i: initials) {
      s=i.accumulateFreeSymbols(s);
    }
    return s;
  }
 
  @Override
  public void validate() {
    // OK?
  }


}
TOP

Related Classes of kiss.lang.expression.Loop

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.