]> thyrsus.com Git - mad.git/commitdiff
Canonicalize integer constants.
authorEric S. Raymond <esr@thyrsus,com>
Wed, 21 Jan 2004 02:01:41 +0000 (02:01 +0000)
committerEric S. Raymond <esr@thyrsus,com>
Wed, 21 Jan 2004 02:01:41 +0000 (02:01 +0000)
mad

diff --git a/mad b/mad
index ce10bc804292b840294af47b5d9d967291e10328..382ed019c0a864d01515dbcc32684f561304618a 100755 (executable)
--- a/mad
+++ b/mad
@@ -41,8 +41,7 @@ t_DIVIDE  = r'/'
 t_EQUALS  = r'='
 t_LPAREN  = r'\('
 t_RPAREN  = r'\)'
-t_FLOATNUM= r'\d+\.\d*'
-t_INTNUM  = r'\d+'
+#t_INTNUM  = r'\d+'
 t_STRING  = r'\$[^$]*\$'
 
 reserved_map = { }
@@ -58,6 +57,19 @@ def t_NAME(t):
     t.value = t.value.lower()
     return t
 
+def t_FLOATNUM(t):
+    r'\d+\.\d*'
+    if t.value[-1] == '.':
+        t.value += "0"
+    return t
+
+def t_INTNUM(t):
+    r'\d+'
+    # Leading zeros flip us into ocal in C, therefore strip them.
+    while len(t.value) > 1 and t.value[0] == '0':
+        t.value = t.value[1:]
+    return t
+
 t_ignore = ' \n'
 
 def t_error(t):
@@ -88,7 +100,7 @@ sourcefile = ""
 sourceline = 0
 deck = []
 scopes = []
-targets = []
+targets = {}
 untyped = []
 
 # Program level
@@ -175,7 +187,7 @@ def p_map_continue(t):
 def p_transfer(t):
     'statement : TRANSFER TO NAME'
     t[0] = ('goto', t[3])
-    targets.append(t[3])
+    targets[t[3]] = targets.get(t[3], 0) + 1
 
 ## WHENEVER
 def p_whenever_simple(t):
@@ -440,7 +452,11 @@ def fmt_convert(str, write=True):
     return res
 
 def print_statement(statement):
-    if statement[0] in ('dimension', 'end_program', 'integer', 'values'):
+    if statement[0] in ('dimension',
+                        'end_program',
+                        'function',
+                        'integer',
+                        'values'):
         pass
     elif statement[0] == 'for':
         (keyword, label, dummy, start, increment, predicate) = statement
@@ -452,7 +468,11 @@ def print_statement(statement):
     elif statement[0] == 'read':
         return 'scanf("' + fmt_convert(format[statement[1]], write=False) + '", ' + ', '.join(map(lambda x: '&'+x, statement[2:])) + ');'
     elif statement[0] == 'print':
-        return 'printf("' + fmt_convert(format[statement[1]]) + '", ' + ', '.join(statement[2:]) + ');'
+        fmt = fmt_convert(format[statement[1]])
+        if len(statement) < 3:
+            return 'printf("' + fmt + '");'
+        else:
+            return 'printf("' + fmt + '", ' + ', '.join(statement[2:]) + ');'
     elif statement[0] == 'substitution':
         return statement[1] + ' = ' + print_expr(statement[2]) + ';'
     else:
@@ -462,10 +482,10 @@ def generate(out):
     out.write('#include <math.h>\n\n')
 
     for (line, label, statement) in deck:
-        if statement == 'function':
+        if statement[0] == 'function':
             # FIXME: someday, deduce when return is of integral type
-            out.write('float %s {return %s;}' \
-                      (t[1], print_expr(('apply', t[2], t[3])),t[4]))
+            out.write('float %s {return %s;}\n' % \
+                      (print_expr(('apply', statement[1], statement[2])), print_expr(statement[3])))
 
     out.write('\nmain(int argc, char *argv[])\n')
     out.write('{\n')
@@ -483,7 +503,7 @@ def generate(out):
     global sourceline
     for (sourceline, label, statement) in deck:
         if label in targets:
-            sys.stdout.write(label+':')
+            out.write(label+':')
         rep = print_statement(statement)
         if rep:
             out.write('\t' + '    '*indent + rep + '\n')
@@ -523,7 +543,7 @@ if __name__ == '__main__':
         yacc.parse(source, debug=mad_debug)
 
     # Perform global analysis
-    analyze(deck)    
+    analyze(deck)
     # Generate code
     if arguments == ('-',):
         generate(sys.stdout)