|
18 | 18 |
|
19 | 19 | # Checks if an expression is an escaped expression (e.g. on the form `$(Expr(:escape, :Y))`)
|
20 | 20 | function is_escaped_expr(expr)
|
21 |
| - return (expr isa Expr) && (expr.head == :escape) && (length(expr.args) == 1) |
| 21 | + return Meta.isexpr(expr, :escape) && (length(expr.args) == 1) |
22 | 22 | end
|
23 | 23 |
|
24 | 24 | ### Parameters/Species/Variables Symbols Correctness Checking ###
|
@@ -52,52 +52,48 @@ function option_block_form(expr)
|
52 | 52 | return Expr(:block, expr)
|
53 | 53 | end
|
54 | 54 |
|
55 |
| -# In variable/species/parameters on the forms like: |
| 55 | +# In variable/species/parameters on the forms like (examples, 16 alternatives in total): |
56 | 56 | # X
|
57 |
| -# X = 1.0 |
58 |
| -# X, [metadata=true] |
59 |
| -# X = 1.0, [metadata=true] |
60 |
| -# X(t) |
61 |
| -# X(t) = 1.0 |
62 |
| -# X(t), [metadata=true] |
63 |
| -# X(t) = 1.0, [metadata=true] |
64 |
| -# Finds the: Variable name (X), Independent variable name(s) ([t]), default value (2.0), and metadata (:([metadata=true])). |
65 |
| -# If a field does not exist (e.g. independent variable in `X, [metadata=true]`), gives nothing. |
66 |
| -# The independent variables are given as a vector (empty if none given). |
67 |
| -# Does not support e.g. "X [metadata=true]" (when metadata does not have a comma before). |
68 |
| -function find_varinfo_in_declaration(expr) |
69 |
| - # Handles the $(Expr(:escape, :Y)) case: |
70 |
| - is_escaped_expr(expr) && (return find_varinfo_in_declaration(expr.args[1])) |
| 57 | +# X = 1.0, [misc=5] |
| 58 | +# X(t)[1:2] |
| 59 | +# X(t) = 1.0, [misc=5] |
| 60 | +# X(t)[1:2] = 1.0, [misc = 5] |
| 61 | +# Finds the: Variable name (X), Independent variable name(s) ([t]), indexes (1:2), |
| 62 | +# default value (1.0), and metadata (:([metadata=true])). |
| 63 | +# Information that does not exist (e.g. independent variable in `X, [metadata=true]`), is |
| 64 | +# returned as `nothing`. |
| 65 | +# The independent variables are returned as a vector (empty if none given). |
| 66 | +function find_varinfo_in_declaration(expr::ExprValues) |
| 67 | + # Initialises values. Step by step, reads one and scales it away from the expression |
| 68 | + metadata = default = idxs = ivs = nothing |
71 | 69 |
|
72 |
| - # Case: X |
73 |
| - (expr isa Symbol) && (return expr, [], nothing, nothing) |
74 |
| - # Case: X(t) |
75 |
| - (expr.head == :call) && (return expr.args[1], expr.args[2:end], nothing, nothing) |
76 |
| - if expr.head == :(=) |
77 |
| - # Case: X = 1.0 |
78 |
| - (expr.args[1] isa Symbol) && (return expr.args[1], [], expr.args[2], nothing) |
79 |
| - # Case: X(t) = 1.0 |
80 |
| - (expr.args[1].head == :call) && |
81 |
| - (return expr.args[1].args[1], expr.args[1].args[2:end], expr.args[2].args[1], |
82 |
| - nothing) |
| 70 | + # Reads and removes metadata (e.g. `[misc = 5]` in `:(X(t)[1:2] = 1.0, [misc = 5])`). |
| 71 | + if Meta.isexpr(expr, :tuple) |
| 72 | + metadata = expr.args[2] |
| 73 | + expr = expr.args[1] |
83 | 74 | end
|
84 |
| - if expr.head == :tuple |
85 |
| - # Case: X, [metadata=true] |
86 |
| - (expr.args[1] isa Symbol) && (return expr.args[1], [], nothing, expr.args[2]) |
87 |
| - # Case: X(t), [metadata=true] |
88 |
| - (expr.args[1].head == :call) && |
89 |
| - (return expr.args[1].args[1], expr.args[1].args[2:end], nothing, expr.args[2]) |
90 |
| - if expr.args[1].head == :(=) |
91 |
| - # Case: X = 1.0, [metadata=true] |
92 |
| - (expr.args[1].args[1] isa Symbol) && |
93 |
| - (return expr.args[1].args[1], [], expr.args[1].args[2], expr.args[2]) |
94 |
| - # Case: X(t) = 1.0, [metadata=true] |
95 |
| - (expr.args[1].args[1].head == :call) && |
96 |
| - (return expr.args[1].args[1].args[1], expr.args[1].args[1].args[2:end], |
97 |
| - expr.args[1].args[2].args[1], expr.args[2]) |
98 |
| - end |
| 75 | + # Reads and removes metadata (e.g. `1.0` in `:(X(t)[1:2] = 1.0)`). |
| 76 | + if Meta.isexpr(expr, :(=)) |
| 77 | + default = expr.args[2] |
| 78 | + expr = expr.args[1] |
99 | 79 | end
|
100 |
| - error("Unable to detect the variable declared in expression: $expr.") |
| 80 | + # Reads and removes indexes (e.g. `[1:2]` in `:(X(t)[1:2])`). |
| 81 | + if Meta.isexpr(expr, :ref) |
| 82 | + idxs = expr.args[2] |
| 83 | + expr = expr.args[1] |
| 84 | + end |
| 85 | + # Reads and removes independent variables (e.g. `t` in `:(X(t))`). |
| 86 | + if Meta.isexpr(expr, :call) |
| 87 | + ivs = expr.args[2:end] |
| 88 | + expr = expr.args[1] |
| 89 | + end |
| 90 | + isnothing(ivs) && (ivs = []) |
| 91 | + |
| 92 | + # If escaped expression, extract symbol. Checks that the expression is a symbol (e.g. `X` in `:(X(t))`). |
| 93 | + Meta.isexpr(expr, :escape) && (expr = expr.args[1]) |
| 94 | + (expr isa Symbol) || |
| 95 | + error("Erroneous expression encountered in `find_varinfo_in_declaration` (got `$expr` after processing, this should be a symbol).") |
| 96 | + return (;sym = expr, ivs, idxs, default, metadata) |
101 | 97 | end
|
102 | 98 |
|
103 | 99 | # Converts an expression of the forms:
|
|
0 commit comments