1
|
|
function _parse_julia_file(filename::String)
|
2
|
0
|
return Base.parse_input_line(read(filename, String); filename = filename)
|
3
|
0
|
end
|
4
|
|
|
5
|
0
|
function lowercase_drive(a)
|
6
|
|
if length(a) >= 2 && a[2] == ':'
|
7
|
|
return lowercase(a[1]) * a[2:end]
|
8
|
|
else
|
9
|
|
return a
|
10
|
|
end
|
11
|
0
|
end
|
12
|
|
|
13
|
0
|
const SRC_DIR = joinpath(Sys.BINDIR, "..", "..", "base")
|
14
|
|
const RELEASE_DIR = joinpath(Sys.BINDIR, "..", "share", "julia", "base")
|
15
|
|
basepath(file) = normpath(joinpath((@static isdir(SRC_DIR) ? SRC_DIR : RELEASE_DIR), file))
|
16
|
0
|
|
17
|
0
|
maybe_quote(x) = (isa(x, Expr) || isa(x, Symbol)) ? QuoteNode(x) : x
|
18
|
|
|
19
|
0
|
# all calls in the current frame and the same "line"
|
20
|
0
|
calls_on_line(state, args...) = calls_on_line(state.frame, args...)
|
21
|
0
|
calls_on_line(::Nothing, args...) = []
|
22
|
0
|
function calls_on_line(frame::JuliaInterpreter.Frame, line = nothing)
|
23
|
|
if line === nothing
|
24
|
0
|
loc = JuliaInterpreter.whereis(frame)
|
25
|
|
if loc === nothing
|
26
|
|
return []
|
27
|
0
|
end
|
28
|
|
line = loc[2]
|
29
|
0
|
end
|
30
|
0
|
|
31
|
0
|
src = frame.framecode.src
|
32
|
|
|
33
|
0
|
exprs = []
|
34
|
0
|
for pc in frame.pc:length(src.codelocs)
|
35
|
|
loc = JuliaInterpreter.whereis(frame, pc)
|
36
|
|
|
37
|
0
|
if loc === nothing || loc[2] > line
|
38
|
0
|
return exprs
|
39
|
0
|
end
|
40
|
0
|
|
41
|
|
expr = JuliaInterpreter.pc_expr(src, pc)
|
42
|
0
|
if Meta.isexpr(expr, :call)
|
43
|
0
|
for i in 1:length(expr.args)
|
44
|
0
|
expr.args[i] = maybe_quote(expr.args[i])
|
45
|
0
|
end
|
46
|
|
push!(exprs, (pc = pc, expr = prettyprint_expr(expr, src)))
|
47
|
|
elseif Meta.isexpr(expr, :(=))
|
48
|
0
|
expr = expr.args[2]
|
49
|
|
push!(exprs, (pc = pc, expr = prettyprint_expr(expr, src)))
|
50
|
|
end
|
51
|
|
end
|
52
|
0
|
exprs
|
53
|
0
|
end
|
54
|
0
|
|
55
|
|
function prettyprint_expr(expr, src)
|
56
|
|
io = IOBuffer()
|
57
|
|
prettyprint_expr(io, expr, src)
|
58
|
0
|
return String(take!(io))
|
59
|
0
|
end
|
60
|
0
|
|
61
|
0
|
function prettyprint_expr(io, expr, src)
|
62
|
0
|
if Meta.isexpr(expr, :call)
|
63
|
0
|
for (i, ex) in enumerate(expr.args)
|
64
|
0
|
if ex isa QuoteNode
|
65
|
0
|
print(io, ex.value)
|
66
|
|
elseif ex isa JuliaInterpreter.SlotNumber || ex isa Core.SlotNumber
|
67
|
0
|
print(io, src.slotnames[ex.id])
|
68
|
|
elseif ex isa JuliaInterpreter.SSAValue || ex isa Core.SSAValue
|
69
|
0
|
print(io, '%', ex.id)
|
70
|
0
|
else
|
71
|
0
|
prettyprint_expr(io, ex, src)
|
72
|
0
|
end
|
73
|
|
if i == 1
|
74
|
0
|
print(io, '(')
|
75
|
|
elseif i == length(expr.args)
|
76
|
|
print(io, ')')
|
77
|
|
else
|
78
|
0
|
print(io, ", ")
|
79
|
|
end
|
80
|
|
end
|
81
|
|
else
|
82
|
|
show(io, expr)
|
83
|
0
|
end
|
84
|
0
|
end
|
85
|
|
|
86
|
0
|
# all calls in the current frame after (and including) the current pc
|
87
|
0
|
calls_in_frame(state) = calls_in_frame(state.frame)
|
88
|
0
|
calls_in_frame(::Nothing) = []
|
89
|
0
|
function calls_in_frame(frame::JuliaInterpreter.Frame)
|
90
|
0
|
exprs = []
|
91
|
0
|
for pc in frame.pc:length(frame.framecode.src.codelocs)
|
92
|
0
|
expr = JuliaInterpreter.pc_expr(frame, pc)
|
93
|
0
|
if Meta.isexpr(expr, :call)
|
94
|
|
push!(exprs, (pc = pc, expr = expr))
|
95
|
|
elseif Meta.isexpr(expr, :(=))
|
96
|
0
|
expr = expr.args[2]
|
97
|
|
push!(exprs, (pc = pc, expr = expr))
|
98
|
|
end
|
99
|
|
end
|
100
|
|
exprs
|
101
|
|
end
|