All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.snapscript.tree.function.ParameterExtractor Maven / Gradle / Ivy

There is a newer version: 1.4.6
Show newest version
package org.snapscript.tree.function;

import java.util.List;
import org.snapscript.core.Index;
import org.snapscript.core.InternalStateException;
import org.snapscript.core.Local;
import org.snapscript.core.Scope;
import org.snapscript.core.State;
import org.snapscript.core.Table;
import org.snapscript.core.Type;
import org.snapscript.core.convert.CompatibilityChecker;
import org.snapscript.core.function.Parameter;
import org.snapscript.core.function.Signature;

public class ParameterExtractor {
   
   private final CompatibilityChecker checker;
   private final Signature signature;
   private final boolean closure;
   
   public ParameterExtractor(Signature signature) {
      this(signature, false);
   }
   
   public ParameterExtractor(Signature signature, boolean closure) {
      this.checker = new CompatibilityChecker();
      this.signature = signature;
      this.closure = closure;
   }
   
   public void compile(Scope scope) throws Exception {
      List parameters = signature.getParameters();
      int size = parameters.size();
      
      if(size > 0) {
         Index index = scope.getIndex();
         
         for(int i = 0; i < size; i++) {
            Parameter parameter = parameters.get(i);
            String name = parameter.getName();

            index.index(name);
         }
      }
   }

   public Scope extract(Scope scope, Object[] arguments) throws Exception {
      List parameters = signature.getParameters();
      Scope inner = scope.getStack();
      int size = parameters.size();
      
      if(size > 0) {
         State state = inner.getState();
         Table table = inner.getTable();
         
         for(int i = 0; i < size; i++) {
            Parameter parameter = parameters.get(i);
            String name = parameter.getName();
            Object argument = arguments[i];
            Local local = create(inner, argument, i);
            
            if(closure) {
               state.add(name, local); 
            }
            table.add(i, local);
         }
         return inner;
      }
      return inner;
   }

   private Local create(Scope scope, Object value, int index) throws Exception {
      List parameters = signature.getParameters();
      Parameter parameter = parameters.get(index);
      Type type = parameter.getType();
      String name = parameter.getName();
      int length = parameters.size();
      
      if(index >= length -1) {
         if(signature.isVariable()) {
            Object[] list = (Object[])value;
            
            for(int i = 0; i < list.length; i++) {
               Object entry = list[i];
               
               if(!checker.compatible(scope, entry, type)) {
                  throw new InternalStateException("Parameter '" + name + "...' does not match constraint '" + type + "'");
               }
            }
            return create(scope, value, parameter);  
         }
      }
      return create(scope, value, parameter);   
   }
   
   private Local create(Scope scope, Object value, Parameter parameter) throws Exception {
      Type type = parameter.getType();
      String name = parameter.getName();
      
      if(parameter.isConstant()) {
         return Local.getConstant(value, name, type);
      }
      return Local.getReference(value, name, type);       
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy