git.fiddlerwoaroof.com
Browse code

adjusted things to allow stdout to be redirected

fiddlerwoaroof authored on 22/07/2014 03:10:47
Showing 1 changed files
... ...
@@ -1,6 +1,15 @@
1 1
 from __future__ import print_function
2 2
 import sys
3 3
 import inspect
4
+import contextlib
5
+
6
+@contextlib.contextmanager
7
+def redir_stdout(new):
8
+    old = sys.stdout
9
+    sys.stdout = new
10
+    yield
11
+    sys.stdout = old
12
+
4 13
 SPACE = None
5 14
 class _RUN: pass
6 15
 
... ...
@@ -139,7 +148,7 @@ class Reader(object):
139 148
         c = 80 // (mlen + 2)
140 149
         while words:
141 150
             head, words = words[:c], words[c:]
142
-            print(' '.join(x.center(mlen) for x in head))
151
+            print(' '.join(x.center(mlen) for x in head), file=self.out)
143 152
 
144 153
     def forget(self, stack, rstack=None):
145 154
         self.program_ctr += 1 # since the program counter doesn't update until after the yield
... ...
@@ -179,10 +188,10 @@ class Reader(object):
179 188
             self.program_ctr -= 1
180 189
         newfun.__name__ = '_forth_%s' % name
181 190
     def prog_print(self, stack, rstack=None):
182
-        print('<%d>' % len(self.program), end=' ')
191
+        print('<%d>' % len(self.program), end=' ', file=self.out)
183 192
         for n in self.program:
184
-            print(n, end=' ')
185
-        print()
193
+            print(n, end=' ', file=self.out)
194
+        print(file=self.out)
186 195
 
187 196
     def set_pctr(self, v):
188 197
         self.program_ctr = v
... ...
@@ -217,7 +226,7 @@ class Reader(object):
217 226
         dst = stack.pop()
218 227
         self.set_pctr(dst)
219 228
 
220
-    def __init__(self):
229
+    def __init__(self, out=sys.stdout):
221 230
         self.sym_words = SymbolDict()
222 231
         self.stack = []
223 232
         self.rstack = []
... ...
@@ -226,6 +235,7 @@ class Reader(object):
226 235
         self.pcs = []
227 236
         self.mode = 0; # 0 - Normal; 1 - string reading
228 237
         self.program_ctr = 0
238
+        self.out = out
229 239
         self.add_symbol('words')(self.words)
230 240
         self.add_symbol('.p')(self.prog_print)
231 241
         self.add_symbol(':')(self.colon)
... ...
@@ -260,13 +270,13 @@ class Reader(object):
260 270
     def read(self, inp, silent=False):
261 271
         self.inp = [inp]
262 272
         delim = SPACE
263
-        if not silent: print(self.program_ctr, end='? ')
273
+        if not silent: print(self.program_ctr, end='? ', file=self.out)
264 274
         for word in self.read_word():
265 275
             #print('<%s>' % word, end=' ')
266 276
             if word == _RUN:
267 277
                 if not silent:
268
-                    print(' ok')
269
-                    print(self.program_ctr, end='? ')
278
+                    print(' ok', file=self.out)
279
+                    print(self.program_ctr, end='? ', file=self.out)
270 280
                 continue
271 281
             elif word == '."':
272 282
                 out = []
... ...
@@ -274,7 +284,7 @@ class Reader(object):
274 284
                 while word != '"':
275 285
                     out.append(self.__getword)
276 286
                     word = self.__getword()
277
-                print(' '.join(out))
287
+                print(' '.join(out), file=self.out)
278 288
                 continue
279 289
             elif word == '': continue
280 290
             self.stack.append(word)
... ...
@@ -284,13 +294,15 @@ class Reader(object):
284 294
             sym = self.stack.pop()
285 295
         result = None
286 296
         if sym.lower() in self.symbols:
287
-            result = self.symbols[sym.lower()](self.stack, self.rstack)
297
+            with redir_stdout(self.out):
298
+                result = self.symbols[sym.lower()](self.stack, self.rstack)
288 299
         else:
289 300
             result = self.numberp(sym)
290 301
             if result is None: raise ValueError("Symbol %r not found" % sym)
291 302
             else:
292 303
                 self.stack.append(result)
293 304
         return result
305
+
294 306
     def numberp(self, sym):
295 307
         is_valid = -1 # -1 = undecided, 0 = False, 1 = True
296 308
         typ = int
... ...
@@ -470,8 +482,7 @@ def clear(stack, rstack):
470 482
     del stack[:]
471 483
     del rstack[:]
472 484
 
473
-if __name__ == '__main__':
474
-    import sys
485
+def init_reader():
475 486
     reader = Reader()
476 487
     reader.compile(*'0= 0 ='.split(None,1))
477 488
     reader.compile(*'0> 0 >'.split(None,1))
... ...
@@ -504,6 +515,11 @@ if __name__ == '__main__':
504 515
     reader.compile(*'loop r> 1+ r> 2dup >r >r < invert until rdrop rdrop'.split(None, 1))
505 516
     reader.compile('begin', 'markr')
506 517
     reader.compile('until', 'invert if jmpr else clrjmp then')
518
+    return reader
519
+
520
+if __name__ == '__main__':
521
+    import sys
522
+    reader = init_reader()
507 523
 
508 524
     import argparse
509 525
     parser = argparse.ArgumentParser()