@@ -167,6 +167,8 @@ class EndOfFile(Builtin):
167167 </dl>
168168 """
169169
170+ SymbolEndOfFile = Symbol ("EndOfFile" )
171+
170172
171173# TODO: Improve docs for these Read[] arguments.
172174class Byte (Builtin ):
@@ -236,18 +238,24 @@ class Read(Builtin):
236238 <dt>'Read[$stream$, $type$]'
237239 <dd>reads the input stream and returns an object of the given type.
238240
241+ <dt>'Read[$stream$, $type$]'
242+ <dd>reads the input stream and returns an object of the given type.
243+
244+ <dt>'Read[$stream$, Hold[Expression]]'
245+ <dd>reads the input stream for an Expression and puts it inside 'Hold'.
246+
239247 </dl>
240248 $type$ is one of:
241249 <ul>
242- <li>Byte</li>
243- <li>Character</li>
244- <li>Expression</li>
245- <li>HoldExpression</li>
246- <li>Number</li>
247- <li>Real</li>
248- <li>Record</li>
249- <li>String</li>
250- <li>Word</li>
250+ <li>Byte
251+ <li>Character
252+ <li>Expression
253+ <li>HoldExpression
254+ <li>Number
255+ <li>Real
256+ <li>Record
257+ <li>String
258+ <li>Word
251259 </ul>
252260
253261 ## Malformed InputString
@@ -330,12 +338,24 @@ class Read(Builtin):
330338
331339 ## HoldExpression:
332340 >> stream = StringToStream["2+2\\ n2+3"];
341+
342+ 'Read' with a 'Hold[Expression]' returns the expression it reads unevaluated so it can be later inspected and evaluated:
343+
333344 >> Read[stream, Hold[Expression]]
334345 = Hold[2 + 2]
346+
335347 >> Read[stream, Expression]
336348 = 5
337349 >> Close[stream];
338350
351+ Reading a comment however will return the empy list:
352+ >> stream = StringToStream["(* ::Package:: *)"];
353+
354+ >> Read[stream, Hold[Expression]]
355+ = {}
356+
357+ >> Close[stream];
358+
339359 ## Multiple types
340360 >> stream = StringToStream["123 abc"];
341361 >> Read[stream, {Number, Word}]
@@ -612,12 +632,12 @@ def reader(stream, word_separators, accepted=None):
612632 nextline = next (read_record )
613633 tmp = tmp + "\n " + nextline
614634 except EOFError :
615- expr = Symbol ( "EndOfFile" )
635+ expr = SymbolEndOfFile
616636 break
617637 except Exception as e :
618638 print (e )
619639
620- if expr == Symbol ( "EndOfFile" ) :
640+ if expr == SymbolEndOfFile :
621641 evaluation .message (
622642 "Read" , "readt" , tmp , Expression ("InputSteam" , name , n )
623643 )
@@ -626,6 +646,9 @@ def reader(stream, word_separators, accepted=None):
626646 if typ == Symbol ("HoldExpression" ):
627647 expr = Expression ("Hold" , expr )
628648 result .append (expr )
649+ # else:
650+ # TODO: Supposedly we can't get here
651+ # what code should we put here?
629652
630653 elif typ == Symbol ("Number" ):
631654 tmp = next (read_number )
@@ -663,7 +686,7 @@ def reader(stream, word_separators, accepted=None):
663686 result .append (next (read_word ))
664687
665688 except EOFError :
666- return Symbol ( "EndOfFile" )
689+ return SymbolEndOfFile
667690 except UnicodeDecodeError :
668691 evaluation .message ("General" , "ucdec" )
669692
@@ -1695,7 +1718,7 @@ def apply(self, name, n, typ, evaluation):
16951718 try :
16961719 result .append (self .readers [t ](stream .io ))
16971720 except struct .error :
1698- result .append (Symbol ( "EndOfFile" ) )
1721+ result .append (SymbolEndOfFile )
16991722
17001723 if typ .has_form ("List" , None ):
17011724 return Expression ("List" , * result )
@@ -2324,7 +2347,7 @@ def apply(self, channel, types, evaluation, options):
23242347 if tmp == SymbolFailed :
23252348 return
23262349
2327- if tmp == Symbol ( "EndOfFile" ) :
2350+ if tmp == SymbolEndOfFile :
23282351 break
23292352 result .append (tmp )
23302353 return from_python (result )
@@ -2686,7 +2709,7 @@ def apply(self, name, n, types, m, evaluation, options):
26862709 return
26872710 for i in range (py_m ):
26882711 result = super (Skip , self ).apply (channel , types , evaluation , options )
2689- if result == Symbol ( "EndOfFile" ) :
2712+ if result == SymbolEndOfFile :
26902713 return result
26912714 return SymbolNull
26922715
0 commit comments