예제 #1
0
파일: DType.cs 프로젝트: Orvid/D_Parser
 public TemplateParameterSymbol(TemplateParameter tpn, ISemantic typeOrValue, ISyntaxRegion paramIdentifier = null)
     : base(tpn != null ? tpn.Representation : null, AbstractType.Get(typeOrValue), paramIdentifier)
 {
     IsKnowinglyUndetermined = TemplateInstanceHandler.IsNonFinalArgument(typeOrValue);
     this.Parameter          = tpn;
     this.ParameterValue     = typeOrValue as ISymbolValue;
 }
예제 #2
0
        /// <summary>
        /// Checks results for implicit type convertability
        /// </summary>
        public static bool IsImplicitlyConvertible(ISemantic resultToCheck, AbstractType targetType, ResolverContextStack ctxt = null)
        {
            var resToCheck = AbstractType.Get(resultToCheck);

            // Initially remove aliases from results
            var _r = DResolver.StripMemberSymbols(resToCheck);

            if (_r == null)
            {
                return(IsEqual(resToCheck, targetType));
            }
            resToCheck = _r;

            targetType = DResolver.StripAliasSymbol(targetType);

            if (targetType is DSymbol)
            {
                var tpn = ((DSymbol)targetType).Definition as TemplateParameterNode;

                if (tpn != null)
                {
                    var par = tpn.Parent as DNode;

                    if (par != null && par.TemplateParameters != null)
                    {
                        var dedParam = new DeducedTypeDictionary {
                            ParameterOwner = par
                        };
                        foreach (var tp in par.TemplateParameters)
                        {
                            dedParam[tp.Name] = null;
                        }

                        return(new TemplateParameterDeduction(dedParam, ctxt).Handle(tpn.TemplateParameter, resToCheck));
                    }
                }
            }

            _r = DResolver.StripMemberSymbols(targetType);
            if (_r == null)
            {
                return(false);
            }
            targetType = _r;

            if (resToCheck is PrimitiveType && targetType is PrimitiveType)
            {
                var sr1 = (PrimitiveType)resToCheck;
                var sr2 = (PrimitiveType)targetType;

                if (sr1.TypeToken == sr2.TypeToken && sr1.Modifier == sr2.Modifier)
                {
                    return(true);
                }

                switch (sr2.TypeToken)
                {
                case DTokens.Int:
                    return(sr1.TypeToken == DTokens.Uint);

                case DTokens.Uint:
                    return(sr1.TypeToken == DTokens.Int);
                    //TODO: Further types that can be converted into each other implicitly
                }
            }
            else if (resToCheck is UserDefinedType && targetType is UserDefinedType)
            {
                return(IsImplicitlyConvertible((UserDefinedType)resToCheck, (UserDefinedType)targetType));
            }
            else if (resToCheck is DelegateType && targetType is DelegateType)
            {
                //TODO
            }
            else if (resToCheck is ArrayType && targetType is ArrayType)
            {
                var ar1 = (ArrayType)resToCheck;
                var ar2 = (ArrayType)targetType;

                // Key as well as value types must be matching!
                var ar1_n = ar1.KeyType == null;
                var ar2_n = ar2.KeyType == null;

                if (ar1_n != ar2_n)
                {
                    return(false);
                }

                if (ar1_n || IsImplicitlyConvertible(ar1.KeyType, ar2.KeyType, ctxt))
                {
                    return(IsImplicitlyConvertible(ar1.Base, ar2.Base, ctxt));
                }
            }

            else if (resToCheck is TypeTuple && targetType is TypeTuple)
            {
                return(true);
            }
            else if (resToCheck is ExpressionTuple && targetType is ExpressionTuple)
            {
                return(true);
            }

            /*else if (resultToCheck is ExpressionValueResult && targetType is ExpressionValue)
             * {
             *      return ((ExpressionValueResult)resultToCheck).Value.Equals(((ExpressionValueResult)targetType).Value);
             * }*/

            // http://dlang.org/type.html
            //TODO: Pointer to non-pointer / vice-versa checkability? -- Can it really be done implicitly?

            return(false);
        }
