package org.overture.interpreter.eval;
import java.lang.reflect.Method;
import org.overture.ast.analysis.AnalysisException;
import org.overture.ast.definitions.SClassDefinition;
import org.overture.ast.expressions.ANotYetSpecifiedExp;
import org.overture.ast.intf.lex.ILexLocation;
import org.overture.ast.lex.Dialect;
import org.overture.ast.lex.LexNameToken;
import org.overture.ast.messages.InternalException;
import org.overture.ast.modules.AModuleModules;
import org.overture.ast.node.INode;
import org.overture.config.Settings;
import org.overture.interpreter.debug.BreakpointManager;
import org.overture.interpreter.runtime.ClassInterpreter;
import org.overture.interpreter.runtime.Context;
import org.overture.interpreter.runtime.ContextException;
import org.overture.interpreter.runtime.Interpreter;
import org.overture.interpreter.runtime.ModuleInterpreter;
import org.overture.interpreter.runtime.RootContext;
import org.overture.interpreter.runtime.ValueException;
import org.overture.interpreter.runtime.VdmRuntime;
import org.overture.interpreter.runtime.VdmRuntimeError;
import org.overture.interpreter.runtime.state.AModuleModulesRuntime;
import org.overture.interpreter.runtime.state.SClassDefinitionRuntime;
import org.overture.interpreter.values.NaturalOneValue;
import org.overture.interpreter.values.ObjectValue;
import org.overture.interpreter.values.SeqValue;
import org.overture.interpreter.values.TupleValue;
import org.overture.interpreter.values.Value;
import org.overture.interpreter.values.ValueList;
public class DelegateExpressionEvaluator extends ExpressionEvaluator
{
protected Value evalDelegatedANotYetSpecified(INode node,
ILexLocation location, int abortNumber, String type,
boolean failOnUnhandled, Context ctxt) throws AnalysisException
{
BreakpointManager.getBreakpoint(node).check(location, ctxt);
if (location.getModule().equals("VDMUtil")
|| location.getModule().equals("DEFAULT"))
{
if (ctxt.title.equals("get_file_pos()"))
{
// This needs location information from the context, so we
// can't just call down to a native method for this one.
return get_file_pos(ctxt);
}
}
if (location.getModule().equals("IO")
|| location.getModule().equals("DEFAULT"))
{
if (ctxt.title.equals("freadval(filename)"))
{
// This needs type invariant information from the context, so we
// can't just call down to a native method for this one.
try
{
LexNameToken arg = new LexNameToken("IO", "filename", location);
Value fval = ctxt.get(arg);
// We can't link with the IO class directly because it's in the default
// package, so we reflect our way over to it.
@SuppressWarnings("rawtypes")
Class io = Class.forName("IO");
@SuppressWarnings("unchecked")
Method m = io.getMethod("freadval", new Class[] {
Value.class, Context.class });
return (Value) m.invoke(io.newInstance(), new Object[] {
fval, ctxt });
} catch (Exception e)
{
throw new InternalException(62, "Cannot invoke native method: "
+ e.getMessage());
}
}
}
if (Settings.dialect == Dialect.VDM_SL)
{
ModuleInterpreter i = (ModuleInterpreter) Interpreter.getInstance();
AModuleModules module = i.findModule(location.getModule());
if (module != null)
{
AModuleModulesRuntime state = VdmRuntime.getNodeState(module, ctxt.assistantFactory);
if (state.hasDelegate())
{
return state.invokeDelegate(ctxt);
}
}
} else
{
ObjectValue self = ctxt.getSelf();
if (self == null)
{
ClassInterpreter i = (ClassInterpreter) Interpreter.getInstance();
SClassDefinition cls = i.findClass(location.getModule());
if (cls != null)
{
SClassDefinitionRuntime state = VdmRuntime.getNodeState(ctxt.assistantFactory, cls);
if (state.hasDelegate())
{
return state.invokeDelegate(ctxt);
}
}
} else
{
if (self.hasDelegate(ctxt))
{
return self.invokeDelegate(ctxt);
}
}
}
if (failOnUnhandled)
{
return VdmRuntimeError.abort(location, abortNumber, "'not yet specified' "
+ type + " reached", ctxt);
}
return null;
}
@Override
public Value caseANotYetSpecifiedExp(ANotYetSpecifiedExp node, Context ctxt)
throws AnalysisException
{
return evalDelegatedANotYetSpecified(node, node.getLocation(), 4024, "expression", true, ctxt);
}
private Value get_file_pos(Context ctxt)
{
try
{
ValueList tuple = new ValueList();
Context outer = ctxt.getRoot().outer;
RootContext root = outer.getRoot();
tuple.add(new SeqValue(ctxt.location.getFile().getPath()));
tuple.add(new NaturalOneValue(ctxt.location.getStartLine()));
tuple.add(new NaturalOneValue(ctxt.location.getStartPos()));
tuple.add(new SeqValue(ctxt.location.getModule()));
int bra = root.title.indexOf('(');
if (bra > 0)
{
tuple.add(new SeqValue(root.title.substring(0, bra)));
} else
{
tuple.add(new SeqValue(""));
}
return new TupleValue(tuple);
} catch (ValueException e)
{
throw new ContextException(e, ctxt.location);
} catch (Exception e)
{
throw new ContextException(4076, e.getMessage(), ctxt.location, ctxt);
}
}
}