@@ -37,8 +37,6 @@ function _model_macro(mod, name, expr, isconnector)
37
37
exprs = Expr (:block )
38
38
dict = Dict {Symbol, Any} ()
39
39
dict[:kwargs ] = Dict {Symbol, Any} ()
40
- dict[:parameters ] = Any[Dict {Symbol, Dict{Symbol, Any}} ()]
41
- dict[:variables ] = Any[Dict {Symbol, Dict{Symbol, Any}} ()]
42
40
comps = Symbol[]
43
41
ext = Ref {Any} (nothing )
44
42
eqs = Expr[]
@@ -109,7 +107,7 @@ function _model_macro(mod, name, expr, isconnector)
109
107
end
110
108
111
109
function parse_variable_def! (dict, mod, arg, varclass, kwargs;
112
- def = nothing , indices:: Union{Vector{UnitRange{Int}}, Nothing} = nothing )
110
+ def = nothing , indices:: Union{Vector{UnitRange{Int}}, Nothing} = nothing )
113
111
metatypes = [(:connection_type , VariableConnectType),
114
112
(:description , VariableDescription),
115
113
(:unit , VariableUnit),
@@ -144,12 +142,16 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs;
144
142
Base. remove_linenums! (b)
145
143
def, meta = parse_default (mod, b)
146
144
var, def = parse_variable_def! (dict, mod, a, varclass, kwargs; def)
147
- dict[varclass][1 ][ getname (var)][:default ] = def
145
+ dict[varclass][getname (var)][:default ] = def
148
146
if meta != = nothing
149
147
for (type, key) in metatypes
150
148
if (mt = get (meta, key, nothing )) != = nothing
151
149
key == VariableConnectType && (mt = nameof (mt))
152
- dict[varclass][1 ][getname (var)][type] = mt
150
+ if dict[varclass] isa Vector
151
+ dict[varclass][1 ][getname (var)][type] = mt
152
+ else
153
+ dict[varclass][getname (var)][type] = mt
154
+ end
153
155
end
154
156
end
155
157
var = set_var_metadata (var, meta)
@@ -163,7 +165,12 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs;
163
165
for (type, key) in metatypes
164
166
if (mt = get (meta, key, nothing )) != = nothing
165
167
key == VariableConnectType && (mt = nameof (mt))
166
- dict[varclass][1 ][getname (var)][type] = mt
168
+ # @info dict 164
169
+ if dict[varclass] isa Vector
170
+ dict[varclass][1 ][getname (var)][type] = mt
171
+ else
172
+ dict[varclass][getname (var)][type] = mt
173
+ end
167
174
end
168
175
end
169
176
var = set_var_metadata (var, meta)
@@ -185,7 +192,7 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs;
185
192
end
186
193
187
194
function generate_var (a, varclass;
188
- indices:: Union{Vector{UnitRange{Int}}, Nothing} = nothing )
195
+ indices:: Union{Vector{UnitRange{Int}}, Nothing} = nothing )
189
196
var = indices === nothing ? Symbolics. variable (a) : first (@variables $ a[indices... ])
190
197
if varclass == :parameters
191
198
var = toparam (var)
@@ -194,21 +201,27 @@ function generate_var(a, varclass;
194
201
end
195
202
196
203
function generate_var! (dict, a, varclass;
197
- indices:: Union{Vector{UnitRange{Int}}, Nothing} = nothing )
198
- vd = first (dict[varclass])
204
+ indices:: Union{Vector{UnitRange{Int}}, Nothing} = nothing )
205
+ vd = get! (dict, varclass) do
206
+ Dict {Symbol, Dict{Symbol, Any}} ()
207
+ end
208
+ vd isa Vector && (vd = first (vd))
199
209
vd[a] = Dict {Symbol, Any} ()
200
210
indices != = nothing && (vd[a][:size ] = Tuple (lastindex .(indices)))
201
211
generate_var (a, varclass; indices)
202
212
end
203
213
204
214
function generate_var! (dict, a, b, varclass;
205
- indices:: Union{Vector{UnitRange{Int}}, Nothing} = nothing )
215
+ indices:: Union{Vector{UnitRange{Int}}, Nothing} = nothing )
206
216
iv = generate_var (b, :variables )
207
217
prev_iv = get! (dict, :independent_variable ) do
208
218
iv
209
219
end
210
- @assert isequal (iv, prev_iv)
211
- vd = first (dict[varclass])
220
+ @assert isequal (iv, prev_iv) " Multiple independent variables are used in the model"
221
+ vd = get! (dict, varclass) do
222
+ Dict {Symbol, Dict{Symbol, Any}} ()
223
+ end
224
+ vd isa Vector && (vd = first (vd))
212
225
vd[a] = Dict {Symbol, Any} ()
213
226
var = if indices === nothing
214
227
Symbolics. variable (a, T = SymbolicUtils. FnType{Tuple{Real}, Real})(iv)
@@ -271,7 +284,7 @@ function get_var(mod::Module, b)
271
284
end
272
285
273
286
function parse_model! (exprs, comps, ext, eqs, icon, vs, ps, sps,
274
- dict, mod, arg, kwargs)
287
+ dict, mod, arg, kwargs)
275
288
mname = arg. args[1 ]
276
289
body = arg. args[end ]
277
290
if mname == Symbol (" @components" )
@@ -435,6 +448,57 @@ function handle_conditional_vars!(arg, conditional_branch, mod, varclass, kwargs
435
448
conditional_dict
436
449
end
437
450
451
+ function prune_conditional_dict! (conditional_tuple:: Tuple )
452
+ prune_conditional_dict! .(collect (conditional_tuple))
453
+ end
454
+ function prune_conditional_dict! (conditional_dict:: Dict )
455
+ for k in [:parameters , :variables ]
456
+ length (conditional_dict[k]) == 1 && isempty (first (conditional_dict[k])) &&
457
+ delete! (conditional_dict, k)
458
+ end
459
+ isempty (conditional_dict[:kwargs ]) && delete! (conditional_dict, :kwargs )
460
+ end
461
+ prune_conditional_dict! (_) = return nothing
462
+
463
+ function get_conditional_dict! (conditional_dict, conditional_y_tuple:: Tuple )
464
+ k = get_conditional_dict! .(Ref (conditional_dict), collect (conditional_y_tuple))
465
+ push_something! (conditional_dict,
466
+ k... )
467
+ conditional_dict
468
+ end
469
+
470
+ function get_conditional_dict! (conditional_dict:: Dict , conditional_y_tuple:: Dict )
471
+ merge! (conditional_dict[:kwargs ], conditional_y_tuple[:kwargs ])
472
+ for key in [:parameters , :variables ]
473
+ merge! (conditional_dict[key][1 ], conditional_y_tuple[key][1 ])
474
+ end
475
+ conditional_dict
476
+ end
477
+
478
+ get_conditional_dict! (a, b) = (return nothing )
479
+
480
+ function push_conditional_dict! (dict, condition, conditional_dict,
481
+ conditional_y_tuple, varclass)
482
+ vd = get! (dict, varclass) do
483
+ Dict {Symbol, Dict{Symbol, Any}} ()
484
+ end
485
+ for k in keys (conditional_dict[varclass][1 ])
486
+ vd[k] = copy (conditional_dict[varclass][1 ][k])
487
+ vd[k][:condition ] = (:if , condition, conditional_dict, conditional_y_tuple)
488
+ end
489
+ conditional_y_dict = Dict (:kwargs => Dict (),
490
+ :parameters => Any[Dict {Symbol, Dict{Symbol, Any}} ()],
491
+ :variables => Any[Dict {Symbol, Dict{Symbol, Any}} ()])
492
+ get_conditional_dict! (conditional_y_dict, conditional_y_tuple)
493
+
494
+ prune_conditional_dict! (conditional_y_dict)
495
+ prune_conditional_dict! (conditional_dict)
496
+ ! isempty (conditional_y_dict) && for k in keys (conditional_y_dict[varclass][1 ])
497
+ vd[k] = copy (conditional_y_dict[varclass][1 ][k])
498
+ vd[k][:condition ] = (:if , condition, conditional_dict, conditional_y_tuple)
499
+ end
500
+ end
501
+
438
502
function parse_variables! (exprs, vs, dict, mod, body, varclass, kwargs)
439
503
expr = Expr (:block )
440
504
push! (exprs, expr)
@@ -449,7 +513,7 @@ function parse_variables!(exprs, vs, dict, mod, body, varclass, kwargs)
449
513
varclass,
450
514
kwargs)
451
515
push! (expr. args, conditional_expr)
452
- push ! (dict[varclass], ( :if , condition, conditional_dict, nothing ) )
516
+ push_conditional_dict ! (dict, condition, conditional_dict, nothing , varclass )
453
517
end
454
518
Expr (:if , condition, x, y) => begin
455
519
conditional_expr = Expr (:if , condition, Expr (:block ))
@@ -458,15 +522,18 @@ function parse_variables!(exprs, vs, dict, mod, body, varclass, kwargs)
458
522
mod,
459
523
varclass,
460
524
kwargs)
461
- conditional_y_expr, conditional_y_dict = handle_y_vars (y,
525
+ conditional_y_expr, conditional_y_tuple = handle_y_vars (y,
462
526
conditional_dict,
463
527
mod,
464
528
varclass,
465
529
kwargs)
466
530
push! (conditional_expr. args, conditional_y_expr)
467
531
push! (expr. args, conditional_expr)
468
- push! (dict[varclass],
469
- (:if , condition, conditional_dict, conditional_y_dict))
532
+ push_conditional_dict! (dict,
533
+ condition,
534
+ conditional_dict,
535
+ conditional_y_tuple,
536
+ varclass)
470
537
end
471
538
_ => parse_variable_arg! (exprs, vs, dict, mod, arg, varclass, kwargs)
472
539
end
@@ -492,10 +559,11 @@ function handle_y_vars(y, dict, mod, varclass, kwargs)
492
559
end
493
560
494
561
function handle_if_x_equations! (condition, dict, ifexpr, x)
495
- push! (ifexpr. args, condition, :(push! (equations, $ (x. args... ))))
496
- # push!(dict[:equations], [:if, readable_code(condition), readable_code.(x.args)])
497
- readable_code .(x. args)
562
+ push! (ifexpr. args, condition, :(push! (equations, $ (x. args... ))))
563
+ # push!(dict[:equations], [:if, readable_code(condition), readable_code.(x.args)])
564
+ readable_code .(x. args)
498
565
end
566
+
499
567
function handle_if_y_equations! (ifexpr, y, dict)
500
568
if y. head == :elseif
501
569
elseifexpr = Expr (:elseif )
@@ -506,10 +574,11 @@ function handle_if_y_equations!(ifexpr, y, dict)
506
574
push! (ifexpr. args, elseifexpr)
507
575
(eq_entry... ,)
508
576
else
509
- push! (ifexpr. args, :(push! (equations, $ (y. args... ))))
510
- readable_code .(y. args)
577
+ push! (ifexpr. args, :(push! (equations, $ (y. args... ))))
578
+ readable_code .(y. args)
511
579
end
512
580
end
581
+
513
582
function parse_equations! (exprs, eqs, dict, body)
514
583
dict[:equations ] = []
515
584
Base. remove_linenums! (body)
699
768
# Handle top level branching
700
769
push_something! (v, :: Nothing ) = v
701
770
push_something! (v, x) = push! (v, x)
771
+ push_something! (v:: Dict , x:: Dict ) = merge! (v, x)
702
772
push_something! (v, x... ) = push_something! .(Ref (v), x)
703
773
704
774
define_blocks (branch) = [Expr (branch), Expr (branch), Expr (branch), Expr (branch)]
@@ -737,21 +807,23 @@ function parse_top_level_branch(condition, x, y = nothing, branch = :if)
737
807
for i in 1 : lastindex (yblocks)
738
808
if lastindex (blocks[i]. args) == 1
739
809
push_something! (blocks[i]. args, Expr (:block ), yblocks[i])
810
+ elseif lastindex (blocks[i]. args) == 0
811
+ blocks[i] = yblocks[i]
740
812
else
741
813
push_something! (blocks[i]. args, yblocks[i])
742
814
end
743
815
end
744
816
end
745
817
746
818
for i in 1 : lastindex (blocks)
747
- isempty (blocks[i]. args) && (blocks[i] = nothing )
819
+ blocks[i] != = nothing && isempty (blocks[i]. args) && (blocks[i] = nothing )
748
820
end
749
821
750
822
return blocks
751
823
end
752
824
753
- function parse_conditional_model_statements (comps, dict, eqs, exprs, kwargs, mod, ps, vs,
754
- component_blk, equations_blk, parameter_blk, variable_blk)
825
+ function parse_conditional_model_statements (comps, dict, eqs, exprs, kwargs, mod,
826
+ ps, vs, component_blk, equations_blk, parameter_blk, variable_blk)
755
827
parameter_blk != = nothing &&
756
828
parse_variables! (exprs. args, ps, dict, mod, :(begin
757
829
$ parameter_blk
0 commit comments