diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-09-11 11:22:02 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-09-11 11:22:02 +0000 |
commit | f78d8b3fe57b7eee920a1566f7207708d84a8a3f (patch) | |
tree | fb85897e0924108e20e2a248c8397b730414d860 /src | |
parent | 7686aa3fba8bf1a0ae6829625eb322abc7681ed6 (diff) |
interim checkin
Diffstat (limited to 'src')
-rw-r--r-- | src/boot.clj | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 77 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 93 |
3 files changed, 92 insertions, 81 deletions
diff --git a/src/boot.clj b/src/boot.clj index f7b83921..49533032 100644 --- a/src/boot.clj +++ b/src/boot.clj @@ -4,6 +4,9 @@ (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] diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index fb443054..8be6b813 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -182,79 +182,6 @@ static Symbol resolveSymbol(Symbol sym){ return Symbol.intern(currentNS(), sym.name); } -static public Expr syntaxQuote(Object form) throws Exception{ - Expr ret; - if(isSpecial(form)) - ret = new QuoteExpr(form); - else if(form instanceof Symbol) - ret = new QuoteExpr(resolveSymbol((Symbol) form)); - else if(form instanceof IPersistentCollection) - { - if(form instanceof IPersistentMap) - { - IPersistentVector keyvals = flattenMap(form); - PersistentVector v = PersistentVector.EMPTY; - ret = new MapExpr(sqExpandList(v, keyvals.seq())); - } - else if(form instanceof IPersistentVector) - { - PersistentVector v = PersistentVector.EMPTY; - ret = new VectorExpr(sqExpandList(v, ((IPersistentVector) form).seq())); - } - else if(form instanceof ISeq) - { - ISeq seq = RT.seq(form); - if(RT.equal(UNQUOTE, RT.first(seq))) - ret = analyze(C.EXPRESSION, RT.second(form)); - else if(RT.equal(UNQUOTE_SPLICING, RT.first(seq))) - throw new IllegalStateException("splice not in list"); - else - { - PersistentVector v = PersistentVector.EMPTY; - ret = new ListExpr(sqExpandList(v, seq)); - } - } - else - throw new UnsupportedOperationException("Unknown Collection type"); - } - else - ret = new QuoteExpr(form); - - if(form instanceof IObj && ((IObj) form).meta() != null) - return new MetaExpr(ret, (MapExpr) syntaxQuote(((IObj) form).meta())); - else - return ret; -} - -private static PersistentVector sqExpandList(PersistentVector ret, ISeq seq) throws Exception{ - for(; seq != null; seq = seq.rest()) - { - Object item = seq.first(); - if(item instanceof ISeq && RT.equal(UNQUOTE, RT.first(item))) - ret = ret.cons(analyze(C.EXPRESSION, RT.second(item))); - else if(item instanceof ISeq && RT.equal(UNQUOTE_SPLICING, RT.first(item))) - { - if(RT.second(item) == null || 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; -} - -private static IPersistentVector flattenMap(Object form){ - IPersistentVector keyvals = PersistentVector.EMPTY; - for(ISeq s = RT.seq(form); s != null; s = s.rest()) - { - IMapEntry e = (IMapEntry) s.first(); - keyvals = (IPersistentVector) keyvals.cons(e.key()); - keyvals = (IPersistentVector) keyvals.cons(e.val()); - } - return keyvals; -} /* static public Object syntaxQuote(Object form){ @@ -2133,8 +2060,8 @@ private static Expr analyzeSeq(C context, ISeq form, String name) throws Excepti IParser p; if(op.equals(FN)) return FnExpr.parse(context, form, name); - else if(op.equals(SYNTAX_QUOTE)) - return syntaxQuote(RT.second(form)); +// else if(op.equals(SYNTAX_QUOTE)) +// return syntaxQuote(RT.second(form)); else if((p = (IParser) specials.valAt(op)) != null) return p.parse(context, form); else diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index 63a3c564..1c7b7fbb 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -19,10 +19,15 @@ 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 UNQUOTE = Symbol.create(null, "unquote");
-//static Symbol UNQUOTE_SPLICING = Symbol.create(null, "unquote-splicing");
+static Symbol QUOTE = Symbol.create(null, "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 HASHMAP = Symbol.create("clojure", "hashmap");
+static Symbol VECTOR = Symbol.create("clojure", "vector");
+static Symbol WITH_META = Symbol.create("clojure", "with-meta");
static IFn[] macros = new IFn[256];
static Pattern symbolPat = Pattern.compile("[:]?([\\D&&[^:/]][^:/]*/)?[\\D&&[^:/]][^:/]*");
@@ -395,12 +400,88 @@ static class MetaReader extends AFn{ static class SyntaxQuoteReader extends AFn{
public Object invoke(Object reader, Object backquote) throws Exception{
PushbackReader r = (PushbackReader) reader;
- Object o = read(r, true, null, true);
- return RT.list(Compiler.SYNTAX_QUOTE, o);
+ Object form = read(r, true, null, true);
+
+ return syntaxQuote(form);
+ }
+
+ static Object syntaxQuote(Object form) throws Exception{
+ Object ret;
+ if(Compiler.isSpecial(form))
+ ret = RT.list(Compiler.QUOTE, form);
+ else if(form instanceof Symbol)
+ ret = RT.list(Compiler.QUOTE, Compiler.resolveSymbol((Symbol) form));
+ else if(form instanceof IPersistentCollection)
+ {
+ if(form instanceof IPersistentMap)
+ {
+ IPersistentVector keyvals = flattenMap(form);
+ PersistentVector v = PersistentVector.EMPTY;
+ ret = RT.list(HASHMAP, RT.list(CONCAT, sqExpandList(v, keyvals.seq())));
+ }
+ else if(form instanceof IPersistentVector)
+ {
+ PersistentVector v = PersistentVector.EMPTY;
+ ret = RT.list(VECTOR, RT.list(CONCAT, sqExpandList(v, ((IPersistentVector) form).seq())));
+ }
+ else if(form instanceof ISeq)
+ {
+ ISeq seq = RT.seq(form);
+ if(RT.equal(UNQUOTE, RT.first(seq)))
+ ret = form;
+ 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));
+ }
+ }
+ else
+ throw new UnsupportedOperationException("Unknown Collection type");
+ }
+ else if(form instanceof Keyword
+ || form instanceof Num
+ || form instanceof Character
+ || form instanceof String)
+ ret = form;
+ else
+ ret = RT.list(Compiler.QUOTE, form);
+
+ if(form instanceof IObj && ((IObj) form).meta() != null)
+ return RT.list(WITH_META, ret, syntaxQuote(((IObj) form).meta()));
+ else
+ return ret;
+ }
+
+ private static ISeq sqExpandList(PersistentVector ret, ISeq seq) throws Exception{
+ for(; seq != null; seq = seq.rest())
+ {
+ Object item = seq.first();
+ if(item instanceof ISeq && RT.equal(UNQUOTE, RT.first(item)))
+ ret = ret.cons(RT.list(LIST, RT.second(item)));
+ else if(item instanceof ISeq && RT.equal(UNQUOTE_SPLICING, RT.first(item)))
+ ret = ret.cons(RT.second(item));
+ else
+ ret = ret.cons(RT.list(LIST, syntaxQuote(item)));
+ }
+ return ret.seq();
+ }
+
+ private static IPersistentVector flattenMap(Object form){
+ IPersistentVector keyvals = PersistentVector.EMPTY;
+ for(ISeq s = RT.seq(form); s != null; s = s.rest())
+ {
+ IMapEntry e = (IMapEntry) s.first();
+ keyvals = (IPersistentVector) keyvals.cons(e.key());
+ keyvals = (IPersistentVector) keyvals.cons(e.val());
+ }
+ return keyvals;
}
}
+
static class UnquoteReader extends AFn{
public Object invoke(Object reader, Object comma) throws Exception{
PushbackReader r = (PushbackReader) reader;
|