Skip to content

Commit

Permalink
Improve enter macro
Browse files Browse the repository at this point in the history
Check whether it's a simple function call before performing lowering (fixes #14),
and give a better error message when you try to enter something that's not a
function call (fixes #11).
  • Loading branch information
Keno committed Nov 29, 2017
1 parent cc05800 commit 9481073
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 13 deletions.
57 changes: 45 additions & 12 deletions src/ASTInterpreter2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -437,19 +437,52 @@ end

lower(mod, arg) = VERSION < v"0.7-" ? expand(arg) : Meta.lower(mod, arg)

# This is a version of gen_call_with_extracted_types, except that is passes back the call expression
# for further processing.
function extract_args(__module__, ex0)
if isa(ex0, Expr)
kws = collect(filter(x->isexpr(x,:kw),ex0.args))
if !isempty(kws)
return Expr(:tuple,:(Core.kwfunc($(ex0.args[1]))),
Expr(:call,Base.vector_any,mapreduce(
x->[QuoteNode(x.args[1]),x.args[2]],vcat,kws)...),
map(x->isexpr(x, :parameters) ? QuoteNode(x) : x,
filter(x->!isexpr(x, :kw),ex0.args))...)
else
return Expr(:tuple,
map(x->isexpr(x,:parameters) ? QuoteNode(x) : x, ex0.args)...)
end
end
if isa(ex0, Expr) && ex0.head == :macrocall # Make @edit @time 1+2 edit the macro by using the types of the *expressions*
return error("Macros are not supported in @enter")
end
ex = lower(__module__, ex0)
exret = Expr(:none)
if !isa(ex, Expr)
return error("expression is not a function call or symbol")
elseif ex.head == :call
return Expr(:tuple,
map(x->isexpr(x,:parameters) ? QuoteNode(x) : x, ex.args)...)
elseif ex.head == :body
a1 = ex.args[1]
if isa(a1, Expr) && a1.head == :call
a11 = a1.args[1]
if a11 == :setindex!
return Expr(:tuple,
map(x->isexpr(x,:parameters) ? QuoteNode(x) : x, arg.args)...)
end
end
end
return error("expression is not a function call, "
* "or is too complex for @enter to analyze; "
* "break it down to simpler parts if possible")
end

function _make_stack(mod, arg)
arg = lower(mod, arg)
@assert isa(arg, Expr) && arg.head == :call
kws = collect(filter(x->isexpr(x,:kw),arg.args))
if !isempty(kws)
args = Expr(:tuple,:(Core.kwfunc($(args[1]))),
Expr(:call,Base.vector_any,mapreduce(
x->[QuoteNode(x.args[1]),x.args[2]],vcat,kws)...),
map(x->isexpr(x, :parameters) ? QuoteNode(x) : x,
filter(x->!isexpr(x, :kw),arg.args))...)
else
args = Expr(:tuple,
map(x->isexpr(x,:parameters) ? QuoteNode(x) : x, arg.args)...)
args = try
extract_args(mod, arg)
catch e
return :(throw($e))
end
quote
theargs = $(esc(args))
Expand Down
6 changes: 6 additions & 0 deletions test/misc.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Issue #14
stack = @make_stack map(x->2x, 1:10)
state = dummy_state(stack)
execute_command(state, state.stack[1], Val{:finish}(), "finish")
@test isempty(state.stack)
@test state.overall_result == 2 .* [1:10...]
3 changes: 2 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ using Base.Test
include("evaling.jl")
include("stepping.jl")
include("interpret.jl")
include("ui.jl")
include("ui.jl")
include("misc.jl")

0 comments on commit 9481073

Please sign in to comment.