diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-09-20 18:34:00 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-09-20 18:34:00 +0000 |
commit | 3c2265abbab40be15976f8945fba4426c468e836 (patch) | |
tree | c28183c572aed142fcc40f9e645affbf3dff8ae2 /src | |
parent | 98cf7e1cab10a3208c0b60611e9b2b533fbc0eea (diff) |
gensym syntax
Diffstat (limited to 'src')
-rw-r--r-- | src/boot.clj | 5 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 35 |
2 files changed, 34 insertions, 6 deletions
diff --git a/src/boot.clj b/src/boot.clj index 0e6873f1..b1dbe2ab 100644 --- a/src/boot.clj +++ b/src/boot.clj @@ -109,9 +109,8 @@ ([] nil) ([x] x) ([x & rest] - (let [gor (gensym "or__")] - `(let [~gor ~x] - (if ~gor ~gor (or ~@rest)))))) + `(let [or# ~x] + (if or# or# (or ~@rest))))) ;;math stuff (defn + diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index 94789d00..3c6a250e 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -46,6 +46,9 @@ static final Symbol SLASH = Symbol.create("/"); //static Pattern staticMemberPat = Pattern.compile("([a-zA-Z_][\\w\\.]*)\\.([a-zA-Z_]\\w*)");
//static Pattern classNamePat = Pattern.compile("([a-zA-Z_][\\w\\.]*)\\.");
+//symbol->gensymbol
+static Var GENSYM_ENV = Var.create(null);
+
static
{
macros['"'] = new StringReader();
@@ -351,9 +354,18 @@ static class MetaReader extends AFn{ static class SyntaxQuoteReader extends AFn{
public Object invoke(Object reader, Object backquote) throws Exception{
PushbackReader r = (PushbackReader) reader;
- Object form = read(r, true, null, true);
+ try
+ {
+ Var.pushThreadBindings(
+ RT.map(GENSYM_ENV, PersistentHashMap.EMPTY));
- return syntaxQuote(form);
+ Object form = read(r, true, null, true);
+ return syntaxQuote(form);
+ }
+ finally
+ {
+ Var.popThreadBindings();
+ }
}
static Object syntaxQuote(Object form) throws Exception{
@@ -361,7 +373,24 @@ static class SyntaxQuoteReader extends AFn{ if(Compiler.isSpecial(form))
ret = RT.list(Compiler.QUOTE, form);
else if(form instanceof Symbol)
- ret = RT.list(Compiler.QUOTE, Compiler.resolveSymbol((Symbol) form));
+ {
+ Symbol sym = (Symbol) form;
+ if(sym.ns == null && sym.name.endsWith("#"))
+ {
+ IPersistentMap gmap = (IPersistentMap) GENSYM_ENV.get();
+ if(gmap == null)
+ throw new IllegalStateException("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())));
+ sym = gs;
+ }
+ else
+ sym = Compiler.resolveSymbol(sym);
+ ret = RT.list(Compiler.QUOTE, sym);
+ }
else if(form instanceof Unquote)
return ((Unquote) form).o;
else if(form instanceof UnquoteSplicing)
|