def analyze():
"Gather variable types and determine function boundaries."
global deck, currentfunc, hasmain
+ global sourcefile, sourceline
# We may need to generate a pseudo-function call
for i in range(len(deck)):
if deck[i][3][0] != 'remark':
hasmain = True
else:
for i in range(len(deck)):
- (file, line, label, statement) = deck[i]
+ (sourcefile, sourceline, label, statement) = deck[i]
if statement[0] == 'end_function' and i < len(deck)-1 and deck[i+1][3][0] != 'extern':
- deck.insert(i+1, (file, line, None, ('entry', 'main.', ())))
+ deck.insert(i+1, (sourcefile, sourceline, None, ('entry', 'main.', ())))
hasmain = True
# Sanity check -- all labels in through statements must hit targwts
labels = filter(lambda x: x, map(lambda x: x[2], deck))
- for (file, line, label, statement) in deck:
+ for (sourcefile, sourceline, label, statement) in deck:
if statement[0] == 'for':
target = statement[1]
if not target in labels:
- croak((file,line,label,statement),"no such label as "+`target`)
+ croak((sourcefile,sourceline,label,statement),"no such label as "+`target`)
sys.exit(1)
# On to actual analysis
try:
# Mine the code for compile-time directives
- for (file, line, label, statement) in deck:
+ for (sourcefile, sourceline, label, statement) in deck:
if statement[0] == 'boolean':
for var in statement[1:]:
typedict[var] = 'bool'
dimensions[var] = dimlist
elif statement[0] == 'entry':
currentfunc = statement[1]
- funcline = line
+ funcline = sourceline
elif statement[0] == 'integer':
for var in statement[1:]:
typedict[var] = 'int'
savelist = []
internalcount = 0
for i in range(len(deck)):
- (file, line, label, statement) = deck[i]
+ (sourcefile, sourceline, label, statement) = deck[i]
if statement[0] == 'entry':
lastentry = i
internalcount = 1
# Reorder code tuples so SET LIST arrays are global.
firstentry = -1
for i in range(len(deck)):
- (file, line, label, statement) = deck[i]
+ (sourcefile, sourceline, label, statement) = deck[i]
if statement[0] == 'entry' and firstentry == -1:
firstentry = i
elif statement[0] == 'set_list_to':
deck.insert(firstentry, deck.pop(i))
# Do type deductions from format fields
for card in deck:
- (file, line, label, statement) = card
+ (sourcefile, sourceline, label, statement) = card
if statement[0] == 'entry':
currentfunc = statement[1]
- funcline = line
+ funcline = sourceline
elif statement[0] == 'read':
if statement[1] not in format:
croak(card, "uninitialized format string" +`statement[1]`)
while True:
deductions = 0
for card in deck:
- (file, line, label, statement) = card
+ (sourcefile, sourceline, label, statement) = card
if statement[0] == 'entry':
# Bookkeeping, so we know what function we're in
currentfunc = statement[1]
- funcline = line
+ funcline = sourceline
elif statement[0] == 'return' and len(statement) > 1:
# Give the function the type of the last return statement.
# We're screwed if two different returns in a function have
break
# Now associate entry point names with function definitions:
for i in range(len(deck)):
- (file, line, label, statement) = deck[i]
+ (sourcefile, sourceline, label, statement) = deck[i]
if statement[0] == 'entry' and len(statement) == 2:
name = statement[1]
for j in range(i):
prev = deck[i-j-1][3]
if prev[0] == 'external_function':
- deck[i] = (file, line, label, ('entry', name, prev[1]))
+ deck[i] = (sourcefile, sourceline, label, ('entry', name, prev[1]))
break
elif prev[0] == 'entry':
croak(deck[i-j-1],"multiple ENTRY points are not supported")