Represents a Prolog predicate.
Inheritance: PrologCodeTerm
Beispiel #1
0
 /// <summary>
 /// Initializes a new instance of PrologCodeClause class.
 /// </summary>
 public PrologCodeClause()
 {
     this._head  = null;
     this._goals = new ArrayList();
 }
 private void CompilePrologPredicateCall(PrologCodePredicate p)
 {
     if (_dictionary.InLastGoal)
     {
         if (_dictionary.GoalCount > 2)
         {
             _generator.Emit(OpCodes.Deallocate);
         }
         _generator.EmitExecute(p.Name, p.Arity);
     }
     else
     {
         _generator.EmitCall(p.Name, p.Arity);
     }
 }
Beispiel #3
0
 /// <summary>
 /// Initializes a new instance of PrologCodeClause class.
 /// </summary>
 /// <param name="_head">clause head predicate.</param>
 public PrologCodeClause(PrologCodePredicate _head)
 {
     this._head  = _head;
     this._goals = new ArrayList();
 }
 public void GenerateCodeFromPredicate(PrologCodePredicate p, ArrayList a)
 {
     PrologCodeClause clause = new PrologCodeClause(p);
     GenerateCodeFromClause(clause, a);
 }
        private void CompileBuiltinPredicateCall(PrologCodePredicate p)
        {
            AMPredicateSet pset = AMPredicateSet.Instance;
            _generator.EmitBCall((IAbstractMachinePredicate)pset.CreatePredicate(p.Name, p.Arity));

            if (_dictionary.InLastGoal)
            {
                if (_dictionary.GoalCount > 2)
                {
                    _generator.Emit(OpCodes.Deallocate);
                }
                // Emit 'proceed'
                _generator.EndProcedure();
            }
        }
 /// <summary>
 /// Initializes a new instance of PrologCodeClause class.
 /// </summary>
 /// <param name="_head">clause head predicate.</param>
 public PrologCodeClause(PrologCodePredicate _head)
 {
     this._head = _head;
     this._goals = new ArrayList();
 }
 /// <summary>
 /// Initializes a new instance of PrologCodeClause class.
 /// </summary>
 public PrologCodeClause()
 {
     this._head = null;
     this._goals = new ArrayList();
 }
        private void ProcessOperator(PrologCodePredicate p)
        {
            if (!(p.Arguments[0] is PrologCodeIntegerAtom))
            {
                _errors.Add(new PrologCompilerError("P0009", "Invalid operator priority.", "", false, _scanner.Current.Line, _scanner.Current.Column));
            }

            int priority = ((PrologCodeIntegerAtom)p.Arguments[0]).Value;

            if (!(p.Arguments[1] is PrologCodeConstantAtom))
            {
                _errors.Add(new PrologCompilerError("P0010", "Invalid operator associativity specifier.", "", false, _scanner.Current.Line, _scanner.Current.Column));
            }

            string associativity = ((PrologCodeConstantAtom)p.Arguments[1]).Value;

            if (p.Arguments[2] is PrologCodeNonEmptyList)
            {
                ArrayList operators = GetListOperators((PrologCodeNonEmptyList)p.Arguments[2]);

                foreach (PrologCodeTerm op in operators)
                {
                    DefineNewOperator(priority, associativity, op);
                }

            }
            else if(p.Arguments[2] is PrologCodeConstantAtom)
            {

                DefineNewOperator(priority, associativity, (PrologCodeTerm)p.Arguments[2]);
            }
            else if (p.Arguments[2] is PrologCodeStringAtom)
            {
                DefineNewOperator(priority, associativity, (PrologCodeTerm)p.Arguments[2]);
            }
            else
            {
                _errors.Add(new PrologCompilerError("P0011", "Invalid operator definition.", "", false, _scanner.Current.Line, _scanner.Current.Column));
            }
        }
 private void ProcessUsingDirective(PrologCodePredicate pred)
 {
     string ns = ((PrologCodeStringAtom)pred.Arguments[0]).Value;
     ns = ns.Replace("'", "");
     _codeUnit.Namespaces.Add(ns);
 }
        private void ProcessForeignMethod(PrologCodePredicate p)
        {
            // :- foreign(functor(+term,...),'Assembly','Class','MethodName').
            PrologCodeMethod foreignMethod = new PrologCodeMethod();
            PrologCodePredicate predicateFunctor = (PrologCodePredicate)p.Arguments[0];

            // Add argument types
            foreignMethod.Arguments = GetForeignMethodArguments(predicateFunctor);
            foreignMethod.AssemblyName = GetAtomOrStringValue((PrologCodeTerm)p.Arguments[1]);
            foreignMethod.Class = GetAtomOrStringValue((PrologCodeTerm)p.Arguments[2]);
            foreignMethod.PredicateName = predicateFunctor.Name;
            foreignMethod.MethodName = predicateFunctor.Name.Replace("'", "");

            if (p.Arguments.Count == 4)
            {
                foreignMethod.MethodName = GetAtomOrStringValue((PrologCodeTerm)p.Arguments[3]);
            }

            // Add the method
            _codeUnit.Methods.Add(foreignMethod);
        }
 private void ProcessAssemblyDirective(PrologCodePredicate pred)
 {
     string asm = ((PrologCodeStringAtom)pred.Arguments[0]).Value;
     asm = asm.Replace("'", "");
     _codeUnit.AssemblyFiles.Add(asm);
 }
        private ArrayList GetForeignMethodArguments(PrologCodePredicate f)
        {
            ArrayList args = new ArrayList();
            if (f.Arguments[0] is PrologCodeConstantAtom)
            {
                PrologCodeConstantAtom fc = (PrologCodeConstantAtom)f.Arguments[0];
                if (fc.Value == "none")
                {
                    return args;
                }
                else
                {
                    _errors.Add(new PrologCompilerError("P0012", "Invalid predicate-method definition", "", false, _scanner.Current.Line, _scanner.Current.Column));
                    return args;
                }
            }
            PrologCodePredicate functor = (PrologCodePredicate)f;
            foreach (PrologCodePredicate a in functor.Arguments)
            {
                int passing = 0;
                int datatype = 0;

                switch (a.Name)
                {
                    case "+":
                        passing = PrologCodeMethodArgument.PASS_IN;
                        break;
                    case "-":
                        passing = PrologCodeMethodArgument.PASS_OUT;
                        break;
                    case "?":
                        passing = PrologCodeMethodArgument.PASS_INOUT;
                        break;
                    default:
                        break;
                }
                switch (((PrologCodeConstantAtom)a.Arguments[0]).Value)
                {
                    case "string":
                        datatype = PrologCodeMethodArgument.STRING;
                        break;
                    case "char":
                        datatype = PrologCodeMethodArgument.CHAR;
                        break;
                    case "int":
                        datatype = PrologCodeMethodArgument.INT;
                        break;
                    case "float":
                        datatype = PrologCodeMethodArgument.FLOAT;
                        break;
                    case "term":
                        datatype = PrologCodeMethodArgument.TERM;
                        break;
                    case "bool":
                        datatype = PrologCodeMethodArgument.BOOL;
                        break;
                    default:
                        break;
                }
                args.Add(new PrologCodeMethodArgument(datatype, passing));
            }
            return args;
        }
        private PrologCodeTerm ConvertGoalVariableBinaryTreeToCodeDOM(BinaryTree var)
        {
            if (Char.IsUpper(var.Name[0]) || var.Name[0] == '_' || var.Name == "_")
            {
                if (var.Name == "_")
                {
                    _randomVariableID++;
                    return new PrologCodeVariable(var.Name + "%" + _randomVariableID.ToString());
                }
                return new PrologCodeVariable(var.Name);
            }
            else
            {
                // Not a functor, => atom | number | string
                if (var.Arguments == null || var.Arguments.Count == 0)
                {
                    if (var.Name == ".")
                    {
                        // TODO: can place return PrologCodeEmptyList() here.
                        return ConvertBinaryListToCodeDOM(var);
                    }
                    if (var.Left == null && var.Right == null)
                    {
                        // 'Atom string'
                        if (var.Name[0] == '\'')
                        {
                            return new PrologCodeStringAtom(var.Name);
                        }
                        else if (Char.IsDigit(var.Name[0]))
                        {
                            // 1.234
                            if (var.Name.IndexOf('.') != -1)
                            {
                                return new PrologCodeFloatAtom(float.Parse(var.Name));
                            }
                            // 213
                            else
                            {
                                return new PrologCodeIntegerAtom(Int32.Parse(var.Name));
                            }
                        }
                        else if (var.Name == "_")
                        {
                            return new PrologCodeNilAtom();
                        }
                        // atom
                        else
                        {

                            return new PrologCodeConstantAtom(var.Name);
                        }
                    }
                    else if (var.Left != null && var.Right != null)
                    {
                        PrologCodePredicate infixPredicate = new PrologCodePredicate(var.Name);
                        infixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Left));
                        infixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Right));
                        return infixPredicate;
                    }
                    else if (var.Left == null && var.Right != null)
                    {
                        PrologCodePredicate prefixPredicate = new PrologCodePredicate(var.Name);
                        prefixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Right));
                        return prefixPredicate;
                    }
                    else if (var.Left != null && var.Right == null)
                    {
                        PrologCodePredicate postfixPredicate = new PrologCodePredicate(var.Name);
                        postfixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Left));
                        return postfixPredicate;
                    }

                }
                // atom(a,X,atom(X)).
                else
                {
                    PrologCodePredicate functor = new PrologCodePredicate(var.Name);
                    ArrayList arguments = new ArrayList();
                    var.Flatten((BinaryTree)var.Arguments[0], ref arguments);
                    foreach (BinaryTree a in arguments)
                    {
                        functor.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(a));
                    }
                    return functor;
                }

            }
            return null;
        }
        private PrologCodeTerm ConvertGoalBinaryTreeToCodeDOM(BinaryTree goal)
        {
            if (goal.Name == ".")
            {
                return ConvertBinaryListToCodeDOM(goal);
            }
            else if (Char.IsUpper(goal.Name[0]))  // Goal is a variable
            {
                return new PrologCodeVariable(goal.Name);
            }
            else
            {
                PrologCodePredicate goalPredicate = new PrologCodePredicate(goal.Name);
                ArrayList gargs = new ArrayList();
                goal.Flatten(goal, ref gargs);
                goalPredicate.IsMethod = IsMethod(goal.Name, gargs.Count);
                goalPredicate.MethodInfo = GetMethodInfo(goal.Name);

                if (goal.Arguments != null && goal.Arguments.Count != 0)
                {
                    // Example:
                    // goal(X,a).
                    ArrayList arguments = new ArrayList();
                    goal.Flatten((BinaryTree)goal.Arguments[0], ref arguments);
                    foreach (BinaryTree a in arguments)
                    {
                        goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(a));
                    }
                    return goalPredicate;
                }
                else
                {
                    // X = a (goal is '=')
                    if (goal.Left != null && goal.Right != null)
                    {
                        goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Left));
                        goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Right));
                        return goalPredicate;
                    }
                    // [] + foo.
                    if (goal.Left == null && goal.Right != null)
                    {
                        goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Right));
                        return goalPredicate;
                    }
                    // X + []
                    if (goal.Left != null && goal.Right == null)
                    {
                        goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Left));
                        return goalPredicate;
                    }
                    if (goal.Left == null && goal.Right == null)
                    {
                        return goalPredicate;
                    }
                }
            }
            return null;
        }