private void CompileGoal(PrologCodeTerm goal, ArrayList instructions)
{
if (goal is PrologCodePredicate && ((PrologCodePredicate)goal).Arity == 0)
{
PrologCodePredicate goalPredicate = (PrologCodePredicate)goal;
if (goalPredicate.Arity == 0)
{
if (goalPredicate.Name == "!")
{
_generator.Emit(OpCodes.Cut);
if (_dictionary.InLastGoal)
{
_generator.Emit(OpCodes.Deallocate);
_generator.EndProcedure();
}
return;
}
if (goalPredicate.Name == "fail")
{
_generator.Emit(OpCodes.Fail);
_generator.EndProcedure();
return;
}
// TODO: handle methods here...
CompileCall(goalPredicate);
}
}
else if (goal is PrologCodeVariable)
{
CompileGoalVariable((PrologCodeVariable)goal, 0);
if (_dictionary.InLastGoal)
{
if (_dictionary.CurrentGoalIndex > 1)
{
_generator.Emit(OpCodes.Deallocate);
}
_generator.EmitExecuteVar(((PrologCodeVariable)goal).Name, 0);
}
else
{
_generator.EmitCallVar(((PrologCodeVariable)goal).Name, 0);
}
}
else if (goal is PrologCodeNonEmptyList)
{
// TODO: compile list arguments, then call ./2
}
else if (goal is PrologCodeIntegerAtom || goal is PrologCodeFloatAtom)
{
throw new PrologCompilerException("Clause goal cannot be a number.");
}
else if (goal is PrologCodePredicate)
{
CompileGoalArguments(((PrologCodePredicate)goal).Arguments);
CompileCall(goal);
}
}