]> thyrsus.com Git - mad.git/commitdiff
Halfway to MAD indexing.
authorEric S. Raymond <esr@thyrsus,com>
Thu, 19 Feb 2004 20:56:42 +0000 (20:56 +0000)
committerEric S. Raymond <esr@thyrsus,com>
Thu, 19 Feb 2004 20:56:42 +0000 (20:56 +0000)
mad

diff --git a/mad b/mad
index 549c8f42a57aea0cb7343ebf8077a497aa39e350..0a6d7f45808ba7d5fb6354cb6936bd64a8a97674 100755 (executable)
--- a/mad
+++ b/mad
@@ -173,14 +173,26 @@ def p_statement_dimension(t):
     'statement : DIMENSION dimension_list'
     t[0] = ('dimension', t[2])
 def p_dimension_list(t):
-    'dimension_list : arrayref'
-    t[0] = t[1]
+    'dimension_list : dimspec'
+    t[0] = [t[1]]
 def p_dimension_list_continue(t):
-    'dimension_list : dimension_list COMMA arrayref'
-    t[0] = t[1] + t[3]
-def p_arrayref(t):
-    'arrayref : NAME application'
-    t[0] = [[t[1], tuple(t[2])]]
+    'dimension_list : dimension_list COMMA dimspec'
+    t[0] = t[1] + [t[3]]
+# Screwy MAD semantics, all dimensions are bumped up 1.
+# Probably designed as a cheap way to prevent fencepost errors.
+def p_dimspec_0(t):
+    'dimspec : NAME LPAREN INTNUM RPAREN'
+    t[0] = (t[1], `int(t[3])+1`)
+def p_dimspec_1(t):
+    'dimspec : NAME LPAREN INTNUM COMMA NAME RPAREN'
+    t[0] = (t[1], `int(t[3])+1`, t[5])
+    refcount[t[5]] = refcount.get(t[3], 0) + 1
+    typedict[t[5]] = 'int'
+def p_dimspec_2(t):
+    'dimspec : NAME LPAREN INTNUM COMMA NAME LPAREN INTNUM RPAREN RPAREN'
+    t[0] = (t[1], `int(t[3])+1`, t[5], t[7])
+    refcount[t[5]] = refcount.get(t[3], 0) + 1
+    typedict[t[5]] = 'int'
 
 ## END
 def p_end_of_program(t):
@@ -387,6 +399,9 @@ def p_statement_substitution1(t):
 def p_statement_substitution2(t):
     'statement : arrayref EQUALS expression'
     t[0] = ('substitution', tuple(['variable'] + t[1][0]), t[3])
+def p_arrayref(t):
+    'arrayref : NAME application'
+    t[0] = [[t[1], tuple(t[2])]]
 
 # Expression parsing
 
@@ -555,8 +570,8 @@ def analyze():
                 for var in statement[1:]:
                     typedict[var] = 'bool'
             elif statement[0] == 'dimension':
-                for (var, dimlist) in statement[1]:
-                    dimensions[var] = dimlist
+                for metadata in statement[1]:
+                    dimensions[metadata[0]] = metadata[1:]
             elif statement[0] == 'integer':
                 for var in statement[1:]:
                     typedict[var] = 'int'
@@ -721,7 +736,7 @@ def prinC1(t):
             else:
                 # More than one subscript; this is where we implement MAD's
                 # weird reliance on dope vectors.
-                raise IndexError
+                subscript = 'MAD' + `len(t[2])` + '(' + dimensions[t[1]][1] + "," + ','.join(map(print_C_expr, t[2])) + ')'
             res += '[' + subscript + ']'
         return res
     elif t[0] == 'funptr':
@@ -1006,7 +1021,7 @@ def print_C_statement(statement):
         var = statement[1]
         dim = dimensions[var]
         del dimensions[var]
-        return normalmode + " " + prinC1(('variable', var, dim)) + ", *recursor = " + var + ";"
+        return "%s %s[%s], *recursor = %s;" % (normalmode, var, dim[0], var)
     elif statement[0] == 'substitution':
         return print_C_expr(statement[1])+' = '+print_C_expr(statement[2])+';'
     elif statement[0] == 'whenever':
@@ -1041,11 +1056,7 @@ def generate_C_code(out):
             for var in vars:
                 declarations += " " + var
                 if var in dimensions:
-                    # Screwy MAD semantics, all dimensions are bumped up 1.
-                    # Probably designed as a cheap way to prevent fencepost
-                    # errors.
-                    size_expr = ('+', dimensions[var][0], ('intnum', '1'))
-                    declarations += "[" + print_C_expr(size_expr) + "]"
+                    declarations += "[" + dimensions[var][0] + "]"
                 declarations += ","
             declarations = declarations[:-1] + "; "
     if declarations: