Skip to content

Commit 4e3cb7a

Browse files
committed
refactor: use existing parsers for vars/pars whenever they have defined vals
1 parent 97e330d commit 4e3cb7a

File tree

1 file changed

+54
-53
lines changed

1 file changed

+54
-53
lines changed

src/systems/model_parsing.jl

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ function connector_macro(mod, name, body)
2424
vs = Num[]
2525
icon = Ref{Union{String, URI}}()
2626
dict = Dict{Symbol, Any}()
27+
kwargs = []
2728
for arg in body.args
2829
arg isa LineNumberNode && continue
2930
if arg.head == :macrocall && arg.args[1] == Symbol("@icon")
@@ -70,38 +71,32 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs)
7071
end
7172
end
7273

73-
function for_keyword_queue()
74-
# These args contain potential keywords
75-
# Handle it along with vars without defaults
76-
end
77-
78-
# Takes in args and populates kw and var definition exprs.
79-
# This should be modified to handle the other cases (i.e they should use existing
80-
# methods)
81-
function parse_variables_with_kw!(exprs, dict, mod, body, varclass, kwargs)
82-
expr = if varclass == :parameters
83-
:(pss = @parameters begin
84-
end)
85-
elseif varclass == :variables
86-
:(vss = @variables begin
87-
end)
88-
end
89-
74+
function parse_variables_with_kw!(exprs, var, dict, mod, body, varexpr, varclass, kwargs)
9075
for arg in body.args
9176
arg isa LineNumberNode && continue
9277
MLStyle.@match arg begin
93-
78+
Expr(:(=), a, b::Number) => parse_variables!(exprs, var, dict, mod, arg, varclass, kwargs)
79+
Expr(:(=), a, b::Symbol) => begin
80+
isdefined(mod, b) ?
81+
parse_variables!(exprs, var, dict, mod, arg, varclass, kwargs) :
82+
push!(kwargs, b)
83+
end
9484
Expr(:(=), a, b) => begin
9585
def = Base.remove_linenums!(b).args[end]
96-
push!(expr.args[end].args[end].args, :($a = $def))
97-
push!(kwargs, def)
98-
@info "\nIn $varclass $kwargs for arg: $arg"
86+
MLStyle.@match def begin
87+
Expr(:tuple, x::Symbol, y) || x::Symbol => begin
88+
push!(varexpr.args[end].args[end].args, :($a = $def))
89+
push!(kwargs, x)
90+
end
91+
Expr(:tuple, x::Number, y) => parse_variables!(exprs, var, dict, mod, arg, varclass, kwargs)
92+
::Number => parse_variables!(exprs, var, dict, mod, arg, varclass, kwargs)
93+
_ => @info "Got $def"
94+
end
9995
end
10096
_ => "got $arg"
10197
end
10298
end
10399
dict[:kwargs] = kwargs
104-
push!(exprs, expr)
105100
end
106101

107102
function generate_var(a, varclass)
@@ -111,6 +106,7 @@ function generate_var(a, varclass)
111106
end
112107
var
113108
end
109+
114110
function generate_var!(dict, a, varclass)
115111
var = generate_var(a, varclass)
116112
vd = get!(dict, varclass) do
@@ -119,6 +115,7 @@ function generate_var!(dict, a, varclass)
119115
vd[a] = Dict{Symbol, Any}()
120116
var
121117
end
118+
122119
function generate_var!(dict, a, b, varclass)
123120
iv = generate_var(b, :variables)
124121
prev_iv = get!(dict, :independent_variable) do
@@ -145,21 +142,24 @@ function parse_default(mod, a, kwargs)
145142
_ => error("Cannot parse default $a")
146143
end
147144
end
145+
148146
function parse_metadata(mod, a)
149147
MLStyle.@match a begin
150148
Expr(:vect, eles...) => Dict(parse_metadata(mod, e) for e in eles)
151149
Expr(:(=), a, b) => Symbolics.option_to_metadata_type(Val(a)) => get_var(mod, b)
152150
_ => error("Cannot parse metadata $a")
153151
end
154152
end
153+
155154
function set_var_metadata(a, ms)
156155
for (m, v) in ms
157156
a = setmetadata(a, m, v)
158157
end
159158
a
160159
end
160+
161161
function get_var(mod::Module, b)
162-
b isa Symbol ? getproperty(mod, b) : for_keyword_queue()
162+
b isa Symbol ? getproperty(mod, b) : b
163163
end
164164

