Package wyvern.tools.typedAST.core.expressions

Source Code of wyvern.tools.typedAST.core.expressions.Fn

package wyvern.tools.typedAST.core.expressions;

import wyvern.tools.errors.FileLocation;
import wyvern.tools.typedAST.abs.CachingTypedAST;
import wyvern.tools.typedAST.core.evaluation.Closure;
import wyvern.tools.typedAST.core.binding.NameBinding;
import wyvern.tools.typedAST.core.binding.NameBindingImpl;
import wyvern.tools.typedAST.interfaces.*;
import wyvern.tools.types.Environment;
import wyvern.tools.types.Type;
import wyvern.tools.types.TypeResolver;
import wyvern.tools.types.extensions.Arrow;
import wyvern.tools.types.extensions.Unit;
import wyvern.tools.util.TreeWriter;

import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class Fn extends CachingTypedAST implements CoreAST, BoundCode {
  private List<NameBinding> bindings;
  TypedAST body;

  public Fn(List<NameBinding> bindings, TypedAST body) {
    this.bindings = bindings;
    this.body = body;
  }

  @Override
  public void writeArgsToTree(TreeWriter writer) {
    writer.writeArgs(bindings, body);
  }

  @Override
  protected Type doTypecheck(Environment env, Optional<Type> expected) {
    Type argType = null;
    for (int i = 0; i < bindings.size(); i++) {
      NameBinding bdgs = bindings.get(i);
      bindings.set(i, new NameBindingImpl(bdgs.getName(), TypeResolver.resolve(bdgs.getType(), env)));
    }

    if (bindings.size() == 0)
      argType = Unit.getInstance();
    else if (bindings.size() == 1)
      argType = bindings.get(0).getType();
    else
      // TODO: implement multiple args
      throw new RuntimeException("tuple args not implemented");
   
    Environment extEnv = env;
    for (NameBinding bind : bindings) {
      extEnv = extEnv.extend(bind);
    }

    Type resultType = body.typecheck(extEnv, expected.map(exp -> ((Arrow)exp).getResult()));
    return new Arrow(argType, resultType);
  }

  @Override
  public Value evaluate(Environment env) {
    return new Closure(this, env);
  }

  @Override
  public List<NameBinding> getArgBindings() {
    return bindings;
  }

  @Override
  public TypedAST getBody() {
    return body;
  }

  @Override
  public void accept(CoreASTVisitor visitor) {
    visitor.visit(this);
  }

  @Override
  public Map<String, TypedAST> getChildren() {
    Hashtable<String, TypedAST> children = new Hashtable<>();
    children.put("body", body);
    return children;
  }

  @Override
  public TypedAST doClone(Map<String, TypedAST> nc) {
    return new Fn(bindings, nc.get("body"));
  }

  private FileLocation location = FileLocation.UNKNOWN;
  public FileLocation getLocation() {
    return this.location;
  }
}
TOP

Related Classes of wyvern.tools.typedAST.core.expressions.Fn

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.