diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index e5740a5..4e18215 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -92,6 +92,7 @@ static Var ARG_ENV = Var.create(null).setDynamic(); dispatchMacros['!'] = new CommentReader(); dispatchMacros['<'] = new UnreadableReader(); dispatchMacros['_'] = new DiscardReader(); + dispatchMacros['|'] = new MultiLineCommentReader(); } static boolean isWhitespace(int ch){ @@ -469,6 +470,37 @@ public static class StringReader extends AFn{ } } +public static class MultiLineCommentReader extends AFn{ + public Object invoke(Object reader, Object pipe) throws Exception{ + Reader r = (Reader) reader; + int nestLevel = 1; + int ch = r.read(); + int next; + + while (nestLevel > 0) + { + if (ch == -1) + { + return r; // EOF, give up quietly + } + next = r.read(); + if (ch == '#' && next == '|') + { + nestLevel++; + next = 'Z'; // don't match #|# + } + else if (ch == '|' && next == '#') + { + nestLevel--; + next = 'Z'; // don't match |#| + } + ch = next; + } + return r; + } +} + + public static class CommentReader extends AFn{ public Object invoke(Object reader, Object semicolon) throws Exception{ Reader r = (Reader) reader; diff --git a/test/clojure/test_clojure/reader.clj b/test/clojure/test_clojure/reader.clj index 7a06034..98ced10 100644 --- a/test/clojure/test_clojure/reader.clj +++ b/test/clojure/test_clojure/reader.clj @@ -300,6 +300,13 @@ (deftest t-Anonymouns-function-literal) +;; Multiline nesting comment (#|...|#) + +(deftest t-Multi-line-comment + (is (= 1 (read-string "#|2 |# 1"))) + (is (= 1 (read-string "#|2 #|# |# |# 1"))) ; #|# should go deeper + (is (= 1 (read-string "#|2 #| |# |# 1")))) + ;; Syntax-quote (`, note, the "backquote" character), Unquote (~) and ;; Unquote-splicing (~@)