private static object AnalyzeSyntaxQuote(object form, out bool checkMeta)
{
checkMeta = true;
if (Compiler.IsSpecial(form))
return RT.list(Compiler.QuoteSym, form);
Symbol sym = form as Symbol;
if (sym != null)
{
if (sym.Namespace == null && sym.Name.EndsWith("#"))
{
IPersistentMap gmap = (IPersistentMap)GENSYM_ENV.deref();
if (gmap == null)
throw new InvalidDataException("Gensym literal not in syntax-quote");
Symbol gs = (Symbol)gmap.valAt(sym);
if (gs == null)
GENSYM_ENV.set(gmap.assoc(sym, gs = Symbol.intern(null,
sym.Name.Substring(0, sym.Name.Length - 1)
+ "__" + RT.nextID() + "__auto__")));
sym = gs;
}
else if (sym.Namespace == null && sym.Name.EndsWith("."))
{
Symbol csym = Symbol.intern(null, sym.Name.Substring(0, sym.Name.Length - 1));
csym = Compiler.resolveSymbol(csym);
sym = Symbol.intern(null, csym.Name + ".");
}
else if (sym.Namespace == null && sym.Name.StartsWith("."))
{
// simply quote method names
}
else
{
object maybeClass = null;
if (sym.Namespace != null)
maybeClass = Compiler.CurrentNamespace.GetMapping(
Symbol.intern(null, sym.Namespace));
Type t = maybeClass as Type;
if (t != null)
{
// Classname/foo -> package.qualified.Classname/foo
sym = Symbol.intern(t.Name, sym.Name);
}
else
sym = Compiler.resolveSymbol(sym);
}
return RT.list(Compiler.QuoteSym, sym);
}
if (isUnquote(form))
{
checkMeta = false;
return RT.second(form);
}
if (isUnquoteSplicing(form))
throw new ArgumentException("splice not in list");
if (form is IPersistentCollection)
{
if (form is IRecord)
return form;
if (form is IPersistentMap)
{
IPersistentVector keyvals = flattenMap(form);
return RT.list(APPLY, HASHMAP, RT.list(SEQ, RT.cons(CONCAT, sqExpandList(keyvals.seq()))));
}
IPersistentVector v = form as IPersistentVector;
if (v != null)
{
return RT.list(APPLY, VECTOR, RT.list(SEQ, RT.cons(CONCAT, sqExpandList(v.seq()))));
}
IPersistentSet s = form as IPersistentSet;
if (s != null)
{
return RT.list(APPLY, HASHSET, RT.list(SEQ, RT.cons(CONCAT, sqExpandList(s.seq()))));
}
if (form is ISeq || form is IPersistentList)
{
ISeq seq = RT.seq(form);
if (seq == null)
return RT.cons(LIST, null);
else
return RT.list(SEQ, RT.cons(CONCAT, sqExpandList(seq)));
}
else
throw new InvalidOperationException("Unknown Collection type");
}
if (form is Keyword
|| Util.IsNumeric(form)
|| form is Char
|| form is String)
return form;
else
return RT.list(Compiler.QuoteSym, form);
}