#if !defined(vm_h)
#define vm_h
#include "config.h"
#include "rplx.h"
#include "buf.h"
#include "ktable.h"
#include "rpeg.h"
#include "str.h"
typedef enum MatchErr {
MATCH_OK,
MATCH_HALT,
MATCH_ERR_STACK,
MATCH_ERR_BADINST,
MATCH_ERR_CAP,
MATCH_ERR_INPUT_LEN,
MATCH_ERR_STARTPOS,
MATCH_ERR_ENDPOS,
MATCH_ERR_OUTPUT_MEM,
MATCH_ERR_NULL_PATTERN,
MATCH_ERR_NULL_INPUT,
MATCH_ERR_NULL_OUTPUT,
MATCH_ERR_NULL_MATCHRESULT,
MATCH_OPEN_ERROR,
MATCH_CLOSE_ERROR,
MATCH_FULLCAP_ERROR,
MATCH_STACK_ERROR,
MATCH_INVALID_ENCODER,
MATCH_IMPL_ERROR,
MATCH_OUT_OF_MEM,
} MatchErr;
static const char *MATCH_MESSAGES[] __attribute__ ((unused)) = {
"ok",
"halt/abend",
"backtracking stack limit exceeded",
"invalid instruction for matching vm",
"capture limit exceeded (or insufficient memory for captures)",
"input too large",
"start position beyond end of input",
"end position beyond end of input",
"insufficient memory for match data",
"open capture error in rosie match",
"close capture error in rosie match",
"full capture error in rosie match",
"capture stack overflow in rosie match",
"invalid encoder in rosie match",
"null pattern argument",
"null input argument",
"null output buffer argument",
"null match result argument",
"implementation error (bug)",
"out of memory",
};
typedef struct Stats {
unsigned int total_time;
unsigned int match_time;
unsigned int insts;
unsigned int backtrack;
unsigned int caplist;
unsigned int capdepth;
} Stats;
typedef struct Match {
short matched;
short abend;
unsigned int leftover;
Buffer *data;
} Match;
typedef enum CapKind {
Crosiecap, Crosieconst, Cbackref,
Cclose = 0x80,
Cfinal, Ccloseconst,
} CapKind;
#define CAPTURE_NAME(c) (((c) & 0x80) ? CLOSE_CAPTURE_NAMES[(c) & 0x3] : OPEN_CAPTURE_NAMES[(c & 0x3)])
static const char *const OPEN_CAPTURE_NAMES[] = {
"RosieCap", "RosieConst", "Backref",
};
static const char *const CLOSE_CAPTURE_NAMES[] = {
"Close",
"Final", "CloseConst",
};
#define capidx(cap) ((cap)->c.aux)
#define setcapidx(cap, newidx) (cap)->c.aux = (newidx)
#define capkind(cap) ((cap)->c.code)
#define setcapkind(cap, kind) (cap)->c.code = (kind)
typedef struct Capture {
byte_ptr s;
CodeAux c;
} Capture;
typedef struct CapState {
Capture *cap;
Capture *ocap;
byte_ptr s;
Ktable *kt;
} CapState;
#define testchar(st,c) (((int)(st)[((c) >> 3)] & (1 << ((c) & 7))))
#define isopencap(cap) (!(capkind((cap)) & 0x80))
#define isfinalcap(cap) (capkind(cap) == Cfinal)
#define isclosecap(cap) (capkind(cap) == Cclose)
typedef struct {
int (*Open)(CapState *cs, Buffer *buf, int count);
int (*Close)(CapState *cs, Buffer *buf, int count, byte_ptr start);
} Encoder;
int sizei (const Instruction *i);
int vm_match2 (
Chunk *chunk,
struct rosie_string *input, uint32_t startpos, uint32_t endpos,
Encoder encode,
uint8_t collect_times,
Buffer *output,
struct rosie_matchresult *match);
#endif