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

org.snapscript.tree.reference.ReferenceNavigation Maven / Gradle / Ivy

package org.snapscript.tree.reference;

import static org.snapscript.core.constraint.Constraint.NONE;
import static org.snapscript.tree.reference.ReferenceOperator.FORCE;

import org.snapscript.core.Compilation;
import org.snapscript.core.Evaluation;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.module.Module;
import org.snapscript.core.module.Path;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.variable.Value;
import org.snapscript.parse.StringToken;

public class ReferenceNavigation implements Compilation {
   
   private final StringToken operator;
   private final Evaluation part;
   private final Evaluation next;

   public ReferenceNavigation(Evaluation part) {
      this(part, null, null);
   }
   
   public ReferenceNavigation(Evaluation part, StringToken operator, Evaluation next) {
      this.operator = operator;
      this.part = part;
      this.next = next;
   }

   @Override
   public Object compile(Module module, Path path, int line) throws Exception {
      if(next != null) {
         return new CompileResult(part, operator, next);
      }
      return part;
   }
   
   private static class CompileResult extends Evaluation {
   
      private final ReferenceOperator operator;
      private final Evaluation part;
      private final Evaluation next;
      
      public CompileResult(Evaluation part, StringToken operator, Evaluation next) {
         this.operator = ReferenceOperator.resolveOperator(operator);
         this.part = part;
         this.next = next;
      }
      
      @Override
      public void define(Scope scope) throws Exception {
         next.define(scope);
         part.define(scope);
      }
      
      @Override
      public Constraint compile(Scope scope, Constraint left) throws Exception {
         Constraint value = part.compile(scope, left);         
         
         if(operator == FORCE) {
            return next.compile(scope, NONE);
         }
         if(value != null) {
            return next.compile(scope, value);
         }
         return value;
      } 
      
      @Override
      public Value evaluate(Scope scope, Object left) throws Exception {
         Value value = part.evaluate(scope, left);         
         
         if(operator != null) {
            return operator.operate(scope, next, value);
         }
         return value;
      }   
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy