Example #1
0
 /// <summary>
 /// Returns a ParametersParseNode object that represents the parameters defined
 /// for this external function using the values specified in the given control
 /// list dictionary. For parameters where no value is given, a default of 0 or
 /// NULL is substituted.
 /// </summary>
 /// <param name="cilist">A dictionary of control list values</param>
 /// <returns>A ParametersParseNode object.</returns>
 public ParametersParseNode ParametersNode(ControlList cilist)
 {
     if (cilist == null) {
         throw new ArgumentNullException("cilist");
     }
     ParametersParseNode paramList = new ParametersParseNode();
     foreach (FunctionDefinition def in _definitions) {
         if (def.Include) {
             ParseNode exprNode;
             if (!cilist.Has(def.Name)) {
                 if (Symbol.IsNumberType(def.Symbol.Type)) {
                     exprNode = new NumberParseNode(0);
                 } else if (Symbol.IsLogicalType(def.Symbol.Type)) {
                     exprNode = new NumberParseNode(new Variant(false));
                 } else {
                     exprNode = new NullParseNode();
                     exprNode.Type = def.Symbol.Type;
                 }
             } else {
                 exprNode = cilist[def.Name];
             }
             paramList.Add(exprNode, def.Symbol);
         }
     }
     return paramList;
 }
Example #2
0
        // Parse an intrinsic function call
        ParseNode IntrinsicOperand(string name, IdentifierParseNode node)
        {
            ExtCallParseNode tokenNode = new ExtCallParseNode("JComLib.Intrinsics,jcomlib", name);
            IntrDefinition intrDefinition = Intrinsics.IntrinsicDefinition(name);
            Debug.Assert(intrDefinition != null);

            SymType argType = SymType.NONE;
            int countOfParams = 0;

            bool isVarArg = (intrDefinition.Count == ArgCount.TwoOrMore);
            ParametersParseNode paramsNode = new ParametersParseNode();
            VarArgParseNode argList = new VarArgParseNode();

            // Parameters to inlined instrinsics are always passed by value.
            bool useByRef = !(_opts.Inline) || !tokenNode.CanInline();
            if (!intrDefinition.IsPermittedInIntrinsic) {
                useByRef = false;
            }

            for (int c = 0; c < node.Indexes.Count; ++c) {
                ParseNode exprNode = node.Indexes[c];

                if (c > 0 && !ValidateAssignmentTypes(exprNode.Type, argType)) {
                    _messages.Error(MessageCode.TYPEMISMATCH, string.Format("All arguments to {0} must be of the same type", name));
                }
                argType = exprNode.Type;

                if (!intrDefinition.IsValidArgType(argType)) {
                    _messages.Error(MessageCode.TYPEMISMATCH, String.Format("Invalid argument type for {0}", name));
                }
                if (intrDefinition.RequiredType != SymType.GENERIC) {
                    exprNode.Type = intrDefinition.RequiredType;
                }

                if (isVarArg) {
                    argList.Add(exprNode);
                } else {
                    paramsNode.Add(exprNode, useByRef);
                }
                ++countOfParams;
            }
            if (isVarArg) {
                paramsNode.Add(argList, useByRef);
            }
            tokenNode.Parameters = paramsNode;

            // Make sure actual and expected arguments match
            bool match = false;
            switch (intrDefinition.Count) {
                case ArgCount.One: match = (countOfParams == 1); break;
                case ArgCount.OneOrTwo: match = (countOfParams == 1 || countOfParams == 2); break;
                case ArgCount.Two: match = (countOfParams == 2); break;
                case ArgCount.TwoOrMore: match = (countOfParams >= 2); break;
                default: Debug.Assert(false, "Unhandled ArgCount!"); break;
            }
            if (!match) {
                _messages.Error(MessageCode.WRONGNUMBEROFARGUMENTS, String.Format("Wrong number of arguments for {0}", name));
            }

            // Set return type. GENERIC means use the type of the argument
            Debug.Assert(!(intrDefinition.ReturnType == SymType.GENERIC && argType == SymType.NONE), "argType cannot be null here!");
            tokenNode.Type = (intrDefinition.ReturnType == SymType.GENERIC) ? argType : intrDefinition.ReturnType;
            tokenNode.Inline = _opts.Inline;
            return tokenNode;
        }