@@ -39,6 +39,7 @@ function _model_macro(mod, name, expr, isconnector)
3939 exprs = Expr (:block )
4040 dict = Dict {Symbol, Any} (
4141 :constants => Dict {Symbol, Dict} (),
42+ :defaults => Dict {Symbol, Any} (),
4243 :kwargs => Dict {Symbol, Dict} (),
4344 :structural_parameters => Dict {Symbol, Dict} ()
4445 )
@@ -54,6 +55,7 @@ function _model_macro(mod, name, expr, isconnector)
5455 push! (exprs. args, :(parameters = []))
5556 push! (exprs. args, :(systems = ODESystem[]))
5657 push! (exprs. args, :(equations = Equation[]))
58+ push! (exprs. args, :(defaults = Dict {Num, Union{Number, Symbol, Function}} ()))
5759
5860 Base. remove_linenums! (expr)
5961 for arg in expr. args
@@ -99,8 +101,11 @@ function _model_macro(mod, name, expr, isconnector)
99101 gui_metadata = isassigned (icon) > 0 ? GUIMetadata (GlobalRef (mod, name), icon[]) :
100102 GUIMetadata (GlobalRef (mod, name))
101103
104+ @inline pop_structure_dict! .(
105+ Ref (dict), [:constants , :defaults , :kwargs , :structural_parameters ])
106+
102107 sys = :($ ODESystem ($ Equation[equations... ], $ iv, variables, parameters;
103- name, systems, gui_metadata = $ gui_metadata))
108+ name, systems, gui_metadata = $ gui_metadata, defaults ))
104109
105110 if ext[] === nothing
106111 push! (exprs. args, :(var"#___sys___" = $ sys))
@@ -122,6 +127,8 @@ function _model_macro(mod, name, expr, isconnector)
122127 :($ name = $ Model ($ f, $ dict, $ isconnector))
123128end
124129
130+ pop_structure_dict! (dict, key) = length (dict[key]) == 0 && pop! (dict, key)
131+
125132function update_kwargs_and_metadata! (dict, kwargs, a, def, indices, type, var,
126133 varclass, where_types)
127134 if indices isa Nothing
@@ -355,6 +362,8 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, sps,
355362 elseif mname == Symbol (" @icon" )
356363 isassigned (icon) && error (" This model has more than one icon." )
357364 parse_icon! (body, dict, icon, mod)
365+ elseif mname == Symbol (" @defaults" )
366+ parse_system_defaults! (exprs, arg, dict)
358367 else
359368 error (" $mname is not handled." )
360369 end
@@ -400,6 +409,28 @@ function parse_constants!(exprs, dict, body, mod)
400409 end
401410end
402411
412+ push_additional_defaults! (dict, a, b:: Number ) = dict[:defaults ][a] = b
413+ push_additional_defaults! (dict, a, b:: QuoteNode ) = dict[:defaults ][a] = b. value
414+ function push_additional_defaults! (dict, a, b:: Expr )
415+ dict[:defaults ][a] = readable_code (b)
416+ end
417+
418+ function parse_system_defaults! (exprs, defaults_body, dict)
419+ for default_arg in defaults_body. args[end ]. args
420+ # for arg in default_arg.args
421+ MLStyle. @match default_arg begin
422+ # For cases like `p => 1` and `p => f()`. In both cases the definitions of
423+ # `a`, here `p` and when `b` is a function, here `f` are available while
424+ # defining the model
425+ Expr (:call , :(=> ), a, b) => begin
426+ push! (exprs, :(defaults[$ a] = $ b))
427+ push_additional_defaults! (dict, a, b)
428+ end
429+ _ => error (" Invalid `defaults` entry $default_arg $(typeof (a)) $(typeof (b)) " )
430+ end
431+ end
432+ end
433+
403434function parse_structural_parameters! (exprs, sps, dict, mod, body, kwargs)
404435 Base. remove_linenums! (body)
405436 for arg in body. args
0 commit comments