36
36
function _model_macro (mod, name, expr, isconnector)
37
37
exprs = Expr (:block )
38
38
dict = Dict {Symbol, Any} (
39
+ :constants => Dict {Symbol, Dict} (),
39
40
:kwargs => Dict {Symbol, Dict} (),
40
41
:structural_parameters => Dict {Symbol, Dict} ()
41
42
)
@@ -347,6 +348,8 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, sps,
347
348
parse_structural_parameters! (exprs, sps, dict, mod, body, kwargs)
348
349
elseif mname == Symbol (" @equations" )
349
350
parse_equations! (exprs, eqs, dict, body)
351
+ elseif mname == Symbol (" @constants" )
352
+ parse_constants! (exprs, dict, body, mod)
350
353
elseif mname == Symbol (" @icon" )
351
354
isassigned (icon) && error (" This model has more than one icon." )
352
355
parse_icon! (body, dict, icon, mod)
@@ -355,13 +358,53 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, sps,
355
358
end
356
359
end
357
360
361
+ function parse_constants! (exprs, dict, body, mod)
362
+ Base. remove_linenums! (body)
363
+ for arg in body. args
364
+ MLStyle. @match arg begin
365
+ Expr (:(= ), Expr (:(:: ), a, type), Expr (:tuple , b, metadata)) || Expr (:(= ), Expr (:(:: ), a, type), b) => begin
366
+ type = getfield (mod, type)
367
+ b = _type_check! (get_var (mod, b), a, type, :constants )
368
+ constant = first (@constants $ a:: type = b)
369
+ push! (exprs, :($ a = $ constant))
370
+ dict[:constants ][a] = Dict (:value => b, :type => type)
371
+ if @isdefined metadata
372
+ for data in metadata. args
373
+ dict[:constants ][a][data. args[1 ]] = data. args[2 ]
374
+ end
375
+ end
376
+ end
377
+ Expr (:(= ), a, Expr (:tuple , b, metadata)) => begin
378
+ constant = first (@constants $ a = b)
379
+ push! (exprs, :($ a = $ constant))
380
+ dict[:constants ][a] = Dict {Symbol, Any} (:value => get_var (mod, b))
381
+ for data in metadata. args
382
+ dict[:constants ][a][data. args[1 ]] = data. args[2 ]
383
+ end
384
+ end
385
+ Expr (:(= ), a, b) => begin
386
+ constant = first (@constants $ a = b)
387
+ push! (exprs, :($ a = $ constant))
388
+ dict[:constants ][a] = Dict (:value => get_var (mod, b))
389
+ end
390
+ _ => error (""" Malformed constant definition `$arg `. Please use the following syntax:
391
+ ```
392
+ @constants begin
393
+ var = value, [description = "This is an example constant."]
394
+ end
395
+ ```
396
+ """ )
397
+ end
398
+ end
399
+ end
400
+
358
401
function parse_structural_parameters! (exprs, sps, dict, mod, body, kwargs)
359
402
Base. remove_linenums! (body)
360
403
for arg in body. args
361
404
MLStyle. @match arg begin
362
405
Expr (:(= ), Expr (:(:: ), a, type), b) => begin
363
- type = Core . eval (mod, type)
364
- b = _type_check! (Core . eval (mod, b), a, type, :structural_parameters )
406
+ type = getfield (mod, type)
407
+ b = _type_check! (get_var (mod, b), a, type, :structural_parameters )
365
408
push! (sps, a)
366
409
push! (kwargs, Expr (:kw , Expr (:(:: ), a, type), b))
367
410
dict[:structural_parameters ][a] = dict[:kwargs ][a] = Dict (
@@ -922,16 +965,15 @@ function parse_conditional_model_statements(comps, dict, eqs, exprs, kwargs, mod
922
965
end ))
923
966
end
924
967
925
- function _type_check! (val, a, type, varclass )
968
+ function _type_check! (val, a, type, class )
926
969
if val isa type
927
970
return val
928
971
else
929
972
try
930
973
return convert (type, val)
931
- catch
932
- (e)
974
+ catch e
933
975
throw (TypeError (Symbol (" `@mtkmodel`" ),
934
- " `$varclass `, while assigning to `$a `" , type, typeof (val)))
976
+ " `$class `, while assigning to `$a `" , type, typeof (val)))
935
977
end
936
978
end
937
979
end
0 commit comments