From: Eric S. Raymond Date: Tue, 10 Feb 2004 18:13:37 +0000 (+0000) Subject: Generated code for tscheb looks right. X-Git-Tag: 1.0~129 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=1e54cac06379822cc180e25a6c79ee666a200e51;p=mad.git Generated code for tscheb looks right. --- diff --git a/mad b/mad index a006761..689377a 100755 --- a/mad +++ b/mad @@ -105,27 +105,25 @@ precedence = ( ) refcount = {} -sourcefile = "" -sourceline = 0 -deck = [] -scopes = [] -targets = {} -headers = [] -funcnames = [] -typedict = {} -arraydepths = {} -returntypes = {} -normalmode = 'double' -dummycount = 0 -dimensions = {} -static = {} -format = {} -hasmain = False +sourcefile = "" # Current source file for error messages +sourceline = 0 # Current source line for error messages +deck = [] # List of tuples generated by parsing +scopes = [] # THROUGH scopes that are pending +targets = {} # Dictionary of targets of TRANSFERs +headers = [] # Required .h file basenames +funcnames = [] # List of function names +dimensions = {} # Dictionary of array depths +arraydepths = {} # Dictionary of array dimensions +returntypes = {} # Dictionary of function returntypes +normalmode = 'double' # Default type as set by NORMAL statement +dummycount = 0 # Count of FOR VALUES statements +static = {} # Dictionary of static char variables +format = {} # Dictionary of format strings +hasmain = False # Does this program have a main line? def initfunc(f): global currentfunc currentfunc = f - typedict[currentfunc] = {} funcnames.append(currentfunc) initfunc("main.") @@ -154,11 +152,9 @@ def p_boolean(t): def p_boollist(t): 'boollist : NAME' t[0] = [t[1]] - typedict[currentfunc][t[1]] = 'bool' def p_boollist_continue(t): 'boollist : boollist COMMA NAME' t[0] = t[1] + [t[3]] - typedict[currentfunc][t[3]] = 'bool' ## CONTINUE def p_statement_continue(t): @@ -190,9 +186,8 @@ def p_end_of_functions(t): ## ENTRY def p_entry(t): "statement : ENTRY TO FUNCALL" - global currentfunc initfunc(t[3]) - t[0] = ('entry', currentfunc) + t[0] = ('entry', t[3]) ## EXECUTE def p_execute(t): @@ -227,11 +222,9 @@ def p_integer(t): def p_intlist(t): 'intlist : NAME' t[0] = [t[1]] - typedict[currentfunc][t[1]] = 'int' def p_intlist_continue(t): 'intlist : intlist COMMA NAME' t[0] = t[1] + [t[3]] - typedict[currentfunc][t[3]] = 'int' ## INTERNAL FUNCTION def p_internal(t): @@ -461,6 +454,15 @@ def croak(t, msg): (file, line, label, statement) = t sys.stderr.write('"%s", line %d: %s\n' % (file, line, msg)) +# All MAD variables are global, you have to simulate locals using SAVE DATA and +# RETURN DATA. Thus most of the variable lookup tables about are straight +# dictionaries not qualified by current function name. typedict is an +# exception; we use this to generate per-function variables as C auto +# variables and get nicer C code. This would break if two MAD external +# functions deliberately shared a global, but this doesn't happen in +# any of the examples. +typedict = {} # Dictionary of per-function dictionaries of locals + def analyze(): "Gather variable types and determine function boundaries." global deck, currentfunc, hasmain @@ -485,9 +487,10 @@ def analyze(): elif statement[0] == 'dimension': for (var, dimlist) in statement[1]: dimensions[var] = dimlist - elif statement == 'entry': + elif statement[0] == 'entry': currentfunc = statement[1] funcline = line + typedict[currentfunc] = {} elif statement[0] == 'integer': for var in statement[1:]: typedict[currentfunc][var] = 'int' @@ -524,7 +527,10 @@ def analyze(): # Do type deductions from format fields for card in deck: (file, line, label, statement) = card - if statement[0] == 'read': + if statement[0] == 'entry': + currentfunc = statement[1] + funcline = line + elif statement[0] == 'read': if statement[1] not in format: croak(card, "uninitialized format string" +`statement[1]`) else: @@ -541,7 +547,7 @@ def analyze(): deductions = 0 for card in deck: (file, line, label, statement) = card - if statement == 'entry': + if statement[0] == 'entry': # Bookkeeping, so we know what function we're in currentfunc = statement[1] funcline = line @@ -555,8 +561,9 @@ def analyze(): deductions += 1 elif statement[0] == 'substitution': # Propagate type markers through assignment + var = statement[1] m = mode(statement[2]) - typedict[currentfunc][statement[1]] = m + typedict[currentfunc][var] = m if m != normalmode and typedict[currentfunc][statement[1]]!=m: deductions += 1 if deductions == 0: @@ -757,6 +764,7 @@ def fmt_convert(str, write=True): return (res, types) def print_statement(statement): + global currentfunc if statement[0] in ('boolean', 'dimension', 'external_function', @@ -771,9 +779,9 @@ def print_statement(statement): elif statement[0] in ('end_program', 'end_function', 'end_conditional'): return "}" elif statement[0] == 'entry': - func = statement[1] - types = typedict[func] - rep = "\n" + returntypes.get(func, normalmode) + " " + func[:-1] + "(" + currentfunc = statement[1] + types = typedict[currentfunc] + rep = "\n" + returntypes.get(currentfunc, normalmode) + " " + currentfunc[:-1] + "(" defaulted = [] if statement[2]: for (dummy, var) in statement[2]: