Пример #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, LibraryList libraries, bool optimize)
 {
     return(Compile(codeSentence, null, -1, false, libraries, optimize));
 }
Пример #3
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());
        }
Пример #4
0
        private void Put(CodeCompoundTerm codeCompoundTerm, WamInstructionRegister targetRegister, LibraryList libraries)
        {
            WamInstructionRegister[] childrenRegisters = new WamInstructionRegister[codeCompoundTerm.Children.Count];

            // Build substructures.
            //
            for (int idx = 0; idx < codeCompoundTerm.Children.Count; ++idx)
            {
                CodeTerm child = codeCompoundTerm.Children[idx];

                if (child.IsCodeList)
                {
                    child = ConvertCodeList(child.AsCodeList);
                }

                if (child.IsCodeCompoundTerm)
                {
                    childrenRegisters[idx] = GetNextTemporaryRegister();
                    Put(child, childrenRegisters[idx], libraries);
                }
            }

            Functor functor = Functor.Create(codeCompoundTerm.Functor);

            InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.PutStructure, functor, targetRegister));
            for (int idx = 0; idx < codeCompoundTerm.Children.Count; ++idx)
            {
                CodeTerm child = codeCompoundTerm.Children[idx];

                if (child.IsCodeList)
                {
                    child = ConvertCodeList(child.AsCodeList);
                }

                if (child.IsCodeVariable)
                {
                    string variableName = child.AsCodeVariable.Name;
                    WamInstructionRegister variableRegister = GetRegisterAssignment(variableName);
                    if (variableRegister.IsUnused)
                    {
                        variableRegister = GetNextPermanentRegister(variableName);
                        InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.SetUnboundVariable, variableRegister));
                    }
                    else
                    {
                        InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.SetBoundVariable, variableRegister));
                    }
                }
                else if (child.IsCodeCompoundTerm)
                {
                    InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.SetBoundVariable, childrenRegisters[idx]));
                }
                else if (child.IsCodeValue)
                {
                    InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.SetValue, WamValue.Create(child.AsCodeValue)));
                }
                else
                {
                    throw new InvalidOperationException("Unsupported codeTerm type.");
                }
            }
        }