From 06435dd3c9656abc23bfa1132fc6ec249a3055ec Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 31 Jan 2004 00:11:06 +0000 Subject: [PATCH] Declarations are local now. Next, deduce and extract local variables. --- mad | 71 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/mad b/mad index 6b44f90..03e1f07 100755 --- a/mad +++ b/mad @@ -104,9 +104,11 @@ sourceline = 0 deck = [] scopes = [] targets = {} -untyped = [] headers = [] +currentfunc = 'main.' +typedict = {'main.':{}} + # Program level def p_program(t): @@ -153,7 +155,10 @@ def p_end_of_functions(t): ## ENTRY def p_entry(t): "statement : ENTRY TO FUNCALL" - t[0] = ('entry', t[3]) + global currentfunc + currentfunc = t[3] + t[0] = ('entry', currentfunc) + typedict[currentfunc] = {} ## EXECUTE def p_execute(t): @@ -271,9 +276,9 @@ def p_vector_values(t): ## Assignment def p_statement_substitution(t): 'statement : NAME EQUALS expression' - t[0] = ('substitution', t[1], t[3]) - if t[1] not in untyped: - untyped.append(t[1]) + newvar = t[1] + t[0] = ('substitution', newvar, t[3]) + typedict[currentfunc][newvar] = 'double' # Expression parsing @@ -335,7 +340,9 @@ 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 + refcount[var] = refcount.get(var, 0) + 1 + if not var in typedict[currentfunc]: + typedict[currentfunc][var] = 'double' def p_function_application(t): 'expression : FUNCALL application' @@ -361,8 +368,8 @@ def p_expression_name(t): var = t[1] t[0] = ('variable', var) refcount[var] = refcount.get(var, 0) + 1 - if var not in integers + bools + doubles + untyped: - untyped.append(var) + if not var in typedict[currentfunc]: + typedict[currentfunc][var] = 'double' # Error handling @@ -374,9 +381,6 @@ yacc.yacc() import sys, re -integers = [] -doubles = [] -bools = [] dimensions = {} static = {} format = {} @@ -384,21 +388,19 @@ format = {} # Map MAD intrinsics to C library functions madfunc_map = {'elog':'log'} -def declare(var, lst): - if var in untyped: - untyped.remove(var) - lst.append(var) - def croak(t, msg): (file, line, label, statement) = t sys.stderr.write('"%s", line %d: %s\n' % (file, line, msg)) def analyze(): "Gather variable types and determine function boundaries." - global integers, doubles, bools, deck + global deck, currentfunc # We may need to generate a pseudo-function call - if deck[0][3][0] != 'external_function': - deck = [(deck[0][0], 0, None, ('entry', ('apply', 'main.',())))] + deck + for i in range(len(deck)): + if deck[i][3][0] != 'remark': + break + if deck[i][3][0] != 'external_function': + deck.insert(i, (deck[i][0], i, None, ('entry', ('apply', 'main.',())))) else: for i in range(len(deck)): (file, line, label, statement) = deck[i] @@ -409,13 +411,13 @@ def analyze(): if statement[0] == 'dimension': for (var, dimlist) in statement[1]: dimensions[var] = dimlist + elif statement == 'entry': + currentfunc = statement[1][0] elif statement[0] == 'integer': for var in statement[1:]: - declare(var, integers) + typedict[currentfunc][var] = 'integer' elif statement[0] == 'substitution': - var = statement[1] - if var not in integers + bools + doubles + untyped: - untyped.append(var) + typedict[currentfunc][statement[1]] = 'double' elif statement[0] in ('read', 'print'): pass elif statement[0] == 'values': @@ -572,7 +574,14 @@ def print_statement(statement): elif statement[0] in ('end_program', 'end_function', 'end_conditional'): return "}" elif statement[0] == 'entry': - return "\n" + print_expr(statement[1]) + " {" + rep = "\n" + print_expr(statement[1]) + " {" + funcname = statement[1][1] + localvars = typedict[funcname].keys() + for type in ('double', 'integer'): + vars = filter(lambda x: typedict[funcname][x] == type, localvars) + if vars: + rep += "\n " + type + " " + ", ".join(vars) + ";" + return rep elif statement[0] == 'execute': return print_expr(statement[1]) + ";" elif statement[0] == 'external_call': @@ -620,14 +629,6 @@ def generate(out): for header in headers: out.write('#include <%s.h>\n\n' % header) - if integers: - out.write('int ' + ', '.join(integers) + ';\t/* INTEGER */\n') - if bools: - out.write('int ' + ', '.join(bools) + ';\t/* boolean */\n') - if untyped: - out.write('double ' + ', '.join(untyped) + ';\t/* untyped */\n') - if doubles: - out.write('double ' + ', '.join(doubles) + ';\n') for (id, value) in static.items(): out.write('static const char *%s\t= "%s";\n' % (id,fmt_convert(value))) for (file, line, label, statement) in deck: @@ -643,11 +644,9 @@ def generate(out): out.write(" " + label+':\n') rep = print_statement(statement) if rep: - if rep[-1] == '}': - indent -= 1 + indent -= rep.count('}') out.write(' '*indent + rep + '\n') - if rep[-1] == '{': - indent += 1 + indent += rep.count('{') if label in scopes: indent -= 1 out.write((' '*indent) + '}\n') -- 2.43.0