Package scriptingLanguage.frames

Source Code of scriptingLanguage.frames.AbstractFrame

package scriptingLanguage.frames;

import java.util.LinkedHashMap;
import java.util.Set;

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

public abstract class AbstractFrame {
  protected final AbstractFrame previous;
  protected LinkedHashMap<String, Pair<AbstractClass<?>, Token>> variables;
  protected final Interpreter interpreter;
 
  public AbstractFrame(AbstractFrame base, AbstractFrame previous) {
    this.previous = previous == null ? base.previous : previous;
    interpreter = base.interpreter;
  }
 
  public AbstractFrame(AbstractFrame previous, Interpreter interpreter) {
    this.previous = previous;
    this.interpreter = interpreter;
  }
 
  public abstract boolean writeVariable(String variable, Token value, boolean isNew) throws InterpreterException;
 
  public Token readVariable(String variable) throws InterpreterException {
    AbstractFrame frame = this;
    do {
      if (frame.variables.containsKey(variable))
        return frame.variables.get(variable).getY();
    } while ((frame = frame.previous) != null);
   
    if (variable.contains(":{")) { //Check for functions with inheritance
      frame = this;
      String[] temp = variable.substring(variable.indexOf(":{") + 2, variable.length() - 1).split(", ");
      Variable<?>[] varParams = new Variable<?>[temp.length];
      for (int i = 0; i < temp.length; i++)
        varParams[i] = getType(temp[i]); //Convert these to types for efficiency
      int closest = -1;
      String name = variable.substring(0, variable.indexOf(":{")), closestKey = "";
      do {
        for (String key : frame.variables.keySet()) {
          if (key.indexOf(":{") < 1 || !key.substring(0, key.indexOf(":{")).equals(name))
            continue;
          String[] keyParams = key.substring(key.indexOf(":{") + 2, key.length() - 1).split(", ");
          if (keyParams.length != varParams.length)
            continue;
          int close = 0, dist = 0;
          for (int i = 0; i < keyParams.length; i++) {
            dist = varParams[i].extend(getType(keyParams[i]));
            if (dist == -1)
              break;
            close += dist;
          }
          if (dist == -1)
            continue;
          if (closest == -1 || close < closest) {
            closest = close;
            closestKey = key;
          }
        }
        if (closest > -1)
          return frame.variables.get(closestKey).getY();
      } while ((frame = frame.previous) != null);
    }
    throw new VariableNotFoundException(variable + " is not defined in the current frame.");
  }
 
  public abstract void addImport(String name) throws FrameAccessException;
 
  public abstract String getImport(String name) throws FrameAccessException;
 
  public abstract Token makeNew(AbstractClass<?> caller, String type, Token parameters, AbstractFrame call) throws InterpreterException, ArrayIndexOutOfBoundsException;
 
  public abstract void addType(String name, AbstractClass<?> type) throws FrameAccessException;
 
  public final AbstractClass<?> getType(String type) throws UnexpectedTypeException, FrameAccessException {
    switch (type) {
      case "Object":
        return Interpreter.ObjectClass;
      case "Integer":
        return Interpreter.integerClass;
      case "Double":
        return Interpreter.doubleClass;
      case "Boolean":
        return Interpreter.booleanClass;
      case "Character":
        return Interpreter.characterClass;
      case "String":
        return Interpreter.stringClass;
      case "Complex":
        return Interpreter.complexClass;
      case "void":
      case "Void":
        return Interpreter.voidClass;
      case "Long":
        return Interpreter.longClass;
      case "Float":
        return Interpreter.floatClass;
      case "Byte":
        return Interpreter.byteClass;
      case "Short":
        return Interpreter.shortClass;
      default:
        return getType0(type);
    }
  }
 
  protected abstract AbstractClass<?> getType0(String type) throws UnexpectedTypeException, FrameAccessException;
 
  public final boolean hasType(String type) throws FrameAccessException {
    return type.equals("Integer") || type.equals("String") || type.equals("Character") || type.equals("Double") || type.equals("Boolean") || type.equals("Complex") || type.equals("Long") ||
        type.equals("Short") || type.equals("Byte") || type.equalsIgnoreCase("void") || hasType0(type);
  }
 
  protected abstract boolean hasType0(String type) throws FrameAccessException;
 
  public boolean hasVariable(String variable) {
    return variables.containsKey(variable) || (previous != null && previous.hasVariable(variable));
  }
 
  public AbstractFrame getPrevious() {
    return previous;
  }
 
  public Interpreter getInterpreter() {
    return interpreter;
  }
 
  public Set<String> getVariables() {
    return variables.keySet();
  }
}
TOP

Related Classes of scriptingLanguage.frames.AbstractFrame

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.