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 void ProcessAssemblyDirective(PrologCodePredicate pred)
        {
            string asm = ((PrologCodeStringAtom)pred.Arguments[0]).Value;

            asm = asm.Replace("'", "");
            _codeUnit.AssemblyFiles.Add(asm);
        }
        private bool ResolveConflicts(PrologCodeTerm term, int index)
        {
            PrologVariableDictionaryEntry entry = _dictionary.GetVariable(index);

            if (_dictionary.CurrentGoalIndex != 1 || entry == null || entry.LastGoalArgument < index)
            {
                PrologRegisterTable.Instance.AllocateRegister(index);
                return(false);
            }
            if (term is PrologCodePredicate)
            {
                PrologCodePredicate predicate = (PrologCodePredicate)term;
                for (int i = index + 1; i < entry.LastGoalArgument; i++)
                {
                    if (predicate.Name == entry.Name &&
                        (_dictionary.GetVariable(i) == null || ResolveConflicts(term, i)))
                    {
                        entry.TemporaryIndex = i;
                        _generator.Emit(OpCodes.Put_Value, X(index), X(i));
                        return(true);
                    }
                }
                // I WAS HERE
            }
            //return true; THIS WAS THERE
            entry.TemporaryIndex = PrologRegisterTable.Instance.FindRegister();
            _generator.Emit(OpCodes.Put_Value, X(index), X(entry.TemporaryIndex));
            return(true);
        }
        private void ProcessUsingDirective(PrologCodePredicate pred)
        {
            string ns = ((PrologCodeStringAtom)pred.Arguments[0]).Value;

            ns = ns.Replace("'", "");
            _codeUnit.Namespaces.Add(ns);
        }
        /* Initialize temporary goal variables in the dictionary */
        private void InitializeGoalTemporaryVariables(PrologCodeTerm goal)
        {
            /* Free all registers */
            PrologRegisterTable.Instance.FreeAllRegisters();

            int reg = 0;

            if (goal is PrologCodePredicate)
            {
                PrologCodePredicate g = (PrologCodePredicate)goal;

                if (g.Arity > 0)
                {
                    foreach (PrologCodeTerm var in g.Arguments)
                    {
                        if (var is PrologCodeVariable)
                        {
                            PrologVariableDictionaryEntry entry = _dictionary.GetVariable(((PrologCodeVariable)var).Name);
                            if (entry != null)
                            {
                                if (entry.IsTemporary && entry.TemporaryIndex == -1)
                                {
                                    _dictionary.AllocateTemporaryVariable(entry, reg);
                                }
                            }
                            reg++;
                        }
                    }
                }
            }
        }
 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 PrologCodeTerm ConvertGoalBinaryTreeToCodeDOM(BinaryTree goal)
        {
            if (goal.Name == ".")
            {
                return(ConvertBinaryListToCodeDOM(goal));
            }
            else if (Char.IsUpper(goal.Name[0]))  // Goal is a variable
            {
                return(new PrologCodeVariable(goal.Name));
            }
            else
            {
                PrologCodePredicate goalPredicate = new PrologCodePredicate(goal.Name);
                ArrayList           gargs         = new ArrayList();
                goal.Flatten(goal, ref gargs);
                goalPredicate.IsMethod   = IsMethod(goal.Name, gargs.Count);
                goalPredicate.MethodInfo = GetMethodInfo(goal.Name);

                if (goal.Arguments != null && goal.Arguments.Count != 0)
                {
                    // Example:
                    // goal(X,a).
                    ArrayList arguments = new ArrayList();
                    goal.Flatten((BinaryTree)goal.Arguments[0], ref arguments);
                    foreach (BinaryTree a in arguments)
                    {
                        goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(a));
                    }
                    return(goalPredicate);
                }
                else
                {
                    // X = a (goal is '=')
                    if (goal.Left != null && goal.Right != null)
                    {
                        goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Left));
                        goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Right));
                        return(goalPredicate);
                    }
                    // [] + foo.
                    if (goal.Left == null && goal.Right != null)
                    {
                        goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Right));
                        return(goalPredicate);
                    }
                    // X + []
                    if (goal.Left != null && goal.Right == null)
                    {
                        goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Left));
                        return(goalPredicate);
                    }
                    if (goal.Left == null && goal.Right == null)
                    {
                        return(goalPredicate);
                    }
                }
            }
            return(null);
        }
