public void Build(PrologCodeClause clause)
        {
            /* reset goal count */
            _goalCount = 0;

            // reset everything.
            this.Reset();

            // set current goal index
            _currentGoalIndex = 0;

            // store head variables
            AddGoalVariables(clause.Head);
            _currentGoalIndex++;

            // build clause body goals
            foreach (PrologCodeTerm goal in clause.Goals)
            {
                AddGoalVariables(goal);
                _currentGoalIndex++;
            }

            // set goal count to where we reached so far
            _goalCount = _currentGoalIndex;

            // Mark temporary variables
            MarkTemporaryVariables();

            // Mark permanent variables
            MarkPermanentVariables();
        }
        public void GenerateCodeFromUnit(PrologCodeUnit unit, ArrayList instructions)
        {
            _generator = new AMGenerator(instructions);

            foreach (PrologCodeTerm term in unit.Terms)
            {
                ArrayList inst = new ArrayList();

                if (term is PrologCodeClause)
                {
                    GenerateCodeFromClause((PrologCodeClause)term, inst);
                    instructions.AddRange(inst);
                }
                else if (term is PrologCodePredicate)
                {
                    PrologCodeClause c = new PrologCodeClause((PrologCodePredicate)term);
                    GenerateCodeFromClause(c, inst);
                    instructions.AddRange(inst);
                }
                else
                {
                    throw new PrologCompilerException("Unknown term type: " + term.ToString());
                }
            }
        }
        public void ArityTest()
        {
            PrologCodeClause prologCodeClause = new PrologCodeClause();

            int result = prologCodeClause.Arity;

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

            int result = prologCodeClause.Arity;

            Assert.AreEqual(result, 0);
        }
 public PrologCodeTerm ConvertBinaryTreeToCodeDOM(BinaryTree tree)
 {
     // Clause
     if (tree.Name == ":-")
     {
         PrologCodeClause term = new PrologCodeClause();
         if (tree.Left != null)
         {
             ArrayList goals = new ArrayList();
             tree.Flatten(tree.Right, ref goals);
             foreach (BinaryTree goal in goals)
             {
                 term.Goals.Add(ConvertGoalBinaryTreeToCodeDOM(goal));
             }
             term.Head = (PrologCodePredicate)ConvertBinaryTreeToCodeDOM(tree.Left);
             return(term);
         }
         // Headless clause
         else
         {
             // process headless clause here
             PrologCodeHeadlessClause hClause = new PrologCodeHeadlessClause();
             ArrayList goals = new ArrayList();
             tree.Flatten(tree.Right, ref goals);
             foreach (BinaryTree goal in goals)
             {
                 hClause.Goals.Add(ConvertGoalBinaryTreeToCodeDOM(goal));
             }
             return(hClause);
         }
     }
     else if (tree.Name == ".")
     {
         return(ConvertBinaryListToCodeDOM(tree));
     }
     // Variable
     else if (Char.IsUpper(tree.Name[0]))
     {
         if (tree.Left != null || tree.Right != null)
         {
             ParserError("Something was not parsed right. Variable has arity > 0", 0, 0);
         }
         PrologCodeVariable var = new PrologCodeVariable(tree.Name);
         return(var);
     }
     else
     {
         return(ConvertGoalBinaryTreeToCodeDOM(tree));
     }
     //return null;
 }
        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();
        }
        public void GenerateCodeFromPredicate(PrologCodePredicate p, ArrayList a)
        {
            PrologCodeClause clause = new PrologCodeClause(p);

            GenerateCodeFromClause(clause, a);
        }