]> thyrsus.com Git - mad.git/commitdiff
Generated code for tscheb looks right.
authorEric S. Raymond <esr@thyrsus,com>
Tue, 10 Feb 2004 18:13:37 +0000 (18:13 +0000)
committerEric S. Raymond <esr@thyrsus,com>
Tue, 10 Feb 2004 18:13:37 +0000 (18:13 +0000)
mad

diff --git a/mad b/mad
index a006761e042632f6564afed2602dede240c54420..689377a43f56e916c50b02c39438a06ca263af5b 100755 (executable)
--- a/mad
+++ b/mad
@@ -105,27 +105,25 @@ precedence = (
     )
 
 refcount = {}
-sourcefile = ""
-sourceline = 0
-deck = []
-scopes = []
-targets = {}
-headers = []
-funcnames = []
-typedict = {}
-arraydepths = {}
-returntypes = {}
-normalmode = 'double'
-dummycount = 0
-dimensions = {}
-static = {}
-format = {}
-hasmain = False
+sourcefile = ""                # Current source file for error messages
+sourceline = 0         # Current source line for error messages
+deck = []              # List of tuples generated by parsing
+scopes = []            # THROUGH scopes that are pending
+targets = {}           # Dictionary of targets of TRANSFERs
+headers = []           # Required .h file basenames
+funcnames = []         # List of function names
+dimensions = {}                # Dictionary of array depths
+arraydepths = {}       # Dictionary of array dimensions
+returntypes = {}       # Dictionary of function returntypes
+normalmode = 'double'  # Default type as set by NORMAL statement
+dummycount = 0         # Count of FOR VALUES statements
+static = {}            # Dictionary of static char variables
+format = {}            # Dictionary of format strings
+hasmain = False                # Does this program have a main line?
 
 def initfunc(f):
     global currentfunc
     currentfunc = f
-    typedict[currentfunc] = {}
     funcnames.append(currentfunc)
 
 initfunc("main.")
@@ -154,11 +152,9 @@ def p_boolean(t):
 def p_boollist(t):
     'boollist : NAME'
     t[0] = [t[1]]
-    typedict[currentfunc][t[1]] = 'bool'
 def p_boollist_continue(t):
     'boollist : boollist COMMA NAME'
     t[0] = t[1] + [t[3]]
-    typedict[currentfunc][t[3]] = 'bool'
 
 ## CONTINUE
 def p_statement_continue(t):
@@ -190,9 +186,8 @@ def p_end_of_functions(t):
 ## ENTRY
 def p_entry(t):
     "statement : ENTRY TO FUNCALL"
-    global currentfunc
     initfunc(t[3])
-    t[0] = ('entry', currentfunc)
+    t[0] = ('entry', t[3])
 
 ## EXECUTE
 def p_execute(t):
@@ -227,11 +222,9 @@ def p_integer(t):
 def p_intlist(t):
     'intlist : NAME'
     t[0] = [t[1]]
-    typedict[currentfunc][t[1]] = 'int'
 def p_intlist_continue(t):
     'intlist : intlist COMMA NAME'
     t[0] = t[1] + [t[3]]
-    typedict[currentfunc][t[3]] = 'int'
 
 ## INTERNAL FUNCTION
 def p_internal(t):
@@ -461,6 +454,15 @@ def croak(t, msg):
     (file, line, label, statement) = t
     sys.stderr.write('"%s", line %d: %s\n' % (file, line, msg))
 
+# All MAD variables are global, you have to simulate locals using SAVE DATA and
+# RETURN DATA.  Thus most of the variable lookup tables about are straight
+# dictionaries not qualified by current function name.  typedict is an
+# exception; we use this to generate per-function variables as C auto
+# variables and get nicer C code.  This would break if two MAD external
+# functions deliberately shared a global, but this doesn't happen in
+# any of the examples.
+typedict = {}          # Dictionary of per-function dictionaries of locals
+
 def analyze():
     "Gather variable types and determine function boundaries."
     global deck, currentfunc, hasmain
@@ -485,9 +487,10 @@ def analyze():
         elif statement[0] == 'dimension':
             for (var, dimlist) in statement[1]:
                 dimensions[var] = dimlist
-        elif statement == 'entry':
+        elif statement[0] == 'entry':
             currentfunc = statement[1]
             funcline = line
+            typedict[currentfunc] = {}
         elif statement[0] == 'integer':
             for var in statement[1:]:
                 typedict[currentfunc][var] = 'int'
@@ -524,7 +527,10 @@ def analyze():
     # Do type deductions from format fields
     for card in deck:
         (file, line, label, statement) = card
-        if statement[0] == 'read':
+        if statement[0] == 'entry':
+            currentfunc = statement[1]
+            funcline = line
+        elif statement[0] == 'read':
             if statement[1] not in format:
                 croak(card, "uninitialized format string" +`statement[1]`)
             else:
@@ -541,7 +547,7 @@ def analyze():
         deductions = 0
         for card in deck:
             (file, line, label, statement) = card
-            if statement == 'entry':
+            if statement[0] == 'entry':
                 # Bookkeeping, so we know what function we're in
                 currentfunc = statement[1]
                 funcline = line
@@ -555,8 +561,9 @@ def analyze():
                     deductions += 1
             elif statement[0] == 'substitution':
                 # Propagate type markers through assignment
+                var = statement[1]
                 m = mode(statement[2])
-                typedict[currentfunc][statement[1]] = m
+                typedict[currentfunc][var] = m
                 if m != normalmode and typedict[currentfunc][statement[1]]!=m:
                     deductions += 1
         if deductions == 0:
@@ -757,6 +764,7 @@ def fmt_convert(str, write=True):
     return (res, types)
 
 def print_statement(statement):
+    global currentfunc
     if statement[0] in ('boolean',
                         'dimension',
                         'external_function',
@@ -771,9 +779,9 @@ def print_statement(statement):
     elif statement[0] in ('end_program', 'end_function', 'end_conditional'):
         return "}"
     elif statement[0] == 'entry':
-        func = statement[1]
-        types = typedict[func]
-        rep = "\n" + returntypes.get(func, normalmode) + " " + func[:-1] + "("
+        currentfunc = statement[1]
+        types = typedict[currentfunc]
+        rep = "\n" + returntypes.get(currentfunc, normalmode) + " " + currentfunc[:-1] + "("
         defaulted = []
         if statement[2]:
             for (dummy, var) in statement[2]: