]> thyrsus.com Git - mad.git/commitdiff
Summand parsing is screwed up.
authorEric S. Raymond <esr@thyrsus,com>
Wed, 14 Jan 2004 19:03:32 +0000 (19:03 +0000)
committerEric S. Raymond <esr@thyrsus,com>
Wed, 14 Jan 2004 19:03:32 +0000 (19:03 +0000)
mad

diff --git a/mad b/mad
index 42dead654dd1f8b41740e30e30d2e0cccb2a1636..d99123dc10cc0a450667a784bb8affedb98cb987 100755 (executable)
--- a/mad
+++ b/mad
@@ -81,9 +81,10 @@ precedence = (
     ('right', 'ABS', 'UPLUS')
     )
 
-cards = []
+deck = []
 scopes = []
 targets = []
+untyped = []
 
 # Program level
 
@@ -93,11 +94,11 @@ def p_program(t):
 
 def p_card(t):
     'card : TAB statement SEMI' 
-    cards.append((None, t[2]))
+    deck.append((None, t[2]))
 
 def p_labeled_card(t):
     'card : NAME TAB statement SEMI'
-    cards.append((t[1], t[3]))
+    deck.append((t[1], t[3]))
 
 # Statement level
 
@@ -183,6 +184,8 @@ def p_whenever_complex(t):
 def p_statement_substitution(t):
     'statement : NAME EQUALS expression'
     t[0] = ('substitution', t[1], t[3])
+    if t[1] not in untyped:
+        untyped.append(t[1])
 
 # Expression parsing
 
@@ -191,6 +194,7 @@ def p_expression_binop1(t):
                   | expression MINUS expression
                   | expression TIMES expression
                   | expression DIVIDE expression'''
+    print "Foo"
     t[0] = (t[2].lower(), t[1], t[3])
 
 def p_expression_binop2(t):
@@ -234,7 +238,7 @@ def p_expression_integer(t):
 
 def p_expression_float(t):
     'expression : FLOATNUM'
-    t[0] = ('float', t[1])
+    t[0] = ('floatnum', t[1])
 
 def p_expression_subscript(t):
     'expression : NAME application'
@@ -270,18 +274,31 @@ yacc.yacc()
 
 import sys, re
 
-indent = 0
-
-def recode(cards):
-    "Rewrite the statement list."
-    # Find first INTEGER declaration, move it to the front.
-    for statement in cards:
-        if statement[1][0] == 'integer':
-            declaration = statement
-            cards.remove(declaration)
-            cards = [declaration] + cards
-            break
-    return cards
+integers = []
+floats = []
+bools = []
+dimensions = {}
+
+def declare(var, lst):
+    if var in untyped:
+        untyped.remove(var)
+    lst.append(var)
+
+def analyze(deck):
+    "Gather variable types."
+    global integers, floats, bools
+    for (label, statement) in deck:
+        if statement[0] == 'integer':
+            print "Bar!", statement
+            for var in statement[1:]:
+                declare(var, integers)
+        elif statement[0] == 'dimension':
+            for (var, dimlist) in statement[1]:
+                dimensions[var] = dimlist
+        elif statement[0] == 'substitution':
+            var = statement[1]
+            if var not in integers + bools + floats + untyped:
+                untyped.append(var)
 
 def print_expr(t):
     if t[0] == 'variable':
@@ -312,7 +329,7 @@ def print_expr(t):
         return "(%s == %s)" % (print_expr(t[1]), print_expr(t[2]))
     elif t[0] == 'ne':
         return "(%s != %s)" % (print_expr(t[1]), print_expr(t[2]))
-    elif t[0] == 'pow':
+    elif t[0] == 'p':
         return "pow(%s, %s)" % (print_expr(t[1]), print_expr(t[2]))
     elif t[0] == 'and':
         return "(%s && %s)" % (print_expr(t[1]), print_expr(t[2]))
@@ -328,33 +345,23 @@ def print_expr(t):
         return "%s" % print_expr(t[1])
     elif t[0] == '-':
         return "(-%s)" % print_expr(t[1])
-    elif t[0] == 'intnum':
+    elif t[0] in ('intnum', 'floatnum'):
         return t[1]
     else:
         return "***"+`t`
 
 def print_statement(statement):
-    global indent
-    if statement[0] == 'end_program':
-        return "/* END OF PROGRAM */"
-    elif statement[0] == 'dimension':
-        declaration = "int";
-        for (var, dimlist) in statement[1]:
-            declaration += " " + var
-            for dim in dimlist:
-                declaration += "[" + dim[1] + "]"
-            declaration += ", "
-        return(declaration[:-2] + ";")
+    if statement[0] in ('dimension', 'end_program', 'integer'):
+        pass
     elif statement[0] == 'for':
         (keyword, label, dummy, start, increment, predicate) = statement
-        indent += 1
         return "for (%s = %s; %s; %s += %s) {" % (dummy, print_expr(start), print_expr(predicate), dummy, print_expr(increment))
+    elif statement[0] == 'goto':
+        return "goto " + statement[1] + ";" 
     elif statement[0] == 'if':
-        return "if (" + print_expr(statement[1]) + ") " + print_statement(statement[2]) + ";"
-    elif statement[0] == 'integer':
-        return "int " + ", ".join(statement[1:]) + ";"
+        return "if (" + print_expr(statement[1]) + ") " + print_statement(statement[2])
     elif statement[0] == 'substitution':
-        return statement[1] + " = " + print_expr(statement[2]) 
+        return statement[1] + " = " + print_expr(statement[2]) + ";"
     else:
         return(`statement`)
 
@@ -362,16 +369,30 @@ if __name__ == '__main__':
     source = sys.stdin.read()
     # Grotty hack to add end-of-statement delimiters
     source = re.sub("\n([A-Z]|\t)", " ;\n\\1", source).rstrip() + " ;\n"
-    yacc.parse(source)
-    cards = recode(cards)
+    yacc.parse(source, debug=1)
+
+    analyze(deck)
 
     print "#include <math.h>"
     print "main(int argc, char *argv[])"
     print "{"
-    for (label, statement) in cards:
+    if integers:
+        print "\tint " + ", ".join(integers) + ";\t/* INTEGER */"
+    if bools:
+        print "\tint " + ", ".join(bools) + ";\t/* boolean */"
+    if untyped:
+        print "\tint " + ", ".join(untyped) + ";\t/* untyped */"
+    if floats:
+        print "\tfloat " + ", ".join(floats) + ";"
+    indent = 0
+    for (label, statement) in deck:
         if label in targets:
             sys.stdout.write(label+":")
-        sys.stdout.write("\t" + "    "*indent +print_statement(statement) + "\n")
+        rep = print_statement(statement)
+        if rep:
+            sys.stdout.write("\t" + "    "*indent + rep + "\n")
+            if rep[-1] == '{':
+                indent += 1
         if label in scopes:
             indent -= 1
             print ("\t" + "    "*indent) + "}"