]> thyrsus.com Git - mad.git/commitdiff
We comiple maxfunc.
authorEric S. Raymond <esr@thyrsus,com>
Mon, 9 Feb 2004 10:22:00 +0000 (10:22 +0000)
committerEric S. Raymond <esr@thyrsus,com>
Mon, 9 Feb 2004 10:22:00 +0000 (10:22 +0000)
mad

diff --git a/mad b/mad
index 506fd6f5451ab7d48df33286a45cc46cd45e7e94..0cc3815bd794881db3821d30461fe8965c92c979 100755 (executable)
--- a/mad
+++ b/mad
@@ -107,6 +107,8 @@ scopes = []
 targets = {}
 headers = []
 funcnames = []
+arraydepths = {}
+returntypes = {}
 
 currentfunc = 'main.'
 typedict = {'main.':{}}
@@ -174,6 +176,7 @@ def p_entry(t):
     currentfunc = t[3]
     t[0] = ('entry', currentfunc)
     typedict[currentfunc] = {}
+    arraydepths[currentfunc] = {}
     funcnames.append(currentfunc)
 
 ## EXECUTE
@@ -370,6 +373,7 @@ def p_expression_subscript(t):
     t[0] = ('variable', t[1], tuple(t[2]))
     var = t[1]
     refcount[var] = refcount.get(var, 0) + 1
+    arraydepths[currentfunc][var] = len(t[2])
 
 def p_function_application(t):
     'expression : FUNCALL application'
@@ -435,13 +439,18 @@ def analyze():
     for (file, line, label, statement) in deck:
         if statement[0] == 'dimension':
             for (var, dimlist) in statement[1]:
-                dimensions[var] = dimlist
+                dimensions[currentfunc][var] = dimlist
         elif statement == 'entry':
             currentfunc = statement[1]
+            dimensions[currentfunc] = {}
             funcline = line
         elif statement[0] == 'integer':
             for var in statement[1:]:
                 typedict[currentfunc][var] = 'int'
+        elif statement[0] == 'return':
+            # Crude type inference -- give the function the type of the
+            # last return.
+            returntypes[currentfunc] = mode(statement[1])
         elif statement[0] == 'substitution':
             typedict[currentfunc][statement[1]] = 'double'
         elif statement[0] == 'values':
@@ -663,23 +672,29 @@ def print_statement(statement):
     elif statement[0] == 'entry':
         func = statement[1]
         types = typedict[func]
-        rep = "\n" + func[:-1] + "("
+        depths = arraydepths[currentfunc]
+        rep = "\n" + returntypes.get(func, "double") + " " + func[:-1] + "("
+        defaulted = []
         if statement[2]:
             for (dummy, var) in statement[2]:
+                declarator = ("*" * depths.get(var, 0)) + var
                 if var in types:
-                    rep += types[var] + " " + var + ", "
+                    rep += types[var] + " " + declarator + ", "
                     del types[var]
                 else:
-                    rep += "UNTYPED " + var + ", "
+                    rep += "double " + declarator + ", "
+                    defaulted.append(var)
             rep = rep[:-2]
-        rep  = rep + ") {"
+        rep  = rep + ") {\n"
+        if defaulted:
+            sys.stderr.write("warning: defaulted base type for %s\n" % ", ".join(defaulted))
         declarations = ""
        for type in ('double', 'int', 'bool'):
             vars = filter(lambda x: types[x] == type, types.keys())
             if vars: 
                 declarations +=  type + " " + ", ".join(vars) + "; "
         if declarations:
-            rep += "\n    " + declarations[:-1] + "\n"
+            rep += "    " + declarations[:-1] + "\n"
         return rep
     elif statement[0] == 'execute':
         return print_expr(statement[1]) + ";"
@@ -709,7 +724,7 @@ def print_statement(statement):
         if len(statement) == 1:
             return "return;"
         else:
-            return "return %s" % print_expr(statement[1])
+            return "return %s;" % print_expr(statement[1])
     elif statement[0] == 'or':
         return 'else if (' + print_expr(statement[2]) + ') {'
     elif statement[0] == 'otherwise':
@@ -795,8 +810,6 @@ if __name__ == '__main__':
         # by whitespace and a continuation digit
         source = source.replace("\n", " ;\n")
         source = re.sub(';\n(\s*)[0-9]+', '\n\\1', source)
-        sys.stdout.write(source)
-        sys.exit(1)
         # Parse
         yacc.parse(source, debug=mad_debug)