]> thyrsus.com Git - mad.git/commitdiff
We deduce function return types.
authorEric S. Raymond <esr@thyrsus,com>
Sun, 1 Feb 2004 08:10:12 +0000 (08:10 +0000)
committerEric S. Raymond <esr@thyrsus,com>
Sun, 1 Feb 2004 08:10:12 +0000 (08:10 +0000)
mad

diff --git a/mad b/mad
index 8a48df955d4a276594aa44b13128524289e646a0..ed6cd8cda1b13e6cf2ba0a6904d850871fd70618 100755 (executable)
--- a/mad
+++ b/mad
@@ -10,7 +10,7 @@ reserved = ('BOOLEAN', 'CONDITIONAL', 'CONTINUE', 'DIMENSION', 'END',
 
 tokens = reserved + (
     'SEMI', 'COMMA',
-    'NAME','INTNUM', 'FLOATNUM', 'STRING', 'FUNCALL',
+    'NAME','INTNUM', 'FLOATNUM', 'BOOLNUM', 'STRING', 'FUNCALL',
     'LPAREN','RPAREN',
     'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
     'NOT', 'OR', 'AND', 'THEN', 'EQV',
@@ -46,6 +46,7 @@ t_EQUALS  = r'='
 t_LPAREN  = r'\('
 t_RPAREN  = r'\)'
 t_STRING  = r'\$[^$]*\$'
+t_BOOLNUM = r'[01]B'
 
 reserved_map = { }
 for r in reserved:
@@ -66,13 +67,10 @@ def t_FLOATNUM(t):
     return t
 
 def t_INTNUM(t):
-    r'\d+B?'
-    # Leading zeros flip us into ocal in C, therefore strip them.
+    r'\d+'
+    # Leading zeros flip us into octal in C, therefore strip them.
     while len(t.value) > 1 and t.value[0] == '0':
         t.value = t.value[1:]
-    # Handle binary constants here
-    if t.value[-1] == "B":
-        t.value = t.value[:-1]
     return t
 
 t_ignore = ' \n\t'
@@ -363,6 +361,10 @@ def p_expression_float(t):
     'expression : FLOATNUM'
     t[0] = ('floatnum', t[1])
 
+def p_expression_bool(t):
+    'expression : BOOLNUM'
+    t[0] = ('boolnum', t[1])
+
 def p_expression_subscript(t):
     'expression : NAME application'
     t[0] = ('variable', t[1], tuple(t[2]))
@@ -476,12 +478,42 @@ def analyze():
 
 def mode(t):
     "Compute the return type of an expression"
+    #print "->mode", t
     if t[0] == 'variable':
+        #print "<-mode of ", t[1]
         return typedict[currentfunc].get(t[1], 'double')
+    elif t[0] in ('UMINUS', 'UPLUS', 'POW', 'ABS'):
+        #print "<-mode of ", t[1]
+        return mode(t[1])
+    elif t[0] == 'intnum':
+        #print "<-mode of integer constant", t[1]
+        return 'int'
+    elif t[0] == 'floatnum':
+        #print "<-mode of float constant", t[1]
+        return 'double'
+    elif t[0] == 'boolnum':
+        #print "<-mode of boolean constant", t[1]
+        return 'bool'
+    elif t[0] == 'string':
+        # Yes, MAD considers strings to have int type, see section
+        # 2.10.  In the original 709 implementation they were 6-byte
+        # constants that fit in a 36-bit machine word.
+        #print "<-mode of string ", t[1]
+        return 'int'
     elif t[0] in logops:
+        #print "<-bool (logical operator)", t[1]
         return 'bool'
     else:
-        return 'double'
+        left = mode(t[1])
+        right = mode(t[2])
+        if left == 'double' or right == 'double':
+            #print "<-mode of binary operand"
+            return 'double'
+        if left == 'int' or right == 'int':
+            #print "<-mode of binary operand"
+            return 'int'
+        sys.write.stderr("mad: internal error while computing mode of %s\n"%t)
+        sys.exit(1)
 
 def prin1(t):
     if t[0] == 'variable':
@@ -653,8 +685,8 @@ def print_statement(statement):
     elif statement[0] == 'if':
         return 'if (' + print_expr(statement[1]) + ') ' + print_statement(statement[2])
     elif statement[0] == 'internal':
-        return '    double %s {return %s;}\n' % \
-                      (print_expr(('apply', statement[1], statement[2])), print_expr(statement[3]))
+        return '    %s %s {return %s;}\n' % \
+                      (mode(statement[3]), print_expr(('apply', statement[1], statement[2])), print_expr(statement[3]))
     elif statement[0] == 'pause':
         return('printf("%o", ' + print_expr(statement[1]) + '); getchar();')
     elif statement[0] == 'read':