%{
import apple_io
+ import data_types
import element
- import math
%}
%%
class NodeExpressionFloatLiteral: NodeExpression;
class NodeExpressionStrLiteral: NodeExpression;
class NodeExpressionVariable: NodeExpression;
+class NodeExpressionStrDollar: NodeExpression;
+class NodeExpressionVal: NodeExpression;
%%
raise Exception(
f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
)
- elif name[-1] == '%':
- if not isinstance(value, float):
- raise Exception(
- f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
- )
- value = ((int(math.floor(value)) + 0x8000) & 0xffff) - 0x8000
else:
if not isinstance(value, float):
raise Exception(
f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
)
+ if name[-1] == '%':
+ value = data_types.cint(value)
context.variables[name] = value
@method(NodeStatementPrint)
def execute(self, context):
for i in self.children:
value = i.evaluate(context)
if isinstance(value, float):
- sign = ''
- if value < 0.:
- sign = '-'
- value = -value
-
- if value == 0.:
- value = '0.'
- exponent = ''
- else:
- exponent = int(math.floor(math.log10(value)))
- if exponent < -99:
- value = '0.'
- exponent = ''
- else:
- if exponent >= 100:
- raise Exception(
- f'?OVERFLOW ERROR IN {context.line_number():d}'
- )
- value *= 10. ** (8 - exponent)
-
- int_value = int(round(value))
- assert int_value >= 100000000
- if int_value >= 1000000000:
- value /= 10.
- exponent += 1
- if exponent >= 100:
- raise Exception(
- f'?OVERFLOW ERROR IN {context.line_number():d}'
- )
- int_value = int(round(value))
- assert int_value >= 100000000 and int_value < 1000000000
-
- value = str(int_value)
- if exponent >= -2 and exponent < 9:
- exponent += 1
- if exponent < 0:
- value = '0' * -exponent + value
- exponent = 0
- value = value[:exponent] + '.' + value[exponent:]
- exponent = ''
- else:
- value = value[:1] + '.' + value[1:]
- exponent_sign = '+'
- if exponent < 0:
- exponent_sign = '-'
- exponent = -exponent
- exponent = 'E' + exponent_sign + ('0' + str(exponent))[-2:]
-
- i = len(value) - 1
- while value[i] == '0':
- i -= 1
- if value[i] != '.':
- i += 1
- value = sign + value[:i] + exponent
+ value = data_types.str_dollar(value)
apple_io._print(value)
if not self.semicolon:
apple_io.cr() # really writes \r\n
f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
)
value = item.text[0]
- elif name[-1] == '%':
- if isinstance(item, NodeTextIntLiteral):
- value = item.int_value
- elif isinstance(item, NodeFloatLiteral):
- value = int(math.floor(item.float_value))
- else:
- raise Exception(
- f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
- )
- value = ((value + 0x8000) & 0xffff) - 0x8000
else:
if isinstance(item, NodeTextIntLiteral):
value = float(item.int_value)
raise Exception(
f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
)
+ if name[-1] == '%':
+ value = data_types.cint(value)
context.variables[name] = value
@method(NodeStatementRestore)
def execute(self, context):
raise Exception(
f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
)
- apple_io.htab(int(math.floor(value)))
+ apple_io.htab(data_types.cint(value))
@method(NodeStatementVTab)
def execute(self, context):
value = self.children[0].evaluate(context)
raise Exception(
f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
)
- apple_io.vtab(int(math.floor(value)))
+ apple_io.vtab(data_types.cint(value))
@method(NodeStatementGet)
def execute(self, context):
name = self.children[0].str_value
name = self.children[-1].str_value
value = apple_io.input()
if name[-1] != '$':
- value = float(value)
+ value = data_types.val(value)
if name[-1] == '%':
- value = ((int(math.floor(value)) + 0x8000) & 0xffff) - 0x8000
+ value = data_types.cint(value)
context.variables[name] = value
del execute
else:
value = context.variables.get(name, 0.)
return value
+@method(NodeExpressionStrDollar)
+def evaluate(self, context):
+ value = self.children[0].evaluate(context)
+ if not isinstance(value, float):
+ raise Exception(
+ f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
+ )
+ return data_types.str_dollar(value)
+@method(NodeExpressionVal)
+def evaluate(self, context):
+ value = self.children[0].evaluate(context)
+ if not isinstance(value, str):
+ raise Exception(
+ f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
+ )
+ return data_types.val(value)
del evaluate
--- /dev/null
+import math
+
+def cint(value):
+ assert isinstance(value, float)
+ return ((int(math.floor(value)) + 0x8000) & 0xffff) - 0x8000
+
+def str_dollar(value):
+ assert isinstance(value, float)
+ sign = ''
+ if value < 0.:
+ sign = '-'
+ value = -value
+
+ if value == 0.:
+ value = '0.'
+ exponent = ''
+ else:
+ exponent = int(math.floor(math.log10(value)))
+ if exponent < -99:
+ value = '0.'
+ exponent = ''
+ else:
+ if exponent >= 100:
+ raise Exception(
+ f'?OVERFLOW ERROR IN {context.line_number():d}'
+ )
+ value *= 10. ** (8 - exponent)
+
+ int_value = int(round(value))
+ assert int_value >= 100000000
+ if int_value >= 1000000000:
+ value /= 10.
+ exponent += 1
+ if exponent >= 100:
+ raise Exception(
+ f'?OVERFLOW ERROR IN {context.line_number():d}'
+ )
+ int_value = int(round(value))
+ assert int_value >= 100000000 and int_value < 1000000000
+
+ value = str(int_value)
+ if exponent >= -2 and exponent < 9:
+ exponent += 1
+ if exponent < 0:
+ value = '0' * -exponent + value
+ exponent = 0
+ value = value[:exponent] + '.' + value[exponent:]
+ exponent = ''
+ else:
+ value = value[:1] + '.' + value[1:]
+ exponent_sign = '+'
+ if exponent < 0:
+ exponent_sign = '-'
+ exponent = -exponent
+ exponent = 'E' + exponent_sign + ('0' + str(exponent))[-2:]
+
+ i = len(value) - 1
+ while value[i] == '0':
+ i -= 1
+ if value[i] != '.':
+ i += 1
+ return sign + value[:i] + exponent
+
+def val(value):
+ # make this more sophisticated later
+ assert isinstance(value, str)
+ return float(value)