From cb60955e4d2ffb713570061326c036ae11a6f10b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 20 Jan 2004 11:20:59 +0000 Subject: [PATCH] First version of working format converter. --- mad | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/mad b/mad index 805448c..d5614de 100755 --- a/mad +++ b/mad @@ -166,7 +166,6 @@ def p_map_continue(t): def p_transfer(t): "statement : TRANSFER TO NAME" t[0] = ('goto', t[3]) - print "Foo!", t[3] targets.append(t[3]) ## WHENEVER @@ -263,7 +262,10 @@ def p_expression_tail_nonempty(t): def p_expression_name(t): 'expression : NAME' - t[0] = ('variable', t[1]) + var = t[1] + t[0] = ('variable', var) + if var not in integers + bools + floats + untyped: + untyped.append(var) # Error handling @@ -279,6 +281,7 @@ integers = [] floats = [] bools = [] dimensions = {} +static = {} # Map MAD intrinsics to C library functions madfunc_map = {'elog':'log'} @@ -291,6 +294,7 @@ def declare(var, lst): def analyze(deck): "Gather variable types." global integers, floats, bools + # Mine the code for compile-time directives for (label, statement) in deck: if statement[0] == 'integer': print "Bar!", statement @@ -303,6 +307,8 @@ def analyze(deck): var = statement[1] if var not in integers + bools + floats + untyped: untyped.append(var) + if statement[0] == 'values': + static[statement[1]] = statement[2] def print_expr(t): if t[0] == 'variable': @@ -358,7 +364,7 @@ def print_expr(t): return "***"+`t` def print_statement(statement): - if statement[0] in ('dimension', 'end_program', 'integer'): + if statement[0] in ('dimension', 'end_program', 'integer', 'values'): pass elif statement[0] == 'for': (keyword, label, dummy, start, increment, predicate) = statement @@ -374,7 +380,48 @@ def print_statement(statement): elif statement[0] == 'substitution': return statement[1] + " = " + print_expr(statement[2]) + ";" else: - return(`statement`) + return("// " + `statement`) + +def fmt_convert(str): + "Convert MAD format string to C printf/scanf" + res = "" + str = str[1:-1] + while True: + if str[0] == "*": + break + elif str[0] == 'S': + i = 0 + while str[i].isdigit(): + i += 1 + if i <= 0: + sys.stderr.write("invalid spacer in %s\n" % str) + sys.exit(1) + count = int(str[:i]) + res += " " * count + str = str[i:] + break + # All other format codes require a prefix. + i = 0 + while str[i].isdigit(): + i += 1 + if i <= 0: + sys.stderr.write("invalid format string %s\n" % str) + sys.exit(1) + count = int(str[:i]) + str = str[i:] + if str[0] == 'F': + i = 1 + while str[i] in "0123456789.": + i += 1 + res += ("%" + str[1:i] + "f") * count + str = str[i:] + elif str[0] == 'H': + res += str[1:count+1] + str = str[count+1:] + else: + sys.stderr.write("invalid field code in format string!") + sys.exit(1) + return res if __name__ == '__main__': source = sys.stdin.read() @@ -392,9 +439,11 @@ if __name__ == '__main__': if bools: print "\tint " + ", ".join(bools) + ";\t/* boolean */" if untyped: - print "\tint " + ", ".join(untyped) + ";\t/* untyped */" + print "\tfloat " + ", ".join(untyped) + ";\t/* untyped */" if floats: print "\tfloat " + ", ".join(floats) + ";" + for (id, value) in static.items(): + print '\tstatic const char *%s\t= "%s";' % (id, fmt_convert(value)) indent = 0 for (label, statement) in deck: if label in targets: -- 2.43.0