Skip to content

Commit

Permalink
Better types for uniontypes
Browse files Browse the repository at this point in the history
  • Loading branch information
JKRT committed Jul 3, 2021
1 parent bbade82 commit ff4e145
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 8 deletions.
41 changes: 33 additions & 8 deletions src/union.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,24 +82,49 @@ function makeUniontypes(name, records, lineNode::LineNumberNode)
local block = r[2] #= Get the block. That is r[2]=#
blckExprs = block.args
varToDecl = Dict()
local i::Int = 0
local exprCounter::Int = 1
varToContainerDecl = Dict()
local i = 0
local cti = 0
for expr in blckExprs
if typeof(expr) === LineNumberNode #= Ignore comment lines =#
#= Skip comments =#
if typeof(expr) === LineNumberNode
continue
end
#= Ignore option types=#
if @capture(expr, T_::Option{TYPE_})
continue
end
#= Below is some better code for better type stability in uniontypes... =#
#= Check if we have a container type =#
if @capture(expr, T_::F_{TYPE_})
#= Keep abstract type as is=#
@assert expr.head === :(::)
containerType = expr.args[2]
#= Write to <Container>{<InnerType>} =#
res = @capture(containerType, OUTER_{INNER_})
#= Assert that the type is on this format =#
@assert res == true
#= containerType.args[2] = <:Any =#
local parametricType = Symbol("CT", cti)
varToContainerDecl[T] = [parametricType, INNER]
containerType.args[2] = parametricType
#= Write to the innermost type =#
cti += 1
continue
end
#= Check if we have a uniontype type declaration. =#
if (@capture(expr, T_::TYPE_))
parametricType::Symbol = Symbol("T", i)
varToDecl[T] = [parametricType, TYPE]
local parametricType = Symbol("T", i)
i += 1
varToDecl[T] = [parametricType, TYPE]
newExpr = expr
newExpr.args[2] = parametricType
end
exprCounter += 1
end
local structName = r[1]
parametricTypes::Vector{Expr} = [ :($(varToDecl[i][1]) <: $(varToDecl[i][2])) for i in keys(varToDecl)]
parametricTypes::Vector = [ :($(varToDecl[i][1]))
for i in keys(varToDecl)]
parametricContainerTypes::Vector = [ :($(varToContainerDecl[i][1]))
for i in keys(varToContainerDecl)]
recordNode = quote
struct $(structName){$(parametricTypes...)} <: $name
$(r[2])
Expand Down
70 changes: 70 additions & 0 deletions test/runtimeTest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,69 @@ end
@test length(arr) == 6
end

using MetaModelica
using Test
using Revise
@Uniontype Complex begin
@Record COMPLEX begin
r::ModelicaReal
i::ModelicaReal
end
@Record COMPLEX_INT begin
r::ModelicaInteger
i::ModelicaInteger
end
end

@Uniontype EvenMoreComplex begin
@Record EVENMORECOMPLEX begin
lst::List{Complex}
end
end

@Uniontype EvenMoreComplexVector begin
@Record EVENMORECOMPLEXVECTOR begin
lst::Vector{Complex}
end
end


@Uniontype InnerLists begin
@Record INNERLISTS begin
a::String
lst0::List{String}
lst1::List{String}
lst2::List{String}
end
end

@Uniontype InnerVectors begin
@Record INNERVECTORS begin
a::String
lst0::Vector{String}
lst1::Vector{String}
lst2::Vector{String}
end
end

@Uniontype Comment begin
@Record COMMENT begin
annotation_::Option{String}
comment::Option{String}
end
end

struct TEST2{T0 <: String}
lst0::Vector{T0}
lst1::Vector{T0}
lst2::Vector{T0}
end

struct TEST4{T0 <: String, T1 <: String, T2 <: String, T3 <: String}
a::T0
lst0::List{T1}
lst1::List{T2}
lst2::List{T3}
end

@testset "Complex structure test" begin
Expand All @@ -69,6 +127,18 @@ end
local L::List{Complex} = arrayList(A)
@test length(L) == 5
end
@testset "Test even more complex (Uniontype with abstract containers)" begin
a = COMPLEX(1., 2.)
tst = EVENMORECOMPLEX(list(a))
@test length(tst.lst) == 1
tst = EVENMORECOMPLEX(list(COMPLEX(1., 2.), COMPLEX_INT(1,1)))
@test length(tst.lst) == 2
tst = EVENMORECOMPLEXVECTOR([COMPLEX(1., 2.), COMPLEX(1., 2.)])
@test length(tst.lst) == 2
tst = INNERVECTORS("foo", ["FOO"], String[], String[])
tst = INNERLISTS("foo", list("FOO"), Nil{String}(), Nil{String}())
tst = COMMENT(NONE(), NONE())
end
end

@testset "Testing array copy" begin
Expand Down

0 comments on commit ff4e145

Please sign in to comment.