targets = {}
headers = []
funcnames = []
+arraydepths = {}
+returntypes = {}
currentfunc = 'main.'
typedict = {'main.':{}}
currentfunc = t[3]
t[0] = ('entry', currentfunc)
typedict[currentfunc] = {}
+ arraydepths[currentfunc] = {}
funcnames.append(currentfunc)
## EXECUTE
t[0] = ('variable', t[1], tuple(t[2]))
var = t[1]
refcount[var] = refcount.get(var, 0) + 1
+ arraydepths[currentfunc][var] = len(t[2])
def p_function_application(t):
'expression : FUNCALL application'
for (file, line, label, statement) in deck:
if statement[0] == 'dimension':
for (var, dimlist) in statement[1]:
- dimensions[var] = dimlist
+ dimensions[currentfunc][var] = dimlist
elif statement == 'entry':
currentfunc = statement[1]
+ dimensions[currentfunc] = {}
funcline = line
elif statement[0] == 'integer':
for var in statement[1:]:
typedict[currentfunc][var] = 'int'
+ elif statement[0] == 'return':
+ # Crude type inference -- give the function the type of the
+ # last return.
+ returntypes[currentfunc] = mode(statement[1])
elif statement[0] == 'substitution':
typedict[currentfunc][statement[1]] = 'double'
elif statement[0] == 'values':
elif statement[0] == 'entry':
func = statement[1]
types = typedict[func]
- rep = "\n" + func[:-1] + "("
+ depths = arraydepths[currentfunc]
+ rep = "\n" + returntypes.get(func, "double") + " " + func[:-1] + "("
+ defaulted = []
if statement[2]:
for (dummy, var) in statement[2]:
+ declarator = ("*" * depths.get(var, 0)) + var
if var in types:
- rep += types[var] + " " + var + ", "
+ rep += types[var] + " " + declarator + ", "
del types[var]
else:
- rep += "UNTYPED " + var + ", "
+ rep += "double " + declarator + ", "
+ defaulted.append(var)
rep = rep[:-2]
- rep = rep + ") {"
+ rep = rep + ") {\n"
+ if defaulted:
+ sys.stderr.write("warning: defaulted base type for %s\n" % ", ".join(defaulted))
declarations = ""
for type in ('double', 'int', 'bool'):
vars = filter(lambda x: types[x] == type, types.keys())
if vars:
declarations += type + " " + ", ".join(vars) + "; "
if declarations:
- rep += "\n " + declarations[:-1] + "\n"
+ rep += " " + declarations[:-1] + "\n"
return rep
elif statement[0] == 'execute':
return print_expr(statement[1]) + ";"
if len(statement) == 1:
return "return;"
else:
- return "return %s" % print_expr(statement[1])
+ return "return %s;" % print_expr(statement[1])
elif statement[0] == 'or':
return 'else if (' + print_expr(statement[2]) + ') {'
elif statement[0] == 'otherwise':
# by whitespace and a continuation digit
source = source.replace("\n", " ;\n")
source = re.sub(';\n(\s*)[0-9]+', '\n\\1', source)
- sys.stdout.write(source)
- sys.exit(1)
# Parse
yacc.parse(source, debug=mad_debug)