@@ -24,14 +24,13 @@ function connector_macro(mod, name, body)
24
24
vs = Num[]
25
25
icon = Ref {Union{String, URI}} ()
26
26
dict = Dict {Symbol, Any} ()
27
- kwargs = []
28
27
for arg in body. args
29
28
arg isa LineNumberNode && continue
30
29
if arg. head == :macrocall && arg. args[1 ] == Symbol (" @icon" )
31
30
parse_icon! (icon, dict, dict, arg. args[end ])
32
31
continue
33
32
end
34
- push! (vs, Num (parse_variable_def! (dict, mod, arg, :variables , kwargs )))
33
+ push! (vs, Num (parse_variable_def! (dict, mod, arg, :variables )))
35
34
end
36
35
iv = get (dict, :independent_variable , nothing )
37
36
if iv === nothing
@@ -48,19 +47,25 @@ function connector_macro(mod, name, body)
48
47
end
49
48
end
50
49
51
- function parse_variable_def! (dict, mod, arg, varclass, kwargs )
50
+ function parse_variable_def! (dict, mod, arg, varclass)
52
51
MLStyle. @match arg begin
53
52
:: Symbol => generate_var! (dict, arg, varclass)
54
53
Expr (:call , a, b) => generate_var! (dict, a, b, varclass)
55
54
Expr (:(= ), a, b) => begin
56
- var = parse_variable_def! (dict, mod, a, varclass, kwargs )
57
- def = parse_default (mod, b, kwargs )
55
+ var = parse_variable_def! (dict, mod, a, varclass)
56
+ def, meta = parse_default (mod, b)
58
57
dict[varclass][getname (var)][:default ] = def
59
58
var = setdefault (var, def)
59
+ if ! isnothing (meta)
60
+ if (ct = get (meta, VariableConnectType, nothing )) != = nothing
61
+ dict[varclass][getname (var)][:connection_type ] = nameof (ct)
62
+ end
63
+ var = set_var_metadata (var, meta)
64
+ end
60
65
var
61
66
end
62
67
Expr (:tuple , a, b) => begin
63
- var = parse_variable_def! (dict, mod, a, varclass, kwargs )
68
+ var = parse_variable_def! (dict, mod, a, varclass)
64
69
meta = parse_metadata (mod, b)
65
70
if (ct = get (meta, VariableConnectType, nothing )) != = nothing
66
71
dict[varclass][getname (var)][:connection_type ] = nameof (ct)
@@ -75,25 +80,33 @@ function parse_variables_with_kw!(exprs, var, dict, mod, body, varexpr, varclass
75
80
for arg in body. args
76
81
arg isa LineNumberNode && continue
77
82
MLStyle. @match arg begin
78
- Expr (:(= ), a, b:: Number ) => parse_variables! (exprs, var, dict, mod, arg, varclass, kwargs)
83
+ :: Symbol || Expr (:tuple , a, b) || Expr (:call , a, b) || Expr (:(= ), a, b:: Number ) => begin
84
+ parse_variables! (exprs, var, dict, mod, arg, varclass)
85
+ end
79
86
Expr (:(= ), a, b:: Symbol ) => begin
80
87
isdefined (mod, b) ?
81
- parse_variables! (exprs, var, dict, mod, arg, varclass, kwargs ) :
82
- push! (varexpr. args[end ]. args[end ]. args, arg)
88
+ parse_variables! (exprs, var, dict, mod, arg, varclass) :
89
+ push! (varexpr. args[end ]. args[end ]. args, arg)
83
90
end
84
91
Expr (:(= ), a, b) => begin
85
92
def = Base. remove_linenums! (b)
86
93
MLStyle. @match def begin
87
- Expr (:tuple , x:: Symbol , y) || x:: Symbol => begin
88
- push! (varexpr. args[end ]. args[end ]. args, :($ a = $ (def. args[end ])))
94
+ Expr (:tuple , x:: Symbol , y) => begin
95
+ isdefined (mod, x) ?
96
+ parse_variables! (exprs, var, dict, mod, arg, varclass) :
97
+ push! (varexpr. args[end ]. args[end ]. args, arg)
89
98
end
90
- Expr (:tuple , x:: Number , y) => (@info " 111" ; parse_variables! (exprs, var, dict, mod, arg, varclass, kwargs))
91
- :: Number => parse_variables! (exprs, var, dict, mod, arg, varclass, kwargs)
92
- :: Expr => push! (varexpr. args[end ]. args[end ]. args, :($ a = $ (def. args[end ])))
93
- _ => @info " Got $def "
99
+ :: Symbol => push! (varexpr. args[end ]. args[end ]. args,
100
+ :($ a = $ (def. args[end ])))
101
+ :: Number || Expr (:tuple , x:: Number , y) => begin
102
+ parse_variables! (exprs, var, dict, mod, arg, varclass)
103
+ end
104
+ :: Expr => push! (varexpr. args[end ]. args[end ]. args,
105
+ :($ a = $ (def. args[end ])))
106
+ _ => error (" Got $def " )
94
107
end
95
108
end
96
- _ => " got $ arg"
109
+ _ => error ( " Could not parse this $varclass definition $ arg" )
97
110
end
98
111
end
99
112
dict[:kwargs ] = kwargs
@@ -133,12 +146,17 @@ function generate_var!(dict, a, b, varclass)
133
146
var
134
147
end
135
148
136
- function parse_default (mod, a, kwargs )
149
+ function parse_default (mod, a)
137
150
a = Base. remove_linenums! (deepcopy (a))
138
151
MLStyle. @match a begin
139
- Expr (:block , a) => get_var (mod, a)
140
- :: Symbol => get_var (mod, a)
141
- :: Number => a
152
+ Expr (:block , x) => parse_default (mod, x)
153
+ Expr (:tuple , x, y) => begin
154
+ def, _ = parse_default (mod, x)
155
+ meta = parse_metadata (mod, y)
156
+ (def, meta)
157
+ end
158
+ :: Symbol => (get_var (mod, a), nothing )
159
+ :: Number => (a, nothing )
142
160
_ => error (" Cannot parse default $a " )
143
161
end
144
162
end
@@ -173,7 +191,8 @@ macro model(fcall::Expr, expr)
173
191
fcall. head == :call || " Couldn't comprehend the model $arg "
174
192
175
193
arglist, kwargs = if lastindex (fcall. args) > 1 && is_kwarg (fcall. args[2 ])
176
- (lastindex (fcall. args) > 2 ? (@info 1 ; Set (fcall. args[3 : end ])) : (@info 2 ; Set ())), Set (fcall. args[2 ]. args)
194
+ (lastindex (fcall. args) > 2 ? Set (fcall. args[3 : end ]) : Set ()),
195
+ Set (fcall. args[2 ]. args)
177
196
else
178
197
Set (), Set (fcall. args[2 : end ])
179
198
end
@@ -189,15 +208,14 @@ function model_macro(mod, name, expr; arglist = Set([]), kwargs = Set([]))
189
208
icon = Ref {Union{String, URI}} ()
190
209
vs = []
191
210
ps = []
192
- parexpr = :(pss = @parameters begin
193
- end )
194
- varexpr = :(vss = @variables begin
195
- end )
211
+ parexpr = :(pss = @parameters begin end )
212
+ varexpr = :(vss = @variables begin end )
196
213
197
214
for arg in expr. args
198
215
arg isa LineNumberNode && continue
199
216
if arg. head == :macrocall
200
- parse_model! (exprs. args, comps, ext, eqs, icon, vs, varexpr, ps, parexpr, dict, mod, arg, kwargs)
217
+ parse_model! (exprs. args, comps, ext, eqs, icon, vs, varexpr, ps,
218
+ parexpr, dict, mod, arg, kwargs)
201
219
elseif arg. head == :block
202
220
push! (exprs. args, arg)
203
221
else
@@ -213,7 +231,7 @@ function model_macro(mod, name, expr; arglist = Set([]), kwargs = Set([]))
213
231
push! (exprs. args, parexpr)
214
232
215
233
gui_metadata = isassigned (icon) > 0 ? GUIMetadata (GlobalRef (mod, name), icon[]) :
216
- nothing
234
+ nothing
217
235
218
236
sys = :($ ODESystem ($ Equation[$ (eqs... )], $ iv, [$ (vs... ), vss... ], [$ (ps... ), pss... ];
219
237
systems = [$ (comps... )], name, gui_metadata = $ gui_metadata))
@@ -226,7 +244,8 @@ function model_macro(mod, name, expr; arglist = Set([]), kwargs = Set([]))
226
244
:($ name = $ Model (($ (arglist... ); name, $ (kwargs... )) -> $ exprs, $ dict))
227
245
end
228
246
229
- function parse_model! (exprs, comps, ext, eqs, icon, vs, varexpr, ps, parexpr, dict, mod, arg, kwargs)
247
+ function parse_model! (exprs, comps, ext, eqs, icon, vs, varexpr, ps, parexpr, dict,
248
+ mod, arg, kwargs)
230
249
mname = arg. args[1 ]
231
250
body = arg. args[end ]
232
251
if mname == Symbol (" @components" )
@@ -276,7 +295,9 @@ function _rename(compname, varname)
276
295
end
277
296
278
297
function component_args! (a, b, expr, kwargs)
279
- start = b. head == :parameters ? 1 : 2
298
+ # Whenever `b` is a function call, skip the first arg aka the function name.
299
+ # Whenver it is a kwargs list, include it.
300
+ start = b. head == :call ? 2 : 1
280
301
for i in start: lastindex (b. args)
281
302
arg = b. args[i]
282
303
arg isa LineNumberNode && continue
@@ -304,7 +325,7 @@ function component_args!(a, b, expr, kwargs)
304
325
push! (expr. args, :($ y = $ _v))
305
326
push! (kwargs, Expr (:kw , _v, y))
306
327
end
307
- _ => " Got this: $arg "
328
+ _ => error ( " Could not parse $arg of component $a " )
308
329
end
309
330
end
310
331
end
@@ -336,11 +357,11 @@ function parse_extend!(exprs, ext, dict, body)
336
357
end
337
358
end
338
359
339
- function parse_variables! (exprs, vs, dict, mod, arg, varclass, kwargs )
360
+ function parse_variables! (exprs, vs, dict, mod, arg, varclass)
340
361
expr = Expr (:block )
341
362
push! (exprs, expr)
342
363
arg isa LineNumberNode && return
343
- vv = parse_variable_def! (dict, mod, arg, varclass, kwargs )
364
+ vv = parse_variable_def! (dict, mod, arg, varclass)
344
365
v = Num (vv)
345
366
name = getname (v)
346
367
push! (vs, name)
0 commit comments