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

org.snapscript.compile.assemble.OperationTraverser Maven / Gradle / Ivy

package org.snapscript.compile.assemble;

import java.util.List;

import org.snapscript.core.error.InternalStateException;
import org.snapscript.core.module.Path;
import org.snapscript.core.type.Type;
import org.snapscript.parse.Line;
import org.snapscript.parse.SyntaxNode;
import org.snapscript.parse.Token;
import org.snapscript.tree.Operation;
import org.snapscript.tree.OperationResolver;

public class OperationTraverser {
   
   private final OperationResolver resolver;
   private final OperationBuilder builder;
   private final Object[] empty;

   public OperationTraverser(OperationBuilder builder, OperationResolver resolver) {
      this.empty = new Object[]{};
      this.resolver = resolver;
      this.builder = builder;
   }

   public Object create(SyntaxNode node, Path path) throws Exception {
      return create(node, path, 0);
   }
   
   private Object create(SyntaxNode node, Path path, int depth) throws Exception {
      List children = node.getNodes();
      String grammar = node.getGrammar();
      Operation type = resolver.resolve(grammar);
      int size = children.size();
      
      if (type == null) {
         return createChild(node, path, children, type,depth);
      }
      if (size > 0) {
         return createBranch(node, path, children, type,depth);
      }
      return createLeaf(node, path, children, type,depth);
   }
   
   private Object createBranch(SyntaxNode node, Path path, List children, Operation operation, int depth) throws Exception {
      Type type = operation.getType();
      Line line = node.getLine();
      int size = children.size();
      
      if(size > 0) {
         Object[] arguments = new Object[size];

         for (int i = 0; i < size; i++) {
            SyntaxNode child = children.get(i);
            Object argument = create(child, path, depth+1);

            arguments[i] = argument;
         }
         return builder.create(type, arguments, line);
      }
      return builder.create(type, empty, line);
   }

   private Object createChild(SyntaxNode node, Path path, List children, Operation operation, int depth) throws Exception {
      String grammar = node.getGrammar();
      int size = children.size();
      
      if (size > 1) {
         throw new InternalStateException("No type defined for '" + grammar + "'");
      }
      if (size > 0) {
         SyntaxNode child = children.get(0);

         if (child == null) {
            throw new InternalStateException("No child for '" + grammar + "'");
         }
         return create(child, path, depth);
      }
      if (size > 0) {
         return createBranch(node, path, children, operation, depth);
      }
      return createLeaf(node, path, children, operation, depth);
   }
   
   private Object createLeaf(SyntaxNode node, Path path, List children, Operation operation, int depth) throws Exception {
      Token token = node.getToken();     
      Line line = node.getLine();
      
      if (operation != null) {
         Type type = operation.getType();
         
         if (token == null) {
            return builder.create(type, empty, line); // no line number????
         }      
         return builder.create(type, new Object[]{token}, line);
      }
      return token;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy