Skip to content

Commit

Permalink
Add validator convenience function
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobnissen committed Jul 21, 2022
1 parent 8470f31 commit 6114823
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/codegen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,32 @@ end

const DefaultCodeGenContext = CodeGenContext()

"""
generate_validator_function(name::Symbol, machine::Machine, goto=false)
Generate code that, when evaluated, defines a function named `name`, which takes a
single argument `data`, interpreted as a sequence of bytes.
The function returns `nothing` if `data` matches `Machine`, else the index of the first
invalid byte. If the machine reached unexpected EOF, returns `sizeof(data) + 1`.
If `goto`, the function uses the faster but more complicated `:goto` code.
"""
function generate_validator_function(name::Symbol, machine::Machine, goto::Bool=false)
ctx = goto ? CodeGenContext(generator=:goto) : DefaultCodeGenContext
return quote
"""
$($(name))(data)::Union{Int, Nothing}
Checks if `data`, interpreted as a bytearray, conforms to the given `Automa.Machine`.
Returns `nothing` if it does, else the byte index of the first invalid byte.
If the machine reached unexpected EOF, returns `sizeof(data) + 1`.
"""
function $(name)(data)
$(generate_code(ctx, machine))
iszero(cs) ? nothing : p
end
end
end

"""
generate_code([::CodeGenContext], machine::Machine, actions=nothing)::Expr
Expand Down
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ include("test17.jl")
include("test18.jl")
include("simd.jl")
include("unicode.jl")
include("validator.jl")

module TestFASTA
using Test
Expand Down
36 changes: 36 additions & 0 deletions test/validator.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module Validator

import Automa
import Automa.RegExp: @re_str
using Test

@testset "Validator" begin
machine = let
Automa.compile(re"a(bc)*|(def)|x+" | re"def" | re"x+")
end
eval(Automa.generate_validator_function(:foobar, machine, false))
eval(Automa.generate_validator_function(:barfoo, machine, true))

for good_data in [
"def"
"abc"
"abcbcbcbcbc"
"x"
"xxxxxx"
]
@test foobar(good_data) === barfoo(good_data) === nothing
end

for bad_data in [
"",
"abcabc",
"abcbb",
"abcbcb",
"defdef",
"xabc"
]
@test foobar(bad_data) === barfoo(bad_data) !== nothing
end
end

end # module

0 comments on commit 6114823

Please sign in to comment.