Example #1
0
    /// <inheritdoc/>
    public IEnumerable <CToken> Expand(IPreProcessor preProcessor, IReadOnlyList <IReadOnlyList <CToken> > arguments)
    {
        var isVariadic = this.Parameters is not null &&
                         this.Parameters.Count > 0 &&
                         this.Parameters[this.Parameters.Count - 1] == "...";
        var hasVariadicArgs = true;

        if (this.Parameters is not null && this.Parameters.Count != arguments.Count)
        {
            // This can still be ok if we are variadic and the count is only one less
            if (!isVariadic || this.Parameters.Count != arguments.Count + 1)
            {
                // TODO: Proper error handling
                throw new NotImplementedException();
            }
            if (isVariadic)
            {
                hasVariadicArgs = false;
            }
        }

        // Assign the arguments
        var argDict = new Dictionary <string, IReadOnlyList <CToken> >();

        if (this.Parameters is not null)
        {
            for (var i = 0; i < arguments.Count;)
            {
                var paramName = this.Parameters[i];
                if (paramName == "...")
                {
                    paramName = "__VA_ARGS__";
                }
                // We expand each argument to conform standards
                argDict[paramName] = preProcessor.Expand(arguments[i]).ToList();
                ++i;
            }
        }

        // If we have no variadic arguments but need it, just define it as empty
        if (!hasVariadicArgs)
        {
            argDict["__VA_ARGS__"] = Array.Empty <CToken>();
        }

        // Do the substitution
        var result = new List <CToken>();

        foreach (var element in this.body)
        {
            result.AddRange(ExpandElement(argDict, element));
        }
        return(result);
    }