private bool ApplySignature(FunctionNameAndArity name, FunctionType?type, List <ValueType> paramTypes) { var registeredSignature = Context.LookupSignature(name); var signature = registeredSignature; if (signature != null && signature.FullyTyped) { throw new InvalidOperationException("Cannot apply signature to an already typed name"); } if (signature == null) { signature = new FunctionSignature { Name = name.Name, Type = (type == null) ? FunctionType.Database : (FunctionType)type, Inserted = false, Deleted = false, Read = false }; } else { if (type != null && signature.Type != type) { // TODO error code! // TODO location of definition Context.Log.Error(null, DiagnosticCode.ProcTypeMismatch, "Auto-typing name {0}: first seen as {1}, now seen as {2}", name, signature.Type, type); } } signature.FullyTyped = !paramTypes.Any(ty => ty == null); signature.Params = new List <FunctionParam>(paramTypes.Count); foreach (var paramType in paramTypes) { var sigParam = new FunctionParam { Type = paramType, Direction = ParamDirection.In, Name = null }; signature.Params.Add(sigParam); } if (registeredSignature == null) { Context.RegisterFunction(signature, null); } return(signature.FullyTyped); }
/// <summary> /// Creates and loads a function declaration from an AST node. /// </summary> private bool LoadFunctionFromAST(ASTFunction astFunction) { var args = new List <FunctionParam>(astFunction.Params.Count); foreach (var astParam in astFunction.Params) { var type = Context.LookupType(astParam.Type); // Since types and alias types are declared at the beginning of the // story header, we shold have full type information here, so any // unresolved types will be flagged as an error. if (type == null) { Context.Log.Error(null, DiagnosticCode.UnresolvedTypeInSignature, String.Format("Function \"{0}({1})\" argument \"{2}\" has unresolved type \"{3}\"", astFunction.Name, astFunction.Params.Count, astParam.Name, astParam.Type)); continue; } var param = new FunctionParam { Name = astParam.Name, Type = type, Direction = astParam.Direction }; args.Add(param); } var signature = new FunctionSignature { Name = astFunction.Name, Type = astFunction.Type, Params = args, FullyTyped = true, Inserted = false, Deleted = false, Read = false }; var func = new BuiltinFunction { Signature = signature, Meta1 = astFunction.Meta1, Meta2 = astFunction.Meta2, Meta3 = astFunction.Meta3, Meta4 = astFunction.Meta4 }; return(Context.RegisterFunction(signature, func)); }
private void VerifyParamCompatibility(FunctionSignature func, int paramIndex, FunctionParam param, IRValue value) { if (param.Type.IntrinsicTypeId != value.Type.IntrinsicTypeId) { object paramName = (param.Name != null) ? (object)param.Name : paramIndex; Context.Log.Error(value.Location, DiagnosticCode.LocalTypeMismatch, "Parameter {0} of {1} \"{2}\" expects {3}; {4} specified", paramName, func.Type, func.Name, TypeToName(param.Type.IntrinsicTypeId), TypeToName(value.Type.IntrinsicTypeId)); return; } if (IsGuidAliasToAliasCast(param.Type, value.Type)) { object paramName = (param.Name != null) ? (object)param.Name : paramIndex; Context.Log.Error(value.Location, DiagnosticCode.GuidAliasMismatch, "Parameter {0} of {1} \"{2}\" has GUID type {3}; {4} specified", paramName, func.Type, func.Name, TypeToName(param.Type.TypeId), TypeToName(value.Type.TypeId)); return; } }
private void VerifyParamCompatibility(FunctionSignature func, int paramIndex, FunctionParam param, IRValue value) { if (param.Type.IntrinsicTypeId != value.Type.IntrinsicTypeId) { // BG3 allows promoting integer constants to float if (Game == TargetGame.BG3 && value is IRConstant && (param.Type.IntrinsicTypeId == Value.Type.Float || param.Type.IntrinsicTypeId == Value.Type.Integer64) && value.Type.IntrinsicTypeId == Value.Type.Integer) { return; } object paramName = (param.Name != null) ? (object)param.Name : paramIndex; Context.Log.Error(value.Location, DiagnosticCode.LocalTypeMismatch, "Parameter {0} of {1} \"{2}\" expects {3}; {4} specified", paramName, func.Type, func.Name, param.Type.Name, value.Type.Name); return; } if (IsGuidAliasToAliasCast(param.Type, value.Type)) { object paramName = (param.Name != null) ? (object)param.Name : paramIndex; Context.Log.Error(value.Location, DiagnosticCode.GuidAliasMismatch, "Parameter {0} of {1} \"{2}\" has GUID type {3}; {4} specified", paramName, func.Type, func.Name, param.Type.Name, value.Type.Name); return; } }