pass
@method(StatementInput)
def execute(self, context):
- apple_io._print(
- self.children[-2].text[0]
- if len(self.children) >= 2 else
- '?'
- )
- value = apple_io.input()
- self.children[-1].set_val(context, value)
+ while True:
+ apple_io._print(
+ self.children[-2].text[0]
+ if len(self.children) >= 2 else
+ '?'
+ )
+ value = apple_io.input()
+ lvalue = self.children[-1]
+ name = lvalue.children[0].str_value
+ if name[-1] != '$':
+ n, result = data_types.val(value)
+ if n == 0 or n < len(value):
+ apple_io._print('?REENTER\r')
+ continue
+ value = result
+ if name[-1] == '%':
+ value = data_types.cint(value)
+ lvalue.find_variable(context).value = value
+ break
@method(StatementDel)
def execute(self, context):
assert False
while context.m < len(statement.children):
item = statement.children[context.m]
context.m += 1
- self.children[i].set_val(context, item.text[0])
+ value = item.text[0]
+ lvalue = self.children[i]
i += 1
+ name = lvalue.children[0].str_value
+ if name[-1] != '$':
+ n, result = data_types.val(value)
+ if n < len(value):
+ raise Exception(
+ f'?SYNTAX ERROR IN {context.line_number():d}'
+ )
+ value = result
+ if name[-1] == '%':
+ value = data_types.cint(value)
+ lvalue.find_variable(context).value = value
if i >= len(self.children):
return
context.l += 1
for i in self.children:
value = i.get(context)
if isinstance(value, float):
- value = data_types.str_dollar(value)
+ value = data_types.str_dollar(context, value)
apple_io._print(value)
if not self.semicolon:
apple_io._print('\r')
@method(RValueStrDollar)
def get(self, context):
value = self.children[0].get_float(context)
- return data_types.str_dollar(value)
+ return data_types.str_dollar(context, value)
@method(RValueVal)
def get(self, context):
value = self.children[0].get_str(context)
- return data_types.val(value)
+ return data_types.val(value)[1] # ignore n chars converted
@method(RValueAsc)
def get(self, context):
value = self.children[0].get_str(context)
value = data_types.cint(value)
self.find_variable(context).value = value
del set
-
-@method(LValue)
-def set_val(self, context, value):
- assert isinstance(value, str)
- name = self.children[0].str_value
- if name[-1] != '$':
- value = data_types.val(value)
- if name[-1] == '%':
- value = data_types.cint(value)
- self.find_variable(context).value = value
-del set_val
import math
+import re
# note: python 3 returns int type from math.floor(), I don't really
# like this, but I rely on it below to avoid needing explicit int()
assert isinstance(value, float)
return ((math.floor(value) + 0x8000) & 0xffff) - 0x8000
-def str_dollar(value):
+def str_dollar(context, value):
assert isinstance(value, float)
sign = ''
if value < 0.:
i += 1
return sign + value[:i] + exponent
+# (\ *[+-])? 1
+# ( 2
+# ( 3
+# (\ *[0-9]*)* 4
+# )
+# \ *\.
+# ( 5
+# (\ *[0-9])* 6
+# )
+# |
+# ( 7
+# (\ *[0-9])+ 8
+# )
+# )
+# ( 9
+# \ *E
+# (\ *[+-])? 10
+# \ *
+# ( 11
+# (\ *[0-9])+ 12
+# )
+# )?
+re_val = re.compile(
+ '(\ *[+-])?(((\ *[0-9]*)*)\ *\.((\ *[0-9])*)|((\ *[0-9])+))(\ *E(\ *[+-])?\ *((\ *[0-9])+))?'
+)
def val(value):
- # make this more sophisticated later
- assert isinstance(value, str)
- value = value.replace(' ', '')
- return float(value) if len(value) else 0.
+ match = re_val.match(value)
+ if match is None:
+ return 0, 0.
+ sign = (match.group(1) or '').replace(' ', '')
+ integer = (match.group(3) or match.group(7) or '').replace(' ', '')
+ fraction = (match.group(5) or '').replace(' ', '')
+ exp = 0
+ if match.group(9) is not None:
+ exp_sign = (match.group(10) or '').replace(' ', '')
+ exp = int(match.group(11).replace(' ', ''))
+ if exp_sign == '-':
+ exp = -exp
+ result = int(integer + fraction) * 10. ** (exp - len(fraction))
+ if sign == '-':
+ result = -result
+ return len(match.group(0)), result