private static Expression ProcessQuasiquote(Expression expression, SymbolTable symbols, Int32 level)
{
return (expression as ListExpression).Null(el => el[0].Id().Let(i => i == "quasiquote"
? ProcessQuasiquote(el[1], symbols, ++level)
: i == "unquote"
? Unquote(el, symbols, level)
: el.Elements
.PartitionBy(_ => _.List("unquote-splicing") != null)
.Select(p => (p.First().List("unquote-splicing") != null
? p.Select(e => ((ListExpression) e)[1]
.Reduce(symbols)
.If(_ => typeof(YacqSequenceExpression).IsAppropriate(_.Type), _ => _.Member(symbols, "Elements"))
)
: p.Select(e => Unquote(e, symbols, level))
).ToArray())
.ToArray()
.Let(ps => ps
.Skip(1)
.Aggregate((Expression) Vector(symbols, ps.First()), (v, p) => v.Method(symbols, "+", p))
.Method(symbols, "list")
)
))
?? (expression as VectorExpression).Null(ev => Vector(symbols, ev.Elements.Select(e => ProcessQuasiquote(e, symbols, level))))
?? (expression as LambdaListExpression).Null(el => LambdaList(symbols, el.Elements.Select(e => ProcessQuasiquote(e, symbols, level))))
?? (Expression) Quote(symbols, expression);
}