package nl.rug.ai.mas.oops.lua;
import nl.rug.ai.mas.oops.formula.Agent;
import nl.rug.ai.mas.oops.formula.AgentId;
import nl.rug.ai.mas.oops.formula.Formula;
import nl.rug.ai.mas.oops.formula.FullSubstitution;
import nl.rug.ai.mas.oops.formula.Substitution;
import nl.rug.ai.mas.oops.formula.Variable;
import nl.rug.ai.mas.oops.parser.Context;
import nl.rug.ai.mas.oops.parser.FormulaParser;
import org.luaj.vm.LFunction;
import org.luaj.vm.LTable;
import org.luaj.vm.LUserData;
import org.luaj.vm.LuaState;
public class LuaFormula {
FormulaParser d_parser;
private LTable d_table;
public LuaFormula() {
d_parser = new FormulaParser(new Context());
}
/**
* Register LuaFormula with the Lua VM. Leaves a constructor method on the stack.
* @param L
*/
public void register(LuaState L) {
d_table = new LTable();
d_table.put("__index", d_table);
d_table.put("substitute", new FunctionSubstitute());
L.pushfunction(new Constructor());
}
private final class Constructor extends LFunction {
public int invoke(LuaState L) {
Formula f = checkFormula(L, 1);
L.pushlvalue(new LUserData(f, d_table));
return 1;
}
}
private final class FunctionSubstitute extends LFunction {
public int invoke(LuaState L) {
Formula f = checkFormula(L, 1);
LTable fTable = L.totable(2);
LTable aTable = L.totable(3);
Substitution<Formula> fSubst = checkFormulaSubstitution(L, fTable);
Substitution<Agent> aSubst = checkAgentSubstitution(L, aTable);
L.pushlvalue(new LUserData(f.substitute(new FullSubstitution(aSubst, fSubst)), d_table));
return 1;
}
}
public Formula checkFormula(LuaState L, int pos, FormulaParser parser) {
String s = L.tostring(pos);
return checkFormula(L, s, parser);
}
private Formula checkFormula(LuaState L, int pos) {
return checkFormula(L, pos, d_parser);
}
private Formula checkFormula(LuaState L, String s, FormulaParser parser) {
if (!parser.parse(s)) {
L.error(parser.getErrorCause().toString());
}
return parser.getFormula();
}
private final class SubConstrFuncA extends LFunction {
private Substitution<Agent> d_sub = new Substitution<Agent>();
public int invoke(LuaState L) {
Variable<Agent> v = d_parser.getContext().getAgentVarMap().getOrCreate(L.tostring(1));
AgentId id = d_parser.getContext().getAgentIdMap().getOrCreate(L.tostring(2));
d_sub.put(v, id);
return 0;
}
public Substitution<Agent> getSubstitution() {
return d_sub;
}
}
public Substitution<Agent> checkAgentSubstitution(LuaState L, LTable table) {
SubConstrFuncA scf = new SubConstrFuncA();
table.foreach(L, scf, false);
return scf.getSubstitution();
}
private final class SubConstrFunc extends LFunction {
private Substitution<Formula> d_sub = new Substitution<Formula>();
public int invoke(LuaState L) {
Variable<Formula> v = d_parser.getContext().getFormulaVarMap().getOrCreate(L.tostring(1));
Formula f = checkFormula(L, 2);
d_sub.put(v, f);
return 0;
}
public Substitution<Formula> getSubstitution() {
return d_sub;
}
}
public Substitution<Formula> checkFormulaSubstitution(LuaState L, LTable table) {
SubConstrFunc scf = new SubConstrFunc();
table.foreach(L, scf, false);
return scf.getSubstitution();
}
}