Example #8
0
        public void NameTest()
        {
            PrologCodePredicate prologCodePredicate = new PrologCodePredicate("male");

            string result = prologCodePredicate.Name;

            Assert.AreEqual("male", result);
        }
Example #9
0
        public void ArgumentsTest()
        {
            PrologCodePredicate prologCodePredicate = new PrologCodePredicate("predicate");

            ArrayList result = prologCodePredicate.Arguments;

            Assert.AreEqual(0, result.Count);
        }
        public void ArgumentsTest()
        {
            PrologCodePredicate prologCodePredicate = new PrologCodePredicate("predicate");

            ArrayList result = prologCodePredicate.Arguments;

            Assert.AreEqual(0, result.Count);
        }
Example #11
0
        public void ArityTest()
        {
            PrologCodePredicate prologCodePredicate = new PrologCodePredicate();

            int result = prologCodePredicate.Arity;

            Assert.AreEqual(0, result);
        }
        public void ArityTest()
        {
            PrologCodePredicate prologCodePredicate = new PrologCodePredicate();

            int result = prologCodePredicate.Arity;

            Assert.AreEqual(0, result);
        }
        public void NameTest()
        {
            PrologCodePredicate prologCodePredicate = new PrologCodePredicate("male");

            string result = prologCodePredicate.Name;

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

            object result = prologCodeNonEmptyList.Head;

            Assert.AreEqual(head, result);
        }
 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);
     }
 }
        public void HeadTest()
        {
            PrologCodePredicate head = new PrologCodePredicate("head");
            PrologCodeNonEmptyList prologCodeNonEmptyList = new PrologCodeNonEmptyList(head);

            object result = prologCodeNonEmptyList.Head;

            Assert.AreEqual(head, result);
        }
        private void ProcessHeadlessClause(PrologCodeTerm term)
        {
            PrologCodeHeadlessClause clause = (PrologCodeHeadlessClause)term;

            foreach (PrologCodeTerm t in clause.Goals)
            {
                if (t is PrologCodePredicate)
                {
                    PrologCodePredicate pred = (PrologCodePredicate)t;
                    switch (pred.Name)
                    {
                    case "op":
                        ProcessOperator(pred);
                        break;

                    case "class":
                        PrologCodeTerm arg = (PrologCodeTerm)pred.Arguments[0];
                        if (arg is PrologCodeConstantAtom)
                        {
                            PrologCodeConstantAtom atom = (PrologCodeConstantAtom)arg;
                            _codeUnit.Class = atom.Value;
                        }
                        else if (arg is PrologCodeStringAtom)
                        {
                            PrologCodeStringAtom atom = (PrologCodeStringAtom)arg;
                            _codeUnit.Class = atom.Value.Replace("'", "");
                        }
                        else
                        {
                            _errors.Add(new PrologCompilerError("P0002", "Illegal class name.", "", false, _scanner.Current.Line, _scanner.Current.Column));
                        }
                        break;

                    case "foreign":
                        ProcessForeignMethod(pred);
                        break;

                    case "load_assembly":
                        ProcessAssemblyDirective(pred);
                        break;

                    case "using":
                        ProcessUsingDirective(pred);
                        break;
                    }
                }
                else if (t is PrologCodeList)
                {
                }
            }
        }
 private void CompilePrologPredicateCall(PrologCodePredicate p)
 {
     if (_dictionary.InLastGoal)
     {
         if (_dictionary.GoalCount > 2)
         {
             _generator.Emit(OpCodes.Deallocate);
         }
         _generator.EmitExecute(p.Name, p.Arity);
     }
     else
     {
         _generator.EmitCall(p.Name, p.Arity);
     }
 }
 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 void CompileBuiltinPredicateCall(PrologCodePredicate p)
        {
            AMPredicateSet pset = AMPredicateSet.Instance;

            _generator.EmitBCall((IAbstractMachinePredicate)pset.CreatePredicate(p.Name, p.Arity));

            if (_dictionary.InLastGoal)
            {
                if (_dictionary.GoalCount > 2)
                {
                    _generator.Emit(OpCodes.Deallocate);
                }
                // Emit 'proceed'
                _generator.EndProcedure();
            }
        }
        private void CompileCall(PrologCodeTerm p)
        {
            AMPredicateSet      builtins  = AMPredicateSet.Instance;
            PrologCodePredicate predicate = (PrologCodePredicate)p;

            if (builtins.IsBuiltin(predicate.Name, predicate.Arity))
            {
                CompileBuiltinPredicateCall(predicate);
            }
            else if (predicate.IsMethod)
            {
                CompileMethod(predicate);
            }
            else
            {
                CompilePrologPredicateCall(predicate);
            }
        }
        private void CompileMethod(PrologCodeTerm method)
        {
            PrologCodePredicate predicate = (PrologCodePredicate)method;

            _generator.EmitFCall(predicate.MethodInfo.PredicateName,
                                 predicate.MethodInfo.MethodName,
                                 predicate.MethodInfo.AssemblyName,
                                 predicate.MethodInfo.Class);

            if (_dictionary.InLastGoal)
            {
                if (_dictionary.GoalCount > 2)
                {
                    _generator.Emit(OpCodes.Deallocate);
                }
                // Emit 'proceed'
                _generator.EndProcedure();
            }
        }
        private void ProcessForeignMethod(PrologCodePredicate p)
        {
            // :- foreign(functor(+term,...),'Assembly','Class','MethodName').
            PrologCodeMethod    foreignMethod    = new PrologCodeMethod();
            PrologCodePredicate predicateFunctor = (PrologCodePredicate)p.Arguments[0];

            // Add argument types
            foreignMethod.Arguments     = GetForeignMethodArguments(predicateFunctor);
            foreignMethod.AssemblyName  = GetAtomOrStringValue((PrologCodeTerm)p.Arguments[1]);
            foreignMethod.Class         = GetAtomOrStringValue((PrologCodeTerm)p.Arguments[2]);
            foreignMethod.PredicateName = predicateFunctor.Name;
            foreignMethod.MethodName    = predicateFunctor.Name.Replace("'", "");

            if (p.Arguments.Count == 4)
            {
                foreignMethod.MethodName = GetAtomOrStringValue((PrologCodeTerm)p.Arguments[3]);
            }

            // Add the method
            _codeUnit.Methods.Add(foreignMethod);
        }
        private void ProcessOperator(PrologCodePredicate p)
        {
            if (!(p.Arguments[0] is PrologCodeIntegerAtom))
            {
                _errors.Add(new PrologCompilerError("P0009", "Invalid operator priority.", "", false, _scanner.Current.Line, _scanner.Current.Column));
            }

            int priority = ((PrologCodeIntegerAtom)p.Arguments[0]).Value;

            if (!(p.Arguments[1] is PrologCodeConstantAtom))
            {
                _errors.Add(new PrologCompilerError("P0010", "Invalid operator associativity specifier.", "", false, _scanner.Current.Line, _scanner.Current.Column));
            }

            string associativity = ((PrologCodeConstantAtom)p.Arguments[1]).Value;

            if (p.Arguments[2] is PrologCodeNonEmptyList)
            {
                ArrayList operators = GetListOperators((PrologCodeNonEmptyList)p.Arguments[2]);

                foreach (PrologCodeTerm op in operators)
                {
                    DefineNewOperator(priority, associativity, op);
                }
            }
            else if (p.Arguments[2] is PrologCodeConstantAtom)
            {
                DefineNewOperator(priority, associativity, (PrologCodeTerm)p.Arguments[2]);
            }
            else if (p.Arguments[2] is PrologCodeStringAtom)
            {
                DefineNewOperator(priority, associativity, (PrologCodeTerm)p.Arguments[2]);
            }
            else
            {
                _errors.Add(new PrologCompilerError("P0011", "Invalid operator definition.", "", false, _scanner.Current.Line, _scanner.Current.Column));
            }
        }
        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 ArrayList GetForeignMethodArguments(PrologCodePredicate f)
        {
            ArrayList args = new ArrayList();

            if (f.Arguments[0] is PrologCodeConstantAtom)
            {
                PrologCodeConstantAtom fc = (PrologCodeConstantAtom)f.Arguments[0];
                if (fc.Value == "none")
                {
                    return(args);
                }
                else
                {
                    _errors.Add(new PrologCompilerError("P0012", "Invalid predicate-method definition", "", false, _scanner.Current.Line, _scanner.Current.Column));
                    return(args);
                }
            }
            PrologCodePredicate functor = (PrologCodePredicate)f;

            foreach (PrologCodePredicate a in functor.Arguments)
            {
                int passing  = 0;
                int datatype = 0;

                switch (a.Name)
                {
                case "+":
                    passing = PrologCodeMethodArgument.PASS_IN;
                    break;

                case "-":
                    passing = PrologCodeMethodArgument.PASS_OUT;
                    break;

                case "?":
                    passing = PrologCodeMethodArgument.PASS_INOUT;
                    break;

                default:
                    break;
                }
                switch (((PrologCodeConstantAtom)a.Arguments[0]).Value)
                {
                case "string":
                    datatype = PrologCodeMethodArgument.STRING;
                    break;

                case "char":
                    datatype = PrologCodeMethodArgument.CHAR;
                    break;

                case "int":
                    datatype = PrologCodeMethodArgument.INT;
                    break;

                case "float":
                    datatype = PrologCodeMethodArgument.FLOAT;
                    break;

                case "term":
                    datatype = PrologCodeMethodArgument.TERM;
                    break;

                case "bool":
                    datatype = PrologCodeMethodArgument.BOOL;
                    break;

                default:
                    break;
                }
                args.Add(new PrologCodeMethodArgument(datatype, passing));
            }
            return(args);
        }
        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");
                }
            }
        }
        public void GenerateCodeFromPredicate(PrologCodePredicate p, ArrayList a)
        {
            PrologCodeClause clause = new PrologCodeClause(p);

            GenerateCodeFromClause(clause, a);
        }
        public void GenerateCodeFromClause(PrologCodeClause clause, ArrayList instructions)
        {
            /* Do we need to allocate an environment? */
            bool hasEnvironment = clause.Goals.Count > 1;

            /* Initialize variable dictionary */
            _dictionary = new PrologVariableDictionary();

            /* Build the variable dictionary for this clause */
            _dictionary.Build(clause);

            /* Free all registers */
            PrologRegisterTable registers = PrologRegisterTable.Instance;

            registers.FreeAllRegisters();

            /* Prepare head variables for code generation */
            int reg = 0;

            if (clause.Head.Arity > 0)
            {
                headArity = clause.Head.Arity;
                foreach (PrologCodeTerm argument in clause.Head.Arguments)
                {
                    if (argument is PrologCodeVariable)
                    {
                        PrologCodeVariable            var   = (PrologCodeVariable)argument;
                        PrologVariableDictionaryEntry entry = _dictionary.GetVariable(var.Name);
                        if (entry != null)
                        {
                            if (entry.IsTemporary && entry.TemporaryIndex == -1)
                            {
                                entry.IsReferenced = true;
                                _dictionary.AllocateTemporaryVariable(entry, reg);
                            }
                        }
                        //BUG: reg++;
                    }
                    reg++;
                }
            }

            /* Prepare first goal variables */
            int            xreg = 0;
            PrologCodeTerm fg   = null;

            if (clause.Goals.Count > 0)
            {
                fg = (PrologCodeTerm)clause.Goals[0];
            }
            if (fg is PrologCodePredicate)
            {
                PrologCodePredicate firstGoal = (PrologCodePredicate)fg;
                if (firstGoal.Name == "!")
                {
                    hasEnvironment = true;
                }
                if (firstGoal.Arity > 0)
                {
                    foreach (PrologCodeTerm variable in firstGoal.Arguments)
                    {
                        if (variable is PrologCodeVariable)
                        {
                            PrologVariableDictionaryEntry entry = _dictionary.GetVariable(((PrologCodeVariable)variable).Name);
                            if (entry != null)
                            {
                                if (entry.IsTemporary && entry.TemporaryIndex == -1)
                                {
                                    if (!registers.InUse(xreg))
                                    {
                                        _dictionary.AllocateTemporaryVariable(entry, xreg);
                                    }
                                }
                            }
                        }
                        xreg++;
                    }
                }
            }
            /* Reserve required registers */
            for (int i = 0; i < Math.Max(reg, xreg); i++)
            {
                registers.AllocateRegister(i);
            }

            /* Emit predicate label */
            _generator.DeclareProcedure(clause.Head.Name, clause.Head.Arity);

            /* Allocate an environment if needed */
            if (hasEnvironment)
            {
                _generator.Emit(OpCodes.Allocate);
            }

            /* Compile clause head */
            CompileClauseHead(clause.Head, instructions);

            /* Set current goal to 1 */
            _dictionary.CurrentGoalIndex = 1;

            if (clause.Goals.Count == 0)
            {
                _generator.EndProcedure();

                /* Reset variable dictionary */
                _dictionary.Reset();
                instructions = _generator.Instructions;
                return;
            }

            /* Compile first goal */
            CompileGoal(fg, instructions);
            _dictionary.CurrentGoalIndex++;

            /* Compile the rest of the goals */
            for (int goalIndex = 1; goalIndex < clause.Goals.Count; goalIndex++)
            {
                PrologCodeTerm goal = (PrologCodeTerm)clause.Goals[goalIndex];
                InitializeGoalTemporaryVariables(goal);

                /* reserve registers */
                for (int i = 0; i < reg; i++)
                {
                    registers.AllocateRegister(i);
                }

                /* Clear temporary index of permanent variables */
                _dictionary.ClearTempIndexOfPermanentVariables();

                /* Compile goal */
                CompileGoal(goal, instructions);

                /* Advance to next goal */
                _dictionary.CurrentGoalIndex += 1;
            }

            /* Reset instruction set, code pointer, and variable
             * dictionary.
             */
            _dictionary.Reset();
        }
        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 PrologCodeTerm ConvertGoalVariableBinaryTreeToCodeDOM(BinaryTree var)
 {
     if (Char.IsUpper(var.Name[0]) || var.Name[0] == '_' || var.Name == "_")
     {
         if (var.Name == "_")
         {
             _randomVariableID++;
             return(new PrologCodeVariable(var.Name + "%" + _randomVariableID.ToString()));
         }
         return(new PrologCodeVariable(var.Name));
     }
     else
     {
         // Not a functor, => atom | number | string
         if (var.Arguments == null || var.Arguments.Count == 0)
         {
             if (var.Name == ".")
             {
                 // TODO: can place return PrologCodeEmptyList() here.
                 return(ConvertBinaryListToCodeDOM(var));
             }
             if (var.Left == null && var.Right == null)
             {
                 // 'Atom string'
                 if (var.Name[0] == '\'')
                 {
                     return(new PrologCodeStringAtom(var.Name));
                 }
                 else if (Char.IsDigit(var.Name[0]))
                 {
                     // 1.234
                     if (var.Name.IndexOf('.') != -1)
                     {
                         return(new PrologCodeFloatAtom(float.Parse(var.Name)));
                     }
                     // 213
                     else
                     {
                         return(new PrologCodeIntegerAtom(Int32.Parse(var.Name)));
                     }
                 }
                 else if (var.Name == "_")
                 {
                     return(new PrologCodeNilAtom());
                 }
                 // atom
                 else
                 {
                     return(new PrologCodeConstantAtom(var.Name));
                 }
             }
             else if (var.Left != null && var.Right != null)
             {
                 PrologCodePredicate infixPredicate = new PrologCodePredicate(var.Name);
                 infixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Left));
                 infixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Right));
                 return(infixPredicate);
             }
             else if (var.Left == null && var.Right != null)
             {
                 PrologCodePredicate prefixPredicate = new PrologCodePredicate(var.Name);
                 prefixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Right));
                 return(prefixPredicate);
             }
             else if (var.Left != null && var.Right == null)
             {
                 PrologCodePredicate postfixPredicate = new PrologCodePredicate(var.Name);
                 postfixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Left));
                 return(postfixPredicate);
             }
         }
         // atom(a,X,atom(X)).
         else
         {
             PrologCodePredicate functor   = new PrologCodePredicate(var.Name);
             ArrayList           arguments = new ArrayList();
             var.Flatten((BinaryTree)var.Arguments[0], ref arguments);
             foreach (BinaryTree a in arguments)
             {
                 functor.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(a));
             }
             return(functor);
         }
     }
     return(null);
 }