/
_repl.py
126 lines (97 loc) · 3.9 KB
/
_repl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
from .shakespeare import Shakespeare
from .errors import ShakespeareError
from ._utils import normalize_name
from tatsu.exceptions import FailedParse
try:
import readline
except ModuleNotFoundError:
print("readline module is not supported in Windows, continuing without it.")
import sys
DEFAULT_PLAY_TEMPLATE = """
A REPL-tastic Adventure.
<dramatis personae>
Act I: All the World.
Scene I: A Stage.
[Enter <entrance list>]
"""
def start_console(characters=["Romeo", "Juliet"]):
dramatis_personae = "\n".join([name + ", a player." for name in characters])
entrance_list = _entrance_list_from_characters(characters)
play = DEFAULT_PLAY_TEMPLATE.replace(
"<dramatis personae>", dramatis_personae
).replace("<entrance list>", entrance_list)
print(play)
interpreter = Shakespeare(play)
# Run the entrance
interpreter.step_forward()
run_repl(interpreter)
# E.g. ["Mercutio", "Romeo", "Tybalt"] => "Mercutio, Romeo and Tybalt"
def _entrance_list_from_characters(characters):
all_commas = ", ".join(characters)
split_on_last = all_commas.rsplit(", ", 1)
return " and ".join(split_on_last)
def debug_play(text, input_style="interactive", output_style="verbose"):
interpreter = Shakespeare(text, input_style=input_style, output_style=output_style)
def on_breakpoint():
print("-----\n" + interpreter.next_operation_text() + "\n-----\n")
run_repl(interpreter)
interpreter.run(on_breakpoint)
def run_repl(interpreter):
previous_input_style = interpreter.settings.input_style
previous_output_style = interpreter.settings.output_style
interpreter.settings.input_style = "interactive"
interpreter.settings.output_style = "verbose"
current_character = None
while True:
try:
pos_before = interpreter.current_position
repl_input = input(">> ")
if repl_input in ["exit", "quit"]:
sys.exit()
elif repl_input == "continue":
break
elif repl_input == "next":
if interpreter.play_over():
break
interpreter.step_forward()
elif repl_input == "state":
print(str(interpreter.state))
else:
# TODO: make this not an awkward return value
current_character = _run_repl_input(
interpreter, repl_input, current_character
)
if interpreter.current_position != pos_before:
if interpreter.play_over():
break
print("\n-----\n" + interpreter.next_operation_text() + "\n-----\n")
except ShakespeareError as e:
print(str(e), file=sys.stderr)
interpreter.input_style = previous_input_style
interpreter.output_style = previous_output_style
def _run_repl_input(interpreter, repl_input, current_character):
ast = interpreter.parse(repl_input + "\n", "repl_input")
event = ast.event
sentences = ast.sentences
# Events that are lines should be considered sets of sentences.
if event and event.parseinfo.rule == "line":
current_character = normalize_name(event.character)
sentences = event.contents
event = None
if event:
interpreter.run_event(event)
elif sentences:
if not current_character:
print("Who's saying this?")
return
for sentence in sentences:
interpreter.run_sentence(sentence, current_character)
elif ast.value:
if ast.expression_character:
current_character = normalize_name(ast.expression_character)
print(interpreter.evaluate_expression(ast.value, current_character))
elif ast.display_character:
print(
interpreter.state.character_by_name(normalize_name(ast.display_character))
)
return current_character