Skip to content

Commit

Permalink
Escape in the macro (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tortar authored Sep 11, 2024
1 parent 1bac093 commit e0bf2c0
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 46 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "LightSumTypes"
uuid = "f56206fc-af4c-5561-a72a-43fe2ca5a923"
version = "4.0.1"
version = "4.0.2"

[deps]
ExprTools = "e2ba6199-217a-4e67-a87a-7c52f15ade04"
Expand Down
88 changes: 46 additions & 42 deletions src/LightSumTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ module LightSumTypes

using MacroTools: namify

export @sumtype, variant, variantof, allvariants, is_sumtype
export @sumtype, sumtype_expr, variant, variantof, allvariants, is_sumtype

unwrap(sumt) = getfield(sumt, :variants)

"""
@sumtype SumTypeName(Types) [<: AbstractType]
The macro creates a sumtypes composed by the given types.
Creates a sumtype composed by the given types.
It optionally accept also an abstract supertype.
## Example
Expand All @@ -25,11 +25,15 @@ julia> @sumtype AB(A, B)
```
"""
macro sumtype(typedef)
expr = _sumtype(typedef)
return expr
return esc(sumtype_expr(typedef))
end

function _sumtype(typedef)
"""
sumtype_expr(:(SumTypeName(Types) [<: AbstractType]))
Returns the expression evaluated by the @sumtype macro.
"""
function sumtype_expr(typedef)
if typedef.head === :call
abstract_type = :Any
type_with_variants = typedef
Expand Down Expand Up @@ -79,45 +83,45 @@ function _sumtype(typedef)
)
end

esc(quote
struct $type <: $(abstract_type)
variants::Union{$(variants...)}
$(constructors...)
end
$(constructors_extra...)
@inline function $Base.getproperty(sumt::$typename, s::Symbol)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, :(return $Base.getproperty(v, s)))...)
end
if any(ismutabletype(v) for v in [$((variants_bounded)...)])
@inline function $Base.setproperty!(sumt::$typename, s::Symbol, value)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, :(return $Base.setproperty!(v, s, value)))...)
end
end
function $Base.propertynames(sumt::$typename)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, :(return $Base.propertynames(v)))...)
end
function $Base.hasproperty(sumt::$typename, s::Symbol)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, :(return $Base.hasproperty(v, s)))...)
end
function $Base.copy(sumt::$typename)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, :(return $type(Base.copy(v))))...)
end
@inline $LightSumTypes.variant(sumt::$typename) = $LightSumTypes.unwrap(sumt)
@inline function $LightSumTypes.variant_idx(sumt::$typename)
quote
struct $type <: $(abstract_type)
variants::Union{$(variants...)}
$(constructors...)
end
$(constructors_extra...)
@inline function $Base.getproperty(sumt::$typename, s::Symbol)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, :(return $Base.getproperty(v, s)))...)
end
if any(ismutabletype(v) for v in [$((variants_bounded)...)])
@inline function $Base.setproperty!(sumt::$typename, s::Symbol, value)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, [:(return $i) for i in 1:length(variants)])...)
$(branchs(variants, variants_with_P, :(return $Base.setproperty!(v, s, value)))...)
end
$LightSumTypes.variantof(sumt::$typename) = typeof($LightSumTypes.variant(sumt))
$LightSumTypes.allvariants(sumt::Type{$typename}) = $(Expr(:tuple, (:($nv = $(v in variants_with_P ? namify(v) : v))
for (nv, v) in zip(variants_names, variants))...))
$LightSumTypes.is_sumtype(sumt::Type{$typename}) = true
nothing
end)
end
function $Base.propertynames(sumt::$typename)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, :(return $Base.propertynames(v)))...)
end
function $Base.hasproperty(sumt::$typename, s::Symbol)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, :(return $Base.hasproperty(v, s)))...)
end
function $Base.copy(sumt::$typename)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, :(return $type(Base.copy(v))))...)
end
@inline $LightSumTypes.variant(sumt::$typename) = $LightSumTypes.unwrap(sumt)
@inline function $LightSumTypes.variant_idx(sumt::$typename)
v = $LightSumTypes.unwrap(sumt)
$(branchs(variants, variants_with_P, [:(return $i) for i in 1:length(variants)])...)
end
$LightSumTypes.variantof(sumt::$typename) = typeof($LightSumTypes.variant(sumt))
$LightSumTypes.allvariants(sumt::Type{$typename}) = $(Expr(:tuple, (:($nv = $(v in variants_with_P ? namify(v) : v))
for (nv, v) in zip(variants_names, variants))...))
$LightSumTypes.is_sumtype(sumt::Type{$typename}) = true
nothing
end
end

function branchs(variants, variants_with_P, outputs)
Expand Down
6 changes: 3 additions & 3 deletions src/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ using PrecompileTools
struct C
z::Int
end
_sumtype(:(S(C)))
_sumtype(:(S{X}(A{X},C)))
_sumtype(:(S{X}(A{X},B{Int},C) <: AbstractS))
sumtype_expr(:(S(C)))
sumtype_expr(:(S{X}(A{X},C)))
sumtype_expr(:(S{X}(A{X},B{Int},C) <: AbstractS))
end
end

0 comments on commit e0bf2c0

Please sign in to comment.