private void CompileStructArguments(ArrayList arguments)
{
ArrayList records = new ArrayList();
// TODO: Why is it 20 here? was there a maximum number of records originally.
for (int i = 0; i < 20; i++)
{
records.Add(new Record());
}
int nRecs = 0;
for (int i = 0; i < arguments.Count; i++)
{
PrologCodeTerm term = (PrologCodeTerm)arguments[i];
if (term is PrologCodeNilAtom)
{
_generator.Emit(OpCodes.Unify_Constant, "[]");
}
else if (term is PrologCodeAtom)
{
if (term is PrologCodeConstantAtom)
{
_generator.Emit(OpCodes.Unify_Constant, ((PrologCodeConstantAtom)term).Value);
}
else if (term is PrologCodeIntegerAtom)
{
_generator.Emit(OpCodes.Unify_Constant, ((PrologCodeIntegerAtom)term).Value.ToString());
}
else if (term is PrologCodeFloatAtom)
{
_generator.Emit(OpCodes.Unify_Constant, ((PrologCodeFloatAtom)term).Value.ToString());
}
else if (term is PrologCodeStringAtom)
{
_generator.Emit(OpCodes.Unify_Constant, ((PrologCodeStringAtom)term).Value);
}
}
else if (term is PrologCodeVariable)
{
PrologVariableDictionaryEntry entry = _dictionary.GetVariable(((PrologCodeVariable)term).Name);
if (entry.IsReferenced)
{
if (entry.IsTemporary)
{
if (entry.IsGlobal)
{
_generator.Emit(OpCodes.Unify_Value, X(entry.TemporaryIndex));
}
else
{
// TODO: maybe this should be unify_variable
_generator.Emit(OpCodes.Unify_Local_Value, X(entry.TemporaryIndex));
entry.IsGlobal = true;
}
}
else
{
if (entry.IsGlobal)
{
_generator.Emit(OpCodes.Unify_Value, Y(entry.PermanentIndex));
}
else
{
_generator.Emit(OpCodes.Unify_Local_Value, Y(entry.PermanentIndex));
}
}
}
// not referenced
else
{
if (entry.IsTemporary)
{
if (entry.Occurrences == 1)
{
_generator.Emit(OpCodes.Unify_Void, "1");
}
else
{ // used to be i < entry.TemporaryIndex
if (_currArgN < entry.TemporaryIndex && entry.TemporaryIndex < headArity)
{
entry.TemporaryIndex = PrologRegisterTable.Instance.FindRegister();
}
_generator.Emit(OpCodes.Unify_Variable, X(entry.TemporaryIndex));
}
}
else
{
_generator.Emit(OpCodes.Unify_Variable, Y(entry.PermanentIndex));
}
entry.IsGlobal = true;
}
}
else if (term is PrologCodeEmptyList)
{
_generator.Emit(OpCodes.Unify_Constant, "[]");
}
else
{
((Record)records[nRecs]).Term = term;
((Record)records[nRecs]).TemporaryIndex = PrologRegisterTable.Instance.FindRegister();
_generator.Emit(OpCodes.Unify_Variable, X(((Record)records[nRecs]).TemporaryIndex));
nRecs++;
}
}
for (int i = 0; i < nRecs; i++)
{
Record r = (Record)records[i];
if (r.Term is PrologCodeNonEmptyList)
{
_generator.Emit(OpCodes.Get_List, X(r.TemporaryIndex));
PrologRegisterTable.Instance.FreeRegister(r.TemporaryIndex);
ArrayList listArguments = new ArrayList();
PrologCodeNonEmptyList NEList = (PrologCodeNonEmptyList)r.Term;
listArguments.Add(NEList.Head);
listArguments.Add(NEList.Tail);
CompileStructArguments(listArguments);
}
else if (r.Term is PrologCodePredicate)
{
PrologCodePredicate structure = (PrologCodePredicate)r.Term;
_generator.Emit(OpCodes.Get_Structure, structure.Name + "/" + structure.Arity, X(r.TemporaryIndex));
CompileStructArguments(structure.Arguments);
}
else
{
throw new PrologCompilerException("Unknown argument type (" + r.Term.GetType().ToString() + ") in structure arguments");
}
}
}