summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-09-11 12:59:32 +0000
committerRich Hickey <richhickey@gmail.com>2007-09-11 12:59:32 +0000
commitd4d0a25f1da9d71fe1fd737eb2a59a710ad59413 (patch)
treea632628378f6b32e3ea711d1d677f0a9649c2373 /src
parentf78d8b3fe57b7eee920a1566f7207708d84a8a3f (diff)
syntax quoting
Diffstat (limited to 'src')
-rw-r--r--src/boot.clj120
-rw-r--r--src/jvm/clojure/lang/Compiler.java107
-rw-r--r--src/jvm/clojure/lang/LispReader.java17
3 files changed, 76 insertions, 168 deletions
diff --git a/src/boot.clj b/src/boot.clj
index 49533032..213b70a0 100644
--- a/src/boot.clj
+++ b/src/boot.clj
@@ -4,30 +4,23 @@
(def defn (fn [name & fdecl]
(list 'def name (cons 'fn fdecl))))
-;(def defn (fn [name & fdecl]
-; `(def ~name (fn ~@fdecl))))
-
(. (the-var defn) (setMacro))
-(def syntax-quote (fn [form]
- (. clojure.lang.Compiler (syntaxQuote form))))
-
-(. (the-var syntax-quote) (setMacro))
-
-(defn contains [coll key]
- (. RT (contains coll key)))
-
-(defn get [coll key]
- (. RT (get coll key)))
+(defn vector
+ ([] [])
+ ([& args]
+ (. clojure.lang.PersistentVector (create args))))
-(defn assoc [coll key val]
- (. RT (assoc coll key val)))
+(defn hashmap
+ ([] {})
+ ([& args]
+ (. clojure.lang.PersistentHashMap (create args))))
-(defn dissoc [coll key]
- (. RT (dissoc coll key)))
+(defn meta [x]
+ (. x (meta)))
-(defn count [coll]
- (. RT (count coll)))
+(defn with-meta [x m]
+ (. x (withMeta m)))
(def defmacro (fn [name & args]
(list 'do
@@ -44,11 +37,6 @@
(def t (. RT T))
-(defn vector
- ([] [])
- ([& args]
- (. clojure.lang.PersistentVector (create args))))
-
(defn nil? [x] (if x nil t))
(defn not [x] (nil? x))
@@ -75,31 +63,49 @@
(second clauses)
(cons 'cond (rest (rest clauses))))))
-(defmacro and
- ([] t)
- ([x] x)
- ([x & rest] (list 'if x (cons 'and rest))))
-
-(defmacro or
- ([] nil)
- ([x] x)
- ([x & rest]
- (let [gor (gensym "or__")]
- (list 'let (vector gor x)
- (list 'if gor gor (cons 'or rest))))))
-
(defn spread [arglist]
(cond
(nil? arglist) nil
(nil? (rest arglist)) (first arglist)
:else (cons (first arglist) (thisfn (rest arglist)))))
-
+
(defn apply [f & args]
(. f (applyTo (spread args))))
(defn list* [& args]
(spread args))
+(defmacro delay [& body]
+ (list '. 'clojure.lang.Delay (list 'new (list* 'fn [] body))))
+
+(defmacro lazy-cons [x & body]
+ (list '. 'clojure.lang.FnSeq (list 'new x (list* 'delay body))))
+
+(defn concat
+ ([] nil)
+ ([x & xs]
+ (cond
+ (nil? xs) x
+ (nil? x) (recur (first xs) (rest xs))
+ :else (lazy-cons (first x) (apply concat (rest x) xs)))))
+
+;;at this point all the support for syntax-quote exists
+
+(defmacro and
+ ([] t)
+ ([x] x)
+ ([x & rest] `(if ~x (and ~@rest))))
+
+(defmacro or
+ ([] nil)
+ ([x] x)
+ ([x & rest]
+ (let [gor (gensym "or__")]
+ `(let [~gor ~x]
+ (if ~gor ~gor (or ~@rest))))))
+
+
+;;math stuff
(defn +
([] 0)
([x] x)
@@ -180,26 +186,23 @@
(defn identity [x] x)
-(defmacro locking [x & body]
- (let [gsym (gensym)]
- (list 'let [gsym x]
- (list 'try-finally
- (cons 'do (cons (list 'monitor-enter gsym) body))
- (list 'monitor-exit gsym)))))
+;;map stuff
-(defmacro delay [& body]
- (list '. 'clojure.lang.Delay (list 'new (list* 'fn [] body))))
+(defn contains [coll key]
+ (. RT (contains coll key)))
-(defmacro lazy-cons [x & body]
- (list '. 'clojure.lang.FnSeq (list 'new x (list* 'delay body))))
+(defn get [coll key]
+ (. RT (get coll key)))
+
+(defn assoc [coll key val]
+ (. RT (assoc coll key val)))
+
+(defn dissoc [coll key]
+ (. RT (dissoc coll key)))
+
+(defn count [coll]
+ (. RT (count coll)))
-(defn concat
- ([] nil)
- ([x & xs]
- (cond
- (nil? xs) x
- (nil? x) (recur (first xs) (rest xs))
- :else (lazy-cons (first x) (apply concat (rest x) xs)))))
(defn andfn [& args]
(if (nil? (rest args))
@@ -211,3 +214,10 @@
nil
(or (first args) (recur (rest args)))))
+
+(defmacro locking [x & body]
+ (let [gsym (gensym)]
+ `(let [~gsym ~x]
+ (try-finally
+ (do (monitor-enter ~gsym) ~@body)
+ (monitor-exit ~gsym))))) \ No newline at end of file
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 8be6b813..f0ebf1bc 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -46,7 +46,7 @@ static final Symbol THISFN = Symbol.create("thisfn");
static final Symbol CLASS = Symbol.create("class");
static final Symbol UNQUOTE = Symbol.create("unquote");
static final Symbol UNQUOTE_SPLICING = Symbol.create("unquote-splicing");
-static final Symbol SYNTAX_QUOTE = Symbol.create("clojure", "syntax-quote");
+//static final Symbol SYNTAX_QUOTE = Symbol.create("clojure", "syntax-quote");
static final Symbol LIST = Symbol.create("clojure", "list");
static final Symbol HASHMAP = Symbol.create("clojure", "hashmap");
static final Symbol VECTOR = Symbol.create("clojure", "vector");
@@ -80,8 +80,8 @@ static IPersistentMap specials = RT.map(
CLASS, null,
UNQUOTE, null,
UNQUOTE_SPLICING, null,
- SYNTAX_QUOTE, null,
- _AMP_, null
+// SYNTAX_QUOTE, null,
+_AMP_, null
);
private static final int MAX_POSITIONAL_ARITY = 20;
@@ -182,107 +182,6 @@ static Symbol resolveSymbol(Symbol sym){
return Symbol.intern(currentNS(), sym.name);
}
-
-/*
-static public Object syntaxQuote(Object form){
- if(isSpecial(form))
- return RT.list(QUOTE, form);
- else if(form instanceof Symbol)
- {
- Symbol sym = (Symbol) form;
- //already qualified or classname?
- if(sym.ns != null || sym.name.indexOf('.') > 0)
- return RT.list(QUOTE,sqMeta(sym, sym.meta()));
- IPersistentMap imports = (IPersistentMap) RT.IMPORTS.get();
- //imported class?
- String className = (String) imports.valAt(sym);
- if(className != null)
- return RT.list(QUOTE, sqMeta(Symbol.intern(null, className), sym.meta()));
- //refers?
- IPersistentMap refers = (IPersistentMap) RT.REFERS.get();
- Var var = (Var) refers.valAt(sym);
- if(var != null)
- return RT.list(QUOTE, sqMeta(var.sym, sym.meta()));
-
- return RT.list(QUOTE, sqMeta(Symbol.intern(currentNS(), sym.name), sym.meta()));
- }
- else if(form instanceof IPersistentCollection)
- {
- if(form instanceof IPersistentMap)
- {
- IPersistentVector keyvals = flattenMap(form);
- IObj ret = PersistentHashMap.create((ISeq) syntaxQuote(keyvals.seq()));
- if(form instanceof IObj)
- return sqMeta(ret, ((IObj) form).meta());
- else
- return ret;
- }
- else if(form instanceof IPersistentVector)
- {
- IObj ret = PersistentVector.create((ISeq) syntaxQuote(((IPersistentVector) form).seq()));
- if(form instanceof IObj)
- return sqMeta(ret, ((IObj) form).meta());
- else
- return ret;
- }
- else if(form instanceof ISeq)
- {
- ISeq seq = RT.seq(form);
- if(RT.equal(UNQUOTE, RT.first(seq)))
- return RT.second(form);
- else if(RT.equal(UNQUOTE_SPLICING, RT.first(seq)))
- throw new IllegalStateException("splice not in list");
- else
- {
- PersistentVector ret = PersistentVector.EMPTY;
- ret = sqExpandList(ret, seq);
-
- if(form instanceof IObj)
- return RT.cons(LIST, sqMeta((IObj) ret.seq(), ((IObj) form).meta()));
- else
- return RT.cons(LIST, ret.seq());
- }
- }
- else
- throw new UnsupportedOperationException("Unknown Collection type");
- }
- else if(form instanceof IObj)
- return sqMeta((IObj) form, ((IObj) form).meta());
- else
- return RT.list(QUOTE, form);
-}
-
-
-private static PersistentVector sqExpandList(PersistentVector ret, ISeq seq){
- for(; seq != null; seq = seq.rest())
- {
- Object item = seq.first();
- if(item instanceof ISeq && RT.equal(UNQUOTE, RT.first(item)))
- ret = ret.cons(RT.second(item));
- else if(item instanceof ISeq && RT.equal(UNQUOTE_SPLICING, RT.first(item)))
- {
- if(RT.second(item) instanceof ISeq)
- ret = sqExpandList(ret, (ISeq) RT.second(item));
- else
- throw new IllegalStateException("splicing non-list");
- }
- else
- ret = ret.cons(syntaxQuote(item));
- }
- return ret;
-}
-
-static Object sqMeta(IObj obj, IPersistentMap meta){
- if(meta != null)
- {
- PersistentVector ret = PersistentVector.EMPTY;
- ret = sqExpandList(ret, flattenMap(meta).seq());
- return obj.withMeta(PersistentHashMap.create(ret.seq()));
- }
- else
- return obj;
-}
- */
static class DefExpr implements Expr{
final Var var;
final Expr init;
diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java
index 1c7b7fbb..33348a9e 100644
--- a/src/jvm/clojure/lang/LispReader.java
+++ b/src/jvm/clojure/lang/LispReader.java
@@ -20,11 +20,12 @@ import java.math.BigInteger;
public class LispReader{
static Symbol QUOTE = Symbol.create(null, "quote");
-static Symbol SYNTAX_QUOTE = Symbol.create(null, "syntax-quote");
+//static Symbol SYNTAX_QUOTE = Symbol.create(null, "syntax-quote");
static Symbol UNQUOTE = Symbol.create(null, "unquote");
static Symbol UNQUOTE_SPLICING = Symbol.create(null, "unquote-splicing");
static Symbol CONCAT = Symbol.create("clojure", "concat");
static Symbol LIST = Symbol.create("clojure", "list");
+static Symbol APPLY = Symbol.create("clojure", "apply");
static Symbol HASHMAP = Symbol.create("clojure", "hashmap");
static Symbol VECTOR = Symbol.create("clojure", "vector");
static Symbol WITH_META = Symbol.create("clojure", "with-meta");
@@ -416,25 +417,22 @@ static class SyntaxQuoteReader extends AFn{
if(form instanceof IPersistentMap)
{
IPersistentVector keyvals = flattenMap(form);
- PersistentVector v = PersistentVector.EMPTY;
- ret = RT.list(HASHMAP, RT.list(CONCAT, sqExpandList(v, keyvals.seq())));
+ ret = RT.list(APPLY, HASHMAP, RT.cons(CONCAT, sqExpandList(keyvals.seq())));
}
else if(form instanceof IPersistentVector)
{
- PersistentVector v = PersistentVector.EMPTY;
- ret = RT.list(VECTOR, RT.list(CONCAT, sqExpandList(v, ((IPersistentVector) form).seq())));
+ ret = RT.list(APPLY, VECTOR, RT.cons(CONCAT, sqExpandList(((IPersistentVector) form).seq())));
}
else if(form instanceof ISeq)
{
ISeq seq = RT.seq(form);
if(RT.equal(UNQUOTE, RT.first(seq)))
- ret = form;
+ return RT.second(seq);
else if(RT.equal(UNQUOTE_SPLICING, RT.first(seq)))
throw new IllegalStateException("splice not in list");
else
{
- PersistentVector v = PersistentVector.EMPTY;
- ret = RT.list(CONCAT, sqExpandList(v, seq));
+ ret = RT.cons(CONCAT, sqExpandList(seq));
}
}
else
@@ -454,7 +452,8 @@ static class SyntaxQuoteReader extends AFn{
return ret;
}
- private static ISeq sqExpandList(PersistentVector ret, ISeq seq) throws Exception{
+ private static ISeq sqExpandList(ISeq seq) throws Exception{
+ PersistentVector ret = PersistentVector.EMPTY;
for(; seq != null; seq = seq.rest())
{
Object item = seq.first();