Skip to content

Commit 73daad1

Browse files
feat: add function to parse variable from string
1 parent f284c3f commit 73daad1

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

src/systems/abstractsystem.jl

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3285,6 +3285,79 @@ function dump_unknowns(sys::AbstractSystem)
32853285
end
32863286
end
32873287

3288+
# syntax:
3289+
# varname = "D(" varname ")" | arrvar | maybe_dummy_var
3290+
# arrvar = maybe_dummy_var "[idxs...]"
3291+
# idxs = int | int "," idxs
3292+
# maybe_dummy_var = namespacedvar | namespacedvar "(t)" |
3293+
# namespacedvar "(t)" "ˍ" ts | namespacedvar "ˍ" ts |
3294+
# namespacedvar "ˍ" ts "(t)"
3295+
# ts = "t" | "t" ts
3296+
# namespacedvar = ident "₊" namespacedvar | ident "." namespacedvar | ident
3297+
#
3298+
# I'd write a regex to validate this, but https://xkcd.com/1171/
3299+
function parse_variable(sys::AbstractSystem, str::AbstractString)
3300+
str = strip(str)
3301+
derivative_level = 0
3302+
while startswith(str, "D(") && endswith(str, ")")
3303+
derivative_level += 1
3304+
str = _string_view_inner(str, 2, 1)
3305+
end
3306+
3307+
arr_idxs = nothing
3308+
if endswith(str, ']')
3309+
open_idx = only(findfirst('[', str))
3310+
idxs_range = nextind(str, open_idx):prevind(str, lastindex(str))
3311+
idxs_str = view(str, idxs_range)
3312+
str = view(str, firstindex(str):prevind(str, open_idx))
3313+
arr_idxs = map(Base.Fix1(parse, Int), eachsplit(idxs_str, ","))
3314+
end
3315+
3316+
if endswith(str, "(t)")
3317+
str = _string_view_inner(str, 0, 3)
3318+
end
3319+
3320+
dummyderivative_level = 0
3321+
if (dd_idx = findfirst('ˍ', str)) !== nothing
3322+
t_idx = nextind(str, dd_idx)
3323+
while checkbounds(Bool, str, t_idx)
3324+
if str[t_idx] != 't'
3325+
throw(ArgumentError("Dummy derivative must be 'ˍ' followed by one or more 't'."))
3326+
end
3327+
dummyderivative_level += 1
3328+
t_idx = nextind(str, t_idx)
3329+
end
3330+
str = view(str, firstindex(str):prevind(str, dd_idx))
3331+
end
3332+
3333+
if endswith(str, "(t)")
3334+
str = _string_view_inner(str, 0, 3)
3335+
end
3336+
3337+
cur = sys
3338+
for ident in eachsplit(str, ('.', NAMESPACE_SEPARATOR))
3339+
ident = Symbol(ident)
3340+
hasproperty(cur, ident) ||
3341+
throw(ArgumentError("System $(nameof(cur)) does not have a subsystem/variable named $(ident)"))
3342+
cur = getproperty(cur, ident)
3343+
end
3344+
3345+
if arr_idxs !== nothing
3346+
cur = cur[arr_idxs...]
3347+
end
3348+
3349+
for i in 1:(derivative_level + dummyderivative_level)
3350+
cur = Differential(get_iv(sys))(cur)
3351+
end
3352+
3353+
return cur
3354+
end
3355+
3356+
function _string_view_inner(str, startoffset, endoffset)
3357+
view(str,
3358+
nextind(str, firstindex(str), startoffset):prevind(str, lastindex(str), endoffset))
3359+
end
3360+
32883361
### Functions for accessing algebraic/differential equations in systems ###
32893362

32903363
"""

0 commit comments

Comments
 (0)