Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.snapscript.core.function.dispatch.TypeLocalDispatcher Maven / Gradle / Ivy
package org.snapscript.core.function.dispatch;
import static org.snapscript.core.error.Reason.INVOKE;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.error.ErrorHandler;
import org.snapscript.core.function.Connection;
import org.snapscript.core.function.resolve.FunctionCall;
import org.snapscript.core.function.resolve.FunctionResolver;
import org.snapscript.core.module.Module;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.type.Type;
import org.snapscript.core.variable.Value;
public class TypeLocalDispatcher implements FunctionDispatcher {
private final FunctionResolver resolver;
private final ErrorHandler handler;
private final String name;
public TypeLocalDispatcher(FunctionResolver resolver, ErrorHandler handler, String name) {
this.resolver = resolver;
this.handler = handler;
this.name = name;
}
@Override
public Constraint compile(Scope scope, Constraint constraint, Type... arguments) throws Exception {
Type object = constraint.getType(scope);
FunctionCall match = bind(scope, object, arguments);
if(match == null) {
Type type = scope.getType();
if(type != null) {
handler.handleCompileError(INVOKE, scope, type, name, arguments);
} else {
handler.handleCompileError(INVOKE, scope, name, arguments);
}
}
return match.check(scope, constraint, arguments);
}
@Override
public Connection connect(Scope scope, Value value, Object... arguments) throws Exception {
Scope object = value.getValue();
Connection call = bind(scope, object, arguments);
if(call == null) {
Type type = scope.getType();
if(type != null) {
handler.handleRuntimeError(INVOKE, scope, type, name, arguments);
} else {
handler.handleRuntimeError(INVOKE, scope, name, arguments);
}
}
return call;
}
private FunctionCall bind(Scope scope, Type object, Type... arguments) throws Exception {
Type type = scope.getType();
FunctionCall local = resolver.resolveInstance(scope, type, name, arguments);
if(local == null) {
Module module = scope.getModule();
FunctionCall external = resolver.resolveModule(scope, module, name, arguments); // maybe closure should be first
if(external != null) {
return external;
}
FunctionCall closure = resolver.resolveScope(scope, name, arguments); // closure
if(closure != null) {
return closure;
}
}
return local;
}
private Connection bind(Scope scope, Scope object, Object... arguments) throws Exception {
FunctionCall local = resolver.resolveInstance(scope, scope, name, arguments);
if(local == null) {
Module module = scope.getModule();
FunctionCall external = resolver.resolveModule(scope, module, name, arguments); // maybe closure should be first
if(external != null) {
return new TypeLocalConnection(external, module);
}
FunctionCall closure = resolver.resolveScope(scope, name, arguments); // closure
if(closure != null) {
return new TypeLocalConnection(closure, null);
}
return null;
}
return new TypeLocalConnection(local, null);
}
private static class TypeLocalConnection implements Connection {
private final FunctionCall call;
private final Module module;
public TypeLocalConnection(FunctionCall call, Module module) {
this.module = module;
this.call = call;
}
@Override
public boolean match(Scope scope, Object object, Object... arguments) throws Exception {
return call.match(scope, object, arguments);
}
@Override
public Object invoke(Scope scope, Object object, Object... arguments) throws Exception {
if(module != null) {
return call.invoke(scope, module, arguments);
}
return call.invoke(scope, scope, arguments);
}
}
}