From fa30b264ba7e67779ab7a18f3005bae3218a14fa Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 1 Feb 2004 08:10:12 +0000 Subject: [PATCH] We deduce function return types. --- mad | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/mad b/mad index 8a48df9..ed6cd8c 100755 --- 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': -- 2.43.0