Package scriptingLanguage.frames

Source Code of scriptingLanguage.frames.Frame

package scriptingLanguage.frames;

import java.util.LinkedHashMap;

import lipstone.joshua.customStructures.tuples.Pair;
import scriptingLanguage.Interpreter;
import scriptingLanguage.Token;
import scriptingLanguage.errors.InterpreterException;
import scriptingLanguage.errors.InvalidAssignmentException;
import scriptingLanguage.errors.UnexpectedTypeException;
import scriptingLanguage.errors.VariableNotFoundException;
import scriptingLanguage.frames.errors.FrameAccessException;
import scriptingLanguage.variables.AbstractClass;
import scriptingLanguage.variables.Variable;

public class Frame extends AbstractFrame {
 
  /**
   * Used for in-method nested frames
   *
   * @param base
   */
  public Frame(AbstractFrame base) {
    super(base.previous, base.interpreter);
    variables = new LinkedHashMap<>(base.variables);
  }
 
  /**
   * Creates a shallow copy of the given frame such that only the maps are guarenteed to be separate.</br> If staticFrame
   * is null, it uses the types from base.
   *
   * @param base
   *            the frame to copy
   * @param staticFrame
   *            the static frame or null
   */
  public Frame(AbstractFrame base, AbstractFrame previous) {
    super(base, previous);
    variables = new LinkedHashMap<>(base.variables);
  }
 
  public Frame(AbstractFrame previous, Interpreter interpreter) {
    super(previous, interpreter);
    this.variables = new LinkedHashMap<>();
  }
 
  public boolean writeVariable(String variable, AbstractClass<?> type) throws InvalidAssignmentException {
    if (variables.containsKey(variable))
      throw new InvalidAssignmentException("The a variable called " + variable + " already exists in this frame.");
    variables.put(variable, new Pair<AbstractClass<?>, Token>(type, null));
    return true;
  }
 
  @Override
  public boolean writeVariable(String variable, Token value, boolean isNew) throws InterpreterException {
    if (isNew) {
      if (variables.containsKey(variable))
        throw new InvalidAssignmentException("The a variable called " + variable + " already exists in this frame.");
      variables.put(variable, new Pair<AbstractClass<?>, Token>(((Variable<?>) value.getCar()).getType(), value));
      return true;
    }
    if (variables.containsKey(variable)) {
      Pair<AbstractClass<?>, Token> pair = variables.get(variable);
      if (((Variable<?>) value.getCar()).getType().extend(pair.getX()) != -1) {
        pair.setY(value);
        return true;
      }
      throw new InvalidAssignmentException("Cannot assign a value of the type, " + ((Variable<?>) value.getCar()).getType() + ", to the type " + pair.getX());
    }
    else if (previous != null && !(previous instanceof RootFrame))
      return previous.writeVariable(variable, value, false); //Cannot be a first assignment
    throw new VariableNotFoundException(variable + " has not been declared in this frame or scope.");
  }
 
  @Override
  public Token readVariable(String variable) throws InterpreterException {
    try {
      return super.readVariable(variable);
    }
    catch (VariableNotFoundException e) {
      return getRoot().readVariable(variable);
    }
  }
 
  @Override
  public AbstractClass<?> getType0(String type) throws UnexpectedTypeException, FrameAccessException {
    return getRoot().getType(type);
  }
 
  protected RootFrame getRoot() throws FrameAccessException {
    AbstractFrame frame = this;
    do
      if (frame instanceof RootFrame)
        return (RootFrame) frame;
    while ((frame = frame.previous) != null);
    throw new FrameAccessException("Could not access the root frame.");
  }
 
  @Override
  public void addImport(String name) throws FrameAccessException {
    getRoot().addImport(name);
  }
 
  @Override
  public String getImport(String name) throws FrameAccessException {
    return getRoot().getImport(name);
  }
 
  @Override
  public boolean hasType0(String type) throws FrameAccessException {
    return getRoot().hasType0(type);
  }
 
  @Override
  public void addType(String name, AbstractClass<?> type) throws FrameAccessException {
    getRoot().addType(name, type);
  }
 
  @Override
  public Token makeNew(AbstractClass<?> caller, String type, Token parameters, AbstractFrame call) throws InterpreterException, ArrayIndexOutOfBoundsException {
    return getRoot().makeNew(caller, type, parameters, call);
  }
}
TOP

Related Classes of scriptingLanguage.frames.Frame

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.