@@ -3,11 +3,14 @@ Julia expression wrapper
33"""
44struct Expression
55 expr:: Expr
6- syms:: Vector{Symbol}
6+ syms:: Dict{Symbol,Int}
7+ end
8+ function Expression (ex:: Expr )
9+ syms = Dict ( s=> i for (i,s) in pairs (sort! (symbols (ex))) )
10+ Expression (ex, syms)
711end
8- Expression (ex:: Expr ) = Expression (ex, sort! (symbols (ex)))
912show (io:: IO , e:: Expression ) = infix (io, e. expr)
10- (e:: Expression )(val) = evaluate (val, e. expr, e. syms)
13+ (e:: Expression )(vals :: T... ) where {T} = evaluate (e. expr, e. syms, vals ... )
1114
1215function symbols (ex:: Expr )
1316 syms = Symbol[]
@@ -18,6 +21,11 @@ function symbols(ex::Expr)
1821 unique! (syms)
1922end
2023
24+ function compile (ex:: Expr , params:: Vector{Symbol} )
25+ tprm = Expr (:tuple , params... )
26+ Expr (:-> , tprm, ex)
27+ end
28+
2129height (ex) = isa (ex, Expr) ? maximum ( height (e) for e in ex. args )+ 1 : 0
2230nodes (ex) = ! isa (ex, Expr) ? 1 : length (ex. args) > 0 ? sum ( nodes (e) for e in ex. args ) : 0
2331length (ex) = nodes (ex)
@@ -79,15 +87,18 @@ isdiv(ex) = ex in [/, div, pdiv, aq]
7987isexpr (ex) = isa (ex, Expr)
8088issym (ex) = isa (ex, Symbol)
8189
82- function evaluate (val, ex:: Expr , psyms:: Vector {Symbol} )
90+ function evaluate (ex:: Expr , psyms:: Dict {Symbol,Int} , vals :: T... ) :: T where {T}
8391 exprm = ex. args
84- exvals = (isexpr (nex) || issym (nex) ? evaluate (val, nex, psyms) : nex for nex in exprm[2 : end ])
92+ exvals = (isexpr (nex) || issym (nex) ? evaluate (nex, psyms, vals ... ) : nex for nex in exprm[2 : end ])
8593 exprm[1 ](exvals... )
8694end
8795
88- function evaluate (val, ex:: Symbol , psyms:: Vector{Symbol} )
89- pidx = findfirst (isequal (ex), psyms)
90- val[pidx]
96+ function evaluate (ex:: Symbol , psyms:: Dict{Symbol,Int} , vals:: T... ):: T where {T}
97+ pidx = get (psyms, ex, 0 )
98+ if pidx == 0
99+ @error " Undefined symbol: $ex "
100+ end
101+ return T (vals[pidx])
91102end
92103
93104
@@ -114,9 +125,9 @@ function simplifybinary!(root)
114125 root = 1
115126 elseif (fn == (* ) || isdiv (fn)) && (iszeronum (op1) || iszeronum (op2)) # look for 0: x*0 = 0*x = 0
116127 root = 0
117- elseif (fn == (+ ) || fn == (- )) && iszeronum (op2) # look for 0: x ± 0 = 0
128+ elseif (fn == (+ ) || fn == (- )) && iszeronum (op2) # look for 0: x ± 0 = x
118129 root = op1
119- elseif fn == (+ ) && iszeronum (op1) # look for 0: 0 ± x = 0
130+ elseif fn == (+ ) && iszeronum (op1) # look for 0: 0 + x = x
120131 root = op2
121132 elseif (fn == (* ) || isdiv (fn)) && isonenum (op2) # x*1 = x || x/1 = x
122133 root = op1
0 commit comments