deck = []
scopes = []
targets = {}
-untyped = []
headers = []
+currentfunc = 'main.'
+typedict = {'main.':{}}
+
# Program level
def p_program(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):
## 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
'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'
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
import sys, re
-integers = []
-doubles = []
-bools = []
dimensions = {}
static = {}
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]
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':
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':
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:
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')