Package wyvern.tools.typedAST.core.expressions

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

package wyvern.tools.typedAST.core.expressions;

import wyvern.tools.errors.FileLocation;
import wyvern.tools.typedAST.abs.AbstractTypedAST;
import wyvern.tools.typedAST.core.binding.AssignableValueBinding;
import wyvern.tools.typedAST.core.binding.NameBinding;
import wyvern.tools.typedAST.core.binding.evaluation.VarValueBinding;
import wyvern.tools.typedAST.core.binding.typechecking.AssignableNameBinding;
import wyvern.tools.typedAST.core.values.VarValue;
import wyvern.tools.typedAST.interfaces.*;
import wyvern.tools.types.Environment;
import wyvern.tools.types.Type;
import wyvern.tools.types.TypeResolver;
import wyvern.tools.util.TreeWriter;

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

import static wyvern.tools.errors.ErrorMessage.VARIABLE_NOT_DECLARED;
import static wyvern.tools.errors.ToolError.reportError;


public class Variable extends AbstractTypedAST implements CoreAST, Assignable {
  private NameBinding binding;
 
  public Variable(NameBinding binding, FileLocation location) {
    this.binding = binding;
    this.location = location;
  }

  public String getName() {
    return this.binding.getName();
  }
 
  @Override
  public Type getType() {
    return binding.getType();
  }

  @Override
  public void writeArgsToTree(TreeWriter writer) {
    writer.writeArgs(binding.getName());   
  }

  @Override
  public Type typecheck(Environment env, Optional<Type> expected) {
    Type type = getType();
    if (type == null) {
      String name = binding.getName();
      binding = env.lookup(name);
      if (binding == null)
        reportError(VARIABLE_NOT_DECLARED, this, name);
      else
        type = binding.getType();
    }
    return TypeResolver.resolve(type,env);
  }

  @Override
  public Value evaluate(Environment env) {
    //Value value = binding.getValue(env);
    Value value = env.getValue(binding.getName());
    assert value != null;
    if (value instanceof VarValue) {
      return ((VarValue)value).getValue();
    }
    return value;
  }

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

  @Override
  public void checkAssignment(Assignment ass, Environment env) {
    AssignableNameBinding vb =
        env.lookupBinding(binding.getName(), AssignableNameBinding.class)
          .orElseThrow(() -> new RuntimeException("Cannot set a non-existent or immutable var"));
  }

  @Override
  public Value evaluateAssignment(Assignment ass, Environment env) {
    Value value = ass.getValue().evaluate(env);
    env.lookupBinding(binding.getName(), AssignableValueBinding.class)
        .orElseThrow(() -> new RuntimeException("Invalid assignment"))
        .assign(value);

    return value;
  }

  @Override
  public Map<String, TypedAST> getChildren() {
    return new Hashtable<>();
  }

  @Override
  public TypedAST cloneWithChildren(Map<String, TypedAST> nc) {
    return new Variable(binding, location);
  }

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

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

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.