-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🚧 Start fixing tests, find how to inject _hook::System with @method.
- Loading branch information
Showing
8 changed files
with
203 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
# HERE: a working snippet to be integrated into @method. | ||
|
||
struct Value end | ||
struct System{V} | ||
_value::V | ||
end | ||
|
||
# Lib. | ||
f(a::Value, b, args...; c=5, kwargs...) = a + b - c | ||
g(a::Value, b, _s::System, args...; c=5, kwargs...) = a + b - c | ||
|
||
# Framework. | ||
# f(a::System, b, args...; c = 5, kwargs...) = f(a._value, b, args...; c = 5, kwargs...) | ||
# g(a::System, b, _s::System, args...; c = 5, kwargs...) = g(a._value, b, _s, args...; c = 5, kwargs...) | ||
|
||
ValueType = Value | ||
fn_xp = :f | ||
fn = eval(fn_xp) | ||
__module__ = Main | ||
efn = :($__module__.$fn_xp) | ||
xerr = (mess) -> throw(mess) | ||
|
||
to_override = [] | ||
for mth in methods(fn) | ||
|
||
# Retrieve fixed-parameters types for the method. | ||
parms = collect(mth.sig.parameters[2:end]) | ||
isempty(parms) && continue | ||
# Retrieve their names. | ||
# https://discourse.julialang.org/t/get-the-argument-names-of-an-function/32902/4?u=iago-lito | ||
pnames = ccall(:jl_uncompress_argnames, Vector{Symbol}, (Any,), mth.slot_syms)[2:end] | ||
|
||
# Among them, find which one to use as the system "receiver": | ||
# either the only one typed with 'ValueType', | ||
# or the first one if 'Any'. | ||
# Take this opportunity to also look for a single parameter | ||
# typed with `System` or `System{ValueType}`. | ||
# If present, the overriding method will pass | ||
# a reference to the global system through it. | ||
values = Set() | ||
system_values = Set() | ||
systems_only = Set() | ||
for (name, p) in zip(pnames, parms) | ||
p isa Core.TypeofVararg && continue | ||
p <: ValueType && push!(values, name) | ||
p <: System{ValueType} && push!(system_values, name) | ||
p === System && push!(systems_only, name) | ||
end | ||
length(values) > 1 && xerr("Receiving several (possibly different) system/values \ | ||
is not yet supported by the framework. \ | ||
Here both :$(pop!(values)) and :$(pop!(values)) \ | ||
are of type $ValueType.") | ||
receiver = if isempty(values) | ||
parms[1] === Any || continue | ||
pnames[1] | ||
else | ||
pop!(values) | ||
end | ||
sv = system_values | ||
length(sv) > 1 && xerr("Receiving several (possibly different) system hooks \ | ||
is not yet supported by the framework. \ | ||
Here both :$(pop!(sv)) and :$(pop!(sv)) \ | ||
are of type $(System{ValueType}).") | ||
hook = if isempty(system_values) | ||
so = systems_only | ||
length(so) > 1 && xerr("Receiving several (possibly different) system hooks \ | ||
is not yet supported by the framework. \ | ||
Here both :$(pop!(so)) and :$(pop!(so)) \ | ||
are of type $System.") | ||
isempty(so) ? nothing : pop!(so) | ||
else | ||
pop!(system_values) | ||
end | ||
|
||
# Record for overriding. | ||
push!(to_override, (mth, parms, pnames, receiver, hook)) | ||
end | ||
isempty(to_override) && xerr("No suitable method has been found to mark $fn as a system method. \ | ||
Valid methods must have at least one argument of type ::$ValueType \ | ||
or a first ::Any argument to be implicitly considered as such.") | ||
|
||
for (mth, parms, pnames, receiver, hook) in to_override | ||
xp = quote | ||
function $efn(; kwargs...) | ||
$efn(; kwargs...) | ||
end | ||
end | ||
xp_parms = xp.args[2].args[1].args | ||
xp_args = xp.args[2].args[2].args[3].args | ||
for (name, type) in zip(pnames, parms) | ||
parm, arg = if type isa Core.TypeofVararg | ||
(:($name::$(type.T)...), :($name...)) | ||
else | ||
if name == receiver | ||
# Dispatch on the system to transmit the inner value. | ||
(:($name::System{$type}), :($name._value)) | ||
elseif name == hook | ||
# Don't receive at all, but transmit from the receiver. | ||
(nothing, receiver) | ||
else | ||
# Other arguments are just forwarded. | ||
(:($name::$type), name) | ||
end | ||
end | ||
isnothing(parm) || push!(xp_parms, parm) | ||
push!(xp_args, arg) | ||
end | ||
print(xp) | ||
|
||
eval(xp) | ||
any = true | ||
|
||
end | ||
|
||
|
||
# User. | ||
s = System{Value}(Value()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters