package org.perl6.metamodel;
import java.util.*;
import org.perl6.metamodel.metaclass.Dispatcher;
public abstract class MetaModel {
private static Stack CURRENT_DISPATCHER = new Stack();
public static java.lang.Object call_method (java.lang.Object inv, String label, ArrayList args)
throws Exception {
Dispatcher dispatcher = null;
HashMap options = new HashMap();
HashMap context = new HashMap();
if (inv.getClass().getName() == "org.perl6.metamodel.Instance") {
Instance inst = (Instance) inv;
dispatcher = inst._class().meta().dispatcher();
options.put("for", "INSTANCE");
}
else if (inv.getClass().getName() == "org.perl6.metamodel.Class") {
Class cls = (Class) inv;
dispatcher = cls.meta().dispatcher();
options.put("for", "CLASS");
}
else {
throw new Exception("Unsupported invocant");
}
context.put("dispatcher", dispatcher);
context.put("label", label);
context.put("options", options);
context.put("inv", inv);
context.put("args", args);
CURRENT_DISPATCHER.push(context);
Method method = WALKMETH(dispatcher, label, options);
java.lang.Object rval = method.call(inv, args);
CURRENT_DISPATCHER.pop();
return rval;
}
public static java.lang.Object next_METHOD () throws Exception {
HashMap curr_context = (HashMap) CURRENT_DISPATCHER.peek();
Method method = WALKMETH((Dispatcher)curr_context.get("dispatcher"),
(String)curr_context.get("label"),
(HashMap)curr_context.get("options"));
return method.call((java.lang.Object)curr_context.get("inv"),
(ArrayList)curr_context.get("args"));
}
public static MetaClass WALKCLASS (Dispatcher dispatcher, HashMap options) {
if (dispatcher.hasNext())
return dispatcher.next();
else return null;
}
public static Method WALKMETH (Dispatcher dispatcher, String method_name)
throws Exception {
return WALKMETH(dispatcher, method_name, new HashMap());
}
public static Method WALKMETH (Dispatcher dispatcher, String label, HashMap options)
throws Exception {
ArrayList tried = new ArrayList();
MetaClass current = WALKCLASS(dispatcher, options);
while(current != null) {
if (current.has_method(label, (String)options.get("for")))
return current.get_method(label, (String)options.get("for"));
tried.add(current.name());
current = WALKCLASS(dispatcher, options);
}
throw new Exception("Method " + label + " not found in: " + tried.toString());
}
public static MetaClass CLASS () throws Exception {
if (Method.CURRENT_CLASS_STACK.size() == 0)
throw new Exception("You cannot call $?CLASS from outside of a MetaModel method");
return (MetaClass)Method.CURRENT_CLASS_STACK.peek();
}
public static Object SELF () throws Exception {
if (Method.CURRENT_INVOCANT_STACK.size() == 0)
throw new Exception("You cannot call $.WHICH from outside of a MetaModel method");
return (Object)Method.CURRENT_INVOCANT_STACK.peek();
}
}