예제 #1
0
            /// <summary>
            /// Creates a hierarchical structure from the given namespaces.
            /// </summary>
            /// <param name="namespaces">The namespaces.</param>
            public static List <StructuredNamespace> StructureNamespaces(Namespace[] namespaces)
            {
                List <StructuredNamespace> list = new List <StructuredNamespace>();

                foreach (var ns in namespaces)
                {
                    var currentNsLevel = list;
                    for (int i = 0; i < ns.Path.Length; i++)
                    {
                        var pathAnalogon = currentNsLevel.Find(x => x.Name == ns.Path[i]);
                        if (pathAnalogon == null)
                        {
                            if (i == ns.Path.Length - 1)
                            {
                                pathAnalogon = new StructuredNamespace(ns);
                            }
                            else
                            {
                                pathAnalogon = new StructuredNamespace(ns.Path[i]);
                            }
                            currentNsLevel.Add(pathAnalogon);
                        }
                        else if (i == ns.Path.Length - 1)
                        {
                            pathAnalogon.UserFunctions.AddRange(ns.Functions);
                            foreach (var kv in ns.TypeDefinitions)
                            {
                                pathAnalogon.TypeDefinitions[kv.Key] = kv.Value;
                            }
                        }
                        currentNsLevel = pathAnalogon.Children;
                    }
                }
                return(list);
            }
예제 #2
0
        /// <summary>
        /// Adds a built-in function to this compiler instance.
        /// </summary>
        /// <param name="func">
        /// The function description.
        /// The `IsBuiltin` and `Index` fields are ignored and overwritten.
        /// </param>
        public void AddBuiltinFunction(FunctionSignature func)
        {
            if (object.ReferenceEquals(null, func.Arguments) ||
                string.IsNullOrEmpty(func.Name) ||
                object.ReferenceEquals(null, func.Namespace))
            {
                throw new ArgumentNullException("func");
            }

            // Find (or create) associated namespace
            StructuredNamespace ptr = _rootNamespace;

            foreach (string nsPart in func.Namespace)
            {
                var ns = ptr.Children.Find(x => x.Name == nsPart);
                if (ns == null)
                {
                    ptr.Children.Add(ns = new StructuredNamespace(nsPart));
                }
                ptr = ns;
            }

            // Make sure function has valid properties
            func.IsBuiltin = true;
            func.Index     = ptr.BuiltinFunctions.Where(x => x.Name == func.Name).Count();

            // Add the function
            ptr.BuiltinFunctions.Add(func);
        }
예제 #3
0
 /// <summary>
 /// Initializes a new compiler.
 /// </summary>
 /// <param name="appName">The name of the application.</param>
 /// <param name="namespaces">The namespaces containing the operations to be compiled.</param>
 /// <param name="typeTable">The type look-up table.</param>
 public CompilerBase(string appName, Namespace[] namespaces, ITypeTable builtinTypes)
 {
     if (object.ReferenceEquals(null, appName))
     {
         throw new ArgumentNullException("appName");
     }
     if (object.ReferenceEquals(null, namespaces))
     {
         throw new ArgumentNullException("namespaces");
     }
     if (object.ReferenceEquals(null, builtinTypes))
     {
         throw new ArgumentNullException("builtinTypes");
     }
     _appName                = appName;
     _rootNamespace          = StructuredNamespace.CreateRoot();
     _rootNamespace.Children = StructuredNamespace.StructureNamespaces(namespaces);
     _builtinTypes           = builtinTypes;
 }
예제 #4
0
        /// <summary>
        /// Resolves the given function in the specified context.
        /// </summary>
        /// <param name="funcPath">The (absolute or relative) path to the function.</param>
        /// <param name="namespaceContext">The namespace in which the function is called.</param>
        /// <param name="scope">The scope in which the function is called.</param>
        /// <param name="arguments">The arguments with which the function is called.</param>
        /// <returns>the function if it was found, an empty element with .Index == -1 otherwise.</returns>
        protected FunctionSignature ResolveFunction(string[] funcPath, string[] namespaceContext, Scope scope, IType[] arguments)
        {
            // List all potential functions
            List <FunctionSignature> potentialFunctions = new List <FunctionSignature>();
            string funcName = funcPath[funcPath.Length - 1];

            // `funcPath` can be relative to any part of `namespaceContext`
            for (int context = namespaceContext.Length; context >= 0; context--)
            {
                StructuredNamespace ptr = _rootNamespace; // pointer to the current namespace in the search process
                for (int i = 0; ptr != null && i < context + funcPath.Length - 1; i++)
                {
                    string token = i < context ? namespaceContext[i] : funcPath[i - context];
                    ptr = ptr.Children.Find(x => x.Name == token);
                }
                if (ptr != null)
                {
                    potentialFunctions.AddRange(ptr.BuiltinFunctions.
                                                Concat(ptr.UserFunctions.Select(f => f.Signature)).
                                                Where(f => f.Name == funcName));
                }
            }

            // `funcPath` can be relative to any imported namespace
            foreach (var ns in scope.GetImportedNamespaces())
            {
                StructuredNamespace ptr = _rootNamespace; // pointer to the current namespace in the search process
                for (int i = 0; ptr != null && i < ns.Length + funcPath.Length - 1; i++)
                {
                    string token = i < ns.Length ? ns[i] : funcPath[i - ns.Length];
                    ptr = ptr.Children.Find(x => x.Name == token);
                }
                if (ptr != null)
                {
                    potentialFunctions.AddRange(ptr.BuiltinFunctions.
                                                Concat(ptr.UserFunctions.Select(f => f.Signature)).
                                                Where(f => f.Name == funcName));
                }
            }

            // Search for the first function which matches the signature
            foreach (var f in potentialFunctions)
            {
                if (f.Arguments.Length != arguments.Length)
                {
                    continue;
                }
                bool signatureMatch = true;
                for (int i = 0; i < f.Arguments.Length; i++)
                {
                    if (!arguments[i].CanCastTo(f.Arguments[i].Type))
                    {
                        signatureMatch = false;
                        break;
                    }
                }
                if (signatureMatch)
                {
                    return(f);
                }
            }

            return(new FunctionSignature {
                Index = -1
            });
        }