@@ -20,19 +20,32 @@ any generated functions will use your registered method. See
20
20
macro register (sig)
21
21
splitsig = splitdef (:($ sig = nothing ))
22
22
name = splitsig[:name ]
23
+
24
+ # Extract the module and function name from the signature
25
+ if name isa Symbol
26
+ mod = __module__ # Calling module
27
+ funcname = name
28
+ else
29
+ mod = name. args[1 ]
30
+ funcname = name. args[2 ]. value
31
+ end
32
+
23
33
args = splitsig[:args ]
24
34
typargs = typed_args (args)
25
35
defs = :()
26
36
for typarg in typargs
27
37
splitsig[:args ] = typarg
28
- splitsig[:body ] = :(Operation ($ name, Expression[$ (args... )]))
38
+ if mod == (@__MODULE__ ) # If the calling module is ModelingToolkit itself...
39
+ splitsig[:body ] = :(Operation ($ name, Expression[$ (args... )]))
40
+ else
41
+ # Register the function's associated model so we can inject it in later.
42
+ splitsig[:body ] = quote
43
+ get! (ModelingToolkit. registered_external_functions, Symbol ($ (" $funcname " )), $ mod)
44
+ Operation ($ name, Expression[$ (args... )])
45
+ end
46
+ end
29
47
defs = :($ defs; $ (combinedef (splitsig)))
30
48
end
31
- if (@__MODULE__ ) != ModelingToolkit
32
- # Register external module registrations so we can rewrite any generated
33
- # functions through JuliaVariables.solve().
34
- get! (ModelingToolkit. registered_external_functions, name, @__MODULE__ )
35
- end
36
49
esc (defs)
37
50
end
38
51
# Create all valid combinations of Expression,Number for function signature
@@ -95,28 +108,10 @@ function inject_registered_module_functions(expr)
95
108
MacroTools. @capture (x, f_ (xs__)) # We need to find all function calls in the expression.
96
109
# If the function call has been converted to a JuliaVariables.Var and matches
97
110
# one of the functions we've registered...
98
- if ! isnothing (f) && x . args[ 1 ] isa JuliaVariables . Var && x . args[1 ] . name in keys (registered_external_functions)
99
- # Rewrite it from a Var to a regular function call.
100
- x . args[1 ] = getproperty (registered_external_functions[x . args[ 1 ] . name], x . args[1 ]. name )
111
+ if ! isnothing (f) && f isa Expr && f . head == :. && f . args[2 ] isa QuoteNode
112
+ f_name = f . args[ 2 ] . value
113
+ f . args[1 ] = get (registered_external_functions, f_name, f . args[1 ])
101
114
end
102
115
return x # Make sure we rebuild the expression as is.
103
116
end
104
- end
105
-
106
- # TODO : Overwriting this function works, but is quite ugly. Is there a nicer way to inject the module names?
107
- function GeneralizedGenerated. mk_function (mod:: Module , ex)
108
- ex = macroexpand (mod, ex)
109
- ex = GeneralizedGenerated. simplify_ex (ex)
110
- ex = GeneralizedGenerated. solve (ex)
111
-
112
- # We need to modify the expression built by the JuliaVariables.solve(ex)
113
- # method, before GeneralizedGenerated.closure_conv(mod, ex) converts it to a
114
- # RuntimeFn (as done in GeneralizedGenerated.mk_function(mod, ex)).
115
- ex = inject_registered_module_functions (ex)
116
-
117
- fn = GeneralizedGenerated. closure_conv (mod, ex)
118
- if ! (fn isa GeneralizedGenerated. RuntimeFn)
119
- error (" Expect an unnamed function expression. " )
120
- end
121
- fn
122
117
end
0 commit comments