summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-09-20 18:34:00 +0000
committerRich Hickey <richhickey@gmail.com>2007-09-20 18:34:00 +0000
commit3c2265abbab40be15976f8945fba4426c468e836 (patch)
treec28183c572aed142fcc40f9e645affbf3dff8ae2 /src
parent98cf7e1cab10a3208c0b60611e9b2b533fbc0eea (diff)
gensym syntax
Diffstat (limited to 'src')
-rw-r--r--src/boot.clj5
-rw-r--r--src/jvm/clojure/lang/LispReader.java35
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)