From a458b3932d42d9438b628c45ea66f11ab6f643fd Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 10 Feb 2004 04:00:38 +0000 Subject: [PATCH] Before generating dummy variables. --- mad | 102 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 40 deletions(-) diff --git a/mad b/mad index 4f49544..ac44b35 100755 --- a/mad +++ b/mad @@ -11,7 +11,7 @@ reserved = ('BOOLEAN', 'CONDITIONAL', 'CONTINUE', 'DIMENSION', 'END', tokens = reserved + ( 'SEMI', 'COMMA', - 'NAME','INTNUM', 'FLOATNUM', 'BOOLNUM', 'STRING', 'FUNCALL', + 'NAME','INTNUM', 'DOUBLENUM', 'BOOLNUM', 'STRING', 'FUNCALL', 'LPAREN','RPAREN', 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', 'NOT', 'OR', 'AND', 'THEN', 'EQV', @@ -60,7 +60,7 @@ def t_NAME(t): t.value = t.value.lower() return t -def t_FLOATNUM(t): +def t_DOUBLENUM(t): r'\d+\.\d*' if t.value[-1] == '.': t.value += "0" @@ -290,11 +290,9 @@ def p_varlist_continue(t): def p_through_for(t): 'statement : THROUGH NAME COMMA FOR NAME EQUALS expression COMMA expression COMMA expression' t[0] = ('for', t[2], t[5], t[7], t[9], t[11]) - scopes.append(t[2]) def p_through_map(t): 'statement : THROUGH NAME COMMA FOR VALUES OF NAME EQUALS value_list' t[0] = ('map', t[2], t[7], t[9]) - scopes.append(t[2]) def p_map(t): 'value_list : expression' t[0] = [t[1]] @@ -387,8 +385,8 @@ def p_expression_integer(t): t[0] = ('intnum', t[1]) def p_expression_float(t): - 'expression : FLOATNUM' - t[0] = ('floatnum', t[1]) + 'expression : DOUBLENUM' + t[0] = ('doublenum', t[1]) def p_expression_subscript(t): 'expression : NAME application' @@ -484,7 +482,7 @@ def analyze(): static[var] = statement[2] untyped.remove(var) else: - format[var] = statement[2] + format[var] = statement[2][1:-1] # Reorder code tuples so internal functions are just after entry points for i in range(len(deck)): (file, line, label, statement) = deck[i] @@ -561,7 +559,7 @@ def mode(t): elif t[0] == 'intnum': #print "<-mode of integer constant", t[1] return 'int' - elif t[0] == 'floatnum': + elif t[0] == 'doublenum': #print "<-mode of float constant", t[1] return 'double' elif t[0] == 'boolnum': @@ -599,50 +597,52 @@ def prin1(t): return res elif t[0] == 'apply': madfunc = t[1][:-1] - return madfunc_map.get(madfunc, madfunc) + '(' + ', '.join(map(print_expr, t[2])) + ')' + return madfunc_map.get(madfunc, madfunc) + '(' + ', '.join(map(prin1, t[2])) + ')' elif t[0] == '+': if len(t) == 2: - return '%s' % print_expr(t[1]) + return '%s' % prin1(t[1]) else: - return '(%s + %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s + %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == '-': if len(t) == 2: - return '-%s' % print_expr(t[1]) + return '-%s' % prin1(t[1]) else: - return '(%s - %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s - %s)' % (prin1(t[1]), prin1(t[2])) + elif t[0] == 'not': + return "!%s" % prin1(t[1]) elif t[0] == '*': - return '(%s * %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s * %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == '/': - return '(%s / %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s / %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'l': - return '(%s < %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s < %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'g': - return '(%s > %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s > %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'le': - return '(%s <= %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s <= %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'ge': - return '(%s >= %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s >= %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'e': - return '(%s == %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s == %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'ne': - return '(%s != %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s != %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'p': - return 'pow(%s, %s)' % (print_expr(t[1]), print_expr(t[2])) + return 'pow(%s, %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'and': - return '(%s && %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s && %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'or': - return '(%s || %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s || %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'then': - return '!(%s && !(%s))' % (print_expr(t[1]), print_expr(t[2])) + return '!(%s && !(%s))' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'eqv': - return '(%s == %s)' % (print_expr(t[1]), print_expr(t[2])) + return '(%s == %s)' % (prin1(t[1]), prin1(t[2])) elif t[0] == 'abs': argmode = mode(t[1]) if argmode == 'double': - return 'fabs(%s)' % print_expr(t[1]) + return 'fabs(%s)' % prin1(t[1]) else: - return 'abs(%s)' % print_expr(t[1]) # int or bool - elif t[0] in ('intnum', 'floatnum'): + return 'abs(%s)' % prin1(t[1]) # int or bool + elif t[0] in ('intnum', 'doublenum'): return t[1] else: return '***'+`t` @@ -654,15 +654,15 @@ def print_expr(t): res = res[1:-1] return res -def fmt_convert(fmt, write=True): +def fmt_convert(str, write=True): "Convert MAD format string to C printf/scanf" + #print "->fmt_convert(%s)" % str res = '' types = [] - str = fmt[1:-1] while True: if str[0] == '*': break - if str[0] == '/': + elif str[0] == '/': res += '\\n' break elif str[0] in (' ', '\n', ','): @@ -676,8 +676,7 @@ def fmt_convert(fmt, write=True): sys.stderr.write('"%s", line %d: invalid spacer in %s\n' % (sourcefile, sourceline, str)) sys.exit(1) count = int(str[1:i]) - if write: - res += ' ' * count + res += ' ' * count str = str[i:] continue # All other format codes may take a prefix. @@ -688,7 +687,15 @@ def fmt_convert(fmt, write=True): if i > 0: count = int(str[:i]) str = str[i:] - if str[0] == 'F': + # Now process the actual format item + if str[0] == '(': + i = str.find(')') + (innerfmt, innertypes) = fmt_convert(str[1:i]+"*", write=False) + res += innerfmt * count + str = str[i+1:] + for i in range(count): + types += innertypes * count + elif str[0] == 'F': i = 1 while str[i] in '0123456789.': i += 1 @@ -704,7 +711,10 @@ def fmt_convert(fmt, write=True): i = 1 while str[i] in '0123456789': i += 1 - res += ('%' + str[1:i] + 'd') * count + lenprefix = str[1:i] + if lenprefix == '1': + lenprefix = '' + res += ('%' + lenprefix + 'd') * count str = str[i:] types += ['int'] * count else: @@ -714,6 +724,7 @@ def fmt_convert(fmt, write=True): if write: res = res[1:] res = res + '\\n' + #print "<-fmt_convert() = %s" % res return (res, types) def print_statement(statement): @@ -765,10 +776,17 @@ def print_statement(statement): elif statement[0] == 'goto': return 'goto ' + statement[1] + ';' elif statement[0] == 'if': + scopes.append(t[1]) return 'if (' + print_expr(statement[1]) + ') ' + print_statement(statement[2]) elif statement[0] == 'internal': - return ' %s %s {return %s;}' % \ + return '%s %s {return %s;}' % \ (returntypes.get(statement[1], normalmode), print_expr(('apply', statement[1], statement[2])), print_expr(statement[3])) + elif statement[0] == 'map': + scopes.append(statement[1]) + count = len(statement[3]) + rep='for (i = 0; i < %d; i++) { %s = '%(count ,statement[2]) + rep += "((%s [%d]){%s})[i];" % (statement[3][0][0][:-3], count, ", ".join(map(lambda x: `x[1]`, statement[3]))) + return rep elif statement[0] == 'otherwise': return 'else {' elif statement[0] == 'pause': @@ -822,12 +840,16 @@ def generate(out): out.write(" " + label+':\n') rep = print_statement(statement) if rep: - indent -= rep.count('}') + indentchange = rep.count('{') - rep.count('}') + if indentchange < 0: + indent += indentchange out.write(' '*indent + rep + '\n') - indent += rep.count('{') - if label in scopes: + if indentchange > 0: + indent += indentchange + while scopes and label == scopes[-1]: indent -= 1 out.write((' '*indent) + '}\n') + scopes.pop() if __name__ == '__main__': import os, getopt -- 2.43.0