Replacing Macros With Function Calls

Argus defines a domain-specific language for working with patterns, rules and other syntactic constructs. This is by design, to aid with readability and expressivity. However, almost all Argus structures can be defined using constructors and function calls.

@pattern expr is equivalent to Pattern(:( expr )).

@define_syntax_class :name "description" begin
    pattern1
    pattern2
end

is equivalent to

sc = SyntaxClass("description", [pattern1, pattern2])
register_syntax_class!(:name, sc)
@rule "rule-name" begin
    description = descr,
    pattern = patt,
    template = templ,
    hooks = Dict(...)
end

is equivalent to Rule("rule-name", descr, patt, templ, Dict(...))

@define_rule_in_group group "rule-name" begin
    description = descr,
    pattern = patt,
    template = templ,
    hooks = Dict(...)
end

is equivalent to

group["rule-name"] = Rule("rule-name", descr, patt, templ, Dict(...))

The only exception is @define_rule_hook. Pre- and post-match checks are runtime-generated functions that introduce special inner functions such as skip_match(). These are automatically generated by @define_rule_hook.

The user could define their own runtime-generated functions and pass them to the RuleHook constructor. Then, they can use register_rule_hook! to make their hook available in Argus. The functions should define current_file() and skip_match() and should have the following signature: <check>(rule::Rule, current_file_name::AbstractString, bindings::BindingSet).