Beispiel #1
0
        public NativeFunctionReference(Token firstToken, NativeFunction nativeFunctionId, Expression context) : base(firstToken)
        {
            this.NativeFunctionId = nativeFunctionId;
            this.Context          = context;

            this.ReturnType         = NativeFunctionUtil.GetNativeFunctionReturnType(this.NativeFunctionId);
            this.ArgTypes           = NativeFunctionUtil.GetNativeFunctionArgTypes(this.NativeFunctionId);
            this.ArgTypesIsRepeated = NativeFunctionUtil.GetNativeFunctionIsArgTypeRepeated(this.NativeFunctionId);
        }
        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);
        }