Пример #1
0
        /// <summary>
        /// Creates a signature from a CallExpression object
        /// </summary>
        /// <param name="callExpr">CallExpresion object</param>
        public Signature(CallExpression callExpr)
        {
            // Set fully qualified name and return type
            name = callExpr.methodName;
            returnType = callExpr.returnType;
            arguments = new List<BaseType>();

            // Populate argument list
            foreach (Expression expr in callExpr.arguments)
            {
                arguments.Add(expr.returnType);
            }
        }
Пример #2
0
        void UnaryExpr(out Expression expr)
        {
            expr = null;
            switch (la.kind) {
            case 40: {
            Get();
            expr = new UnaryExpression(UnaryOperator.UMinus);
            expr.t = t;

            UnaryExpr(out (expr as UnaryExpression).operand);
            break;
            }
            case 41: {
            Get();
            expr = new UnaryExpression(UnaryOperator.Not);
            expr.t = t;

            UnaryExpr(out (expr as UnaryExpression).operand);
            break;
            }
            case 2: case 3: case 4: case 26: case 27: {
            ConstantExpression(out expr);
            break;
            }
            case 36: {
            Get();
            Expect(21);
            expr = new CastExpression(PrimitiveType.INT);
            expr.t = t;

            Expect(43);
            UnaryExpr(out (expr as CastExpression).operand);
            break;
            }
            case 1: {
            Get();
            expr = new VariableReferenceExpression(t.val);
            expr.t = t;

            while (la.kind == 32) {
                Get();
                Expect(1);
                (expr as VariableReferenceExpression).name += "." + t.val;
            }
            if (la.kind == 38) {
                Get();
                expr = new CallExpression((expr as VariableReferenceExpression).name, expr.t);
                Expression argument;

                if (StartOf(3)) {
                    Expression(out argument);
                    (expr as CallExpression).AddArgument(argument);
                    while (la.kind == 31) {
                        Get();
                        Expression(out argument);
                        (expr as CallExpression).AddArgument(argument);
                    }
                }
                Expect(45);
            }
            if (la.kind == 37) {
                Get();
                expr = new IndexerExpression(expr);
                Expression indexer;

                Expression(out indexer);
                (expr as IndexerExpression).AddIndexer(indexer);
                while (la.kind == 31) {
                    Get();
                    Expression(out indexer);
                    (expr as IndexerExpression).AddIndexer(indexer);
                }
                Expect(44);
            }
            break;
            }
            case 38: {
            Get();
            Expression(out expr);
            Expect(45);
            break;
            }
            default: SynErr(56); break;
            }
        }
Пример #3
0
        /// <summary>
        /// Retrieves a function MethodInfo from a given call expression
        /// </summary>
        /// <param name="callExpr">CallExpression object</param>
        /// <returns>MethodInfo of closest matching function or null if no matching function
        /// is found</returns>
        public override MethodInfo GetMethodInfo(CallExpression callExpr)
        {
            // Convert call expression to signature
            Signature sig = new Signature(callExpr);

            // Candidates to best match
            List<Signature> candidates = new List<Signature>();
            List<MethodInfo> candidatesMethodInfo = new List<MethodInfo>();

            // For each function in function list
            foreach (FunctionDeclaration decl in functions)
            {
                // Create signature
                Signature testSig = decl.ToSignature();

                // If name is different, continue to next function
                if (sig.name != testSig.name)
                {
                    continue;
                }

                // If an exact match is found, return it
                if (sig.IsExactMatch(testSig))
                {
                    return decl.mb;
                }

                // If signatures are incompatible, continue to next function
                if (!sig.IsCompatible(testSig))
                {
                    continue;
                }

                bool add = false, brk = false;

                // Check current signature against each other candidate
                foreach (Signature candSig in candidates)
                {
                    // Pick best signature from current signature and candidate
                    switch (sig.BestSignature(candSig, testSig))
                    {
                        // If neither is better, mark add to add this function to the list of candidates
                        case Match.Ambiguos:
                            add = true;
                            break;
                        // If this is better, remove the candidate from the list and mark add
                        case Match.SecondBest:
                            candidatesMethodInfo.RemoveAt(candidates.IndexOf(candSig));
                            candidates.Remove(candSig);
                            add = true;
                            break;
                        // If candidate is better, stop evaluating
                        case Match.FirstBest:
                            brk = true;
                            break;
                    }

                    // If brk is true, stop evaluating
                    if (brk)
                    {
                        break;
                    }
                }

                // If add is true, add this function to the candidate list
                if (add)
                {
                    candidates.Add(testSig);
                }
            }

            // Check if candidate list is empty
            if (candidates.Count == 0)
            {
                // If no match was found, delegate request to parent scope
                return parentScope.GetMethodInfo(callExpr);
            }
            // Check if a single match was found
            else if (candidates.Count == 1)
            {
                // Return match
                return candidatesMethodInfo[0];
            }
            // More than one match - ambiguos
            else
            {
                // Cannot determine which function to call
                return null;
            }
        }
