예제 #1
0
        internal override Expression ResolveTypes(ParserContext parser, TypeResolver typeResolver)
        {
            int length = this.Keys.Length;

            this.ResolvedKeyType   = typeResolver.ResolveType(this.KeyType);
            this.ResolvedValueType = typeResolver.ResolveType(this.ValueType);
            for (int i = 0; i < length; ++i)
            {
                this.Keys[i]   = this.Keys[i].ResolveTypes(parser, typeResolver);
                this.Values[i] = this.Values[i].ResolveTypes(parser, typeResolver);

                if (!this.Keys[i].ResolvedType.CanAssignToA(this.ResolvedKeyType))
                {
                    throw new ParserException(this.Keys[i], "This key is the incorrect type.");
                }
                if (!this.Values[i].ResolvedType.CanAssignToA(this.ResolvedValueType))
                {
                    throw new ParserException(this.Values[i], "This value is the incorrect type.");
                }
            }

            if (this.ResolvedKeyType == parser.TypeContext.ANY || this.ResolvedValueType == parser.TypeContext.ANY)
            {
                this.ResolvedType = parser.TypeContext.ANY;
            }
            else
            {
                this.ResolvedType = ResolvedType.GetDictionaryType(this.ResolvedKeyType, this.ResolvedValueType);
            }

            return(this);
        }
예제 #2
0
        public ResolvedType ResolveType(AType type)
        {
            if (type.IsAnyType)
            {
                return(this.typeContext.ANY);
            }

            switch (type.RootType)
            {
            case "void": return(this.typeContext.VOID);

            case "int": return(this.typeContext.INTEGER);

            case "bool": return(this.typeContext.BOOLEAN);

            case "float": return(this.typeContext.FLOAT);

            case "string": return(this.typeContext.STRING);

            case "object": return(this.typeContext.OBJECT);

            case "[":
            case "List":
                if (type.Generics.Length != 1)
                {
                    throw new ParserException(type.FirstToken, "A list type has 1 generic.");
                }
                return(ResolvedType.ListOrArrayOf(ResolveType(type.Generics[0])));

            case "Dictionary":
                if (type.Generics.Length != 2)
                {
                    throw new ParserException(type.FirstToken, "A dictionary type has 2 generics.");
                }
                ResolvedType keyType   = ResolveType(type.Generics[0]);
                ResolvedType valueType = ResolveType(type.Generics[1]);
                switch (keyType.Category)
                {
                case ResolvedTypeCategory.INSTANCE:
                case ResolvedTypeCategory.INTEGER:
                case ResolvedTypeCategory.STRING:
                    // This is fine.
                    break;

                default:
                    throw new ParserException(type.Generics[0].FirstToken, "This is not a valid key type for a dictionary.");
                }
                return(ResolvedType.GetDictionaryType(keyType, valueType));

            default:
                ClassDefinition classDef = this.owner.FileScope.DoClassLookup(this.owner, type.FirstToken, type.RootType);
                return(ResolvedType.GetInstanceType(this.typeContext, classDef));
            }
        }