.macro PCRE_INIT (var)
    loadlib .var, "libpcre"
    store_global "pcre::lib", .var
    load_bytecode "library/libpcre.imc"
    # pcre *pcre_compile(const char *pattern, int options,
    #            const char **errptr, int *erroffset,
    #            const unsigned char *tableptr
    dlfunc $P0, .var, "pcre_compile", "ptiB3P"
    store_global "pcre::compile", $P0
    #int pcre_exec(const pcre *code, const pcre_extra *extra,
    #        const char *subject, int length, int startoffset,
    #        int options, int *ovector, int ovecsize);
    dlfunc $P0, .var, "pcre_exec", "ipPtiiipi"
    store_global "pcre::exec", $P0

    #int pcre_copy_substring(const char *subject, int *ovector,
    #        int stringcount, int stringnumber, char *buffer,
    #        int buffersize);
    dlfunc $P0, .var, "pcre_copy_substring", "itpiibi"
    store_global "pcre::copy_substring", $P0
.endm

.macro PCRE_COMPILE(pattern, options, regex, error, errptr)
    $P0 = global "pcre::compile"
    $P1 = global "_pcre_compile"
    .pcc_begin prototyped
    .arg .pattern
    .arg .options
    .pcc_call $P1
    .result .regex
    .result .error
    .result .errptr
    .pcc_end
.endm

.macro PCRE_MATCH(regex, str, start, options, ok, res)
    $P0 = global "pcre::exec"
    $P1 = global "_pcre_exec"
    .pcc_begin prototyped
    .arg .regex
    .arg .str
    .arg .start
    .arg .options
    .pcc_call $P1
    .result .ok
    .result .res
    .pcc_end
.endm

.macro PCRE_DOLLAR(str, ok, res, n, matched)
    $P1 = global "_pcre_result"
    .pcc_begin prototyped
    .arg .str
    .arg .ok
    .arg .res
    .arg .n
    .pcc_call $P1
    .result .matched
    .pcc_end
.endm
