Skip to content

Commit 879b399

Browse files
committed
Clean up
1 parent 69f9907 commit 879b399

File tree

3 files changed

+236
-235
lines changed

3 files changed

+236
-235
lines changed

src/ModelingToolkit.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ include("utils.jl")
118118
include("domains.jl")
119119

120120
include("systems/abstractsystem.jl")
121+
include("systems/model_parsing.jl")
121122
include("systems/connectors.jl")
122123
include("systems/callbacks.jl")
123124

src/systems/connectors.jl

Lines changed: 0 additions & 235 deletions
Original file line numberDiff line numberDiff line change
@@ -10,241 +10,6 @@ macro connector(expr)
1010
esc(component_post_processing(expr, true))
1111
end
1212

13-
macro connector(name::Symbol, body)
14-
esc(connector_macro(__module__, name, body))
15-
end
16-
17-
struct Model{F, S}
18-
f::F
19-
structure::S
20-
end
21-
(m::Model)(args...; kw...) = m.f(args...; kw...)
22-
23-
using MLStyle
24-
function connector_macro(mod, name, body)
25-
if !Meta.isexpr(body, :block)
26-
err = """
27-
connector body must be a block! It should be in the form of
28-
```
29-
@connector Pin begin
30-
v(t) = 1
31-
(i(t) = 1), [connect = Flow]
32-
end
33-
```
34-
"""
35-
error(err)
36-
end
37-
vs = Num[]
38-
dict = Dict{Symbol, Any}()
39-
for arg in body.args
40-
arg isa LineNumberNode && continue
41-
push!(vs, Num(parse_variable_def!(dict, mod, arg, :variables)))
42-
end
43-
iv = get(dict, :independent_variable, nothing)
44-
if iv === nothing
45-
error("$name doesn't have a independent variable")
46-
end
47-
quote
48-
$name = $Model((; name) -> begin
49-
var"#___sys___" = $ODESystem($(Equation[]), $iv, $vs, $([]);
50-
name)
51-
$Setfield.@set!(var"#___sys___".connector_type=$connector_type(var"#___sys___"))
52-
end, $dict)
53-
end
54-
end
55-
56-
function parse_variable_def!(dict, mod, arg, varclass)
57-
MLStyle.@match arg begin
58-
::Symbol => generate_var!(dict, arg, varclass)
59-
Expr(:call, a, b) => generate_var!(dict, a, b, varclass)
60-
Expr(:(=), a, b) => begin
61-
var = parse_variable_def!(dict, mod, a, varclass)
62-
def = parse_default(mod, b)
63-
dict[varclass][getname(var)][:default] = def
64-
setdefault(var, def)
65-
end
66-
Expr(:tuple, a, b) => begin
67-
var = parse_variable_def!(dict, mod, a, varclass)
68-
meta = parse_metadata(mod, b)
69-
if (ct = get(meta, VariableConnectType, nothing)) !== nothing
70-
dict[varclass][getname(var)][:connection_type] = nameof(ct)
71-
end
72-
set_var_metadata(var, meta)
73-
end
74-
_ => error("$arg cannot be parsed")
75-
end
76-
end
77-
78-
function generate_var(a, varclass)
79-
var = Symbolics.variable(a)
80-
if varclass == :parameters
81-
var = toparam(var)
82-
end
83-
var
84-
end
85-
function generate_var!(dict, a, varclass)
86-
var = generate_var(a, varclass)
87-
vd = get!(dict, varclass) do
88-
Dict{Symbol, Dict{Symbol, Any}}()
89-
end
90-
vd[a] = Dict{Symbol, Any}()
91-
var
92-
end
93-
function generate_var!(dict, a, b, varclass)
94-
iv = generate_var(b, :variables)
95-
prev_iv = get!(dict, :independent_variable) do
96-
iv
97-
end
98-
@assert isequal(iv, prev_iv)
99-
vd = get!(dict, varclass) do
100-
Dict{Symbol, Dict{Symbol, Any}}()
101-
end
102-
vd[a] = Dict{Symbol, Any}()
103-
var = Symbolics.variable(a, T = SymbolicUtils.FnType{Tuple{Real}, Real})(iv)
104-
if varclass == :parameters
105-
var = toparam(var)
106-
end
107-
var
108-
end
109-
function parse_default(mod, a)
110-
a = Base.remove_linenums!(deepcopy(a))
111-
MLStyle.@match a begin
112-
Expr(:block, a) => get_var(mod, a)
113-
::Symbol => get_var(mod, a)
114-
::Number => a
115-
_ => error("Cannot parse default $a")
116-
end
117-
end
118-
function parse_metadata(mod, a)
119-
MLStyle.@match a begin
120-
Expr(:vect, eles...) => Dict(parse_metadata(mod, e) for e in eles)
121-
Expr(:(=), a, b) => Symbolics.option_to_metadata_type(Val(a)) => get_var(mod, b)
122-
_ => error("Cannot parse metadata $a")
123-
end
124-
end
125-
function set_var_metadata(a, ms)
126-
for (m, v) in ms
127-
a = setmetadata(a, m, v)
128-
end
129-
a
130-
end
131-
function get_var(mod::Module, b)
132-
b isa Symbol ? getproperty(mod, b) : b
133-
end
134-
macro model(name::Symbol, expr)
135-
esc(model_macro(__module__, name, expr))
136-
end
137-
function model_macro(mod, name, expr)
138-
exprs = Expr(:block)
139-
dict = Dict{Symbol, Any}()
140-
comps = Symbol[]
141-
ext = Ref{Any}(nothing)
142-
vs = Symbol[]
143-
ps = Symbol[]
144-
eqs = Expr[]
145-
for arg in expr.args
146-
arg isa LineNumberNode && continue
147-
arg.head == :macrocall || error("$arg is not valid syntax. Expected a macro call.")
148-
parse_model!(exprs.args, comps, ext, eqs, vs, ps, dict, mod, arg)
149-
end
150-
iv = get(dict, :independent_variable, nothing)
151-
if iv === nothing
152-
iv = dict[:independent_variable] = variable(:t)
153-
end
154-
sys = :($ODESystem($Equation[$(eqs...)], $iv, [$(vs...)], [$(ps...)];
155-
systems = [$(comps...)], name))
156-
if ext[] === nothing
157-
push!(exprs.args, sys)
158-
else
159-
push!(exprs.args, :($extend($sys, $(ext[]))))
160-
end
161-
:($name = $Model((; name) -> $exprs, $dict))
162-
end
163-
function parse_model!(exprs, comps, ext, eqs, vs, ps, dict, mod, arg)
164-
mname = arg.args[1]
165-
body = arg.args[end]
166-
if mname == Symbol("@components")
167-
parse_components!(exprs, comps, dict, body)
168-
elseif mname == Symbol("@extend")
169-
parse_extend!(exprs, ext, dict, body)
170-
elseif mname == Symbol("@variables")
171-
parse_variables!(exprs, vs, dict, mod, body, :variables)
172-
elseif mname == Symbol("@parameters")
173-
parse_variables!(exprs, ps, dict, mod, body, :parameters)
174-
elseif mname == Symbol("@equations")
175-
parse_equations!(exprs, eqs, dict, body)
176-
else
177-
error("$mname is not handled.")
178-
end
179-
end
180-
function parse_components!(exprs, cs, dict, body)
181-
expr = Expr(:block)
182-
push!(exprs, expr)
183-
comps = Vector{String}[]
184-
for arg in body.args
185-
arg isa LineNumberNode && continue
186-
MLStyle.@match arg begin
187-
Expr(:(=), a, b) => begin
188-
push!(cs, a)
189-
push!(comps, [String(a), String(b.args[1])])
190-
arg = deepcopy(arg)
191-
b = deepcopy(arg.args[2])
192-
push!(b.args, Expr(:kw, :name, Meta.quot(a)))
193-
arg.args[2] = b
194-
push!(expr.args, arg)
195-
end
196-
_ => error("`@components` only takes assignment expressions. Got $arg")
197-
end
198-
end
199-
dict[:components] = comps
200-
end
201-
function parse_extend!(exprs, ext, dict, body)
202-
expr = Expr(:block)
203-
push!(exprs, expr)
204-
body = deepcopy(body)
205-
MLStyle.@match body begin
206-
Expr(:(=), a, b) => begin
207-
vars = nothing
208-
if Meta.isexpr(b, :(=))
209-
vars = a
210-
if !Meta.isexpr(vars, :tuple)
211-
error("`@extend` destructuring only takes an tuple as LHS. Got $body")
212-
end
213-
a, b = b.args
214-
vars, a, b
215-
end
216-
ext[] = a
217-
push!(b.args, Expr(:kw, :name, Meta.quot(a)))
218-
dict[:extend] = [Symbol.(vars.args), a, readable_code(b)]
219-
push!(expr.args, :($a = $b))
220-
if vars !== nothing
221-
push!(expr.args, :(@unpack $vars = $a))
222-
end
223-
end
224-
_ => error("`@extend` only takes an assignment expression. Got $body")
225-
end
226-
end
227-
function parse_variables!(exprs, vs, dict, mod, body, varclass)
228-
expr = Expr(:block)
229-
push!(exprs, expr)
230-
for arg in body.args
231-
arg isa LineNumberNode && continue
232-
vv = parse_variable_def!(dict, mod, arg, varclass)
233-
v = Num(vv)
234-
name = getname(v)
235-
push!(vs, name)
236-
push!(expr.args, :($name = $v))
237-
end
238-
end
239-
function parse_equations!(exprs, eqs, dict, body)
240-
for arg in body.args
241-
arg isa LineNumberNode && continue
242-
push!(eqs, arg)
243-
end
244-
# TODO: does this work with TOML?
245-
dict[:equations] = readable_code.(eqs)
246-
end
247-
24813
abstract type AbstractConnectorType end
24914
struct StreamConnector <: AbstractConnectorType end
25015
struct RegularConnector <: AbstractConnectorType end

0 commit comments

Comments
 (0)