Skip to content

Commit

Permalink
Immutable assignment support (#44)
Browse files Browse the repository at this point in the history
* Fixed build script
* Supporting MetaModelica assignment semantics
  • Loading branch information
JKRT committed Mar 21, 2020
1 parent ad3101b commit 475f93e
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 8 deletions.
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
ExportAll = "ad2082ca-a69e-11e9-38fa-e96309a31fe4"
ImmutableList = "4a558cac-c1ed-11e9-20da-3584bcd8709a"
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"

[compat]
julia = "1.1"
9 changes: 5 additions & 4 deletions src/MetaModelica.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module MetaModelica
import MacroTools
import MacroTools: @capture
import ExportAll
#=
import Setfield: @set!
import Setfield: @set
#=
Have to treat the types slightly different.
Precompilation of the types need to occur before everything else
=#
Expand All @@ -18,17 +20,16 @@ include("matchcontinue.jl")
include("functionInheritance.jl")
include("metaRuntime.jl")
include("shouldFail.jl")
include("utilityMacros.jl")

export @match, @matchcontinue, MatchFailure, ModelicaReal, ModelicaInteger
export @Uniontype, @Record, @UniontypeDecl, @ExtendedFunction, @ExtendedAnonFunction
export List, list, Nil, nil, Cons, cons, =>, Option, SOME, NONE, SourceInfo, SOURCEINFO
export @do_threaded_for, <|, @shouldFail, sourceInfo, _cons, @importDBG
export @assign

include("exportmetaRuntime.jl")
include("dangerous.jl")
include("array.jl")


#=============================#
end

9 changes: 5 additions & 4 deletions src/matchcontinue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
limitations under the License.
The code is based on https://github.com/RelationalAI-oss/Rematch.jl with
changed to allow keyword argument matching on a struct as well as
supporting @matchcontinue (try the next case when any exception is thrown).
"""
changed to allow keyword argument matching on a struct, matching on the immutable list construct
accompanying MetaModelica.
It also provides @matchcontinue macro (try the next case when any exception is thrown).
"""

include("fixLines.jl")

Expand Down Expand Up @@ -421,7 +422,7 @@ end
end
Return `result` for the first matching `pattern`. If there are no matches, throw `MatchFailure`.
"""
"""
macro match(value, cases)
res = handle_match_cases(value, cases ; mathcontinue = false)
replaceLineNum(res, @__FILE__, __source__)
Expand Down
35 changes: 35 additions & 0 deletions src/utilityMacros.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Setfield
"""
Helper function for the assignmacro, see @assign
We have one case where we assign a immutable structure to an immutable structure or something to a primitive variable.
If it is not a primitive we assign to a subcomponent of that structure. We then clone the structure with that particular field changed.
"""
function assignFunc(expr)
res = if @capture(expr, lhs_._= rhs_)
if !isprimitivetype(typeof(lhs))
Setfield.setmacro(identity, expr, overwrite=true)
else
quote
$(esc(expr))
end
end
else
quote
$(esc(expr))
end
end
return res
end

"""
This macro reimplements the MetaModelica assignment semantics using
setfield to assign to variables.
For assignments using primitives, the regular Julia assignment is generated.
For cases where deeply nested immutable structures are manipulated we use setfield
E.g.:
a.b.c = 5
Where a is a nested immutable struct
"""
macro assign(expr)
assignFunc(expr)
end
19 changes: 19 additions & 0 deletions test/runtimeTest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,24 @@ end
@test "AB" == "A" + "B"
end

@testset "Testing MetaModelica assignment semantics" begin
struct A
a
end
struct B
b
end
struct C
c
end
nested = A(B(C(1)))
@assign nested.a.b.c = 4
@test nested.a.b.c == 4
@assign a = 4
@test a == 4
@assign simple = 4
@test simple == 4
end

end #=End runtime tests=#
end #=End module=#

0 comments on commit 475f93e

Please sign in to comment.