Skip to content

Commit c5cc728

Browse files
authored
Implement include() with Base.IncludeInto and similarly for eval (#68)
Adopt the changes from JuliaLang/julia#55949 to define module-local include / eval in terms of `Base.IncludeInto` and `Core.EvalInto`. It previously made sense to define `include()` and `eval()` as part of desugaring. But now that `include` is just an instance of `IncludeInto` the runtime can define these without calling into flisp so I've reverted to letting `jl_eval_module_expr()` do that from the C code.
1 parent 092e716 commit c5cc728

File tree

4 files changed

+33
-60
lines changed

4 files changed

+33
-60
lines changed

src/desugaring.jl

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4248,56 +4248,7 @@ function expand_module(ctx, ex::SyntaxTree)
42484248
@chk kind(modname_ex) == K"Identifier"
42494249
modname = modname_ex.name_val
42504250

4251-
std_defs = if !has_flags(ex, JuliaSyntax.BARE_MODULE_FLAG)
4252-
@ast ctx (@HERE) [
4253-
K"block"
4254-
[K"using"(@HERE)
4255-
[K"importpath"
4256-
"Base" ::K"Identifier"
4257-
]
4258-
]
4259-
[K"function"(@HERE)
4260-
[K"call"
4261-
"eval" ::K"Identifier"
4262-
"x" ::K"Identifier"
4263-
]
4264-
[K"call"
4265-
"eval" ::K"core"
4266-
modname ::K"Identifier"
4267-
"x" ::K"Identifier"
4268-
]
4269-
]
4270-
[K"function"(@HERE)
4271-
[K"call"
4272-
"include" ::K"Identifier"
4273-
"x" ::K"Identifier"
4274-
]
4275-
[K"call"
4276-
"_call_latest" ::K"core"
4277-
"include" ::K"top"
4278-
modname ::K"Identifier"
4279-
"x" ::K"Identifier"
4280-
]
4281-
]
4282-
[K"function"(@HERE)
4283-
[K"call"
4284-
"include" ::K"Identifier"
4285-
[K"::"
4286-
"mapexpr" ::K"Identifier"
4287-
"Function" ::K"top"
4288-
]
4289-
"x" ::K"Identifier"
4290-
]
4291-
[K"call"
4292-
"_call_latest" ::K"core"
4293-
"include" ::K"top"
4294-
"mapexpr" ::K"Identifier"
4295-
modname ::K"Identifier"
4296-
"x" ::K"Identifier"
4297-
]
4298-
]
4299-
]
4300-
end
4251+
std_defs = !has_flags(ex, JuliaSyntax.BARE_MODULE_FLAG)
43014252

43024253
body = ex[2]
43034254
@chk kind(body) == K"block"
@@ -4311,10 +4262,10 @@ function expand_module(ctx, ex::SyntaxTree)
43114262
eval_module ::K"Value"
43124263
ctx.mod ::K"Value"
43134264
modname ::K"String"
4265+
std_defs ::K"Bool"
43144266
ctx.expr_compat_mode ::K"Bool"
43154267
[K"inert"(body)
43164268
[K"toplevel"
4317-
std_defs
43184269
children(body)...
43194270
]
43204271
]

src/runtime.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ end
214214
# public modname
215215
#
216216
# And run statments in the toplevel expression `body`
217-
function eval_module(parentmod, modname, expr_compat_mode, body)
217+
function eval_module(parentmod::Module, modname::AbstractString, std_defs::Bool,
218+
expr_compat_mode::Bool, body::SyntaxTree)
218219
# Here we just use `eval()` with an Expr.
219220
# If we wanted to avoid this we'd need to reproduce a lot of machinery from
220221
# jl_eval_module_expr()
@@ -229,11 +230,10 @@ function eval_module(parentmod, modname, expr_compat_mode, body)
229230
# mod = @ccall jl_new_module(Symbol(modname)::Symbol, parentmod::Module)::Any
230231
# ...
231232
name = Symbol(modname)
232-
Core.eval(parentmod, :(
233-
baremodule $name
234-
$eval($name, $body; expr_compat_mode=$expr_compat_mode)
235-
end
236-
))
233+
eval_module_body(mod) = eval(mod, body; expr_compat_mode=expr_compat_mode)
234+
Core.eval(parentmod,
235+
Expr(:module, std_defs, name,
236+
Expr(:block, Expr(:call, eval_module_body, name))))
237237
end
238238

239239
const _Base_has_eval_import = isdefined(Base, :_eval_import)

test/misc_ir.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,26 @@ LoweringError:
182182
(; a=1, f())
183183
# └─┘ ── Invalid named tuple element
184184

185+
########################################
186+
# Module lowering
187+
module Mod
188+
body
189+
stmts
190+
end
191+
#---------------------
192+
1 (call JuliaLowering.eval_module TestMod "Mod" true false (inert (toplevel body stmts)))
193+
2 (return %₁)
194+
195+
########################################
196+
# Bare module lowering
197+
baremodule BareMod
198+
body
199+
stmts
200+
end
201+
#---------------------
202+
1 (call JuliaLowering.eval_module TestMod "BareMod" false false (inert (toplevel body stmts)))
203+
2 (return %₁)
204+
185205
########################################
186206
# Error: Modules not allowed in local scope
187207
let

test/modules.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,19 @@ end
1111
""", "module_test")
1212
@test A isa Module
1313
@test A.g() == "hi"
14-
@test A.include isa Function
14+
@test A.include isa Base.IncludeInto
15+
@test A.eval isa Core.EvalInto
1516
@test A.Base === Base
16-
@test A.eval(:(x = -1)) == -1
17-
@test A.x == -1
17+
@test A.eval(:(x = -2)) == -2
18+
@test A.x == -2
1819

1920
B = JuliaLowering.include_string(test_mod, """
2021
baremodule B
2122
end
2223
""", "baremodule_test")
2324
@test B.Core === Core
2425
@test !isdefined(B, :include)
26+
@test !isdefined(B, :eval)
2527
@test !isdefined(B, :Base)
2628

2729
# modules allowed in nested code in global scope

0 commit comments

Comments
 (0)