Ejemplo n.º 1
0
        /// <summary>
        /// Invokes generation of FieldBuilder, MethodBuilder and ConstructorBuilder objects for type members.
        /// </summary>
        public void CheckMethod(MethodEntity method)
        {
            try
            {
                // exception is good
                ResolveMethod(method.Name, method.GetArgumentTypes(Context), true);

                if (this == Context.MainType)
                {
                    Context.Error(CompilerMessages.FunctionRedefinition, method.Name);
                }
                else
                {
                    Context.Error(CompilerMessages.MethodRedefinition, method.Name, Name);
                }
            }
            catch (KeyNotFoundException)
            {
                if (!_methods.ContainsKey(method.Name))
                {
                    _methods.Add(method.Name, new List <MethodEntity> {
                        method
                    });
                }
                else
                {
                    _methods[method.Name].Add(method);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a pure wrapper for function with 2 and more arguments.
        /// </summary>
        private void createPureWrapperMany(MethodEntity wrapper, string pureName)
        {
            var args = wrapper.GetArgumentTypes(Context);

            var fieldName = string.Format(EntityNames.PureMethodCacheNameTemplate, wrapper.Name);
            var tupleType = FunctionalHelper.CreateTupleType(args);
            var fieldType = typeof(Dictionary <,>).MakeGenericType(tupleType, wrapper.ReturnType);

            CreateField(fieldName, fieldType, true);

            var argGetters = wrapper.Arguments.Select(a => (NodeBase)Expr.Get(a)).ToArray();
            var tupleName  = "<args>";

            wrapper.Body = Expr.Block(
                ScopeKind.FunctionRoot,

                // $tmp = new Tuple<...> $arg1 $arg2 ...
                Expr.Let(tupleName, Expr.New(tupleType, argGetters)),

                // if ($dict == null) $dict = new Dictionary<$tupleType, $valueType> ()
                Expr.If(
                    Expr.Equal(
                        Expr.GetMember(EntityNames.MainTypeName, fieldName),
                        Expr.Null()
                        ),
                    Expr.Block(
                        Expr.SetMember(
                            EntityNames.MainTypeName, fieldName,
                            Expr.New(fieldType)
                            )
                        )
                    ),

                // if(not $dict.ContainsKey key) $dict.Add ($internal arg)
                Expr.If(
                    Expr.Not(
                        Expr.Invoke(
                            Expr.GetMember(EntityNames.MainTypeName, fieldName),
                            "ContainsKey",
                            Expr.Get(tupleName)
                            )
                        ),
                    Expr.Block(
                        Expr.Invoke(
                            Expr.GetMember(EntityNames.MainTypeName, fieldName),
                            "Add",
                            Expr.Get(tupleName),
                            Expr.Invoke(EntityNames.MainTypeName, pureName, argGetters)
                            )
                        )
                    ),

                // $dict[arg]
                Expr.GetIdx(
                    Expr.GetMember(EntityNames.MainTypeName, fieldName),
                    Expr.Get(tupleName)
                    )

                );
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a pure wrapper for function with 1 argument.
        /// </summary>
        private void CreatePureWrapper1(MethodEntity wrapper, string pureName)
        {
            var args    = wrapper.GetArgumentTypes(Context);
            var argName = wrapper.Arguments[0].Name;

            var fieldName = string.Format(EntityNames.PureMethodCacheNameTemplate, wrapper.Name);
            var fieldType = typeof(Dictionary <,>).MakeGenericType(args[0], wrapper.ReturnType);

            CreateField(fieldName, fieldType, true);

            wrapper.Body = Expr.Block(
                ScopeKind.FunctionRoot,

                // if ($dict == null) $dict = new Dictionary<$argType, $valueType> ()
                Expr.If(
                    Expr.Equal(
                        Expr.GetMember(EntityNames.MainTypeName, fieldName),
                        Expr.Null()
                        ),
                    Expr.Block(
                        Expr.SetMember(
                            EntityNames.MainTypeName, fieldName,
                            Expr.New(fieldType)
                            )
                        )
                    ),

                // if(not $dict.ContainsKey key) $dict.Add ($internal arg)
                Expr.If(
                    Expr.Not(
                        Expr.Invoke(
                            Expr.GetMember(EntityNames.MainTypeName, fieldName),
                            "ContainsKey",
                            Expr.Get(argName)
                            )
                        ),
                    Expr.Block(
                        Expr.Invoke(
                            Expr.GetMember(EntityNames.MainTypeName, fieldName),
                            "Add",
                            Expr.Get(argName),
                            Expr.Invoke(EntityNames.MainTypeName, pureName, Expr.Get(argName))
                            )
                        )
                    ),

                // $dict[arg]
                Expr.GetIdx(
                    Expr.GetMember(EntityNames.MainTypeName, fieldName),
                    Expr.Get(argName)
                    )
                );
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Invokes generation of FieldBuilder, MethodBuilder and ConstructorBuilder objects for type members.
        /// </summary>
        public void CheckMethod(MethodEntity method)
        {
            try
            {
                // exception is good
                ResolveMethod(method.Name, method.GetArgumentTypes(Context), true);

                if (this == Context.MainType)
                    Context.Error(CompilerMessages.FunctionRedefinition, method.Name);
                else
                    Context.Error(CompilerMessages.MethodRedefinition, method.Name, Name);
            }
            catch (KeyNotFoundException)
            {
                if (!_Methods.ContainsKey(method.Name))
                    _Methods.Add(method.Name, new List<MethodEntity> { method });
                else
                    _Methods[method.Name].Add(method);
            }
        }
Ejemplo n.º 5
0
        protected override Type resolve(Context ctx, bool mustReturn)
        {
            if(Identifier == "_")
                error(CompilerMessages.UnderscoreNameUsed);

            // local variable
            var local = Local ?? ctx.Scope.FindLocal(Identifier);
            if (local != null)
            {
                // only local constants are cached
                // because mutable variables could be closured later on
                if (local.IsConstant && local.IsImmutable && ctx.Options.UnrollConstants)
                    _LocalConstant = local;

                return local.Type;
            }

            // static function declared in the script
            try
            {
                var methods = ctx.MainType.ResolveMethodGroup(Identifier);
                if (methods.Length > 1)
                    error(CompilerMessages.FunctionInvocationAmbiguous, Identifier);

                _Method = methods[0];
                return FunctionalHelper.CreateFuncType(_Method.ReturnType, _Method.GetArgumentTypes(ctx));
            }
            catch (KeyNotFoundException) { }

            // algebraic type without a constructor
            var type = ctx.FindType(Identifier);
            if (type != null && type.Kind == TypeEntityKind.TypeLabel)
            {
                try
                {
                    type.ResolveConstructor(new Type[0]);
                    _Type = type;
                    return _Type.TypeInfo;
                }
                catch (KeyNotFoundException) { }
            }

            // global property
            try
            {
                _Property = ctx.ResolveGlobalProperty(Identifier);
                return _Property.PropertyType;
            }
            catch (KeyNotFoundException)
            {
                error(CompilerMessages.IdentifierNotFound, Identifier);
            }

            return typeof (UnitType);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Creates a pure wrapper for function with 2 and more arguments.
        /// </summary>
        private void createPureWrapperMany(MethodEntity wrapper, string pureName)
        {
            var args = wrapper.GetArgumentTypes(Context);

            var fieldName = string.Format(EntityNames.PureMethodCacheNameTemplate, wrapper.Name);
            var tupleType = FunctionalHelper.CreateTupleType(args);
            var fieldType = typeof(Dictionary<,>).MakeGenericType(tupleType, wrapper.ReturnType);

            CreateField(fieldName, fieldType, true);

            var argGetters = wrapper.Arguments.Select(a => (NodeBase)Expr.Get(a)).ToArray();
            var tupleName = "<args>";

            wrapper.Body = Expr.Block(
                ScopeKind.FunctionRoot,

                // $tmp = new Tuple<...> $arg1 $arg2 ...
                Expr.Let(tupleName, Expr.New(tupleType, argGetters)),

                // if ($dict == null) $dict = new Dictionary<$tupleType, $valueType> ()
                Expr.If(
                    Expr.Equal(
                        Expr.GetMember(EntityNames.MainTypeName, fieldName),
                        Expr.Null()
                    ),
                    Expr.Block(
                        Expr.SetMember(
                            EntityNames.MainTypeName, fieldName,
                            Expr.New(fieldType)
                        )
                    )
                ),

                // if(not $dict.ContainsKey key) $dict.Add ($internal arg)
                Expr.If(
                    Expr.Not(
                        Expr.Invoke(
                            Expr.GetMember(EntityNames.MainTypeName, fieldName),
                            "ContainsKey",
                            Expr.Get(tupleName)
                        )
                    ),
                    Expr.Block(
                        Expr.Invoke(
                            Expr.GetMember(EntityNames.MainTypeName, fieldName),
                            "Add",
                            Expr.Get(tupleName),
                            Expr.Invoke(EntityNames.MainTypeName, pureName, argGetters)
                        )
                    )
                ),

                // $dict[arg]
                Expr.GetIdx(
                    Expr.GetMember(EntityNames.MainTypeName, fieldName),
                    Expr.Get(tupleName)
                )

            );
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates a pure wrapper for function with 1 argument.
        /// </summary>
        private void createPureWrapper1(MethodEntity wrapper, string pureName)
        {
            var args = wrapper.GetArgumentTypes(Context);
            var argName = wrapper.Arguments[0].Name;

            var fieldName = string.Format(EntityNames.PureMethodCacheNameTemplate, wrapper.Name);
            var fieldType = typeof(Dictionary<,>).MakeGenericType(args[0], wrapper.ReturnType);

            CreateField(fieldName, fieldType, true);

            wrapper.Body = Expr.Block(
                ScopeKind.FunctionRoot,

                // if ($dict == null) $dict = new Dictionary<$argType, $valueType> ()
                Expr.If(
                    Expr.Equal(
                        Expr.GetMember(EntityNames.MainTypeName, fieldName),
                        Expr.Null()
                    ),
                    Expr.Block(
                        Expr.SetMember(
                            EntityNames.MainTypeName, fieldName,
                            Expr.New(fieldType)
                        )
                    )
                ),

                // if(not $dict.ContainsKey key) $dict.Add ($internal arg)
                Expr.If(
                    Expr.Not(
                        Expr.Invoke(
                            Expr.GetMember(EntityNames.MainTypeName, fieldName),
                            "ContainsKey",
                            Expr.Get(argName)
                        )
                    ),
                    Expr.Block(
                        Expr.Invoke(
                            Expr.GetMember(EntityNames.MainTypeName, fieldName),
                            "Add",
                            Expr.Get(argName),
                            Expr.Invoke(EntityNames.MainTypeName, pureName, Expr.Get(argName))
                        )
                    )
                ),

                // $dict[arg]
                Expr.GetIdx(
                    Expr.GetMember(EntityNames.MainTypeName, fieldName),
                    Expr.Get(argName)
                )
            );
        }
Ejemplo n.º 8
0
        protected override Type resolveExpressionType(Context ctx, bool mustReturn = true)
        {
            var local = LocalName ?? ctx.CurrentScope.FindName(Identifier);
            if (local != null)
            {
                // only local constants are cached
                // because mutable variables could be closured later on
                if (local.IsConstant && local.IsImmutable && ctx.Options.UnrollConstants)
                    m_LocalConstant = local;

                return local.Type;
            }

            try
            {
                var methods = ctx.MainType.ResolveMethodGroup(Identifier);
                if (methods.Length > 1)
                    Error(CompilerMessages.FunctionInvocationAmbiguous, Identifier);

                m_Method = methods[0];
                return FunctionalHelper.CreateFuncType(m_Method.ReturnType, m_Method.GetArgumentTypes(ctx));
            }
            catch (KeyNotFoundException) { }

            try
            {
                m_Property = ctx.ResolveGlobalProperty(Identifier);
                return m_Property.PropertyType;
            }
            catch (KeyNotFoundException)
            {
                Error(CompilerMessages.IdentifierNotFound, Identifier);
            }

            return typeof (Unit);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Creates a wrapper from a method entity.
        /// </summary>
        private MethodWrapper wrapMethod(MethodEntity method, bool isPartial = false)
        {
            return new MethodWrapper
            {
                Name = method.Name,
                Type = method.ContainerType.TypeInfo,

                IsStatic = method.IsStatic,
                IsVirtual = method.IsVirtual,
                IsPartiallyApplied = isPartial,
                IsVariadic = method.IsVariadic,

                MethodInfo = method.MethodInfo,
                ArgumentTypes = method.GetArgumentTypes(this),
                ReturnType = method.ReturnType
            };
        }