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); }
internal override Expression ResolveType(VariableScope varScope, PastelCompiler compiler) { // The args were already resolved. // This ensures that they match the core function definition PType[] expectedTypes = CoreFunctionUtil.GetCoreFunctionArgTypes(this.Function); bool[] isArgRepeated = CoreFunctionUtil.GetCoreFunctionIsArgTypeRepeated(this.Function); switch (this.Function) { case CoreFunction.FORCE_PARENS: if (this.Args.Length != 1) { throw new ParserException(this.FirstToken, "Expected 1 arg."); } return(new ForcedParenthesis(this.FirstToken, this.Args[0])); } 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(compiler, expectedTypes[i], this.Args[i].ResolvedType, templateLookup)) { PType expectedType = expectedTypes[i]; if (templateLookup.ContainsKey(expectedType.ToString())) { expectedType = templateLookup[expectedType.ToString()]; } throw new ParserException(this.Args[i].FirstToken, "Incorrect type. Expected " + expectedType + " 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(compiler, 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 = CoreFunctionUtil.GetCoreFunctionReturnType(this.Function); if (returnType.HasTemplates) { returnType = returnType.ResolveTemplates(templateLookup); } this.ResolvedType = returnType; return(this); }