@@ -192,11 +192,19 @@ static public Object read(PushbackReader r, boolean eofIsError, Object eofValue,
192192
193193static public Object read (PushbackReader r , boolean eofIsError , Object eofValue , boolean isRecursive , Object opts )
194194{
195- return read (r , eofIsError , eofValue , null , null , isRecursive , opts , new LinkedList ());
195+ // start with pendingForms null as reader conditional splicing is not allowed at top level
196+ return read (r , eofIsError , eofValue , null , null , isRecursive , opts , null );
196197}
197198
198199static private Object read (PushbackReader r , boolean eofIsError , Object eofValue , boolean isRecursive , Object opts , Object pendingForms ) {
199- return read (r , eofIsError , eofValue , null , null , isRecursive , opts , pendingForms );
200+ return read (r , eofIsError , eofValue , null , null , isRecursive , opts , ensurePending (pendingForms ));
201+ }
202+
203+ static private Object ensurePending (Object pendingForms ) {
204+ if (pendingForms == null )
205+ return new LinkedList ();
206+ else
207+ return pendingForms ;
200208}
201209
202210static private Object installPlatformFeature (Object opts ) {
@@ -584,7 +592,7 @@ public Object invoke(Object reader, Object semicolon, Object opts, Object pendin
584592public static class DiscardReader extends AFn {
585593 public Object invoke (Object reader , Object underscore , Object opts , Object pendingForms ) {
586594 PushbackReader r = (PushbackReader ) reader ;
587- read (r , true , null , true , opts , pendingForms );
595+ read (r , true , null , true , opts , ensurePending ( pendingForms ) );
588596 return r ;
589597 }
590598}
@@ -598,7 +606,7 @@ public WrappingReader(Symbol sym){
598606
599607 public Object invoke (Object reader , Object quote , Object opts , Object pendingForms ) {
600608 PushbackReader r = (PushbackReader ) reader ;
601- Object o = read (r , true , null , true , opts , pendingForms );
609+ Object o = read (r , true , null , true , opts , ensurePending ( pendingForms ) );
602610 return RT .list (sym , o );
603611 }
604612
@@ -618,7 +626,7 @@ public Object invoke(Object reader, Object quote, Object opts, Object pendingFor
618626 " is deprecated; use " + sym .getName () +
619627 " instead" );
620628 PushbackReader r = (PushbackReader ) reader ;
621- Object o = read (r , true , null , true , opts , pendingForms );
629+ Object o = read (r , true , null , true , opts , ensurePending ( pendingForms ) );
622630 return RT .list (sym , o );
623631 }
624632
@@ -627,7 +635,7 @@ public Object invoke(Object reader, Object quote, Object opts, Object pendingFor
627635public static class VarReader extends AFn {
628636 public Object invoke (Object reader , Object quote , Object opts , Object pendingForms ) {
629637 PushbackReader r = (PushbackReader ) reader ;
630- Object o = read (r , true , null , true , opts , pendingForms );
638+ Object o = read (r , true , null , true , opts , ensurePending ( pendingForms ) );
631639// if(o instanceof Symbol)
632640// {
633641// Object v = Compiler.maybeResolveIn(Compiler.currentNS(), (Symbol) o);
@@ -672,6 +680,7 @@ public Object invoke(Object reader, Object hash, Object opts, Object pendingForm
672680 // Try the ctor reader first
673681 if (fn == null ) {
674682 unread ((PushbackReader ) reader , ch );
683+ pendingForms = ensurePending (pendingForms );
675684 Object result = ctorReader .invoke (reader , ch , opts , pendingForms );
676685
677686 if (result != null )
@@ -697,7 +706,7 @@ public Object invoke(Object reader, Object lparen, Object opts, Object pendingFo
697706 Var .pushThreadBindings (
698707 RT .map (ARG_ENV , PersistentTreeMap .EMPTY ));
699708 unread (r , '(' );
700- Object form = read (r , true , null , true , opts , pendingForms );
709+ Object form = read (r , true , null , true , opts , ensurePending ( pendingForms ) );
701710
702711 PersistentVector args = PersistentVector .EMPTY ;
703712 PersistentTreeMap argsyms = (PersistentTreeMap ) ARG_ENV .deref ();
@@ -760,7 +769,7 @@ public Object invoke(Object reader, Object pct, Object opts, Object pendingForms
760769 {
761770 return registerArg (1 );
762771 }
763- Object n = read (r , true , null , true , opts , pendingForms );
772+ Object n = read (r , true , null , true , opts , ensurePending ( pendingForms ) );
764773 if (n .equals (Compiler ._AMP_ ))
765774 return registerArg (-1 );
766775 if (!(n instanceof Number ))
@@ -779,6 +788,7 @@ public Object invoke(Object reader, Object caret, Object opts, Object pendingFor
779788 line = ((LineNumberingPushbackReader ) r ).getLineNumber ();
780789 column = ((LineNumberingPushbackReader ) r ).getColumnNumber ()-1 ;
781790 }
791+ pendingForms = ensurePending (pendingForms );
782792 Object meta = read (r , true , null , true , opts , pendingForms );
783793 if (meta instanceof Symbol || meta instanceof String )
784794 meta = RT .map (RT .TAG_KEY , meta );
@@ -820,7 +830,7 @@ public Object invoke(Object reader, Object backquote, Object opts, Object pendin
820830 Var .pushThreadBindings (
821831 RT .map (GENSYM_ENV , PersistentHashMap .EMPTY ));
822832
823- Object form = read (r , true , null , true , opts , pendingForms );
833+ Object form = read (r , true , null , true , opts , ensurePending ( pendingForms ) );
824834 return syntaxQuote (form );
825835 }
826836 finally
@@ -967,6 +977,7 @@ public Object invoke(Object reader, Object comma, Object opts, Object pendingFor
967977 int ch = read1 (r );
968978 if (ch == -1 )
969979 throw Util .runtimeException ("EOF while reading character" );
980+ pendingForms = ensurePending (pendingForms );
970981 if (ch == '@' )
971982 {
972983 Object o = read (r , true , null , true , opts , pendingForms );
@@ -1035,7 +1046,7 @@ public Object invoke(Object reader, Object leftparen, Object opts, Object pendin
10351046 line = ((LineNumberingPushbackReader ) r ).getLineNumber ();
10361047 column = ((LineNumberingPushbackReader ) r ).getColumnNumber ()-1 ;
10371048 }
1038- List list = readDelimitedList (')' , r , true , opts , pendingForms );
1049+ List list = readDelimitedList (')' , r , true , opts , ensurePending ( pendingForms ) );
10391050 if (list .isEmpty ())
10401051 return PersistentList .EMPTY ;
10411052 IObj s = (IObj ) PersistentList .create (list );
@@ -1090,7 +1101,7 @@ public Object invoke(Object reader, Object eq, Object opts, Object pendingForms)
10901101 }
10911102
10921103 PushbackReader r = (PushbackReader ) reader ;
1093- Object o = read (r , true , null , true , opts , pendingForms );
1104+ Object o = read (r , true , null , true , opts , ensurePending ( pendingForms ) );
10941105 if (o instanceof Symbol )
10951106 {
10961107 return RT .classForName (o .toString ());
@@ -1136,15 +1147,15 @@ else if(o instanceof IPersistentList)
11361147public static class VectorReader extends AFn {
11371148 public Object invoke (Object reader , Object leftparen , Object opts , Object pendingForms ) {
11381149 PushbackReader r = (PushbackReader ) reader ;
1139- return LazilyPersistentVector .create (readDelimitedList (']' , r , true , opts , pendingForms ));
1150+ return LazilyPersistentVector .create (readDelimitedList (']' , r , true , opts , ensurePending ( pendingForms ) ));
11401151 }
11411152
11421153}
11431154
11441155public static class MapReader extends AFn {
11451156 public Object invoke (Object reader , Object leftparen , Object opts , Object pendingForms ) {
11461157 PushbackReader r = (PushbackReader ) reader ;
1147- Object [] a = readDelimitedList ('}' , r , true , opts , pendingForms ).toArray ();
1158+ Object [] a = readDelimitedList ('}' , r , true , opts , ensurePending ( pendingForms ) ).toArray ();
11481159 if ((a .length & 1 ) == 1 )
11491160 throw Util .runtimeException ("Map literal must contain an even number of forms" );
11501161 return RT .map (a );
@@ -1155,7 +1166,7 @@ public Object invoke(Object reader, Object leftparen, Object opts, Object pendin
11551166public static class SetReader extends AFn {
11561167 public Object invoke (Object reader , Object leftbracket , Object opts , Object pendingForms ) {
11571168 PushbackReader r = (PushbackReader ) reader ;
1158- return PersistentHashSet .createWithCheck (readDelimitedList ('}' , r , true , opts , pendingForms ));
1169+ return PersistentHashSet .createWithCheck (readDelimitedList ('}' , r , true , opts , ensurePending ( pendingForms ) ));
11591170 }
11601171
11611172}
@@ -1204,6 +1215,7 @@ public static List readDelimitedList(char delim, PushbackReader r, boolean isRec
12041215public static class CtorReader extends AFn {
12051216 public Object invoke (Object reader , Object firstChar , Object opts , Object pendingForms ){
12061217 PushbackReader r = (PushbackReader ) reader ;
1218+ pendingForms = ensurePending (pendingForms );
12071219 Object name = read (r , true , null , false , opts , pendingForms );
12081220 if (!(name instanceof Symbol ))
12091221 throw new RuntimeException ("Reader tag must be a symbol" );
@@ -1320,6 +1332,8 @@ public static boolean hasFeature(Object feature, Object opts) {
13201332 public static Object readCondDelimited (PushbackReader r , boolean splicing , Object opts , Object pendingForms ) {
13211333 Object result = null ;
13221334 Object form ; // The most recently ready form
1335+ boolean toplevel = (pendingForms == null );
1336+ pendingForms = ensurePending (pendingForms );
13231337
13241338 final int firstline =
13251339 (r instanceof LineNumberingPushbackReader ) ?
@@ -1391,6 +1405,9 @@ public static Object readCondDelimited(PushbackReader r, boolean splicing, Objec
13911405 if (! (result instanceof List ))
13921406 throw Util .runtimeException ("Spliced form list in read-cond-splicing must implement java.util.List" );
13931407
1408+ if (toplevel )
1409+ throw Util .runtimeException ("Reader conditional splicing not allowed at the top level." );
1410+
13941411 ((List )pendingForms ).addAll (0 , (List )result );
13951412
13961413 return r ;
@@ -1435,7 +1452,7 @@ public Object invoke(Object reader, Object mode, Object opts, Object pendingForm
14351452
14361453 if (isPreserveReadCond (opts )) {
14371454 IFn listReader = getMacro (ch ); // should always be a list
1438- Object form = listReader .invoke (r , ch , opts , pendingForms );
1455+ Object form = listReader .invoke (r , ch , opts , ensurePending ( pendingForms ) );
14391456
14401457 return ReaderConditional .create (form , splicing );
14411458 } else {
0 commit comments