Browse code
adjusted things to allow stdout to be redirected
fiddlerwoaroof authored on 22/07/2014 03:10:47
Showing 1 changed files
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() |