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, LibraryList libraries, bool optimize) { return(Compile(codeSentence, null, -1, false, libraries, optimize)); }
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 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."); } } }