org.snapscript.compile.assemble.OperationTraverser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of snap-all Show documentation
Show all versions of snap-all Show documentation
Dynamic scripting for the JVM
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;
}
}