Browse Source

Make asserts toggleable.

pull/19/head
Fredrik Ekre 2 years ago
parent
commit
8927fbcc63
No known key found for this signature in database
GPG Key ID: DE82E6D5E364C0A2
  1. 15
      src/Runic.jl
  2. 44
      src/ToggleableAsserts.jl
  3. 42
      src/chisels.jl

15
src/Runic.jl

@ -5,7 +5,7 @@ module Runic @@ -5,7 +5,7 @@ module Runic
using JuliaSyntax:
JuliaSyntax, @K_str, @KSet_str
# compat for const fields
# Julia compat for const struct fields
@eval macro $(Symbol("const"))(field)
if VERSION >= v"1.8.0-DEV.1148"
Expr(:const, esc(field))
@ -14,7 +14,8 @@ using JuliaSyntax: @@ -14,7 +14,8 @@ using JuliaSyntax:
end
end
include("chisel.jl")
# JuliaSyntax extensions and other utilities
include("chisels.jl")
# Return the result of expr if it doesn't evaluate to `nothing`
macro return_something(expr)
@ -33,6 +34,7 @@ mutable struct Context @@ -33,6 +34,7 @@ mutable struct Context
fmt_tree::Union{JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}, Nothing}
# User settings
verbose::Bool
assert::Bool
debug::Bool
# Current state
# node::Union{JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}, Nothing}
@ -41,14 +43,17 @@ mutable struct Context @@ -41,14 +43,17 @@ mutable struct Context
# parent::Union{JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}, Nothing}
end
function Context(src_str; debug::Bool = false, verbose::Bool = debug)
function Context(src_str; assert::Bool = true, debug::Bool = false, verbose::Bool = debug)
src_io = IOBuffer(src_str)
src_tree = JuliaSyntax.parseall(JuliaSyntax.GreenNode, src_str; ignore_warnings = true)
fmt_io = IOBuffer()
fmt_tree = nothing
# Debug mode enforces verbose and assert
verbose = debug ? true : verbose
assert = debug ? true : assert
return Context(
src_str, src_tree, src_io, fmt_io, fmt_tree, verbose, debug,
nothing, nothing,
src_str, src_tree, src_io, fmt_io, fmt_tree, verbose, assert, debug, nothing,
nothing,
)
end

44
src/ToggleableAsserts.jl

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
# SPDX-License-Identifier: MIT
# The code in this file is derived from the ToggleableAsserts.jl package
# (https://github.com/MasonProtter/ToggleableAsserts.jl) licensed under the MIT license.
# (https://github.com/MasonProtter/ToggleableAsserts.jl/blob/master/LICENSE):
# MIT License
#
# Copyright (c) 2021 Mason Protter
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
assert_enabled() = true
macro assert(expr)
code = macroexpand_assert(expr)
:(assert_enabled() ? $(code) : nothing)
end
const toggle_lock = ReentrantLock()
function enable_assert(enable::Bool)
@lock toggle_lock begin
if assert_enabled() != enable
@eval Runic assert_enabled() = $enable
end
end
end

42
src/chisel.jl → src/chisels.jl

@ -1,5 +1,42 @@ @@ -1,5 +1,42 @@
# SPDX-License-Identifier: MIT
##############
# Debug info #
##############
# @lock is defined but not exported in older Julia versions
if VERSION < v"1.7.0"
using Base: @lock
end
# Code derived from ToggleableAsserts.jl kept in a separate file
include("ToggleableAsserts.jl")
abstract type RunicException <: Exception end
struct AssertionError <: RunicException
msg::String
end
function Base.showerror(io::IO, err::AssertionError)
print(
io,
"Runic.AssertionError: `", err.msg, "`. This is unexpected, " *
"please file an issue with a reproducible example at " *
"https://github.com/fredrikekre/Runic.jl/issues/new.",
)
end
function macroexpand_assert(expr)
msg = string(expr)
return :($(esc(expr)) || throw(AssertionError($msg)))
end
##########################
# JuliaSyntax extensions #
##########################
function is_leaf(node::JuliaSyntax.GreenNode)
return !JuliaSyntax.haschildren(node)
end
@ -23,10 +60,13 @@ end @@ -23,10 +60,13 @@ end
function is_assignment(node::JuliaSyntax.GreenNode)
return JuliaSyntax.is_prec_assignment(node)
end
# Just like `JuliaSyntax.is_infix_op_call`, but also check that the node is K"call"
function is_infix_op_call(node::JuliaSyntax.GreenNode)
return JuliaSyntax.kind(node) === K"call" &&
JuliaSyntax.is_infix_op_call(node)
end
function infix_op_call_op(node::JuliaSyntax.GreenNode)
@assert is_infix_op_call(node)
children = JuliaSyntax.children(node)::AbstractVector
@ -34,9 +74,11 @@ function infix_op_call_op(node::JuliaSyntax.GreenNode) @@ -34,9 +74,11 @@ function infix_op_call_op(node::JuliaSyntax.GreenNode)
op_index = findnext(JuliaSyntax.is_operator, children, first_operand_index + 1)
return children[op_index]
end
function is_comparison_leaf(node::JuliaSyntax.GreenNode)
return is_leaf(node) && JuliaSyntax.is_prec_comparison(node)
end
function is_operator_leaf(node::JuliaSyntax.GreenNode)
return is_leaf(node) && JuliaSyntax.is_operator(node)
end
Loading…
Cancel
Save