From 548c3c6b83cfc85c3b2836c67cc7c36b2d31abbe Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Sun, 7 Jun 2020 02:49:56 -0400 Subject: [PATCH 1/3] WIP generalize Fix1 Fix2 --- base/operators.jl | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/base/operators.jl b/base/operators.jl index 605c0775ad00f..3b7fa653a38f1 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -913,6 +913,7 @@ julia> filter(!isletter, str) """ !(f::Function) = (x...)->!f(x...) +#= """ Fix1(f, x) @@ -946,6 +947,48 @@ struct Fix2{F,T} <: Function end (f::Fix2)(y) = f.f(y, f.x) +=# + + +interleave(bind::Tuple{}, args::Tuple{}) = () +interleave(bind::Tuple{}, args::Tuple) = error("more args than positions") +interleave(bind, args) = _interleave(first(bind), tail(bind), args) + +# `nothing` indicates a position to be bound +_interleave(firstbind::Nothing, tailbind::Tuple, args::Tuple) = ( + first(args), interleave(tailbind, tail(args))...) + +# allow escaping of e.g. `nothing` +_interleave(firstbind::Some{T}, tailbind::Tuple, args::Tuple) where T = ( + something(firstbind), interleave(tailbind, args)...) + +_interleave(firstbind::T, tailbind::Tuple, args::Tuple) where T = ( + firstbind, interleave(tailbind, args)...) + +struct Bind{F, A} + f::F + a::A +end + +function (c::Bind)(args...) + c.f(interleave(c.a, args)...) +end + +c = Bind(==, (3, nothing)) +isnothing2 = Bind(===, (Some(nothing), nothing)) + +const Fix1{F, X} = Bind{F, Tuple{Some{X}, Nothing}} +const Fix2{F, X} = Bind{F, Tuple{Nothing, Some{X}}} +Fix1(f, x) = Bind(f, (Some(x), nothing)) +Fix2(f, x) = Bind(f, (nothing, Some(x))) + +Base.getproperty(f::Fix1, s::Symbol) = s === :x ? something(f.a[1]) : getfield(f, s) +Base.getproperty(f::Fix2, s::Symbol) = s === :x ? something(f.a[2]) : getfield(f, s) + + + + + """ isequal(x) From 7c5a800d733ea531813c130007fcd09b064ee0db Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Sun, 7 Jun 2020 18:05:33 +0200 Subject: [PATCH 2/3] Try to bootstrap --- base/Base.jl | 10 ++++++++-- base/compiler/compiler.jl | 3 +++ base/operators.jl | 12 ++---------- base/strings/search.jl | 12 ++++++------ 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/base/Base.jl b/base/Base.jl index 777e07bd30715..0a8669a1e9450 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -83,11 +83,19 @@ include("traits.jl") include("range.jl") include("error.jl") +# Some type +include("some.jl") + # core numeric operations & types include("bool.jl") include("number.jl") include("int.jl") include("operators.jl") + +# The following definitions are not in `operators.jl` so they are not seen by bootstrapping (`compiler.jl`) +getproperty(f::Fix1, s::Symbol) = s === :x ? getx(f) : getfield(f, s) +getproperty(f::Fix2, s::Symbol) = s === :x ? getx(f) : getfield(f, s) + include("pointer.jl") include("refvalue.jl") include("refpointer.jl") @@ -149,8 +157,6 @@ end include("multimedia.jl") using .Multimedia -# Some type -include("some.jl") include("dict.jl") include("abstractset.jl") diff --git a/base/compiler/compiler.jl b/base/compiler/compiler.jl index 873ce764bccbf..17cd1850c0fc8 100644 --- a/base/compiler/compiler.jl +++ b/base/compiler/compiler.jl @@ -40,6 +40,9 @@ include("range.jl") include("expr.jl") include("error.jl") +# Some type +include("some.jl") + # core numeric operations & types include("bool.jl") include("number.jl") diff --git a/base/operators.jl b/base/operators.jl index 3b7fa653a38f1..92e79bee43129 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -949,7 +949,6 @@ end (f::Fix2)(y) = f.f(y, f.x) =# - interleave(bind::Tuple{}, args::Tuple{}) = () interleave(bind::Tuple{}, args::Tuple) = error("more args than positions") interleave(bind, args) = _interleave(first(bind), tail(bind), args) @@ -974,20 +973,13 @@ function (c::Bind)(args...) c.f(interleave(c.a, args)...) end -c = Bind(==, (3, nothing)) -isnothing2 = Bind(===, (Some(nothing), nothing)) - const Fix1{F, X} = Bind{F, Tuple{Some{X}, Nothing}} const Fix2{F, X} = Bind{F, Tuple{Nothing, Some{X}}} Fix1(f, x) = Bind(f, (Some(x), nothing)) Fix2(f, x) = Bind(f, (nothing, Some(x))) -Base.getproperty(f::Fix1, s::Symbol) = s === :x ? something(f.a[1]) : getfield(f, s) -Base.getproperty(f::Fix2, s::Symbol) = s === :x ? something(f.a[2]) : getfield(f, s) - - - - +getx(f::Fix1) = something(f.a[1]) +getx(f::Fix2) = something(f.a[2]) """ diff --git a/base/strings/search.jl b/base/strings/search.jl index 9d2fdf73afff4..9dea295a9d0bf 100644 --- a/base/strings/search.jl +++ b/base/strings/search.jl @@ -9,7 +9,7 @@ function findnext(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:AbstractChar} throw(BoundsError(s, i)) end @inbounds isvalid(s, i) || string_index_err(s, i) - c = pred.x + c = getx(pred) c ≤ '\x7f' && return nothing_sentinel(_search(s, c % UInt8, i)) while true i = _search(s, first_utf8_byte(c), i) @@ -20,10 +20,10 @@ function findnext(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:AbstractChar} end findfirst(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:Union{Int8,UInt8}}, a::ByteArray) = - nothing_sentinel(_search(a, pred.x)) + nothing_sentinel(_search(a, getx(pred))) findnext(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:Union{Int8,UInt8}}, a::ByteArray, i::Integer) = - nothing_sentinel(_search(a, pred.x, i)) + nothing_sentinel(_search(a, getx(pred), i)) function _search(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = 1) if i < 1 @@ -48,7 +48,7 @@ end function findprev(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:AbstractChar}, s::String, i::Integer) - c = pred.x + c = getx(pred) c ≤ '\x7f' && return nothing_sentinel(_rsearch(s, c % UInt8, i)) b = first_utf8_byte(c) while true @@ -60,10 +60,10 @@ function findprev(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:AbstractChar} end findlast(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:Union{Int8,UInt8}}, a::ByteArray) = - nothing_sentinel(_rsearch(a, pred.x)) + nothing_sentinel(_rsearch(a, getx(pred))) findprev(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:Union{Int8,UInt8}}, a::ByteArray, i::Integer) = - nothing_sentinel(_rsearch(a, pred.x, i)) + nothing_sentinel(_rsearch(a, getx(pred), i)) function _rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = sizeof(a)) if i < 1 From 766beae606156a42970bee28c35ec2939b96cbd3 Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Mon, 8 Jun 2020 07:34:55 +0200 Subject: [PATCH 3/3] Update base/operators.jl Co-authored-by: Takafumi Arakaki --- base/operators.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/operators.jl b/base/operators.jl index 92e79bee43129..8cd1df2dc9860 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -964,7 +964,7 @@ _interleave(firstbind::Some{T}, tailbind::Tuple, args::Tuple) where T = ( _interleave(firstbind::T, tailbind::Tuple, args::Tuple) where T = ( firstbind, interleave(tailbind, args)...) -struct Bind{F, A} +struct Bind{F, A} <: Function f::F a::A end