From 736af94ccdb72098af961835f729a2a93d7d6f99 Mon Sep 17 00:00:00 2001
From: Alan Malloy <alan@malloys.org>
Date: Thu, 13 Jan 2011 11:08:26 -0800
Subject: [PATCH] Add multi-line comments

---
 src/jvm/clojure/lang/LispReader.java |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java
index e5740a5..cbe1b70 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)
+                    {
+                        throw new Exception("EOF while reading comment");
+                    }
+                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;
-- 
1.7.0.4