Пример #4
0
        /// <summary>
        /// Retrieves an external function signature from a given call expression
        /// </summary>
        /// <param name="callExpr">CallExpression object</param>
        /// <returns>Closest matching signature or null if no matching function is found</returns>
        public override Signature GetFunction(CallExpression callExpr)
        {
            // Convert call expression to signature
            Signature sig = new Signature(callExpr);

            // Candidates to best match
            List<Signature> candidates = new List<Signature>();
            List<MethodInfo> candidatesMethodInfo = new List<MethodInfo>();

            // If signature was already found, return it
            if (signatureLookup.ContainsKey(sig.ToString()))
            {
                return signatureLookup[sig.ToString()];
            }

            // If we got to global scope and function doesn't have an FQN,
            // it means the function doesn't exist
            if (!sig.name.Contains("."))
            {
                return null;
            }

            // Split function FQN into type name and function name
            string typeName = sig.name.Substring(0, sig.name.LastIndexOf("."));
            string methodName = sig.name.Substring(sig.name.LastIndexOf(".") + 1);

            // For each assembly reference
            foreach (Assembly asm in references)
            {
                Type type = null;

                // Get type (from FQN type)
                foreach (Type t in asm.GetTypes())
                {
                    if (t.FullName == typeName)
                    {
                        type = t;
                    }
                }

                // If type is not found step to next assembly
                if (type == null)
                {
                    continue;
                }

                // Retrieve function list of the given type
                foreach (MethodInfo mi in type.GetMethods())
                {
                    // If name differs, step to next function
                    if (mi.Name != methodName)
                    {
                        continue;
                    }

                    // Create Signature object to test against
                    Signature testSig = new Signature(mi);

                    // Check if there is an exact match
                    if (sig.IsExactMatch(testSig))
                    {
                        // Add to dictionary
                        signatureLookup.Add(testSig.ToString(), testSig);
                        methodInfoLookup.Add(testSig.ToString(), mi);

                        return testSig;
                    }

                    // If signatures are incompatible, step to next function
                    if (!sig.IsCompatible(testSig))
                    {
                        continue;
                    }

                    bool add = false, brk = false;

                    // Check current signature against each other candidate
                    foreach (Signature candSig in candidates)
                    {
                        // Pick best signature from current signature and candidate
                        switch (sig.BestSignature(candSig, testSig))
                        {
                            // If neither is better, mark add to add this function to the list of candidates
                            case Match.Ambiguos:
                                add = true;
                                break;
                            // If this is better than the candidate
                            case Match.SecondBest:
                                // Remove candidate and mark add to add this function to the list
                                candidatesMethodInfo.RemoveAt(candidates.IndexOf(candSig));
                                candidates.Remove(candSig);
                                add = true;
                                break;
                            // If the candidate is better than this function there is no need to evaluate
                            // against other candidates - there is a better match than this one already found
                            case Match.FirstBest:
                                brk = true;
                                break;
                        }

                        // Stop evaluation if brk is true
                        if (brk)
                        {
                            break;
                        }
                    }

                    // Add function to the list of candidates if add is true
                    if (add)
                    {
                        candidates.Add(testSig);
                        candidatesMethodInfo.Add(mi);
                    }
                }
            }

            // Check if candidate list is empty
            if (candidates.Count == 0)
            {
                // No match was found
                return null;
            }
            // Check if a single candidate is in the list
            else if (candidates.Count == 1)
            {
                // Add to dictionaries
                signatureLookup.Add(candidates[0].ToString(), candidates[0]);
                methodInfoLookup.Add(candidates[0].ToString(), candidatesMethodInfo[0]);

                return candidates[0];
            }
            // If more candidates are in the list
            else
            {
                // Ambiguos call - cannot determine which candidate is the best
                return null;
            }
        }
Пример #5
0
 /// <summary>
 /// Retrieves a function signature from a given call expression
 /// </summary>
 /// <param name="callExpr">CallExpression object</param>
 /// <returns></returns>
 public override Signature GetFunction(CallExpression callExpr)
 {
     // Delegate request to parent scope since functions cannot be declared inside other functions
     return parentScope.GetFunction(callExpr);
 }
Пример #6
0
 /// <summary>
 /// Retrieves metadata information for a function
 /// </summary>
 /// <param name="callExpr">CallExpression for the function</param>
 /// <returns></returns>
 public override MethodInfo GetMethodInfo(CallExpression callExpr)
 {
     // Delegate request to parent scope since functions cannot be declared inside other functions
     return parentScope.GetMethodInfo(callExpr);
 }
Пример #7
0
 /// <summary>
 /// Retrieves metadata information for a function
 /// </summary>
 /// <param name="callExpr">CallExpression for the function</param>
 /// <returns></returns>
 public override MethodInfo GetMethodInfo(CallExpression callExpr)
 {
     // Since signatures are always searched during the evaluation step,
     // a MethodInfo must exist in the dictionary
     return methodInfoLookup[new Signature(callExpr).ToString()];
 }
Пример #8
0
 /// <summary>
 /// Retrieves metadata information for a function
 /// </summary>
 /// <param name="callExpr">CallExpression for the function</param>
 /// <returns></returns>
 public abstract MethodInfo GetMethodInfo(CallExpression callExpr);
Пример #9
0
 /// <summary>
 /// Retrieves the signature of a function
 /// </summary>
 /// <param name="callExpr">CallExpression for the function</param>
 /// <returns></returns>
 public abstract Signature GetFunction(CallExpression callExpr);
Пример #10
0
        /// <summary>
        /// Evaluates this node and all of its children
        /// </summary>
        /// <param name="scope">The scope of this statement</param>
        /// <returns></returns>
        public override Statement Evaluate(Scope scope)
        {
            // Just evaluate inner call expression
            expr = expr.Evaluate(scope) as CallExpression;

            return this;
        }
Пример #11
0
 /// <summary>
 /// Creates a new CallStatement given a CallExpression
 /// </summary>
 /// <param name="expr">CallExpression object</param>
 public CallStatement(Expression expr)
     : base()
 {
     this.expr = expr as CallExpression;
 }