private void AddGoalStructArgumentVariables(PrologCodeTerm term)
 {
     if (PrologCodeTerm.IsAtom(term))
     {
         return;
     }
     else if (PrologCodeTerm.IsVariable(term))
     {
         this.Add(((PrologCodeVariable)term).Name, null);
     }
     else if (PrologCodeTerm.IsList(term))
     {
         if (term is PrologCodeNonEmptyList)
         {
             PrologCodeNonEmptyList list = (PrologCodeNonEmptyList)term;
             AddGoalStructArgumentVariables(list.Head);
             if (list.Tail is PrologCodeNonEmptyList)
             {
                 AddGoalStructArgumentVariables(list.Tail);
             }
             else
             {
                 AddGoalStructArgumentVariables(list.Tail);
             }
         }
     }
     else if (PrologCodeTerm.IsStruct(term))
     {
         PrologCodePredicate structure = (PrologCodePredicate)term;
         foreach (PrologCodeTerm argument in structure.Arguments)
         {
             AddGoalStructArgumentVariables(argument);
         }
     }
 }
        private void CompileClauseHead(PrologCodeTerm head, ArrayList instructions)
        {
            if (head is PrologCodePredicate)
            {
                PrologCodePredicate headPredicate = (PrologCodePredicate)head;

                if (headPredicate.Arity == 0)
                {
                    /* Do nothing */
                }
                else
                {
                    CompileHeadArguments(((PrologCodePredicate)head).Arguments);
                }
            }
            else if (head is PrologCodeNonEmptyList)
            {
                ArrayList headListArguments   = new ArrayList();
                PrologCodeNonEmptyList NEList = (PrologCodeNonEmptyList)head;
                headListArguments.Add(NEList.Head);
                headListArguments.Add(NEList.Tail);
                CompileHeadArguments(headListArguments);
            }
            else if (head is PrologCodeVariable)
            {
                throw new PrologCompilerException("Clause head cannot be a variable.");
            }
            else if (head is PrologCodeIntegerAtom || head is PrologCodeFloatAtom)
            {
                throw new PrologCompilerException("Clause head cannot be a number.");
            }
        }
        private PrologCodeTerm ConvertBinaryListToCodeDOM(BinaryTree l)
        {
            BinaryList list = (BinaryList)l;

            if (list.Head == null && list.Tail == null)
            {
                return(new PrologCodeEmptyList());
            }

            PrologCodeNonEmptyList NEList = null;

            if (list.Head.Name == ".")
            {
                NEList = new PrologCodeNonEmptyList(ConvertBinaryListToCodeDOM(list.Head));
            }
            else
            {
                NEList = new PrologCodeNonEmptyList(ConvertGoalVariableBinaryTreeToCodeDOM(list.Head));
            }

            // Check the tail
            if (list.Tail.Name == ".")
            {
                NEList.Tail = ConvertBinaryListToCodeDOM(list.Tail);
            }
            else
            {
                NEList.Tail = ConvertGoalVariableBinaryTreeToCodeDOM(list.Tail);
            }
            return(NEList);
        }
        public void HeadTest()
        {
            PrologCodePredicate head = new PrologCodePredicate("head");
            PrologCodeNonEmptyList prologCodeNonEmptyList = new PrologCodeNonEmptyList(head);

            object result = prologCodeNonEmptyList.Head;

            Assert.AreEqual(head, result);
        }
        public void HeadTest()
        {
            PrologCodePredicate    head = new PrologCodePredicate("head");
            PrologCodeNonEmptyList prologCodeNonEmptyList = new PrologCodeNonEmptyList(head);

            object result = prologCodeNonEmptyList.Head;

            Assert.AreEqual(head, result);
        }
        public void TailTest()
        {
            PrologCodeAtom head = new PrologCodeAtom();
            PrologCodeNonEmptyList tail = new PrologCodeNonEmptyList(head);
            PrologCodeNonEmptyList prologCodeNonEmptyList = new PrologCodeNonEmptyList(head, tail);

            PrologCodeTerm result = prologCodeNonEmptyList.Tail;

            Assert.AreEqual(tail, result);
        }
        public void TailTest()
        {
            PrologCodeAtom         head = new PrologCodeAtom();
            PrologCodeNonEmptyList tail = new PrologCodeNonEmptyList(head);
            PrologCodeNonEmptyList prologCodeNonEmptyList = new PrologCodeNonEmptyList(head, tail);

            PrologCodeTerm result = prologCodeNonEmptyList.Tail;

            Assert.AreEqual(tail, result);
        }
 private void AddGoalVariables(PrologCodeTerm term)
 {
     // no variables to add: predicate/0
     if (PrologCodeTerm.IsAtom(term) || PrologCodeTerm.IsAtomicPredicate(term))
     {
         return;
     }
     // goal is a variable X
     else if (PrologCodeTerm.IsVariable(term))
     {
         _currentArgumentIndex = 0;
         this.Add(((PrologCodeVariable)term).Name, null);
         return;
     }
     // goal is a list, [Term|Term]
     else if (PrologCodeTerm.IsList(term))
     {
         _currentArgumentIndex = 0;
         if (term is PrologCodeNonEmptyList)
         {
             PrologCodeNonEmptyList list = (PrologCodeNonEmptyList)term;
             AddGoalArgumentVariables(list.Head);
             _currentArgumentIndex = 1;
             if (list.Tail != null)
             {
                 if (list.Tail is PrologCodeNonEmptyList)
                 {
                     AddGoalArgumentVariables(list.Tail);
                 }
                 else
                 {
                     AddGoalArgumentVariables(list.Tail);
                 }
             }
         }
     }
     // Goal is a predicate, term(term,...)
     else if (PrologCodeTerm.IsStruct(term))
     {
         _currentArgumentIndex = 0;
         PrologCodePredicate goal = (PrologCodePredicate)term;
         foreach (PrologCodeTerm argument in goal.Arguments)
         {
             AddGoalArgumentVariables(argument);
             _currentArgumentIndex++;
         }
     }
 }
        private ArrayList GetListOperators(PrologCodeNonEmptyList list)
        {
            ArrayList listMembers = new ArrayList();

            for (PrologCodeTerm l = list.Head; !(l is PrologCodeEmptyList); l = list.Tail)
            {
                if (l is PrologCodeAtom)
                {
                    listMembers.Add(l);
                }
                else
                {
                    _errors.Add(new PrologCompilerError("P0011", "Invalid operator definition.", "", false, _scanner.Current.Line, _scanner.Current.Column));
                }
            }
            return(listMembers);
        }
        private int CompileGoalRecord(PrologCodeTerm term, int index)
        {
            ArrayList recs      = new ArrayList();
            int       nRecs     = 0;
            ArrayList arguments = new ArrayList();

            if (term is PrologCodeNonEmptyList)
            {
                PrologCodeNonEmptyList NEList = (PrologCodeNonEmptyList)term;
                arguments.Add(NEList.Head);
                arguments.Add(NEList.Tail);
            }
            else if (term is PrologCodePredicate)
            {
                arguments = ((PrologCodePredicate)term).Arguments;
            }

            for (int i = 0; i < arguments.Count; i++)
            {
                PrologCodeTerm r = (PrologCodeTerm)arguments[i];
                if (r is PrologCodeNonEmptyList || r is PrologCodePredicate)
                {
                    nRecs = recs.Add(CompileGoalRecord(r, -1));
                }
            }
            if (index == -1)
            {
                index = PrologRegisterTable.Instance.FindRegister();
            }
            if (term is PrologCodeNonEmptyList)
            {
                _generator.Emit(OpCodes.Put_List, X(index));
            }
            else if (term is PrologCodePredicate)
            {
                PrologCodePredicate s = (PrologCodePredicate)term;
                _generator.Emit(OpCodes.Put_Structure, s.Name + "/" + s.Arity, X(index));
            }
            nRecs = 0;
            for (int i = 0; i < arguments.Count; i++)
            {
                PrologCodeTerm t = (PrologCodeTerm)arguments[i];
                if (t is PrologCodeNilAtom || t is PrologCodeEmptyList)
                {
                    _generator.Emit(OpCodes.Set_Constant, "[]");
                }
                else if (t is PrologCodeAtom)
                {
                    if (t is PrologCodeConstantAtom)
                    {
                        _generator.Emit(OpCodes.Set_Constant, ((PrologCodeConstantAtom)t).Value);
                    }
                    else if (t is PrologCodeStringAtom)
                    {
                        _generator.Emit(OpCodes.Set_Constant, ((PrologCodeStringAtom)t).Value);
                    }
                    else if (t is PrologCodeIntegerAtom)
                    {
                        _generator.Emit(OpCodes.Set_Constant, ((PrologCodeIntegerAtom)t).Value.ToString());
                    }
                    else if (t is PrologCodeFloatAtom)
                    {
                        _generator.Emit(OpCodes.Set_Constant, ((PrologCodeFloatAtom)t).Value.ToString());
                    }
                }
                else if (t is PrologCodeVariable)
                {
                    /* Compile Goal record variable */
                    CompileGoalRecordVariable((PrologCodeVariable)t);
                }
                else if (t is PrologCodePredicate || t is PrologCodeNonEmptyList)
                {
                    _generator.Emit(OpCodes.Set_Value, X((int)recs[nRecs]));
                    PrologRegisterTable.Instance.FreeRegister((int)recs[nRecs]);
                    nRecs++;
                }
            }
            return(index);
        }
        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");
                }
            }
        }
        private void CompileHeadArguments(ArrayList arguments)
        {
            for (int i = 0; i < arguments.Count; i++)
            {
                _currArgN = i;
                PrologCodeTerm arg = (PrologCodeTerm)arguments[i];

                if (arg is PrologCodeNilAtom || arg is PrologCodeEmptyList)
                {
                    _generator.Emit(OpCodes.Get_Constant, "[]", X(i));
                }
                else if (arg is PrologCodeAtom)
                {
                    if (arg is PrologCodeConstantAtom)
                    {
                        _generator.Emit(OpCodes.Get_Constant, ((PrologCodeConstantAtom)arg).Value, X(i));
                    }
                    else if (arg is PrologCodeIntegerAtom)
                    {
                        _generator.Emit(OpCodes.Get_Constant, ((PrologCodeIntegerAtom)arg).Value.ToString(), X(i));
                    }
                    else if (arg is PrologCodeFloatAtom)
                    {
                        _generator.Emit(OpCodes.Get_Constant, ((PrologCodeFloatAtom)arg).Value.ToString(), X(i));
                    }
                    else if (arg is PrologCodeStringAtom)
                    {
                        _generator.Emit(OpCodes.Get_Constant, ((PrologCodeStringAtom)arg).Value, X(i));
                    }
                }
                else if (arg is PrologCodeVariable)
                {
                    if (_dictionary.GoalCount == 0)
                    {
                        // warning: singleton variable
                    }
                    PrologVariableDictionaryEntry entry = _dictionary.GetVariable(((PrologCodeVariable)arg).Name);
                    if (entry.IsTemporary)
                    {
                        if (entry.IsReferenced && entry.TemporaryIndex != i)
                        {
                            _generator.Emit(OpCodes.Get_Value, X(entry.TemporaryIndex), X(i));
                        }
                    }
                    else
                    {
                        if (entry.IsReferenced)
                        {
                            _generator.Emit(OpCodes.Get_Value, Y(entry.PermanentIndex), X(i));
                        }
                        else
                        {
                            _generator.Emit(OpCodes.Get_Variable, Y(entry.PermanentIndex), X(i));
                        }
                    }
                }
                else if (arg is PrologCodeNonEmptyList)
                {
                    _generator.Emit(OpCodes.Get_List, X(i));
                    ArrayList listArguments       = new ArrayList();
                    PrologCodeNonEmptyList NEList = (PrologCodeNonEmptyList)arg;
                    listArguments.Add(NEList.Head);
                    listArguments.Add(NEList.Tail);
                    CompileStructArguments(listArguments);
                }
                else if (arg is PrologCodePredicate)
                {
                    PrologCodePredicate structure = (PrologCodePredicate)arg;
                    _generator.Emit(OpCodes.Get_Structure, structure.Name + "/" + structure.Arity, X(i));
                    CompileStructArguments(structure.Arguments);
                }
                else
                {
                    throw new PrologCompilerException("Unknown argument type (" + arg.GetType().ToString() + ") in head arguments");
                }
            }
        }