deck.insert(i, (file, line, None, ('entry', 'main.', ())))
# Mine the code for compile-time directives
for (file, line, label, statement) in deck:
- if statement[0] == 'dimension':
+ if statement[0] == 'boolean':
+ for var in statement[1:]:
+ typedict[currentfunc][var] = 'bool'
+ elif statement[0] == 'dimension':
for (var, dimlist) in statement[1]:
dimensions[currentfunc][var] = dimlist
elif statement == 'entry':
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':
var = statement[1]
if var in refcount:
(fmt, types) = fmt_convert(format[statement[1]])
for (type, var) in zip(types, statement[2:]):
typedict[currentfunc][var] = type
+ # Type inference loop. We initialized for this by deducing types
+ # from READ FORMAT statements. INTEGER, and BOOLEAN declarations
+ # above. Now propagate int and bool type markers through
+ # expression evaluation until we can't deduce any more int or bool
+ # type bindings for variables. Everything else just defaults to
+ # double.
+ while True:
+ deductions = 0
+ for card in deck:
+ (file, line, label, statement) = card
+ if statement == 'entry':
+ # Bookkeeping, so we know what function we're in
+ currentfunc = statement[1]
+ funcline = line
+ elif statement[0] == 'return':
+ # Give the function the type of the last return statement.
+ # We're screwed if two different returns in a function have
+ # different modes.
+ m = mode(statement[1])
+ returntypes[currentfunc] = m
+ if m in ('int','bool') and returntypes[currentfunc] != m:
+ deductions += 1
+ elif statement[0] == 'substitution':
+ # Propagate type markers through assignment
+ m = mode(statement[2])
+ typedict[currentfunc][statement[1]] = m
+ if m in ('int','bool') and typedict[currentfunc][statement[1]]!=m:
+ deductions += 1
+ if deductions == 0:
+ break
# Now associate entry point names with function definitions:
for i in range(len(deck)):
(file, line, label, statement) = deck[i]
# constants that fit in a 36-bit machine word.
#print "<-mode of string ", t[1]
return 'int'
+ elif t[0] == 'apply':
+ return returntypes.get(t[1], "double")
elif t[0] in logops:
#print "<-bool (logical operator)", t[1]
return 'bool'
return 'if (' + print_expr(statement[1]) + ') ' + print_statement(statement[2])
elif statement[0] == 'internal':
return ' %s %s {return %s;}' % \
- (mode(statement[3]), print_expr(('apply', statement[1], statement[2])), print_expr(statement[3]))
+ (returntypes.get(statement[1], "double"), print_expr(('apply', statement[1], statement[2])), print_expr(statement[3]))
elif statement[0] == 'pause':
return('printf("%o", ' + print_expr(statement[1]) + '); getchar();')
elif statement[0] == 'read':