0 | |
#!/usr/bin/env python
|
|
0 |
#!/usr/bin/env python3
|
1 | 1 |
# -*- coding: utf-8 -*-
|
2 | 2 |
|
3 | 3 |
"""
|
|
63 | 63 |
|
64 | 64 |
"""
|
65 | 65 |
def __init__(self, initial):
|
66 | |
self.string = unicode(initial)
|
|
66 |
self.string = initial
|
67 | 67 |
|
68 | 68 |
def __str__(self):
|
69 | 69 |
return self.__unicode__()
|
|
84 | 84 |
return self.string.find(sub)
|
85 | 85 |
|
86 | 86 |
def set(self, string):
|
87 | |
self.string = unicode(string)
|
|
87 |
self.string = string
|
88 | 88 |
|
89 | 89 |
def pos_left(self, locator, delta):
|
90 | 90 |
"""Return the 0-based position within this MutableString of the
|
|
95 | 95 |
is changed.
|
96 | 96 |
|
97 | 97 |
>>> a = MutableString("Mom(*)entous")
|
98 | |
>>> print a.pos_left("(*)", 0)
|
|
98 |
>>> print(a.pos_left("(*)", 0))
|
99 | 99 |
3
|
100 | 100 |
|
101 | 101 |
"""
|
|
114 | 114 |
is changed.
|
115 | 115 |
|
116 | 116 |
>>> a = MutableString("Mom(*)entous")
|
117 | |
>>> print a.pos_right("(*)", 0)
|
|
117 |
>>> print(a.pos_right("(*)", 0))
|
118 | 118 |
6
|
119 | 119 |
|
120 | 120 |
"""
|
|
131 | 131 |
|
132 | 132 |
>>> a = MutableString("Momentous")
|
133 | 133 |
>>> a.insert_locator("(*)", 3)
|
134 | |
>>> print str(a)
|
|
134 |
>>> print(str(a))
|
135 | 135 |
Mom(*)entous
|
136 | 136 |
|
137 | 137 |
"""
|
138 | |
self.set(self[:pos] + unicode(locator) + self[pos:])
|
|
138 |
self.set(self[:pos] + locator + self[pos:])
|
139 | 139 |
|
140 | 140 |
def remove_locator(self, locator):
|
141 | 141 |
"""Remove the given locator from this string.
|
142 | 142 |
|
143 | 143 |
>>> a = MutableString("Mom(*)entous")
|
144 | 144 |
>>> a.remove_locator("(*)")
|
145 | |
>>> print str(a)
|
|
145 |
>>> print(str(a))
|
146 | 146 |
Momentous
|
147 | 147 |
|
148 | 148 |
"""
|
149 | |
locator = unicode(locator)
|
150 | 149 |
posl = self.pos_left(locator, 0)
|
151 | 150 |
posr = self.pos_right(locator, 0)
|
152 | 151 |
self.set(self[:posl] + self[posr:])
|
|
159 | 158 |
|
160 | 159 |
>>> a = MutableString("Mom(*)entous")
|
161 | 160 |
>>> a.move_locator("(*)", +3)
|
162 | |
>>> print str(a)
|
|
161 |
>>> print(str(a))
|
163 | 162 |
Moment(*)ous
|
164 | 163 |
|
165 | 164 |
"""
|
166 | |
locator = unicode(locator)
|
167 | 165 |
posl = self.pos_left(locator, 0)
|
168 | 166 |
posr = self.pos_right(locator, 0)
|
169 | 167 |
self.set(self[:posl] + self[posr:])
|
|
180 | 178 |
|
181 | 179 |
>>> a = MutableString("Mom(*)en(+)tous")
|
182 | 180 |
>>> a.slide_locator("(*)", +1)
|
183 | |
>>> print str(a)
|
|
181 |
>>> print(str(a))
|
184 | 182 |
Mome(*)n(+)tous
|
185 | 183 |
>>> a.slide_locator("(*)", -1)
|
186 | |
>>> print str(a)
|
|
184 |
>>> print(str(a))
|
187 | 185 |
Mom(*)en(+)tous
|
188 | 186 |
|
189 | 187 |
>>> b = MutableString("(-)Cassowary(+)")
|
190 | 188 |
>>> b.slide_locator("(+)", +1)
|
191 | |
>>> print str(b)
|
|
189 |
>>> print(str(b))
|
192 | 190 |
(-)Cassowary(+)
|
193 | 191 |
>>> b.slide_locator("(-)", -1)
|
194 | |
>>> print str(b)
|
|
192 |
>>> print(str(b))
|
195 | 193 |
(-)Cassowary(+)
|
196 | 194 |
|
197 | 195 |
>>> c = MutableString("Imb(+)r(%)oglio")
|
198 | 196 |
>>> c.slide_locator("(+)", +1)
|
199 | |
>>> print str(c)
|
|
197 |
>>> print(str(c))
|
200 | 198 |
Imbr(+)(%)oglio
|
201 | 199 |
|
202 | 200 |
"""
|
203 | |
locator = unicode(locator)
|
204 | 201 |
if delta == +1:
|
205 | 202 |
matching = True
|
206 | 203 |
target = self.pos_right(locator, 0)
|
|
230 | 227 |
"""Retrieve the substring between the two given locators.
|
231 | 228 |
|
232 | 229 |
>>> a = MutableString("This is (a)my string(b) you know.")
|
233 | |
>>> print a.read("(a)", "(b)")
|
|
230 |
>>> print(a.read("(a)", "(b)"))
|
234 | 231 |
my string
|
235 | 232 |
|
236 | 233 |
"""
|
|
243 | 240 |
|
244 | 241 |
>>> a = MutableString("This is (a)my string(b) you know.")
|
245 | 242 |
>>> a.update("(a)", "(b)", "crazy talk")
|
246 | |
>>> print str(a)
|
|
243 |
>>> print(str(a))
|
247 | 244 |
This is (a)crazy talk(b) you know.
|
248 | 245 |
|
249 | 246 |
"""
|
250 | 247 |
a = self.pos_right(left, 0)
|
251 | 248 |
b = self.pos_left(right, 0)
|
252 | |
self.set(self.string[:a] + unicode(string) + self.string[b:])
|
|
249 |
self.set(self.string[:a] + str(string) + self.string[b:])
|
253 | 250 |
|
254 | 251 |
def find_matching(self, pos):
|
255 | 252 |
"""Find the parenthesis which matches the parenthesis at the given
|
|
311 | 308 |
|
312 | 309 |
>>> a = SlottedString("This is (^a)my slot(a$) you know.")
|
313 | 310 |
>>> a.update_slot('a', 'good stuff')
|
314 | |
>>> print str(a)
|
|
311 |
>>> print(str(a))
|
315 | 312 |
This is (^a)good stuff(a$) you know.
|
316 | 313 |
>>> a.update_slot('z', 'bad stuff')
|
317 | 314 |
Traceback (most recent call last):
|
|
319 | 316 |
UndefinedLocatorError: (^z)
|
320 | 317 |
|
321 | 318 |
"""
|
322 | |
slot_name = unicode(slot_name)
|
323 | 319 |
return self.read(u"(^%s)" % slot_name, u"(%s$)" % slot_name)
|
324 | 320 |
|
325 | 321 |
def read_slot_indirect(self, slot_name):
|
326 | 322 |
"""
|
327 | 323 |
>>> p = SlottedString("...(^A)M(A$)...(^R)A(R$)...")
|
328 | |
>>> print p.read_slot_indirect('R')
|
|
324 |
>>> print(p.read_slot_indirect('R'))
|
329 | 325 |
M
|
330 | |
>>> print p.read_slot_indirect('A')
|
|
326 |
>>> print(p.read_slot_indirect('A'))
|
331 | 327 |
Traceback (most recent call last):
|
332 | 328 |
...
|
333 | 329 |
UndefinedLocatorError: (^M)
|
334 | 330 |
|
335 | 331 |
"""
|
336 | |
slot_name = unicode(slot_name)
|
337 | 332 |
slot_name = self.read_slot(slot_name)
|
338 | 333 |
return self.read_slot(slot_name)
|
339 | 334 |
|
|
342 | 337 |
|
343 | 338 |
>>> a = SlottedString("This is (^a)my slot(a$) you know.")
|
344 | 339 |
>>> a.update_slot('a', 'good stuff')
|
345 | |
>>> print str(a)
|
|
340 |
>>> print(str(a))
|
346 | 341 |
This is (^a)good stuff(a$) you know.
|
347 | 342 |
>>> a.update_slot('a', MutableString('mutable stuff'))
|
348 | |
>>> print str(a)
|
|
343 |
>>> print(str(a))
|
349 | 344 |
This is (^a)mutable stuff(a$) you know.
|
350 | 345 |
>>> a.update_slot('z', 'bad stuff')
|
351 | 346 |
Traceback (most recent call last):
|
|
353 | 348 |
UndefinedLocatorError: (^z)
|
354 | 349 |
|
355 | 350 |
"""
|
356 | |
slot_name = unicode(slot_name)
|
357 | |
string = unicode(string)
|
358 | 351 |
return self.update(u"(^%s)" % slot_name, u"(%s$)" % slot_name, string)
|
359 | 352 |
|
360 | 353 |
def update_slot_indirect(self, slot_name, string):
|
361 | 354 |
"""
|
362 | 355 |
>>> p = SlottedString("Dolphin(^A)M(A$)Dolphin(^R)A(R$)Dolphin")
|
363 | 356 |
>>> p.update_slot_indirect('R', 'Porphyry')
|
364 | |
>>> print str(p)
|
|
357 |
>>> print(str(p))
|
365 | 358 |
Dolphin(^A)Porphyry(A$)Dolphin(^R)A(R$)Dolphin
|
366 | 359 |
|
367 | 360 |
"""
|
|
372 | 365 |
"""
|
373 | 366 |
|
374 | 367 |
>>> a = SlottedString("(^G)?(G$) (^P)_(P$) (^`P)Q(`P$) (^`K)(^/)Madge(/$)(`K$)")
|
375 | |
>>> print a.get_slot_name('M')
|
|
368 |
>>> print(a.get_slot_name('M'))
|
376 | 369 |
M
|
377 | |
>>> print a.get_slot_name('G')
|
|
370 |
>>> print(a.get_slot_name('G'))
|
378 | 371 |
G
|
379 | |
>>> print a.get_slot_name('P')
|
|
372 |
>>> print(a.get_slot_name('P'))
|
380 | 373 |
Q
|
381 | |
>>> print a.get_slot_name('K')
|
|
374 |
>>> print(a.get_slot_name('K'))
|
382 | 375 |
Madge
|
383 | 376 |
|
384 | 377 |
"""
|
385 | |
slot_name = unicode(slot_name)
|
386 | 378 |
name_slot = u"`%s" % slot_name
|
387 | 379 |
try:
|
388 | 380 |
slot_name = self.read_slot(name_slot)
|
|
394 | 386 |
def strip_all_locators(self, content):
|
395 | 387 |
"""
|
396 | 388 |
>>> p = Program('')
|
397 | |
>>> print p.strip_all_locators('')
|
|
389 |
>>> print(p.strip_all_locators(''))
|
398 | 390 |
None
|
399 | |
>>> print p.strip_all_locators('X')
|
|
391 |
>>> print(p.strip_all_locators('X'))
|
400 | 392 |
X
|
401 | |
>>> print p.strip_all_locators('Well-tempered')
|
|
393 |
>>> print(p.strip_all_locators('Well-tempered'))
|
402 | 394 |
Well-tempered
|
403 | |
>>> print p.strip_all_locators('(^8)(^7)(7$)CAT(8$)')
|
|
395 |
>>> print(p.strip_all_locators('(^8)(^7)(7$)CAT(8$)'))
|
404 | 396 |
CAT
|
405 | |
>>> print p.strip_all_locators('(^8(beat))D')
|
|
397 |
>>> print(p.strip_all_locators('(^8(beat))D'))
|
406 | 398 |
D
|
407 | |
>>> print p.strip_all_locators('(^8)(^7)(7$)(8$)')
|
|
399 |
>>> print(p.strip_all_locators('(^8)(^7)(7$)(8$)'))
|
408 | 400 |
None
|
409 | 401 |
|
410 | 402 |
"""
|
|
429 | 421 |
|
430 | 422 |
>>> a = SlottedString("This is my (^a)slot(a$) (^b)y(b$)ou know.")
|
431 | 423 |
>>> a.slide_slot('a', +1)
|
432 | |
>>> print str(a)
|
|
424 |
>>> print(str(a))
|
433 | 425 |
This is my s(^a)lot (a$)(^b)y(b$)ou know.
|
434 | 426 |
>>> a.slide_slot('b', -1)
|
435 | |
>>> print str(a)
|
|
427 |
>>> print(str(a))
|
436 | 428 |
This is my s(^a)lot(^b) (a$)(b$)you know.
|
437 | 429 |
|
438 | 430 |
"""
|
439 | |
slot_name = unicode(slot_name)
|
440 | 431 |
if delta > 0:
|
441 | 432 |
self.slide_locator("(%s$)" % slot_name, delta)
|
442 | 433 |
self.slide_locator("(^%s)" % slot_name, delta)
|
|
458 | 449 |
done = False
|
459 | 450 |
string = ''
|
460 | 451 |
for line in file.readlines():
|
461 | |
line = unicode(line, 'utf-8') # for now
|
462 | 452 |
if line.endswith('\n'):
|
463 | 453 |
line = line[:-1]
|
464 | 454 |
if line.startswith('#'):
|
|
473 | 463 |
|
474 | 464 |
>>> p = Program("(^!)A(!$)B(^M)C(M$)D")
|
475 | 465 |
>>> p.advance()
|
476 | |
>>> print str(p)
|
|
466 |
>>> print(str(p))
|
477 | 467 |
A(^!)B(!$)(^M)C(M$)D
|
478 | 468 |
>>> p.advance()
|
479 | |
>>> print str(p)
|
|
469 |
>>> print(str(p))
|
480 | 470 |
AB(^!)(^M)C(!$)(M$)D
|
481 | 471 |
>>> p.advance()
|
482 | |
>>> print str(p)
|
|
472 |
>>> print(str(p))
|
483 | 473 |
AB(^M)C(^!)(M$)D(!$)
|
484 | 474 |
>>> p.advance()
|
485 | |
>>> print str(p)
|
|
475 |
>>> print(str(p))
|
486 | 476 |
AB(^M)C(M$)D(^!)(!$)
|
487 | 477 |
|
488 | 478 |
>>> p = Program("(^!)A(!$)(^Moo)(^Gar)(Gar$)B(Moo$)")
|
489 | 479 |
>>> p.advance()
|
490 | |
>>> print str(p)
|
|
480 |
>>> print(str(p))
|
491 | 481 |
A(^!)(^Moo)(^Gar)(Gar$)B(!$)(Moo$)
|
492 | 482 |
>>> p.advance()
|
493 | |
>>> print str(p)
|
|
483 |
>>> print(str(p))
|
494 | 484 |
A(^Moo)(^Gar)(Gar$)B(^!)(!$)(Moo$)
|
495 | 485 |
|
496 | 486 |
"""
|
|
499 | 489 |
def clean_instruction(self, instruction):
|
500 | 490 |
"""
|
501 | 491 |
>>> p = Program('')
|
502 | |
>>> print p.clean_instruction('')
|
|
492 |
>>> print(p.clean_instruction(''))
|
503 | 493 |
None
|
504 | |
>>> print p.clean_instruction('X')
|
|
494 |
>>> print(p.clean_instruction('X'))
|
505 | 495 |
X
|
506 | |
>>> print p.clean_instruction('Well-tempered')
|
|
496 |
>>> print(p.clean_instruction('Well-tempered'))
|
507 | 497 |
W
|
508 | |
>>> print p.clean_instruction('(^8)(^7)(7$)CAT(8$)')
|
|
498 |
>>> print(p.clean_instruction('(^8)(^7)(7$)CAT(8$)'))
|
509 | 499 |
C
|
510 | |
>>> print p.clean_instruction('(^8(beat))D')
|
|
500 |
>>> print(p.clean_instruction('(^8(beat))D'))
|
511 | 501 |
D
|
512 | |
>>> print p.clean_instruction('(^8)(^7)(7$)(8$)')
|
|
502 |
>>> print(p.clean_instruction('(^8)(^7)(7$)(8$)'))
|
513 | 503 |
None
|
514 | 504 |
|
515 | 505 |
"""
|
|
572 | 562 |
|
573 | 563 |
>>> p = Semantics("(^?)(?$)")
|
574 | 564 |
>>> p.execute('0')
|
575 | |
>>> print str(p)
|
|
565 |
>>> print(str(p))
|
576 | 566 |
(^?)0(?$)
|
577 | 567 |
|
578 | 568 |
* X ("cut") erases (updates with the zero-length string) the selection.
|
579 | 569 |
|
580 | 570 |
>>> p = Semantics("(^/)hi(/$)")
|
581 | 571 |
>>> p.execute('X')
|
582 | |
>>> print str(p)
|
|
572 |
>>> print(str(p))
|
583 | 573 |
(^/)(/$)
|
584 | 574 |
>>> p = Semantics("(^`/)X(`/$)(^X)hi(X$)")
|
585 | 575 |
>>> p.execute('X')
|
586 | |
>>> print str(p)
|
|
576 |
>>> print(str(p))
|
587 | 577 |
(^`/)X(`/$)(^X)(X$)
|
588 | 578 |
|
589 | 579 |
* C ("copy") updates the contents of the clipboard with the contents
|
|
591 | 581 |
|
592 | 582 |
>>> p = Semantics("(^/)hi(/$)(^%)lo(%$)")
|
593 | 583 |
>>> p.execute('C')
|
594 | |
>>> print str(p)
|
|
584 |
>>> print(str(p))
|
595 | 585 |
(^/)hi(/$)(^%)hi(%$)
|
596 | 586 |
>>> p = Semantics("(^/)hi(/$)(^J)lo(J$)(^`%)J(`%$)")
|
597 | 587 |
>>> p.execute('C')
|
598 | |
>>> print str(p)
|
|
588 |
>>> print(str(p))
|
599 | 589 |
(^/)hi(/$)(^J)hi(J$)(^`%)J(`%$)
|
600 | 590 |
|
601 | 591 |
* V ("paste") updates the contents of the selection with the contents
|
|
603 | 593 |
|
604 | 594 |
>>> p = Semantics("(^/)hi(/$)(^%)lo(%$)")
|
605 | 595 |
>>> p.execute('V')
|
606 | |
>>> print str(p)
|
|
596 |
>>> print(str(p))
|
607 | 597 |
(^/)lo(/$)(^%)lo(%$)
|
608 | 598 |
>>> p = Semantics("(^C)lo(C$)(^J)hi(J$)(^`/)J(`/$)(^`%)C(`%$)")
|
609 | 599 |
>>> p.execute('V')
|
610 | |
>>> print str(p)
|
|
600 |
>>> print(str(p))
|
611 | 601 |
(^C)lo(C$)(^J)lo(J$)(^`/)J(`/$)(^`%)C(`%$)
|
612 | 602 |
|
613 | 603 |
* S ("select") selects the contents of the slot indirect by the
|
|
615 | 605 |
|
616 | 606 |
>>> p = Semantics("(^/)foo(/$)(^?)A(?$)(^A)Some text.(A$)")
|
617 | 607 |
>>> p.execute('S')
|
618 | |
>>> print str(p)
|
|
608 |
>>> print(str(p))
|
619 | 609 |
foo(^?)A(?$)(^A)(^/)Some text.(/$)(A$)
|
620 | 610 |
>>> p = Semantics("(^`/)k(`/$)(^k)foo(k$)(^?)A(?$)(^A)Some text.(A$)")
|
621 | 611 |
>>> p.execute('S')
|
622 | |
>>> print str(p)
|
|
612 |
>>> print(str(p))
|
623 | 613 |
(^`/)k(`/$)foo(^?)A(?$)(^A)(^k)Some text.(k$)(A$)
|
624 | 614 |
|
625 | 615 |
* A ("select all") selects the contents of the accumulator.
|
626 | 616 |
|
627 | 617 |
>>> p = Semantics("(^/)foo(/$)(^?)A(?$)(^A)Some text.(A$)")
|
628 | 618 |
>>> p.execute('A')
|
629 | |
>>> print str(p)
|
|
619 |
>>> print(str(p))
|
630 | 620 |
foo(^?)(^/)A(/$)(?$)(^A)Some text.(A$)
|
631 | 621 |
>>> p = Semantics("(^`/)r(`/$)(^r)foo(r$)(^?)A(?$)(^A)Some text.(A$)")
|
632 | 622 |
>>> p.execute('A')
|
633 | |
>>> print str(p)
|
|
623 |
>>> print(str(p))
|
634 | 624 |
(^`/)r(`/$)foo(^?)(^r)A(r$)(?$)(^A)Some text.(A$)
|
635 | 625 |
|
636 | 626 |
* L ("left") slides the left locator of the selection leftward.
|
637 | 627 |
|
638 | 628 |
>>> p = Semantics("foo(^/)bar(/$)")
|
639 | 629 |
>>> p.execute('L')
|
640 | |
>>> print str(p)
|
|
630 |
>>> print(str(p))
|
641 | 631 |
fo(^/)obar(/$)
|
642 | 632 |
>>> p = Semantics("(^/)foobar(/$)")
|
643 | 633 |
>>> p.execute('L')
|
644 | |
>>> print str(p)
|
|
634 |
>>> print(str(p))
|
645 | 635 |
(^/)foobar(/$)
|
646 | 636 |
>>> p = Semantics("foo(^C)bar(C$)(^`/)C(`/$)")
|
647 | 637 |
>>> p.execute('L')
|
648 | |
>>> print str(p)
|
|
638 |
>>> print(str(p))
|
649 | 639 |
fo(^C)obar(C$)(^`/)C(`/$)
|
650 | 640 |
>>> p = Semantics("The last time I saw Charlie")
|
651 | 641 |
>>> p.execute('L')
|
|
657 | 647 |
|
658 | 648 |
>>> p = Semantics("foo(^/)bar(/$)")
|
659 | 649 |
>>> p.execute('R')
|
660 | |
>>> print str(p)
|
|
650 |
>>> print(str(p))
|
661 | 651 |
foob(^/)ar(/$)
|
662 | 652 |
>>> p = Semantics("foo(^/)(/$)bar")
|
663 | 653 |
>>> p.execute('R')
|
664 | |
>>> print str(p)
|
|
654 |
>>> print(str(p))
|
665 | 655 |
foo(^/)(/$)bar
|
666 | 656 |
>>> p = Semantics("foo(^C)bar(C$)(^`/)C(`/$)")
|
667 | 657 |
>>> p.execute('R')
|
668 | |
>>> print str(p)
|
|
658 |
>>> print(str(p))
|
669 | 659 |
foob(^C)ar(C$)(^`/)C(`/$)
|
670 | 660 |
>>> p = Semantics("The last time I saw Charlie")
|
671 | 661 |
>>> p.execute('R')
|
|
679 | 669 |
|
680 | 670 |
>>> p = Semantics("foo(^/)bar(/$)baz")
|
681 | 671 |
>>> p.execute('E')
|
682 | |
>>> print str(p)
|
|
672 |
>>> print(str(p))
|
683 | 673 |
foobar(^/)(/$)baz
|
684 | 674 |
>>> p = Semantics("foo(^a)b(^`/)a(`/$)r(a$)baz")
|
685 | 675 |
>>> p.execute('E')
|
686 | |
>>> print str(p)
|
|
676 |
>>> print(str(p))
|
687 | 677 |
foob(^`/)a(`/$)r(^a)(a$)baz
|
688 | 678 |
>>> p = Semantics("The last time I saw Charlie")
|
689 | 679 |
>>> p.execute('E')
|
|
697 | 687 |
|
698 | 688 |
>>> p = Semantics("(^?)By hook or by crook, we will.(?$)(^%)ook(%$)")
|
699 | 689 |
>>> p.execute('F')
|
700 | |
>>> print str(p)
|
|
690 |
>>> print(str(p))
|
701 | 691 |
(^?)By h(^/)ook(/$) or by crook, we will.(?$)(^%)ook(%$)
|
702 | 692 |
|
703 | 693 |
* D ("drag-and-drop") moves the selection to the accumulator.
|
704 | 694 |
|
705 | 695 |
>>> p = Semantics("(^/)hi(/$)(^?)lo(?$)")
|
706 | 696 |
>>> p.execute('D')
|
707 | |
>>> print str(p)
|
|
697 |
>>> print(str(p))
|
708 | 698 |
hi(^?)(^/)hi(/$)(?$)
|
709 | 699 |
>>> p = Semantics("(^C)lo(C$)(^J)hi(J$)(^`/)J(`/$)(^`?)C(`?$)")
|
710 | 700 |
>>> p.execute('D')
|
711 | |
>>> print str(p)
|
|
701 |
>>> print(str(p))
|
712 | 702 |
(^C)(^J)hi(J$)(C$)hi(^`/)J(`/$)(^`?)C(`?$)
|
713 | 703 |
|
714 | 704 |
* I ("input") waits for a line to appear on standard input, then
|
715 | 705 |
places it (sans newline) in the accumulator.
|
716 | 706 |
|
717 | |
>>> from StringIO import StringIO
|
|
707 |
>>> from io import StringIO
|
718 | 708 |
>>> p = Semantics("(^?)(?$)")
|
719 | 709 |
>>> p.input = StringIO(chr(10).join(["Line.", "Line!", "LINE!"]))
|
720 | 710 |
>>> p.execute('I')
|
721 | |
>>> print str(p)
|
|
711 |
>>> print(str(p))
|
722 | 712 |
(^?)Line.(?$)
|
723 | 713 |
>>> p.execute('I')
|
724 | |
>>> print str(p)
|
|
714 |
>>> print(str(p))
|
725 | 715 |
(^?)Line!(?$)
|
726 | 716 |
>>> p.execute('I')
|
727 | |
>>> print str(p)
|
|
717 |
>>> print(str(p))
|
728 | 718 |
(^?)LINE!(?$)
|
729 | 719 |
>>> p.execute('I')
|
730 | |
>>> print str(p)
|
|
720 |
>>> print(str(p))
|
731 | 721 |
(^?)(?$)
|
732 | 722 |
|
733 | 723 |
* O ("output") outputs the string in the accumulator to standard
|
|
736 | 726 |
>>> p = Semantics("(^?)Hello, world!(?$)")
|
737 | 727 |
>>> p.execute('O')
|
738 | 728 |
Hello, world!
|
739 | |
>>> print str(p)
|
|
729 |
>>> print(str(p))
|
740 | 730 |
(^?)Hello, world!(?$)
|
741 | 731 |
|
742 | 732 |
Now we demonstrate some idioms.
|
|
746 | 736 |
|
747 | 737 |
>>> p = Semantics("(^0)data(0$)(^%)(%$)(^?)(?$)(^!)0(!$)SCAV")
|
748 | 738 |
>>> p.run()
|
749 | |
>>> print str(p)
|
|
739 |
>>> print(str(p))
|
750 | 740 |
(^0)data(0$)(^%)data(%$)(^?)(^/)data(/$)(?$)0SCAV(^!)(!$)
|
751 | 741 |
|
752 | 742 |
New data, say the literal string 1, can be stored into slot 0 with:
|
753 | 743 |
|
754 | 744 |
>>> p = Semantics("(^0)data(0$)(^%)(%$)(^?)(?$)(^!)1(!$)AC0SV")
|
755 | 745 |
>>> p.run()
|
756 | |
>>> print str(p)
|
|
746 |
>>> print(str(p))
|
757 | 747 |
(^0)(^/)1(/$)(0$)(^%)1(%$)(^?)0(?$)1AC0SV(^!)(!$)
|
758 | 748 |
|
759 | 749 |
To copy from any arbitrary slot (say 0) to another (say 1), we can say:
|
760 | 750 |
|
761 | 751 |
>>> p = Semantics("(^0)hi(0$)(^1)(1$)(^%)(%$)(^?)(?$)(^!)0(!$)SC1SV")
|
762 | 752 |
>>> p.run()
|
763 | |
>>> print str(p)
|
|
753 |
>>> print(str(p))
|
764 | 754 |
(^0)hi(0$)(^1)(^/)hi(/$)(1$)(^%)hi(%$)(^?)1(?$)0SC1SV(^!)(!$)
|
765 | 755 |
|
766 | 756 |
Accessing a slot with a longer name, such as (^123)xyz(123$), can be
|
|
768 | 758 |
|
769 | 759 |
>>> p = Semantics("(^0)(0$)(^123)xyz(123$)(^%)(%$)(^?)(?$)(^!)1(!$)AC0SV2AC0SEV3AC0SEV0SCAVSD")
|
770 | 760 |
>>> p.run()
|
771 | |
>>> print str(p)
|
|
761 |
>>> print(str(p))
|
772 | 762 |
(^0)123(0$)(^123)xyz(123$)(^%)123(%$)(^?)(^/)xyz(/$)(?$)1AC0SV2AC0SEV3AC0SEV0SCAVSD(^!)(!$)
|
773 | 763 |
|
774 | 764 |
To write data, say (^8)foo(8$), into a slot whose name is stored in
|
|
776 | 766 |
|
777 | 767 |
>>> p = Semantics("(^8)foo(8$)(^9)jim(9$)(^jim)(jim$)(^%)(%$)(^?)(?$)(^!)8(!$)SC9SDSV")
|
778 | 768 |
>>> p.run()
|
779 | |
>>> print str(p)
|
|
769 |
>>> print(str(p))
|
780 | 770 |
(^8)foo(8$)(^9)jim(9$)(^jim)(^/)foo(/$)(jim$)(^%)foo(%$)(^?)jim(?$)8SC9SDSV(^!)(!$)
|
781 | 771 |
|
782 | 772 |
Finally, a complete, if simple, program:
|
|
851 | 841 |
self.update_slot(self.get_slot_name('?'), new_selection)
|
852 | 842 |
elif instruction == 'O':
|
853 | 843 |
line = self.read_slot('?') + "\n"
|
854 | |
try:
|
855 | |
self.output.write(line.encode('UTF-8'))
|
856 | |
except UnicodeEncodeError:
|
857 | |
self.output.write(line.encode('ascii', 'xmlcharrefreplace'))
|
|
844 |
self.output.write(line)
|
858 | 845 |
elif instruction == 'I':
|
859 | 846 |
text = self.input.readline()
|
860 | 847 |
if text.endswith('\n'):
|
|
895 | 882 |
super(TracedProgram, self).__init__(initial)
|
896 | 883 |
|
897 | 884 |
def run(self):
|
898 | |
print "[%s]" % str(self)
|
|
885 |
print("[%s]" % str(self))
|
899 | 886 |
super(TracedProgram, self).run()
|
900 | 887 |
|
901 | 888 |
def step(self):
|
902 | 889 |
result = super(TracedProgram, self).step()
|
903 | 890 |
if result:
|
904 | |
print "[%s]" % str(self)
|
|
891 |
print("[%s]" % str(self))
|
905 | 892 |
return result
|
906 | 893 |
|
907 | 894 |
|
|
923 | 910 |
(options, args) = optparser.parse_args(argv[1:])
|
924 | 911 |
exit_code = None
|
925 | 912 |
if options.show_license:
|
926 | |
print sys.argv[0]
|
927 | |
print __doc__
|
928 | |
print LICENSE
|
|
913 |
print(sys.argv[0])
|
|
914 |
print(__doc__)
|
|
915 |
print(LICENSE)
|
929 | 916 |
exit_code = 0
|
930 | 917 |
if options.run_tests:
|
931 | 918 |
import doctest
|
932 | 919 |
(fails, something) = doctest.testmod(verbose=True)
|
933 | 920 |
if fails == 0:
|
934 | |
print "All tests passed."
|
|
921 |
print("All tests passed.")
|
935 | 922 |
exit_code = 0
|
936 | 923 |
else:
|
937 | 924 |
exit_code = 1
|