Skip to content

Commit dbcd6f3

Browse files
committed
update README
1 parent 57c8934 commit dbcd6f3

File tree

2 files changed

+121
-68
lines changed

2 files changed

+121
-68
lines changed

README.md

Lines changed: 120 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -9,91 +9,144 @@
99
About
1010
=============
1111

12-
The `solve` function will solve the scopes of a given AST,
13-
and then replace
14-
15-
- all variable symbols with `ScopedVar(::Scope, ::Symbol)`,
16-
- all function definitions with `ScopedFunc(::Scope, ::Expr)`,
17-
- all generators with `ScopedGenerator(::Scope, ::Expr)`
18-
19-
For more details, check the implementation of [NameResolution.jl](https://github.com/thautwarm/NameResolution.jl).
20-
21-
22-
**ATTENTION!!!** :
12+
The `solve` function will solve the scopes of a **simplified** Julia expression.
13+
14+
- The variables(`Symbol`) are transformed to `Var`:
15+
```julia
16+
struct Var
17+
name :: Symbol
18+
is_mutable :: Bool
19+
is_shared :: Bool
20+
is_global :: Bool
21+
end
22+
```
23+
- Some expressions will be wrapped within `Expr(:scoped, (bounds=..., freevars=..., bound_inits=...), inner_expression)`.
2324

24-
`solve` will give up analysing when meeting `macrocall` expressions. You can expand them before using
25-
`solve`.
25+
Example
26+
==============
2627

27-
Usage
28-
==========
28+
`solve` & `solve_from_local`
29+
-----------------------------
2930

3031
```julia
31-
using JuliaVariables
32-
rmlines = JuliaVariables.rmlines
33-
func = solve(:(function f(x)
34-
let y = x + 1
35-
y
32+
julia> using MLStyle
33+
34+
julia> unwrap_scoped(ex) =
35+
@match ex begin
36+
Expr(:scoped, _, a) => unwrap_scoped(a)
37+
Expr(head, args...) => Expr(head, map(unwrap_scoped, args)...)
38+
a => a
39+
end
40+
unwrap_scoped (generic function with 1 method)
41+
42+
julia> quote
43+
x = 1
44+
function (a)
45+
x = 1
46+
end
47+
end |> solve_from_local |> rmlines |> unwrap_scoped
48+
quote
49+
mut @shared x = 1
50+
function (a,)
51+
mut @shared x = 1
3652
end
37-
end))
38-
println(func |> rmlines)
39-
40-
func = solve(:(function f(x)
41-
y = x + 1
42-
z -> z + y
43-
end))
53+
end
4454
45-
println(func |> rmlines)
4655
47-
func = solve(:(function f(x)
48-
y = x + 1
49-
let y = y + 1
50-
(x + y + z for z in 1:10)
56+
julia> quote
57+
x = 1
58+
function ()
59+
x = 1
60+
end
61+
end |> solve |> rmlines
62+
:($(Expr(:scoped, (bounds = Var[], freevars = Var[], bound_inits = Symbol[]), quote
63+
@global x = 1
64+
function ()
65+
$(Expr(:scoped, (bounds = Var[@local x], freevars = Var[], bound_inits = Symbol[]), quote
66+
@local x = 1
67+
end))
5168
end
69+
end)))
70+
71+
72+
julia> quote
73+
x = 1
74+
function ()
75+
x = 1
76+
end
77+
end |> solve_from_local |> rmlines
78+
:($(Expr(:scoped, (bounds = Var[mut @shared x], freevars = Var[], bound_inits = Symbol[]), quote
79+
mut @shared x = 1
80+
function ()
81+
$(Expr(:scoped, (bounds = Var[], freevars = Var[mut @shared x], bound_inits = Symbol[]), quote
82+
mut @shared x = 1
5283
end))
53-
println(func |> rmlines)
84+
end
85+
end)))
86+
```
87+
88+
`simplify_ex`
89+
-------------------
5490

91+
Not all expressions can be accepted as the input of `solve` or `solve_from_local`, thus we provide such a
92+
handy API to apply conversions from almost arbitrary
93+
expressions to the *simplified* expressions.
5594

56-
func = solve(
57-
macroexpand(@__MODULE__,:(
58-
@inline function f(x)
59-
y = x + 1
60-
let y = y + 1
61-
(x + y + z for z in 1:10)
95+
```julia
96+
julia> quote
97+
function f(x)
98+
for i in I, j in J
99+
let x = 1, y
100+
() -> 2
101+
end
102+
end
103+
f(x) = 2
104+
end
105+
end |> rmlines |> simplify_ex
106+
quote
107+
function f(x)
108+
for i = I
109+
for j = J
110+
let x = 1
111+
let y
112+
function ()
113+
2
114+
end
115+
end
116+
end
117+
end
118+
end
119+
function f(x)
120+
2
62121
end
63122
end
64-
)))
65-
println(func |> rmlines)
123+
end
66124
```
67125

68-
=>
126+
The reason why we don't couple this API with `solve` is, we need to let user aware that there exists destructive operations for expressing the scope information, for instance, it's impossible to inject
127+
scope information to `for i in I, j in J; body end`, because
128+
the AST shape of it is
69129

70130
```julia
71-
[]function (f)(@x)
72-
let @y = (@global +)(@x, 1)
73-
@y
74-
end
75-
end
131+
Expr(:for,
132+
Expr(:block,
133+
:(i = I),
134+
:(j = J),
135+
),
136+
Expr(:block, body)
137+
)
138+
```
76139

77-
[]function (f)(@x)
78-
@cell y = (@global +)(@x, 1)
79-
[cell y]@z->begin
80-
(@global +)(@z, @cell y)
81-
end
82-
end
140+
`Expr(:block, body)` is actually in the sub-scope of
141+
that of `:(j = J)`, and `:(j=J)`'s scope in inherited from that of `:(i=I)`, which ruins the handy use(especially the top-down tree visiting) of scoped expressions.
83142
84-
[]function (f)(@cell x)
85-
@y = (@global +)(@cell x, 1)
86-
let @cell y = (@global +)(@cell y, 1)
87-
[cell y,cell x]((@global +)(@cell x, @cell y, @z) for @z = (@global :)(1, 10))
88-
end
89-
end
143+
Not only due to the uselessness of scoping the messy ASTs like `for i in I, j in J; body end`, the analyses for them are also much more ugly to implement than those of the *simplified* expressions. Finally, I give up doing this.
90144
91-
[]function (f)(@cell x)
92-
$(Expr(:meta, @global inline))
93-
@y = (@global +)(@cell x, 1)
94-
let @cell y = (@global +)(@cell y, 1)
95-
[cell y,cell x]((@global +)(@cell x, @cell y, @z) for @z = (@global :)(1, 10))
96-
end
97-
end
145+
If you have understand the above concerns and made
146+
sure it's safe to return a restructured expression after injecting scope information, you can compose
147+
`simplify_ex` and `solve` to gain a more handy API:
98148

99-
```
149+
```julia
150+
mysolve = solve ∘ simplify_ex
151+
mysolve_from_local = solve_from_local ∘ simplify_ex
152+
```

src/JuliaVariables.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module JuliaVariables
22

33
export Scope, Var
4-
export solve_from_local, solve, rmlines, simplify_ex
4+
export solve_from_local, solve, simplify_ex
55

66
using NameResolution
77
using Base.Enums

0 commit comments

Comments
 (0)