mollusk 0e4acfb8f2 fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
2018-06-11 03:28:36 -07:00

83 lines
1.8 KiB
Julia

# This file is a part of Julia. License is MIT: https://julialang.org/license
const InnerConfig = Dict{Char, Vector{Function}}
mutable struct Config
breaking::Vector{Function}
regular::Vector{Function}
inner::InnerConfig
end
Config() = Config(Function[], Function[], InnerConfig())
const META = Dict{Function, Dict{Symbol, Any}}()
getset(coll, key, default) = coll[key] = get(coll, key, default)
meta(f) = getset(META, f, Dict{Symbol, Any}())
breaking!(f) = meta(f)[:breaking] = true
breaking(f) = get(meta(f), :breaking, false)
triggers!(f, ts) = meta(f)[:triggers] = Set{Char}(ts)
triggers(f) = get(meta(f), :triggers, Set{Char}())
# Macros
isexpr(x::Expr, ts...) = x.head in ts
isexpr(x::T, ts...) where {T} = T in ts
macro breaking(ex)
isexpr(ex, :->) || error("invalid @breaking form, use ->")
b, def = ex.args
if b
quote
f = $(esc(def))
breaking!(f)
f
end
else
esc(def)
end
end
macro trigger(ex)
isexpr(ex, :->) || error("invalid @triggers form, use ->")
ts, def = ex.args
quote
f = $(esc(def))
triggers!(f, $ts)
f
end
end
# Construction
function config(parsers::Function...)
c = Config()
for parser in parsers
ts = triggers(parser)
if breaking(parser)
push!(c.breaking, parser)
elseif !isempty(ts)
for t in ts
push!(getset(c.inner, t, Function[]), parser)
end
else
push!(c.regular, parser)
end
end
return c
end
# Flavour definitions
const flavors = Dict{Symbol, Config}()
macro flavor(name, features)
quote
const $(esc(name)) = config($(map(esc,features.args)...))
flavors[$(Expr(:quote, name))] = $(esc(name))
end
end