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); }