public bool TryGetProcedure(Functor functor, out Procedure procedure)
 {
     return(_procedureIndex.TryGetValue(functor, out procedure));
 }
示例#2
0
 public WamInstruction(WamInstructionOpCodes opCode, WamInstructionRegister sourceRegister, Functor functor)
 {
     if (functor == null)
     {
         throw new ArgumentNullException("functor");
     }
     if (sourceRegister.IsUnused)
     {
         throw new ArgumentException("Invalid value.", "sourceRegister");
     }
     _opCode          = opCode;
     _sourceRegister  = sourceRegister;
     _functor         = functor;
     _index           = -1;
     _targetRegister  = WamInstructionRegister.Unused;
     _referenceTarget = null;
 }
示例#3
0
 public static WamCompoundTerm Create(Functor functor)
 {
     return(new WamCompoundTerm(functor));
 }
 public Procedure this[Functor functor]
 {
     get { return(_procedureIndex[functor]); }
 }
示例#5
0
 private void RetryMeElse(Functor functor, int index)
 {
     InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.RetryMeElse, functor, index));
 }
示例#6
0
        private void Execute(CodeFunctor codeFunctor)
        {
            Functor functor = Functor.Create(codeFunctor);

            InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.Execute, functor));
        }
示例#7
0
        private void Get(CodeCompoundTerm codeCompoundTerm, WamInstructionRegister sourceRegister)
        {
            WamInstructionRegister[] childrenRegisters = new WamInstructionRegister[codeCompoundTerm.Children.Count];

            InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.GetStructure, sourceRegister, Functor.Create(codeCompoundTerm.Functor)));
            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.UnifyUnboundVariable, variableRegister));
                    }
                    else
                    {
                        InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.UnifyBoundVariable, variableRegister));
                    }
                }
                else if (child.IsCodeCompoundTerm)
                {
                    childrenRegisters[idx] = GetNextTemporaryRegister();
                    InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.UnifyUnboundVariable, childrenRegisters[idx]));
                }
                else if (child.IsCodeValue)
                {
                    InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.UnifyValue, WamValue.Create(child.AsCodeValue)));
                }
                else
                {
                    throw new InvalidOperationException("Unsupported codeTerm type.");
                }
            }

            // 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)
                {
                    Get(child, childrenRegisters[idx]);
                }
            }
        }
示例#8
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());
        }
        private WamReferenceTarget     m_referenceTarget; // 4 bytes

        #endregion

        #region Constructors

        public WamInstruction(WamInstructionOpCodes opCode, WamInstructionRegister sourceRegister, Functor functor, int index, WamInstructionRegister targetRegister)
        {
            if (sourceRegister.IsUnused)
            {
                throw new ArgumentException("Invalid value.", "sourceRegister");
            }
            if (functor == null)
            {
                throw new ArgumentNullException("functor");
            }
            if (index < 0)
            {
                throw new ArgumentException("Invalid index.", "index");
            }
            if (targetRegister.IsUnused)
            {
                throw new ArgumentException("Invalid value.", "targetRegister");
            }

            m_opCode          = opCode;
            m_sourceRegister  = sourceRegister;
            m_functor         = functor;
            m_index           = index;
            m_targetRegister  = targetRegister;
            m_referenceTarget = null;
        }