@@ -51,7 +51,7 @@ function _model_macro(mod, name, expr, isconnector)
51
51
c_evts = []
52
52
d_evts = []
53
53
kwargs = OrderedCollections. OrderedSet ()
54
- where_types = Expr[]
54
+ where_types = Union{Symbol, Expr} []
55
55
56
56
push! (exprs. args, :(variables = []))
57
57
push! (exprs. args, :(parameters = []))
143
143
pop_structure_dict! (dict, key) = length (dict[key]) == 0 && pop! (dict, key)
144
144
145
145
function update_kwargs_and_metadata! (dict, kwargs, a, def, indices, type, var,
146
- varclass, where_types)
146
+ varclass, where_types, meta )
147
147
if indices isa Nothing
148
- push! (kwargs, Expr (:kw , Expr (:(:: ), a, Union{Nothing, type}), nothing ))
148
+ if ! isnothing (meta) && haskey (meta, VariableUnit)
149
+ uvar = gensym ()
150
+ push! (where_types, uvar)
151
+ push! (kwargs, Expr (:kw , :($ a:: Union{Nothing, $uvar} ), nothing ))
152
+ else
153
+ push! (kwargs, Expr (:kw , :($ a:: Union{Nothing, $type} ), nothing ))
154
+ end
149
155
dict[:kwargs ][getname (var)] = Dict (:value => def, :type => type)
150
156
else
151
157
vartype = gensym (:T )
@@ -154,7 +160,11 @@ function update_kwargs_and_metadata!(dict, kwargs, a, def, indices, type, var,
154
160
Expr (:(:: ), a,
155
161
Expr (:curly , :Union , :Nothing , Expr (:curly , :AbstractArray , vartype))),
156
162
nothing ))
157
- push! (where_types, :($ vartype <: $type ))
163
+ if ! isnothing (meta) && haskey (meta, VariableUnit)
164
+ push! (where_types, vartype)
165
+ else
166
+ push! (where_types, :($ vartype <: $type ))
167
+ end
158
168
dict[:kwargs ][getname (var)] = Dict (:value => def, :type => AbstractArray{type})
159
169
end
160
170
if dict[varclass] isa Vector
166
176
167
177
function parse_variable_def! (dict, mod, arg, varclass, kwargs, where_types;
168
178
def = nothing , indices:: Union{Vector{UnitRange{Int}}, Nothing} = nothing ,
169
- type:: Type = Real)
179
+ type:: Type = Real, meta = Dict {DataType, Expr} () )
170
180
metatypes = [(:connection_type , VariableConnectType),
171
181
(:description , VariableDescription),
172
182
(:unit , VariableUnit),
@@ -186,29 +196,31 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs, where_types;
186
196
a:: Symbol => begin
187
197
var = generate_var! (dict, a, varclass; indices, type)
188
198
update_kwargs_and_metadata! (dict, kwargs, a, def, indices, type, var,
189
- varclass, where_types)
199
+ varclass, where_types, meta )
190
200
return var, def, Dict ()
191
201
end
192
202
Expr (:(:: ), a, type) => begin
193
203
type = getfield (mod, type)
194
- parse_variable_def! (dict, mod, a, varclass, kwargs, where_types; def, type)
204
+ parse_variable_def! (
205
+ dict, mod, a, varclass, kwargs, where_types; def, type, meta)
195
206
end
196
207
Expr (:(:: ), Expr (:call , a, b), type) => begin
197
208
type = getfield (mod, type)
198
209
def = _type_check! (def, a, type, varclass)
199
- parse_variable_def! (dict, mod, a, varclass, kwargs, where_types; def, type)
210
+ parse_variable_def! (
211
+ dict, mod, a, varclass, kwargs, where_types; def, type, meta)
200
212
end
201
213
Expr (:call , a, b) => begin
202
214
var = generate_var! (dict, a, b, varclass, mod; indices, type)
203
215
update_kwargs_and_metadata! (dict, kwargs, a, def, indices, type, var,
204
- varclass, where_types)
216
+ varclass, where_types, meta )
205
217
return var, def, Dict ()
206
218
end
207
219
Expr (:(= ), a, b) => begin
208
220
Base. remove_linenums! (b)
209
221
def, meta = parse_default (mod, b)
210
222
var, def, _ = parse_variable_def! (
211
- dict, mod, a, varclass, kwargs, where_types; def, type)
223
+ dict, mod, a, varclass, kwargs, where_types; def, type, meta )
212
224
if dict[varclass] isa Vector
213
225
dict[varclass][1 ][getname (var)][:default ] = def
214
226
else
@@ -231,9 +243,9 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs, where_types;
231
243
return var, def, Dict ()
232
244
end
233
245
Expr (:tuple , a, b) => begin
234
- var, def, _ = parse_variable_def! (
235
- dict, mod, a, varclass, kwargs, where_types; type)
236
246
meta = parse_metadata (mod, b)
247
+ var, def, _ = parse_variable_def! (
248
+ dict, mod, a, varclass, kwargs, where_types; type, meta)
237
249
if meta != = nothing
238
250
for (type, key) in metatypes
239
251
if (mt = get (meta, key, nothing )) != = nothing
@@ -253,7 +265,7 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs, where_types;
253
265
Expr (:ref , a, b... ) => begin
254
266
indices = map (i -> UnitRange (i. args[2 ], i. args[end ]), b)
255
267
parse_variable_def! (dict, mod, a, varclass, kwargs, where_types;
256
- def, indices, type)
268
+ def, indices, type, meta )
257
269
end
258
270
_ => error (" $arg cannot be parsed" )
259
271
end
@@ -611,16 +623,58 @@ function parse_variable_arg!(exprs, vs, dict, mod, arg, varclass, kwargs, where_
611
623
push! (exprs, ex)
612
624
end
613
625
626
+ function convert_units (varunits:: DynamicQuantities.Quantity , value)
627
+ DynamicQuantities. ustrip (DynamicQuantities. uconvert (
628
+ DynamicQuantities. SymbolicUnits. as_quantity (varunits), value))
629
+ end
630
+
631
+ function convert_units (
632
+ varunits:: DynamicQuantities.Quantity , value:: AbstractArray{T} ) where {T}
633
+ DynamicQuantities. ustrip .(DynamicQuantities. uconvert .(
634
+ DynamicQuantities. SymbolicUnits. as_quantity (varunits), value))
635
+ end
636
+
637
+ function convert_units (varunits:: Unitful.FreeUnits , value)
638
+ Unitful. ustrip (varunits, value)
639
+ end
640
+
641
+ function convert_units (varunits:: Unitful.FreeUnits , value:: AbstractArray{T} ) where {T}
642
+ Unitful. ustrip .(varunits, value)
643
+ end
644
+
614
645
function parse_variable_arg (dict, mod, arg, varclass, kwargs, where_types)
615
646
vv, def, metadata_with_exprs = parse_variable_def! (
616
647
dict, mod, arg, varclass, kwargs, where_types)
617
648
name = getname (vv)
618
649
619
- varexpr = quote
620
- $ name = if $ name === nothing
621
- $ setdefault ($ vv, $ def)
622
- else
623
- $ setdefault ($ vv, $ name)
650
+ varexpr = if haskey (metadata_with_exprs, VariableUnit)
651
+ unit = metadata_with_exprs[VariableUnit]
652
+ quote
653
+ $ name = if $ name === nothing
654
+ $ setdefault ($ vv, $ def)
655
+ else
656
+ try
657
+ $ setdefault ($ vv, $ convert_units ($ unit, $ name))
658
+ catch e
659
+ if isa (e, $ (DynamicQuantities. DimensionError)) ||
660
+ isa (e, $ (Unitful. DimensionError))
661
+ error (" Unable to convert units for \' " * string (:($$ vv)) * " \' " )
662
+ elseif isa (e, MethodError)
663
+ error (" No or invalid units provided for \' " * string (:($$ vv)) *
664
+ " \' " )
665
+ else
666
+ rethrow (e)
667
+ end
668
+ end
669
+ end
670
+ end
671
+ else
672
+ quote
673
+ $ name = if $ name === nothing
674
+ $ setdefault ($ vv, $ def)
675
+ else
676
+ $ setdefault ($ vv, $ name)
677
+ end
624
678
end
625
679
end
626
680
0 commit comments