org.snapscript.tree.CatchBlockList 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.tree;
import static org.snapscript.core.result.Result.NORMAL;
import java.util.concurrent.atomic.AtomicReference;
import org.snapscript.core.Execution;
import org.snapscript.core.Statement;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.convert.TypeInspector;
import org.snapscript.core.error.ErrorCauseExtractor;
import org.snapscript.core.function.Parameter;
import org.snapscript.core.result.Result;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.scope.index.Address;
import org.snapscript.core.scope.index.ScopeIndex;
import org.snapscript.core.scope.index.Local;
import org.snapscript.core.scope.index.ScopeTable;
import org.snapscript.core.type.Type;
import org.snapscript.tree.function.ParameterDeclaration;
public class CatchBlockList {
private final AtomicReference location;
private final ErrorCauseExtractor extractor;
private final TypeInspector inspector;
private final CatchBlock[] blocks;
private final Execution[] list;
public CatchBlockList(CatchBlock... blocks) {
this.location = new AtomicReference();
this.extractor = new ErrorCauseExtractor();
this.inspector = new TypeInspector();
this.list = new Execution[blocks.length];
this.blocks = blocks;
}
public Result define(Scope scope) throws Exception {
for(int i = 0; i < blocks.length; i++){
CatchBlock block = blocks[i];
Statement statement = block.getStatement();
if(statement != null) {
ScopeIndex index = scope.getIndex();
int size = index.size();
try {
ParameterDeclaration declaration = block.getDeclaration();
Parameter parameter = declaration.get(scope, 0);
String name = parameter.getName();
Address address = index.index(name);
location.set(address);
statement.define(scope);
}finally {
index.reset(size);
}
}
}
return NORMAL;
}
public Result compile(Scope scope) throws Exception {
for(int i = 0; i < blocks.length; i++){
CatchBlock block = blocks[i];
Statement statement = block.getStatement();
if(statement != null) {
ParameterDeclaration declaration = block.getDeclaration();
Parameter parameter = declaration.get(scope, 0);
Constraint constraint = parameter.getConstraint();
String name = parameter.getName();
ScopeTable table = scope.getTable();
Local local = Local.getConstant(null, name, constraint);
Address address = location.get();
table.addValue(address, local);
list[i] = statement.compile(scope, null);
}
}
return NORMAL;
}
public Result execute(Scope scope, Result result) throws Exception {
Object data = result.getValue();
for(int i = 0; i < blocks.length; i++){
CatchBlock block = blocks[i];
ParameterDeclaration declaration = block.getDeclaration();
Parameter parameter = declaration.get(scope, 0);
Constraint constraint = parameter.getConstraint();
Type type = constraint.getType(scope);
String name = parameter.getName();
if(data != null) {
Object cause = extractor.extract(scope, data);
if(inspector.isCompatible(type, cause)) {
ScopeTable table = scope.getTable();
Local local = Local.getConstant(cause, name);
Address address = location.get();
table.addValue(address, local);
return list[i].execute(scope);
}
}
}
return result;
}
}