Пример #1
0
        public static WamReferenceTarget Create(CodeTerm codeTerm)
        {
            if (codeTerm == null)
            {
                throw new ArgumentNullException("codeTerm");
            }
            var codeValue = codeTerm as CodeValue;

            if (codeValue != null)
            {
                return(WamValue.Create(codeValue));
            }
            var codeCompoundTerm = codeTerm as CodeCompoundTerm;

            if (codeCompoundTerm != null)
            {
                return(WamCompoundTerm.Create(codeCompoundTerm));
            }
            throw new ArgumentException("Invalid CodeTerm type.");
        }
Пример #2
0
        internal WamReferenceTarget Evaluate(WamReferenceTarget wamReferenceTarget)
        {
            if (wamReferenceTarget == null)
            {
                throw new ArgumentNullException("wamReferenceTarget");
            }

            var wamCompoundTerm = wamReferenceTarget.Dereference() as WamCompoundTerm;

            if (wamCompoundTerm == null)
            {
                return(wamReferenceTarget);
            }

            if (!Program.Libraries.Contains(wamCompoundTerm.Functor))
            {
                return(wamReferenceTarget);
            }

            var method = Program.Libraries[wamCompoundTerm.Functor];

            if (method == null ||
                method.CanEvaluate == false)
            {
                return(wamReferenceTarget);
            }

            var arguments = new WamReferenceTarget[method.Functor.Arity];

            for (var index = 0; index < method.Functor.Arity; ++index)
            {
                arguments[index] = Evaluate(wamCompoundTerm.Children[index]);
            }

            var function = method as Function;

            if (function != null)
            {
                var codeTerms = new CodeTerm[method.Functor.Arity];
                for (var index = 0; index < method.Functor.Arity; ++index)
                {
                    codeTerms[index] = arguments[index].GetCodeTerm();
                }

                CodeTerm result;
                try
                {
                    result = function.FunctionDelegate(codeTerms) ?? new CodeValueObject(null);
                }
                catch (Exception ex)
                {
                    result = new CodeValueException(ex);
                }

                return(WamValue.Create(result));
            }

            var predicate = method as Predicate;

            if (predicate != null)
            {
                bool result;
                try
                {
                    result = predicate.PredicateDelegate(this, arguments);
                }
                catch
                {
                    result = false;
                }

                return(WamValueBoolean.Create(result));
            }
            return(wamReferenceTarget);
        }
Пример #3
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]);
                }
            }
        }
Пример #4
0
 private void Get(CodeValue codeValue, WamInstructionRegister sourceRegister)
 {
     InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.GetValue, sourceRegister, WamValue.Create(codeValue)));
 }
Пример #5
0
 private void Put(CodeValue codeValue, WamInstructionRegister targetRegister)
 {
     InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.PutValue, WamValue.Create(codeValue), targetRegister));
 }
Пример #6
0
        void Put(CodeCompoundTerm codeCompoundTerm, WamInstructionRegister targetRegister, LibraryList libraries)
        {
            var childrenRegisters = new WamInstructionRegister[codeCompoundTerm.Children.Count];

            // Build substructures.
            //
            for (var idx = 0; idx < codeCompoundTerm.Children.Count; ++idx)
            {
                var child = codeCompoundTerm.Children[idx];
                if (child.IsCodeList)
                {
                    child = ConvertCodeList(child.AsCodeList);
                }
                if (child.IsCodeCompoundTerm)
                {
                    childrenRegisters[idx] = GetNextTemporaryRegister();
                    Put(child, childrenRegisters[idx], libraries);
                }
            }

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

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

                if (child.IsCodeList)
                {
                    child = ConvertCodeList(child.AsCodeList);
                }
                if (child.IsCodeVariable)
                {
                    var variableName     = child.AsCodeVariable.Name;
                    var 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.");
                }
            }
        }