示例#1
0
        private void Call(CodeFunctor codeFunctor, LibraryList libraries)
        {
            Functor functor = Functor.Create(codeFunctor);

            if (functor == Functor.CutFunctor)
            {
                InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.Cut));
            }
            else if (libraries.Contains(functor))
            {
                InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.LibraryCall, functor));
            }
            else
            {
                InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.Call, functor));
            }
        }
示例#2
0
        public WamInstructionStream Compile(CodeSentence codeSentence, Functor functor, int index, bool isLast, LibraryList libraries, bool optimize)
        {
            Initialize();

            // When true, indicates we are compiling code for a procedure clause.  When false, indicates we
            // are compiling for an ad hoc query.
            //
            bool isClause = (functor != null);

            if (isClause)
            {
                WamInstructionStreamClauseAttribute clauseAttribute = new WamInstructionStreamClauseAttribute(
                    m_instructionStreamBuilder.NextIndex,
                    functor,
                    index);
                m_instructionStreamBuilder.AddAttribute(clauseAttribute);
            }

            if (isClause)
            {
                if (isLast)
                {
                    if (index == 0)
                    {
                        // Procedure only has one clause in it.  No retry logic required.
                    }
                    else
                    {
                        TrustMe();
                    }
                }
                else
                {
                    if (index == 0)
                    {
                        TryMeElse(functor, index + 1);
                    }
                    else
                    {
                        RetryMeElse(functor, index + 1);
                    }
                }
            }

            Allocate();

            if (codeSentence.Head != null)
            {
                for (int idx = 0; idx < codeSentence.Head.Children.Count; ++idx)
                {
                    Get(codeSentence.Head.Children[idx], GetArgumentRegister(idx));
                }
            }

            if (codeSentence.Body.Count > 0)
            {
                for (int idxProcedure = 0; idxProcedure < codeSentence.Body.Count; ++idxProcedure)
                {
                    CodeCompoundTerm codeCompoundTerm = codeSentence.Body[idxProcedure];

                    for (int idxArgument = 0; idxArgument < codeCompoundTerm.Children.Count; ++idxArgument)
                    {
                        Put(codeCompoundTerm.Children[idxArgument], GetArgumentRegister(idxArgument), libraries);
                    }

                    bool isLastCall = (idxProcedure == codeSentence.Body.Count - 1);

                    if (isClause)
                    {
                        if (isLastCall)
                        {
                            if (optimize &&
                                !libraries.Contains(Functor.Create(codeCompoundTerm.Functor)) &&
                                codeCompoundTerm.Functor != CodeFunctor.CutFunctor)
                            {
                                Deallocate();
                                Execute(codeCompoundTerm.Functor);
                            }
                            else
                            {
                                Call(codeCompoundTerm.Functor, libraries);
                                Deallocate();
                                Proceed();
                            }
                        }
                        else
                        {
                            Call(codeCompoundTerm.Functor, libraries);
                        }
                    }
                    else // isQuery
                    {
                        Call(codeCompoundTerm.Functor, libraries);

                        if (isLastCall)
                        {
                            Success();
                        }
                    }
                }
            }
            else // fact
            {
                if (isClause)
                {
                    Deallocate();
                    Proceed();
                }
                else // isQuery
                {
                    // No action required.
                }
            }

            return(InstructionStreamBuilder.ToInstructionStream());
        }