]> thyrsus.com Git - mad.git/commitdiff
INTEGER FUNCTION parsing.
authorEric S. Raymond <esr@thyrsus,com>
Tue, 20 Jan 2004 18:04:26 +0000 (18:04 +0000)
committerEric S. Raymond <esr@thyrsus,com>
Tue, 20 Jan 2004 18:04:26 +0000 (18:04 +0000)
mad

diff --git a/mad b/mad
index fe0669aebb12b98d74a9a9bb3c79b1612739f5e9..05e66626ececafcf47f4730e1cbf493d16f3b297 100755 (executable)
--- a/mad
+++ b/mad
@@ -1,8 +1,9 @@
 #!/usr/bin/env python
 
 reserved = ('CONDITIONAL', 'DIMENSION', 'END', 'FOR', 'FORMAT',
-            'FUNCTION', 'INTEGER', 'OF', 'PRINT', 'PROGRAM', 'READ',
-            'THROUGH', 'TO', 'TRANSFER', 'VALUES', 'VECTOR', 'WHENEVER')
+            'FUNCTION', 'INTEGER', 'INTERNAL', 'OF', 'PRINT', 'PROGRAM',
+            'READ', 'THROUGH', 'TO', 'TRANSFER', 'VALUES', 'VECTOR',
+            'WHENEVER')
 
 tokens = reserved + (
     'TAB', 'SEMI',
@@ -60,7 +61,7 @@ def t_NAME(t):
 t_ignore = ' \n'
 
 def t_error(t):
-    print 'Illegal character %s' % `t.value[0]`
+    sys.stderr.write('Line %d: illegal character %s\n' % (t.lineno, `t.value[0]`))
     t.skip(1)
     
 # Build the lexer
@@ -137,6 +138,11 @@ def p_varlist_continue(t):
     'varlist : varlist COMMA NAME'
     t[0] = t[1] + [t[3]]
 
+## INTERNAL FUNCTION
+def p_internal(t):
+    "statement : INTERNAL FUNCTION FUNCALL application EQUALS expression"
+    t[0] = ('function', t[3], tuple(t[4]), t[6])
+
 ## READ FORMAT
 def p_read_format(t):
     'statement : READ FORMAT varlist'
@@ -244,6 +250,7 @@ def p_expression_float(t):
 def p_expression_subscript(t):
     'expression : NAME application'
     t[0] = ('variable', t[1], tuple(t[2]))
+    var = t[1]
     refcount[var] = refcount.get(var, 0) + 1 
 
 def p_function_application(t):
@@ -273,7 +280,7 @@ def p_expression_name(t):
 # Error handling
 
 def p_error(t):
-    print 'Syntax error at "%s"' % t.value
+    sys.stderr.write('Line %d: syntax error at "%s"\n' % (t.lineno, t.value))
 
 import yacc
 yacc.yacc()
@@ -379,6 +386,9 @@ def fmt_convert(str, write=True):
     while True:
         if str[0] == '*':
             break
+        elif str[0] in (' ', '\n', ','):
+            str = str[1:]
+            continue
         elif str[0] == 'S':
             i = 1
             while str[i] != ',':
@@ -389,16 +399,16 @@ def fmt_convert(str, write=True):
             count = int(str[1:i])
             if write:
                 res += ' ' * count
-            str = str[i+1:]
-        # All other format codes require a prefix.
+            str = str[i:]
+            continue
+        # All other format codes may take a prefix.
+        count = 1
         i = 0
         while str[i].isdigit():
             i += 1
-        if i <= 0:
-            sys.stderr.write('invalid format string %s\n' % str)
-            sys.exit(1)
-        count = int(str[:i])
-        str = str[i:]
+        if i > 0:
+            count = int(str[:i])
+            str = str[i:]
         if str[0] == 'F':
             i = 1
             while str[i] in '0123456789.':
@@ -409,8 +419,14 @@ def fmt_convert(str, write=True):
             if write:
                 res += str[1:count+1]
             str = str[count+1:]
+        elif str[0] == 'I':
+            i = 1
+            while str[i] in '0123456789':
+                i += 1
+            res += ('%' + str[1:i] + 'd') * count
+            str = str[i:]
         else:
-            sys.stderr.write('invalid field code in format string!')
+            sys.stderr.write('invalid field code in format string %s!\n' % str)
             sys.exit(1)
     # Clip off format character
     if write: