return len(poll_in.poll(1)) != 0
def read(n):
- data = os.read(fd_in, 1)
- if len(data) == 0:
- raise Exception('end of input') # due to piping or input redirection
- return str(data, 'ascii')
+ return str(os.read(fd_in, 1), 'ascii')
-def write(str):
+def write(data):
os.write(fd_out, bytes(data, 'ascii'))
def cr():
# apple treats \r as \r\n, so if you write e.g. \r\n you'll get \r\n\n
write('\r\n')
+def get():
+ data = read(1)
+ if len(data) == 0:
+ raise Exception('end of input') # due to piping or input redirection
+ return data
+
+def input():
+ line = ''
+ while True:
+ key = get()
+ _print(key)
+ if key == '\r':
+ return line
+ if key == '\b':
+ if len(line):
+ write(' \b')
+ line = line[:-1]
+ else:
+ # strictly, apple only does this if cursor not at left, maybe
+ # because it knows the echoed backspace has no effect at left
+ cr()
+ else:
+ if len(line) >= 247:
+ write('\a')
+ if len(line) >= 255:
+ cr()
+ line = ''
+ continue
+ line += key
+
+def _print(data):
+ # basically write(data.replace('\r', '\r\n')) but may be more responsive
+ lines = data.split('\r')
+ for line in lines[:-1]:
+ write(line)
+ cr()
+ write(lines[-1])
+
def htab(x):
write(f'\x1b[{x:d}G')
class NodeStatementHTab: NodeStatement;
class NodeStatementVTab: NodeStatement;
class NodeStatementGet: NodeStatement;
+class NodeStatementInput: NodeStatement;
class NodeExpression: Node;
class NodeExpressionOr: NodeExpression;
class NodeExpressionAnd: NodeExpression;
if value[i] != '.':
i += 1
value = sign + value[:i] + exponent
- else:
- lines = value.split('\r')
- for i in lines[:-1]:
- apple_io.write(i)
- apple_io.cr() # really writes \r\n
- value = lines[-1]
- apple_io.write(value)
+ apple_io._print(value)
if not self.semicolon:
apple_io.cr() # really writes \r\n
@method(NodeStatementGoto)
@method(NodeStatementGet)
def execute(self, context):
name = self.children[0].str_value
- value = apple_io.read(1)
+ value = apple_io.get()
if name[-1] != '$':
raise Exception(
f'?SYNTAX ERROR IN {context.line_number():d}'
)
context.variables[name] = value
+@method(NodeStatementInput)
+def execute(self, context):
+ apple_io._print(
+ self.children[-2].text[0]
+ if len(self.children) >= 2 else
+ '?'
+ )
+ name = self.children[-1].str_value
+ value = apple_io.input()
+ if name[-1] != '$':
+ value = float(value)
+ if name[-1] == '%':
+ value = ((int(math.floor(value)) + 0x8000) & 0xffff) - 0x8000
+ context.variables[name] = value
del execute
@method(NodeExpression)
| %space (?E{t_def.NodeStatementHTab}KEYWORD_HTAB expression)
| %space (?E{t_def.NodeStatementVTab}KEYWORD_VTAB expression)
| %space (?E{t_def.NodeStatementGet}KEYWORD_GET VARIABLE)
+ | %space (?E{t_def.NodeStatementInput}KEYWORD_INPUT VARIABLE)
+ | %space (?E{t_def.NodeStatementInput}KEYWORD_INPUT STR_LITERAL ';' VARIABLE)
;
print_expression_list0