Esempio n. 1
0
        internal override Expression ResolveType(VariableScope varScope, PastelCompiler compiler)
        {
            if (this.Root is Variable && ((Variable)this.Root).Name == "Native")
            {
                string name = this.FieldName.Value;
                return(new ExtensibleFunctionReference(this.FirstToken, name));
            }

            this.Root = this.Root.ResolveType(varScope, compiler);

            string           possibleStructName = this.Root.ResolvedType.RootValue;
            StructDefinition structDef          = compiler.GetStructDefinition(possibleStructName);

            if (structDef != null)
            {
                this.StructType = structDef;
                int fieldIndex;
                if (!structDef.ArgIndexByName.TryGetValue(this.FieldName.Value, out fieldIndex))
                {
                    throw new ParserException(this.FieldName, "The struct '" + structDef.NameToken.Value + "' does not have a field called '" + this.FieldName.Value + "'");
                }
                this.ResolvedType = structDef.ArgTypes[fieldIndex];
                return(this);
            }

            this.NativeFunctionId = this.DetermineNativeFunctionId(this.Root.ResolvedType, this.FieldName.Value);
            if (this.NativeFunctionId != NativeFunction.NONE)
            {
                return(new NativeFunctionReference(this.FirstToken, this.NativeFunctionId, this.Root));
            }

            throw new NotImplementedException();
        }
Esempio n. 2
0
        internal override Expression ResolveWithTypeContext(PastelCompiler compiler)
        {
            for (int i = 0; i < this.Args.Length; ++i)
            {
                this.Args[i] = this.Args[i].ResolveWithTypeContext(compiler);
            }

            string type = this.Type.RootValue;

            switch (type)
            {
            case "Array":
            case "List":
            case "Dictionary":
                break;

            default:
                StructDefinition sd = compiler.GetStructDefinition(this.Type.RootValue);
                if (sd != null)
                {
                    this.StructType = sd;
                }
                break;
            }

            return(this);
        }
Esempio n. 3
0
        public void ResolveParentChain(
            Dictionary <string, StructDefinition> structDefinitions,
            Dictionary <StructDefinition, int> cycleCheck)
        {
            int resolutionStatus = cycleCheck[this];

            if (resolutionStatus == 2)
            {
                return;                        // this has already been resolved
            }
            if (resolutionStatus == 1)
            {
                throw new ParserException(this.FirstToken, "The parent chain for this struct has a cycle.");
            }
            cycleCheck[this] = 1;
            if (this.ParentName != null)
            {
                if (!structDefinitions.ContainsKey(this.ParentName.Value))
                {
                    throw new ParserException(this.ParentName, "There is no struct by the name of '" + this.ParentName.Value + "'");
                }
                this.Parent = structDefinitions[this.ParentName.Value];
                this.Parent.ResolveParentChain(structDefinitions, cycleCheck);
            }
            cycleCheck[this] = 2;
        }
Esempio n. 4
0
        internal override Expression ResolveWithTypeContext(PastelCompiler compiler)
        {
            for (int i = 0; i < this.Args.Length; ++i)
            {
                this.Args[i] = this.Args[i].ResolveWithTypeContext(compiler);
            }

            string type = this.Type.RootValue;

            switch (type)
            {
            case "Array":
            case "List":
            case "Dictionary":
            case "StringBuilder":
                break;

            default:
                PType[] resolvedArgTypes;

                if (this.Type.IsStruct)
                {
                    StructDefinition sd = this.Type.StructDef;
                    this.StructDefinition = sd;
                    resolvedArgTypes      = sd.FlatFieldTypes;
                }
                else if (this.Type.IsClass)
                {
                    ClassDefinition cd = this.Type.ClassDef;
                    this.ClassDefinition = cd;
                    resolvedArgTypes     = cd.Constructor.ArgTypes;
                }
                else
                {
                    throw new ParserException(this.FirstToken, "Cannot instantiate this item.");
                }
                int fieldCount = resolvedArgTypes.Length;
                if (fieldCount != this.Args.Length)
                {
                    throw new ParserException(this.FirstToken, "Incorrect number of args in constructor. Expected " + fieldCount + ", found " + this.Args.Length);
                }

                for (int i = 0; i < fieldCount; ++i)
                {
                    PType actualType   = this.Args[i].ResolvedType;
                    PType expectedType = resolvedArgTypes[i];
                    if (!PType.CheckAssignment(compiler, expectedType, actualType))
                    {
                        throw new ParserException(this.Args[i].FirstToken, "Cannot use an arg of this type for this " + (this.Type.IsClass ? "constructor argument" : "struct field") + ". Expected " + expectedType.ToString() + " but found " + actualType.ToString());
                    }
                }
                break;
            }

            return(this);
        }
Esempio n. 5
0
        internal void FinalizeType(PastelCompiler compilerContext)
        {
            if (this.isTypeFinalized)
            {
                return;
            }
            this.isTypeFinalized = true;

            if (this.Category == TypeCategory.STRUCT_OR_CLASS)
            {
                PastelCompiler targetContext = compilerContext;
                if (this.Namespace != null)
                {
                    if (!compilerContext.IncludedScopeNamespacesToIndex.ContainsKey(this.Namespace))
                    {
                        targetContext = null;
                    }
                    else
                    {
                        int index = compilerContext.IncludedScopeNamespacesToIndex[this.Namespace];
                        targetContext = compilerContext.IncludedScopes[index];
                    }
                }

                if (targetContext != null)
                {
                    this.structReference = targetContext.GetStructDefinition(this.TypeName);
                    this.classReference  = targetContext.GetClassDefinition(this.TypeName);
                    this.Category        = this.structReference == null ? TypeCategory.CLASS : TypeCategory.STRUCT;
                }

                if (this.structReference == null && this.classReference == null)
                {
                    throw new ParserException(this.FirstToken, "Could not find a class or struct by the name of '" + this.RootValue + "'");
                }

                if (this.structReference != null && this.classReference != null)
                {
                    throw new System.InvalidOperationException(); // this shouldn't happen. name conflicts should have been caught by now.
                }
            }

            for (int i = 0; i < this.Generics.Length; ++i)
            {
                this.Generics[i].FinalizeType(compilerContext);
            }
        }
Esempio n. 6
0
        internal bool IsIdenticalOrChildOf(PastelCompiler compiler, PType other)
        {
            if (this.IsIdentical(compiler, other))
            {
                return(true);
            }

            // only structs or classes should be here if this is to return true. If not, then it's a no.
            if (!this.IsStructOrClass || !other.IsStructOrClass)
            {
                return(false);
            }

            if (this.IsStruct != other.IsStruct)
            {
                return(false);
            }
            if (this.IsStruct)
            {
                if (this.StructDef == null || other.StructDef == null)
                {
                    throw new System.Exception("This check cannot occur without resolving struct information for PTypes.");
                }
                StructDefinition walker = this.StructDef;
                StructDefinition target = other.StructDef;
                while (walker != null)
                {
                    if (walker == target)
                    {
                        return(true);
                    }
                    walker = walker.Parent;
                }
            }
            if (this.IsClass)
            {
                throw new System.NotImplementedException();
            }

            return(false);
        }