Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions asteroid/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def initialize(self,module="<input>"):
# stack of 3-tuples for stack trace of function
# calls: (module,lineno,function name)
self.trace_stack = [(module,1,"<toplevel>")]
# if an exception occurs then error_trace will point to
# it. an exception handler is responsible for clearing
# this.
self.error_trace = None

state = State()

Expand All @@ -31,10 +35,15 @@ def warning(str):
print("Warning: {}: {}: {}".format(module, lineno, str))

def dump_trace():
if len(state.trace_stack) == 1:
return
if state.error_trace:
_dump_trace(state.error_trace)
return
else:
print("traceback (most recent call last):")
for i in range(0,len(state.trace_stack)):
(module,lineno,fname) = state.trace_stack[i]
print("{}: {}: calling {}".format(module,lineno,fname))
_dump_trace(state.trace_stack)
return

def _dump_trace(trace):
print("traceback (most recent call last):")
for i in range(0,len(trace)):
(module,lineno,fname) = trace[i]
print("{}: {}: calling {}".format(module,lineno,fname))
18 changes: 18 additions & 0 deletions asteroid/test-suites/regression-tests/test138.ast
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- test case for issue #209
load system io.

function goo with none do
throw Error("exception").
end

function foo with none do
let a = 1.
try
goo().
catch _ do
io @println "exception caught".
end
assert(a==1). -- make that a is still in scope
end

foo ().
2 changes: 1 addition & 1 deletion asteroid/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
# (c) University of Rhode Island
##########################################################################################

VERSION = "1.1.3"
VERSION = "1.1.4"
46 changes: 26 additions & 20 deletions asteroid/walk.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# (c) University of Rhode Island
#########################################################################

from copy import deepcopy
from copy import deepcopy,copy
from re import match as re_match

from asteroid.globals import *
Expand Down Expand Up @@ -941,6 +941,15 @@ def handle_builtins(node):
else:
raise ValueError("unknown builtin unary operation '{}'".format(opname))

#########################################################################
def pop_stackframe(error_trace=False):
# pop frame off the stack
state.symbol_table.pop_scope()
state.symbol_table.set_config(state.symbol_table.saved_configs.pop())
if error_trace:
state.error_trace = copy(state.trace_stack)
state.trace_stack.pop()

#########################################################################
def handle_call(obj_ref, fval, actual_val_args, fname):
# Needed for later
Expand Down Expand Up @@ -1050,19 +1059,11 @@ def handle_call(obj_ref, fval, actual_val_args, fname):
# Reset settings
except RedundantPatternFound as r:
debugging = old_debugging

# coming back from a function call - restore caller's env
# restore caller's env
state.lineinfo = old_lineinfo

# Keep debugger up to date
if debugging:
debugger.set_lineinfo(state.lineinfo)

state.symbol_table.pop_scope()
state.symbol_table.set_config(state.symbol_table.saved_configs.pop())

state.trace_stack.pop()

if debugging: debugger.set_lineinfo(state.lineinfo)
pop_stackframe()
raise r

# execute the function
Expand All @@ -1089,17 +1090,20 @@ def handle_call(obj_ref, fval, actual_val_args, fname):
function_return_value.pop()
return_value = val.value

# coming back from a function call - restore caller's env
except Exception as e:
# we got some other kind of exception within the function call
# clean up our runtime stack and rethrow
# Note: do not reset lineinfo, this way the state points at the source
# of the exception
pop_stackframe(error_trace=True)
raise e

# all done with function call -- clean up and exit
# restore caller's env
state.lineinfo = old_lineinfo

# Keep debugger up to date
if debugging: debugger.set_lineinfo(state.lineinfo)

state.symbol_table.pop_scope()
state.symbol_table.set_config(state.symbol_table.saved_configs.pop())

state.trace_stack.pop()

pop_stackframe()
message_explicit("Return: {} from {}",
[("None" if (not return_value[1]) else gen_t2s(return_value)),
fname],
Expand Down Expand Up @@ -1331,6 +1335,8 @@ def try_stmt(node):
except PatternMatchFailed:
pass
else:
# handler found - null out error_trace
state.error_trace = None
declare_unifiers(unifiers)
walk_stmt_list(catch_stmts, step_state=stepping)
return
Expand Down