165165
macro model(name::Symbol, expr)
@@ -173,9 +173,13 @@ function model_macro(mod, name, expr)
173173
ext = Ref{Any}(nothing)
174174
eqs = Expr[]
175175
icon = Ref{Union{String, URI}}()
176+
vs = []
177+
ps = []
178+
parexpr = :(pss = @parameters begin
179+
end)
180+
varexpr = :(vss = @variables begin
181+
end)
176182
kwargs = []
177-
vs, vss = [], []
178-
ps, pss = [], []
179183
for arg in expr.args
180184
arg isa LineNumberNode && continue
181185
if arg.head == :macrocall
@@ -190,9 +194,14 @@ function model_macro(mod, name, expr)
190194
if iv === nothing
191195
iv = dict[:independent_variable] = variable(:t)
192196
end
197+
198+
push!(exprs.args, varexpr)
199+
push!(exprs.args, parexpr)
200+
193201
gui_metadata = isassigned(icon) > 0 ? GUIMetadata(GlobalRef(mod, name), icon[]) :
194-
nothing
195-
sys = :($ODESystem($Equation[$(eqs...)], $iv, [], [$(ps...); pss...];
202+
nothing
203+
204+
sys = :($ODESystem($Equation[$(eqs...)], $iv, [$(vs...), vss...], [$(ps...), pss...];
196205
systems = [$(comps...)], name, gui_metadata = $gui_metadata))
197206
if ext[] === nothing
198207
push!(exprs.args, sys)
@@ -210,9 +219,9 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, varexpr, ps, parexpr, di
210219
elseif mname == Symbol("@extend")
211220
parse_extend!(exprs, ext, dict, body)
212221
elseif mname == Symbol("@variables")
213-
parse_variables_with_kw!(exprs, dict, mod, body, :variables, kwargs)
222+
parse_variables_with_kw!(exprs, vs, dict, mod, body, varexpr, :variables, kwargs)
214223
elseif mname == Symbol("@parameters")
215-
parse_variables_with_kw!(exprs, dict, mod, body, :parameters, kwargs)
224+
parse_variables_with_kw!(exprs, ps, dict, mod, body, parexpr, :parameters, kwargs)
216225
elseif mname == Symbol("@equations")
217226
parse_equations!(exprs, eqs, dict, body)
218227
elseif mname == Symbol("@icon")
@@ -222,12 +231,10 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, varexpr, ps, parexpr, di
222231
end
223232
end
224233

225-
# components
226234
function parse_components!(exprs, cs, dict, body, kwargs)
227235
expr = Expr(:block)
228236
push!(exprs, expr)
229237
comps = Vector{String}[]
230-
varnamed = []
231238
for arg in body.args
232239
arg isa LineNumberNode && continue
233240
MLStyle.@match arg begin
@@ -242,45 +249,42 @@ function parse_components!(exprs, cs, dict, body, kwargs)
242249
push!(b.args, Expr(:kw, :name, Meta.quot(a)))
243250
arg.args[2] = b
244251
push!(expr.args, arg)
245-
@info "\n\nExpr $expr, b: $b\n\n"
246252
end
247253
_ => error("`@components` only takes assignment expressions. Got $arg")
248254
end
249255
end
250256
dict[:components] = comps
251257
end
252258

253-
function var_rename(compname, varname)
259+
function _rename(compname, varname)
254260
compname = Symbol(compname, :__, varname)
255261
end
256262

257263
function component_args!(a, b, expr, kwargs)
258-
for i in 1:lastindex(b.args)
264+
for i in 2:lastindex(b.args)
259265
arg = b.args[i]
266+
arg isa LineNumberNode && continue
260267
MLStyle.@match arg begin
261268
::Symbol => begin
262-
if b.head == :parameters
263-
_v = varname2(a, arg)
264-
push!(kwargs, _v)
265-
b.args[i] = Expr(:kw, arg, _v)
266-
end
267-
continue
269+
_v = _rename(a, arg)
270+
push!(kwargs, _v)
271+
b.args[i] = Expr(:kw, arg, _v)
268272
end
269273
Expr(:parameters, x...) => begin
270274
component_args!(a, arg, expr, kwargs)
271275
end
272276
Expr(:kw, x) => begin
273-
_v = varname2(a, x)
277+
_v = _rename(a, x)
274278
b.args[i] = Expr(:kw, x, _v)
275279
push!(kwargs, _v)
276280
end
277281
Expr(:kw, x, y::Number) => begin
278-
_v = varname2(a, x)
282+
_v = _rename(a, x)
279283
b.args[i] = Expr(:kw, x, _v)
280284
push!(kwargs, Expr(:kw, _v, y))
281285
end
282286
Expr(:kw, x, y) => begin
283-
_v = varname2(a, x)
287+
_v = _rename(a, x)
284288
push!(expr.args, :($y = $_v))
285289
push!(kwargs, Expr(:kw, _v, y))
286290
end
@@ -289,7 +293,6 @@ function component_args!(a, b, expr, kwargs)
289293
end
290294
end
291295

292-
#
293296
function parse_extend!(exprs, ext, dict, body)
294297
expr = Expr(:block)
295298
push!(exprs, expr)
@@ -317,17 +320,15 @@ function parse_extend!(exprs, ext, dict, body)
317320
end
318321
end
319322

320-
function parse_variables!(exprs, vs, dict, mod, body, varclass, kwargs)
323+
function parse_variables!(exprs, vs, dict, mod, arg, varclass, kwargs)
321324
expr = Expr(:block)
322325
push!(exprs, expr)
323-
for arg in body.args
324-
arg isa LineNumberNode && continue
325-
vv = parse_variable_def!(dict, mod, arg, varclass, kwargs)
326-
v = Num(vv)
327-
name = getname(v)
328-
push!(vs, name)
329-
push!(expr.args, :($name = $v))
330-
end
326+
arg isa LineNumberNode && return
327+
vv = parse_variable_def!(dict, mod, arg, varclass, kwargs)
328+
v = Num(vv)
329+
name = getname(v)
330+
push!(vs, name)
331+
push!(expr.args, :($name = $v))
331332
end
332333

333334
function parse_equations!(exprs, eqs, dict, body)

0 commit comments

Comments
 (0)