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);
        }
Beispiel #2
0
        /// <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));
        }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
0
        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;
            }
        }