internal override Expression ResolveType(VariableScope varScope, PastelCompiler compiler)
        {
            // Args already resolved by FunctionInvocation.ResolveType().

            string             name = this.FunctionRef.Name;
            ExtensibleFunction extensibleFunction;

            if (!compiler.ExtensibleFunctions.TryGetValue(name, out extensibleFunction))
            {
                throw new ParserException(this.FirstToken, "Type information for '" + name + "' extensible function is not defined.");
            }
            this.ResolvedType = extensibleFunction.ReturnType;

            PType[] argTypes = extensibleFunction.ArgTypes;

            if (argTypes.Length != this.Args.Length)
            {
                throw new ParserException(this.FirstToken, "Incorrect number of args for this function. Expected " + argTypes.Length + " but instead found " + this.Args.Length + ".");
            }

            for (int i = 0; i < this.Args.Length; ++i)
            {
                if (!PType.CheckAssignment(compiler, argTypes[i], this.Args[i].ResolvedType))
                {
                    throw new ParserException(this.Args[i].FirstToken, "Invalid argument type. Expected '" + argTypes[i] + "' but found '" + this.Args[i].ResolvedType + "'.");
                }
            }

            return(this);
        }
Пример #2
0
        internal override Expression ResolveType(VariableScope varScope, PastelCompiler compiler)
        {
            for (int i = 0; i < this.Args.Length; ++i)
            {
                this.Args[i] = this.Args[i].ResolveType(varScope, compiler);
            }

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

            if (this.Root is FunctionReference)
            {
                FunctionDefinition functionDefinition = ((FunctionReference)this.Root).Function;
                PType[]            expectedTypes      = functionDefinition.ArgTypes;
                if (expectedTypes.Length != this.Args.Length)
                {
                    throw new ParserException(this.OpenParenToken, "This function invocation has the wrong number of parameters. Expected " + expectedTypes.Length + " but found " + this.Args.Length + ".");
                }

                for (int i = 0; i < this.Args.Length; ++i)
                {
                    if (!PType.CheckAssignment(expectedTypes[i], this.Args[i].ResolvedType))
                    {
                        throw new ParserException(this.Args[i].FirstToken, "Wrong function arg type. Cannot convert a " + this.Args[i].ResolvedType + " to a " + expectedTypes[i]);
                    }
                }

                this.ResolvedType = functionDefinition.ReturnType;
                return(this);
            }
            else if (this.Root is NativeFunctionReference)
            {
                NativeFunctionReference  nfr = (NativeFunctionReference)this.Root;
                NativeFunctionInvocation nfi;
                if (nfr.Context == null)
                {
                    nfi = new NativeFunctionInvocation(this.FirstToken, nfr.NativeFunctionId, this.Args);
                }
                else
                {
                    nfi = new NativeFunctionInvocation(this.FirstToken, nfr.NativeFunctionId, nfr.Context, this.Args);
                }

                return(nfi.ResolveType(varScope, compiler));
            }
            else if (this.Root is LibraryNativeFunctionReference)
            {
                return(new LibraryNativeFunctionInvocation(this.FirstToken, (LibraryNativeFunctionReference)this.Root, this.Args).ResolveType(varScope, compiler));
            }
            else if (this.Root is ConstructorReference)
            {
                return(new ConstructorInvocation(this.FirstToken, ((ConstructorReference)this.Root).TypeToConstruct, this.Args));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Пример #3
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);
        }
Пример #4
0
        internal override void ResolveTypes(VariableScope varScope, PastelCompiler compiler)
        {
            this.Value = this.Value.ResolveType(varScope, compiler);

            if (!PType.CheckAssignment(this.Type, this.Value.ResolvedType))
            {
                throw new ParserException(this.Value.FirstToken, "Cannot assign this type to a " + this.Type);
            }

            varScope.DeclareVariables(this.VariableNameToken, this.Type);
        }
