]> thyrsus.com Git - mad.git/commitdiff
We compile invsf now.
authorEric S. Raymond <esr@thyrsus,com>
Fri, 13 Feb 2004 23:46:05 +0000 (23:46 +0000)
committerEric S. Raymond <esr@thyrsus,com>
Fri, 13 Feb 2004 23:46:05 +0000 (23:46 +0000)
mad

diff --git a/mad b/mad
index 06de6e2f83a1d9037a2fb0d3902a44bf2696dfb7..026710e572264715cef9faef341533bf5d9e43d1 100755 (executable)
--- a/mad
+++ b/mad
@@ -1,11 +1,12 @@
 #!/usr/bin/env python
 
 reserved = ('BOOLEAN', 'CONDITIONAL', 'CONTINUE', 'DATA', 'DIMENSION',
-            'END', 'ENTRY', 'EXECUTE', 'EXTERNAL', 'FOR', 'FUNCTION',
-            'INTEGER', 'INTERNAL', 'IS', 'MODE', 'NORMAL',
-            'OF', 'OR', 'PAUSE', 'PRINT_FORMAT', 'PROGRAM', 'READ_FORMAT',
-            'RESTORE', 'RETURN', 'SAVE', 'SET_LIST_TO', 'THROUGH',
-            'TO', 'TRANSFER', 'VALUES', 'VECTOR', 'WHENEVER',
+            'END', 'ENTRY', 'ERROR', 'EXECUTE', 'EXTERNAL', 'FOR',
+            'FUNCTION', 'INTEGER', 'INTERNAL', 'IS', 'MODE', 'NORMAL',
+            'OF', 'OR', 'OTHERWISE', 'PAUSE', 'PRINT_FORMAT',
+            'PROGRAM', 'READ_FORMAT', 'RESTORE', 'RETURN', 'SAVE',
+            'SET_LIST_TO', 'THROUGH', 'TO', 'TRANSFER', 'VALUES',
+            'VECTOR', 'WHENEVER',
             # COMMENT is a pseudo-keyword generated early in compilation.
             'COMMENT', 'DOTRANGE')
 
@@ -57,11 +58,15 @@ def t_STRING(t):
     t.value = t.value[1:-1]
     return t
 
+def t_FUNCALL(t):
+    r'[A-Z][A-Z0-9]*\.(?=\s*(\(|eos))'
+    t.type = reserved_map.get(t.value, 'FUNCALL')
+    t.value = t.value.lower()
+    return t
+
 def t_NAME(t):
-    r'[A-Z][A-Z0-9_]*(\.(?!P))?'
+    r'[A-Z][A-Z0-9_]*'
     t.type = reserved_map.get(t.value, 'NAME')
-    if t.value[-1] == '.':
-        t.type = 'FUNCALL'
     t.value = t.value.lower()
     return t
 
@@ -145,6 +150,10 @@ def p_labeled_card(t):
     'card : NAME statement EOS'
     deck.append((sourcefile, t.lineno(1), t[1], t[2]))
 
+def p_empty_card(t):
+    'card : EOS'
+    pass
+
 # Statement level
 
 ## BOOLEAN
@@ -191,6 +200,11 @@ def p_entry(t):
     initfunc(t[3])
     t[0] = ('entry', t[3])
 
+## ERROR RETURN
+def p_error_return(t):
+    "statement : ERROR RETURN"
+    t[0] = ('error_return',)
+
 ## EXECUTE
 def p_execute(t):
     'statement : EXECUTE FUNCALL application'
@@ -248,6 +262,11 @@ def p_typeval_bool(t):
     "typeval : BOOLEAN"
     t[0] = 'bool'
 
+## OTHERWISE
+def p_otherwise(t):
+    "statement : OTHERWISE"
+    t[0] = ('else',)
+
 ## PAUSE
 def p_pause(t):
     "statement : PAUSE expression"
@@ -432,25 +451,25 @@ def p_expression_subscript(t):
     refcount[var] = refcount.get(var, 0) + 1
     arraydepths[var] = len(t[2])
 
-def p_function_application(t):
-    'expression : FUNCALL application'
-    t[0] = ('apply', t[1], tuple(t[2]))
-    global headers
-    if t[1] in ('elog.', 'sqrt.') and "math" not in headers:
-        headers.append("math")
-
-def p_expression_application(t):
+def p_application(t):
     'application : LPAREN arglist RPAREN'
     t[0] = t[2]
 
-def p_expression_tail_empty(t):
+def p_application_tail_empty(t):
     'arglist : expression'
     t[0] = [t[1]]
 
-def p_expression_tail_nonempty(t):
+def p_application_tail_nonempty(t):
     'arglist : arglist COMMA expression'
     t[0] = t[1] + [t[3]]
 
+def p_function_application(t):
+    'expression : FUNCALL application'
+    t[0] = ('apply', t[1], tuple(t[2]))
+    global headers
+    if t[1] in ('elog.', 'sqrt.') and "math" not in headers:
+        headers.append("math")
+
 def p_expression_name(t):
     'expression : NAME'
     var = t[1]
@@ -831,6 +850,8 @@ def print_C_statement(statement):
         if mad_debug:
             rep += " /* %s */" % statement[0]
         return rep
+    elif statement[0] == 'else':
+        return "} else {"
     elif statement[0] == 'entry':
         currentfunc = statement[1]
         types = typedict[currentfunc]
@@ -864,6 +885,8 @@ def print_C_statement(statement):
         if declarations:
             rep += "    " + declarations[:-1] + "\n"
         return rep
+    elif statement[0] == 'error_return':
+        return 'puts("ERROR RETURN"); exit(1);'
     elif statement[0] == 'execute':
         return print_C_expr(statement[1]) + ";"
     elif statement[0] == 'external_call':