Improve number printing to make it more symmetrical with parsing
authorNick Downing <nick@ndcode.org>
Sun, 15 May 2022 14:29:38 +0000 (00:29 +1000)
committerNick Downing <nick@ndcode.org>
Sun, 15 May 2022 14:36:57 +0000 (00:36 +1000)
applesoft_basic.t

index 325be7f..cf1bc9f 100644 (file)
@@ -140,7 +140,7 @@ def post_process(self, program):
 @method(NodeTextIntLiteral)
 def post_process(self, program):
   NodeText.post_process(self, program)
-  self.int_value = int(self.str_value)  
+  self.int_value = int(self.str_value)
 del post_process
 @method(NodeFloatLiteral)
 def post_process(self, program):
@@ -185,41 +185,52 @@ def execute(self, context):
       if value < 0.:
         sign = '-'
         value = -value
-      if value == 0. or (value >= .01 and value < 999999999.2):
-        if value >= 100000000.:
-          value = f'{value:.0f}.'
-        elif value >= 10000000.:
-          value = f'{value:.1f}'
-        elif value >= 1000000.:
-          value = f'{value:.2f}'
-        elif value >= 100000.:
-          value = f'{value:.3f}'
-        elif value >= 10000.:
-          value = f'{value:.4f}'
-        elif value >= 1000.:
-          value = f'{value:.5f}'
-        elif value >= 100.:
-          value = f'{value:.6f}'
-        elif value >= 10.:
-          value = f'{value:.7f}'
-        elif value >= 1.:
-          value = f'{value:.8f}'
-        elif value >= .1:
-          value = f'{value:.9f}'
-        else:
-          value = f'{value:.10f}'
+
+      if value == 0.:
+        value = '0.'
         exponent = ''
       else:
-        value = f'{value:10.8e}'
-        assert value[-4] == 'e'
-        exponent = 'E' + value[-3:]
-        value = value[:-4]
-      while value[-1] == '0':
-        value = value[:-1]
-      if value[-1] == '.':
-        value = value[:-1]
-      value = sign + value + exponent
-    assert isinstance(value, str)
+        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
     print(value, end = '')
   if not self.semicolon:
     print()