예제 #3
0
        static StaticProperties()
        {
            var props = new Dictionary <int, StaticPropertyInfo>();

            Properties[PropOwnerType.Generic] = props;

            props.AddProp(new StaticPropertyInfo("init", "A type's or variable's static initializer expression")
            {
                TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType
            });
            props.AddProp(new StaticPropertyInfo("sizeof", "Size of a type or variable in bytes", DTokens.Uint));             // Do not define it as size_t due to unnecessary recursive definition as typeof(int.sizeof)
            props.AddProp(new StaticPropertyInfo("alignof", "Variable offset", DTokens.Uint)
            {
                RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("mangleof", "String representing the ‘mangled’ representation of the type", "string"));
            props.AddProp(new StaticPropertyInfo("stringof", "String representing the source representation of the type", "string")
            {
                ValueGetter = (vp, v) => {
                    var t = AbstractType.Get(v);
                    if (t == null)
                    {
                        return(new NullValue());
                    }
                    return(new ArrayValue(Evaluation.GetStringType(vp.ResolutionContext), (t is DSymbol) ? DNode.GetNodePath((t as DSymbol).Definition, true) : t.ToCode()));
                }
            });



            props = new Dictionary <int, StaticPropertyInfo>();
            Properties[PropOwnerType.Integral] = props;

            props.AddProp(new StaticPropertyInfo("max", "Maximum value")
            {
                TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType
            });
            props.AddProp(new StaticPropertyInfo("min", "Minimum value")
            {
                TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType
            });



            props = new Dictionary <int, StaticPropertyInfo>();
            Properties[PropOwnerType.FloatingPoint] = props;

            props.AddProp(new StaticPropertyInfo("infinity", "Infinity value")
            {
                TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType
            });
            props.AddProp(new StaticPropertyInfo("nan", "Not-a-Number value")
            {
                TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType
            });
            props.AddProp(new StaticPropertyInfo("dig", "Number of decimal digits of precision", DTokens.Int));
            props.AddProp(new StaticPropertyInfo("epsilon", "Smallest increment to the value 1")
            {
                TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType
            });
            props.AddProp(new StaticPropertyInfo("mant_dig", "Number of bits in mantissa", DTokens.Int));
            props.AddProp(new StaticPropertyInfo("max_10_exp", "Maximum int value such that 10^max_10_exp is representable", DTokens.Int));
            props.AddProp(new StaticPropertyInfo("max_exp", "Maximum int value such that 2^max_exp-1 is representable", DTokens.Int));
            props.AddProp(new StaticPropertyInfo("min_10_exp", "Minimum int value such that 10^max_10_exp is representable", DTokens.Int));
            props.AddProp(new StaticPropertyInfo("min_exp", "Minimum int value such that 2^max_exp-1 is representable", DTokens.Int));
            props.AddProp(new StaticPropertyInfo("min_normal", "Number of decimal digits of precision", DTokens.Int));
            props.AddProp(new StaticPropertyInfo("re", "Real part")
            {
                TypeGetter = help_ReflectNonComplexType, ResolvedBaseTypeGetter = help_ReflectResolvedNonComplexType, RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("im", "Imaginary part")
            {
                TypeGetter = help_ReflectNonComplexType, ResolvedBaseTypeGetter = help_ReflectResolvedNonComplexType, RequireThis = true
            });



            props = new Dictionary <int, StaticPropertyInfo>();
            Properties[PropOwnerType.Array] = props;

            props.AddProp(new StaticPropertyInfo("length", "Array length", DTokens.Int)
            {
                RequireThis = true,
                ValueGetter =
                    (vp, v) => {
                    var av = v as ArrayValue;
                    return(new PrimitiveValue(DTokens.Int, av.Elements != null ? av.Elements.Length : 0, null, 0m));
                }
            });

            props.AddProp(new StaticPropertyInfo("dup", "Create a dynamic array of the same size and copy the contents of the array into it.")
            {
                TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("idup", "D2.0 only! Creates immutable copy of the array")
            {
                TypeGetter = (t, ctxt) => new MemberFunctionAttributeDecl(DTokens.Immutable)
                {
                    InnerType = help_ReflectType(t, ctxt)
                }, RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("reverse", "Reverses in place the order of the elements in the array. Returns the array.")
            {
                TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("sort", "Sorts in place the order of the elements in the array. Returns the array.")
            {
                TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("ptr", "Returns pointer to the array")
            {
                ResolvedBaseTypeGetter = (t, ctxt) => new PointerType((t as DerivedDataType).Base, t.DeclarationOrExpressionBase),
                TypeGetter             = (t, ctxt) => new PointerDecl(DTypeToTypeDeclVisitor.GenerateTypeDecl((t as DerivedDataType).Base)),
                RequireThis            = true
            });



            props = new Dictionary <int, StaticPropertyInfo>(props);            // Copy from arrays' properties!
            Properties[PropOwnerType.AssocArray] = props;

            props.AddProp(new StaticPropertyInfo("length", "Returns number of values in the associative array. Unlike for dynamic arrays, it is read-only.", "size_t")
            {
                RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("keys", "Returns dynamic array, the elements of which are the keys in the associative array.")
            {
                TypeGetter = (t, ctxt) => new ArrayDecl {
                    ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).KeyType)
                }, RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("values", "Returns dynamic array, the elements of which are the values in the associative array.")
            {
                TypeGetter = (t, ctxt) => new ArrayDecl {
                    ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).ValueType)
                }, RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("rehash", "Reorganizes the associative array in place so that lookups are more efficient. rehash is effective when, for example, the program is done loading up a symbol table and now needs fast lookups in it. Returns a reference to the reorganized array.")
            {
                TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("byKey", "Returns a delegate suitable for use as an Aggregate to a ForeachStatement which will iterate over the keys of the associative array.")
            {
                TypeGetter = (t, ctxt) => new DelegateDeclaration()
                {
                    ReturnType = new ArrayDecl()
                    {
                        ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).KeyType)
                    }
                }, RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("byValue", "Returns a delegate suitable for use as an Aggregate to a ForeachStatement which will iterate over the values of the associative array.")
            {
                TypeGetter = (t, ctxt) => new DelegateDeclaration()
                {
                    ReturnType = new ArrayDecl()
                    {
                        ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).ValueType)
                    }
                }, RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("get", null)
            {
                RequireThis = true,
                NodeGetter  = (t, ctxt) =>
                {
                    var ad        = t as AssocArrayType;
                    var valueType = DTypeToTypeDeclVisitor.GenerateTypeDecl(ad.ValueType);
                    return(new DMethod()
                    {
                        Name = "get",
                        Description = "Looks up key; if it exists returns corresponding value else evaluates and returns defaultValue.",
                        Type = valueType,
                        Parameters = new List <INode> {
                            new DVariable()
                            {
                                Name = "key",
                                Type = DTypeToTypeDeclVisitor.GenerateTypeDecl(ad.KeyType)
                            },
                            new DVariable()
                            {
                                Name = "defaultValue",
                                Type = valueType,
                                Attributes = new List <DAttribute> {
                                    new Modifier(DTokens.Lazy)
                                }
                            }
                        }
                    });
                }
            });
            props.AddProp(new StaticPropertyInfo("remove", null)
            {
                RequireThis = true,
                NodeGetter  = (t, ctxt) => new DMethod
                {
                    Name        = "remove",
                    Description = "remove(key) does nothing if the given key does not exist and returns false. If the given key does exist, it removes it from the AA and returns true.",
                    Type        = new DTokenDeclaration(DTokens.Bool),
                    Parameters  = new List <INode> {
                        new DVariable {
                            Name = "key",
                            Type = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).KeyType)
                        }
                    }
                }
            });


            props = new Dictionary <int, StaticPropertyInfo>();
            Properties[PropOwnerType.TypeTuple] = props;

            props.AddProp(new StaticPropertyInfo("length", "Returns number of values in the type tuple.", "size_t")
            {
                RequireThis = true,
                ValueGetter =
                    (vp, v) => {
                    var tt = v as DTuple;
                    if (tt == null && v is TypeValue)
                    {
                        tt = (v as TypeValue).RepresentedType as DTuple;
                    }
                    return(tt != null ? new PrimitiveValue(DTokens.Int, tt.Items == null ? 0m : (decimal)tt.Items.Length, null, 0m) : null);
                }
            });



            props = new Dictionary <int, StaticPropertyInfo>();
            Properties[PropOwnerType.Delegate] = props;


            props.AddProp(new StaticPropertyInfo("ptr", "The .ptr property of a delegate will return the frame pointer value as a void*.",
                                                 (ITypeDeclaration) new PointerDecl(new DTokenDeclaration(DTokens.Void)))
            {
                RequireThis = true
            });
            props.AddProp(new StaticPropertyInfo("funcptr", "The .funcptr property of a delegate will return the function pointer value as a function type.")
            {
                RequireThis = true
            });



            props = new Dictionary <int, StaticPropertyInfo>();
            Properties[PropOwnerType.ClassLike] = props;

            props.AddProp(new StaticPropertyInfo("classinfo", "Information about the dynamic type of the class", (ITypeDeclaration) new IdentifierDeclaration("TypeInfo_Class")
            {
                ExpressesVariableAccess = true, InnerDeclaration = new IdentifierDeclaration("object")
            })
            {
                RequireThis = true
            });

            props = new Dictionary <int, StaticPropertyInfo>();
            Properties[PropOwnerType.Struct] = props;

            props.AddProp(new StaticPropertyInfo("sizeof", "Size in bytes of struct", DTokens.Uint));
            props.AddProp(new StaticPropertyInfo("alignof", "Size boundary struct needs to be aligned on", DTokens.Uint));
            props.AddProp(new StaticPropertyInfo("tupleof", "Gets type tuple of fields")
            {
                TypeGetter = (t, ctxt) =>
                {
                    var members = GetStructMembers(t as StructType, ctxt);
                    var l       = new List <IExpression>();

                    var vis = new DTypeToTypeDeclVisitor();
                    foreach (var member in members)
                    {
                        var mt = DResolver.StripMemberSymbols(member);
                        if (mt == null)
                        {
                            l.Add(null);
                            continue;
                        }
                        var td = mt.Accept(vis);
                        if (td == null)
                        {
                            l.Add(null);
                            continue;
                        }
                        l.Add(td as IExpression ?? new TypeDeclarationExpression(td));
                    }

                    return(new TemplateInstanceExpression(new IdentifierDeclaration("Tuple"))
                    {
                        Arguments = l.ToArray()
                    });
                },

                ResolvedBaseTypeGetter = (t, ctxt) =>
                {
                    var members    = GetStructMembers(t as StructType, ctxt);
                    var tupleItems = new List <ISemantic>();

                    foreach (var member in members)
                    {
                        var mt = DResolver.StripMemberSymbols(member);
                        if (mt != null)
                        {
                            tupleItems.Add(mt);
                        }
                    }

                    return(new DTuple(t.DeclarationOrExpressionBase, tupleItems));
                }
            });
        }
예제 #4
0
        /// <summary>
        /// Checks results for implicit type convertability
        /// </summary>
        public static bool IsImplicitlyConvertible(ISemantic resultToCheck, AbstractType targetType, ResolutionContext ctxt = null)
        {
            var  resToCheck = AbstractType.Get(resultToCheck);
            bool isVariable = resToCheck is MemberSymbol;

            // Initially remove aliases from results
            var _r = DResolver.StripMemberSymbols(resToCheck);

            if (_r == null)
            {
                return(IsEqual(resToCheck, targetType));
            }
            resToCheck = _r;

            if (targetType is DSymbol)
            {
                var tpn = ((DSymbol)targetType).Definition as TemplateParameter.Node;

                if (tpn != null)
                {
                    var par = tpn.Parent as DNode;

                    if (par != null && par.TemplateParameters != null)
                    {
                        var dedParam = new DeducedTypeDictionary(par);

                        return(new TemplateParameterDeduction(dedParam, ctxt).Handle(tpn.TemplateParameter, resToCheck));
                    }
                }
            }

            _r = DResolver.StripMemberSymbols(targetType);
            if (_r == null)
            {
                return(false);
            }
            targetType = _r;

            if (resToCheck is PrimitiveType && targetType is PrimitiveType)
            {
                var sr1 = (PrimitiveType)resToCheck;
                var sr2 = (PrimitiveType)targetType;

                //if (sr1.TypeToken == sr2.TypeToken /*&& sr1.Modifier == sr2.Modifier*/)
                //	return true;

                return(IsPrimitiveTypeImplicitlyConvertible(sr1.TypeToken, sr2.TypeToken));
            }
            else if (resToCheck is UserDefinedType && targetType is UserDefinedType)
            {
                return(IsImplicitlyConvertible((UserDefinedType)resToCheck, (UserDefinedType)targetType));
            }
            else if (resToCheck is DelegateType && targetType is DelegateType)
            {
                return(IsEqual(resToCheck, targetType));                //TODO: Can non-equal delegates be converted into each other?
            }
            else if (resToCheck is ArrayType && targetType is ArrayType)
            {
                var ar1 = (ArrayType)resToCheck;
                var ar2 = (ArrayType)targetType;

                // Key as well as value types must be matching!
                var ar1_n = ar1.KeyType == null;
                var ar2_n = ar2.KeyType == null;

                if (ar1_n != ar2_n)
                {
                    return(false);
                }

                if (ar1_n || IsImplicitlyConvertible(ar1.KeyType, ar2.KeyType, ctxt))
                {
                    return(IsImplicitlyConvertible(ar1.Base, ar2.Base, ctxt));
                }
            }
            else if (resToCheck is DSymbol && targetType is DSymbol)
            {
                var r1 = resToCheck as DSymbol;
                var r2 = targetType as DSymbol;

                if (r1.Definition == r2.Definition)
                {
                    //TODO: Compare template param deductions
                    return(true);
                }
            }
            else if (resToCheck is DTuple && targetType is DTuple)
            {
                var tup1 = resToCheck as DTuple;
                var tup2 = resToCheck as DTuple;

                //TODO
                return(true);
            }

            /*else if (resultToCheck is ExpressionValueResult && targetType is ExpressionValue)
             * {
             *      return ((ExpressionValueResult)resultToCheck).Value.Equals(((ExpressionValueResult)targetType).Value);
             * }*/

            // http://dlang.org/type.html
            //TODO: Pointer to non-pointer / vice-versa checkability? -- Can it really be done implicitly?
            else if (!isVariable &&
                     resToCheck is ArrayType &&
                     targetType is PointerType && ((targetType = (targetType as PointerType).Base) is PrimitiveType) &&
                     DTokens.IsBasicType_Character((targetType as PrimitiveType).TypeToken))
            {
                return((resultToCheck as ArrayType).IsString);
            }


            return(false);
        }
예제 #5
0
 public TemplateParameterSymbol(TemplateParameter tpn, ISemantic typeOrValue, ISyntaxRegion paramIdentifier = null)
     : base(tpn != null ? tpn.Representation : null, AbstractType.Get(typeOrValue), paramIdentifier)
 {
     this.Parameter      = tpn;
     this.ParameterValue = typeOrValue as ISymbolValue;
 }
예제 #6
0
 public TemplateParameterSymbol(TemplateParameter.Node tpn, ISemantic typeOrValue, ISyntaxRegion paramIdentifier = null)
     : base(tpn, AbstractType.Get(typeOrValue), paramIdentifier)
 {
     this.Parameter      = tpn.TemplateParameter;
     this.ParameterValue = typeOrValue as ISymbolValue;
 }