Skip to content

Commit 6e6511a

Browse files
refactor: update @constants parsing in @mtkmodel
1 parent b1a0981 commit 6e6511a

File tree

1 file changed

+28
-48
lines changed

1 file changed

+28
-48
lines changed

src/systems/model_parsing.jl

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ function _model_macro(mod, fullname::Union{Expr, Symbol}, expr, isconnector)
5353
end
5454
exprs = Expr(:block)
5555
dict = Dict{Symbol, Any}(
56-
:constants => Dict{Symbol, Dict}(),
5756
:defaults => Dict{Symbol, Any}(),
5857
:kwargs => Dict{Symbol, Dict}(),
5958
:structural_parameters => Dict{Symbol, Dict}()
@@ -125,7 +124,7 @@ function _model_macro(mod, fullname::Union{Expr, Symbol}, expr, isconnector)
125124
description = get(dict, :description, "")
126125

127126
@inline pop_structure_dict!.(
128-
Ref(dict), [:constants, :defaults, :kwargs, :structural_parameters])
127+
Ref(dict), [:defaults, :kwargs, :structural_parameters])
129128

130129
sys = :($type($(flatten_equations)(equations), $iv, variables, parameters;
131130
name, description = $description, systems, gui_metadata = $gui_metadata,
@@ -320,6 +319,10 @@ Base.@nospecializeinfer function parse_variable_def!(
320319
Meta.isexpr(a, :call) && assert_unique_independent_var(dict, a.args[end])
321320
var = :($varname = $first(@parameters ($a[$(indices...)]::$type = $varval),
322321
$meta_val))
322+
elseif varclass == :constants
323+
Meta.isexpr(a, :call) && assert_unique_independent_var(dict, a.args[end])
324+
var = :($varname = $first(@constants ($a[$(indices...)]::$type = $varval),
325+
$meta_val))
323326
else
324327
Meta.isexpr(a, :call) ||
325328
throw("$a is not a variable of the independent variable")
@@ -351,6 +354,12 @@ Base.@nospecializeinfer function parse_variable_def!(
351354
var = :($varname = $varname === $NO_VALUE ? $val : $varname;
352355
$varname = $first(@parameters ($a[$(indices...)]::$type = $varval),
353356
$(def_n_meta...)))
357+
elseif varclass == :constants
358+
Meta.isexpr(a, :call) &&
359+
assert_unique_independent_var(dict, a.args[end])
360+
var = :($varname = $varname === $NO_VALUE ? $val : $varname;
361+
$varname = $first(@constants ($a[$(indices...)]::$type = $varval),
362+
$(def_n_meta...)))
354363
else
355364
Meta.isexpr(a, :call) ||
356365
throw("$a is not a variable of the independent variable")
@@ -366,6 +375,11 @@ Base.@nospecializeinfer function parse_variable_def!(
366375
assert_unique_independent_var(dict, a.args[end])
367376
var = :($varname = $varname === $NO_VALUE ? $def_n_meta : $varname;
368377
$varname = $first(@parameters $a[$(indices...)]::$type = $varname))
378+
elseif varclass == :constants
379+
Meta.isexpr(a, :call) &&
380+
assert_unique_independent_var(dict, a.args[end])
381+
var = :($varname = $varname === $NO_VALUE ? $def_n_meta : $varname;
382+
$varname = $first(@constants $a[$(indices...)]::$type = $varname))
369383
else
370384
Meta.isexpr(a, :call) ||
371385
throw("$a is not a variable of the independent variable")
@@ -393,6 +407,9 @@ Base.@nospecializeinfer function parse_variable_def!(
393407
if varclass == :parameters
394408
Meta.isexpr(a, :call) && assert_unique_independent_var(dict, a.args[end])
395409
var = :($varname = $first(@parameters $a[$(indices...)]::$type = $varname))
410+
elseif varclass == :constants
411+
Meta.isexpr(a, :call) && assert_unique_independent_var(dict, a.args[end])
412+
var = :($varname = $first(@constants $a[$(indices...)]::$type = $varname))
396413
elseif varclass == :variables
397414
Meta.isexpr(a, :call) ||
398415
throw("$a is not a variable of the independent variable")
@@ -453,6 +470,8 @@ function generate_var(a, varclass; type = Real)
453470
var = Symbolics.variable(a; T = type)
454471
if varclass == :parameters
455472
var = toparam(var)
473+
elseif varclass == :constants
474+
var = toconstant(var)
456475
elseif varclass == :independent_variables
457476
var = toiv(var)
458477
end
@@ -513,6 +532,8 @@ function generate_var!(dict, a, b, varclass, mod;
513532
end
514533
if varclass == :parameters
515534
var = toparam(var)
535+
elseif varclass == :constants
536+
var = toconstant(var)
516537
end
517538
var
518539
end
@@ -622,7 +643,7 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, sps, c_evts, d_evts,
622643
elseif mname == Symbol("@equations")
623644
parse_equations!(exprs, eqs, dict, body)
624645
elseif mname == Symbol("@constants")
625-
parse_constants!(exprs, dict, body, mod)
646+
parse_variables!(exprs, ps, dict, mod, body, :constants, kwargs, where_types)
626647
elseif mname == Symbol("@continuous_events")
627648
parse_continuous_events!(c_evts, dict, body)
628649
elseif mname == Symbol("@discrete_events")
@@ -643,49 +664,6 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, sps, c_evts, d_evts,
643664
end
644665
end
645666

646-
function parse_constants!(exprs, dict, body, mod)
647-
Base.remove_linenums!(body)
648-
for arg in body.args
649-
MLStyle.@match arg begin
650-
Expr(:(=), Expr(:(::), a, type), Expr(:tuple, b, metadata)) || Expr(:(=), Expr(:(::), a, type), b) => begin
651-
type = getfield(mod, type)
652-
b = _type_check!(get_var(mod, b), a, type, :constants)
653-
push!(exprs,
654-
:($(Symbolics._parse_vars(
655-
:constants, type, [:($a = $b), metadata], toconstant))))
656-
dict[:constants][a] = Dict(:value => b, :type => type)
657-
if @isdefined metadata
658-
for data in metadata.args
659-
dict[:constants][a][data.args[1]] = data.args[2]
660-
end
661-
end
662-
end
663-
Expr(:(=), a, Expr(:tuple, b, metadata)) => begin
664-
push!(exprs,
665-
:($(Symbolics._parse_vars(
666-
:constants, Real, [:($a = $b), metadata], toconstant))))
667-
dict[:constants][a] = Dict{Symbol, Any}(:value => get_var(mod, b))
668-
for data in metadata.args
669-
dict[:constants][a][data.args[1]] = data.args[2]
670-
end
671-
end
672-
Expr(:(=), a, b) => begin
673-
push!(exprs,
674-
:($(Symbolics._parse_vars(
675-
:constants, Real, [:($a = $b)], toconstant))))
676-
dict[:constants][a] = Dict(:value => get_var(mod, b))
677-
end
678-
_ => error("""Malformed constant definition `$arg`. Please use the following syntax:
679-
```
680-
@constants begin
681-
var = value, [description = "This is an example constant."]
682-
end
683-
```
684-
""")
685-
end
686-
end
687-
end
688-
689667
push_additional_defaults!(dict, a, b::Number) = dict[:defaults][a] = b
690668
push_additional_defaults!(dict, a, b::QuoteNode) = dict[:defaults][a] = b.value
691669
function push_additional_defaults!(dict, a, b::Expr)
@@ -950,6 +928,7 @@ function handle_conditional_vars!(
950928
arg, conditional_branch, mod, varclass, kwargs, where_types)
951929
conditional_dict = Dict(:kwargs => Dict(),
952930
:parameters => Any[Dict{Symbol, Dict{Symbol, Any}}()],
931+
:constants => Any[Dict{Symbol, Dict{Symbol, Any}}()],
953932
:variables => Any[Dict{Symbol, Dict{Symbol, Any}}()])
954933
for _arg in arg.args
955934
name, ex = parse_variable_arg(
@@ -964,7 +943,7 @@ function prune_conditional_dict!(conditional_tuple::Tuple)
964943
prune_conditional_dict!.(collect(conditional_tuple))
965944
end
966945
function prune_conditional_dict!(conditional_dict::Dict)
967-
for k in [:parameters, :variables]
946+
for k in [:parameters, :variables, :constants]
968947
length(conditional_dict[k]) == 1 && isempty(first(conditional_dict[k])) &&
969948
delete!(conditional_dict, k)
970949
end
@@ -981,7 +960,7 @@ end
981960

982961
function get_conditional_dict!(conditional_dict::Dict, conditional_y_tuple::Dict)
983962
merge!(conditional_dict[:kwargs], conditional_y_tuple[:kwargs])
984-
for key in [:parameters, :variables]
963+
for key in [:parameters, :variables, :constants]
985964
merge!(conditional_dict[key][1], conditional_y_tuple[key][1])
986965
end
987966
conditional_dict
@@ -1000,6 +979,7 @@ function push_conditional_dict!(dict, condition, conditional_dict,
1000979
end
1001980
conditional_y_dict = Dict(:kwargs => Dict(),
1002981
:parameters => Any[Dict{Symbol, Dict{Symbol, Any}}()],
982+
:constants => Any[Dict{Symbol, Dict{Symbol, Any}}()],
1003983
:variables => Any[Dict{Symbol, Dict{Symbol, Any}}()])
1004984
get_conditional_dict!(conditional_y_dict, conditional_y_tuple)
1005985

0 commit comments

Comments
 (0)