Пример #5
0
        private void VerifyArgTypes(PType[] expectedTypes, PastelCompiler compiler)
        {
            if (expectedTypes.Length != this.Args.Length)
            {
                throw new ParserException(this.OpenParenToken, "This function invocation has the wrong number of parameters. Expected " + expectedTypes.Length + " but found " + this.Args.Length + ".");
            }

            for (int i = 0; i < this.Args.Length; ++i)
            {
                if (!PType.CheckAssignment(compiler, expectedTypes[i], this.Args[i].ResolvedType))
                {
                    throw new ParserException(this.Args[i].FirstToken, "Wrong function arg type. Cannot convert a " + this.Args[i].ResolvedType + " to a " + expectedTypes[i]);
                }
            }
        }
Пример #6
0
        internal override void ResolveTypes(VariableScope varScope, PastelCompiler compiler)
        {
            this.Value  = this.Value.ResolveType(varScope, compiler);
            this.Target = this.Target.ResolveType(varScope, compiler);

            if (!PType.CheckAssignment(this.Target.ResolvedType, this.Value.ResolvedType))
            {
                if (this.OpToken.Value != "=" &&
                    this.Target.ResolvedType.IsIdentical(PType.DOUBLE) &&
                    this.Value.ResolvedType.IsIdentical(PType.INT))
                {
                    // You can apply incremental ops such as += with an int to a float and that is fine without explicit conversion in any platform.
                }
                else
                {
                    throw new ParserException(this.OpToken, "Cannot assign a " + this.Value.ResolvedType + " to a " + this.Target.ResolvedType);
                }
            }
        }
Пример #7
0
        internal override Expression ResolveType(VariableScope varScope, PastelCompiler compiler)
        {
            // The args were already resolved.
            // This ensures that they match the native function definition

            PType[] expectedTypes = NativeFunctionUtil.GetNativeFunctionArgTypes(this.Function);
            bool[]  isArgRepeated = NativeFunctionUtil.GetNativeFunctionIsArgTypeRepeated(this.Function);

            switch (this.Function)
            {
            case NativeFunction.FORCE_PARENS:
                if (this.Args.Length != 1)
                {
                    throw new ParserException(this.FirstToken, "Expected 1 arg.");
                }

                return(new ForcedParenthesis(this.FirstToken, this.Args[0]));

            case NativeFunction.IS_DEBUG:
#if DEBUG
                bool value = true;
#else
                bool value = false;
#endif
                return(new InlineConstant(PType.BOOL, this.FirstToken, value));
            }

            Dictionary <string, PType> templateLookup = new Dictionary <string, PType>();

            int verificationLength = expectedTypes.Length;
            if (verificationLength > 0 && isArgRepeated[isArgRepeated.Length - 1])
            {
                verificationLength--;
            }

            for (int i = 0; i < verificationLength; ++i)
            {
                if (!PType.CheckAssignmentWithTemplateOutput(expectedTypes[i], this.Args[i].ResolvedType, templateLookup))
                {
                    throw new ParserException(this.Args[i].FirstToken, "Incorrect type. Expected " + expectedTypes[i] + " but found " + this.Args[i].ResolvedType + ".");
                }
            }

            if (expectedTypes.Length < this.Args.Length)
            {
                if (isArgRepeated[isArgRepeated.Length - 1])
                {
                    PType expectedType = expectedTypes[expectedTypes.Length - 1];
                    for (int i = expectedTypes.Length; i < this.Args.Length; ++i)
                    {
                        if (!PType.CheckAssignment(expectedType, this.Args[i].ResolvedType))
                        {
                            throw new ParserException(this.Args[i].FirstToken, "Incorrect type. Expected " + expectedTypes[i] + " but found " + this.Args[i].ResolvedType + ".");
                        }
                    }
                }
                else
                {
                    throw new ParserException(this.FirstToken, "Too many arguments.");
                }
            }

            PType returnType = NativeFunctionUtil.GetNativeFunctionReturnType(this.Function);

            if (returnType.HasTemplates)
            {
                returnType = returnType.ResolveTemplates(templateLookup);
            }

            this.ResolvedType = returnType;

            return(this);
        }