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)); } }
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()); }