예제 #1
0
        public static LNode QuoteOne(LNode node, bool substitutions)
        {
            if (node.Equals(LNode.InParensTrivia))
            {
                return(LNode_InParensTrivia);
            }
            if (node.Equals(LNode.Missing))
            {
                return(LNode_Missing);
            }

            VList <LNode> creationArgs = new VList <LNode>();

            // Translate attributes (if any)
            var attrList = MaybeQuoteList(node.Attrs, substitutions);

            if (attrList != null)
            {
                creationArgs.Add(attrList);
            }

            LNode result;

            switch (node.Kind)
            {
            case LNodeKind.Literal:             // => F.Literal(value)
                creationArgs.Add(node.WithoutAttrs());
                result = F.Call(LNode_Literal, creationArgs);
                break;

            case LNodeKind.Id:             // => F.Id(string), F.Id(CodeSymbols.Name)
                creationArgs.Add(QuoteSymbol(node.Name));
                result = F.Call(LNode_Id, creationArgs);
                break;

            default:             // NodeKind.Call => F.Dot(...), F.Of(...), F.Call(...), F.Braces(...)
                if (substitutions && node.Calls(S.Substitute, 1))
                {
                    result = node.Args[0];
                    if (attrList != null)
                    {
                        if (result.IsCall)
                        {
                            result = LNode.InParens(result);
                        }
                        result = F.Call(F.Dot(result, Id_PlusAttrs), attrList);
                    }
                }                 /*else if (node.Calls(S.Braces)) // F.Braces(...)
                                   *    result = F.Call(LNode_Braces, node.Args.SmartSelect(arg => QuoteOne(arg, substitutions)));
                                   * else if (node.Calls(S.Dot) && node.ArgCount.IsInRange(1, 2))
                                   *    result = F.Call(LNode_Dot, node.Args.SmartSelect(arg => QuoteOne(arg, substitutions)));
                                   * else if (node.Calls(S.Of))
                                   *    result = F.Call(LNode_Of, node.Args.SmartSelect(arg => QuoteOne(arg, substitutions)));*/
                else              // General case: F.Call(<Target>, <Args>)
                {
                    if (node.Target.IsId)
                    {
                        creationArgs.Add(QuoteSymbol(node.Name));
                    }
                    else
                    {
                        creationArgs.Add(QuoteOne(node.Target, substitutions));
                    }

                    var argList = MaybeQuoteList(node.Args, substitutions);
                    if (argList != null)
                    {
                        creationArgs.Add(argList);
                    }
                    result = F.Call(LNode_Call, creationArgs);
                }
                // Note: don't preserve prefix notation because if $op is +,
                // we want $op(x, y) to generate code for x + y (there is no
                // way to express this with infix notation.)
                if (node.BaseStyle != NodeStyle.Default && node.BaseStyle != NodeStyle.PrefixNotation)
                {
                    result = F.Call(F.Dot(result, F.Id("SetStyle")), F.Dot(F.Id("NodeStyle"), F.Id(node.BaseStyle.ToString())));
                }
                break;
            }
            return(result);
        }