diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/peg.c | 35 | ||||
| -rw-r--r-- | src/include/janet.h | 3 |
2 files changed, 34 insertions, 4 deletions
diff --git a/src/core/peg.c b/src/core/peg.c index 93d43d0e..2631696e 100644 --- a/src/core/peg.c +++ b/src/core/peg.c @@ -596,6 +596,30 @@ tail: return text + width; } + case RULE_UNREF: { + int32_t tcap = s->tags->count; + down1(s); + const uint8_t *result = peg_rule(s, s->bytecode + rule[1], text); + up1(s); + if (!result) return NULL; + int32_t final_tcap = s->tags->count; + /* Truncate tagged captures to not include items of the given tag */ + int32_t w = tcap; + /* If no tag is given, drop ALL tagged captures */ + if (rule[2]) { + for (int32_t i = tcap; i < final_tcap; i++) { + if (s->tags->data[i] != (0xFF & rule[2])) { + s->tags->data[w] = s->tags->data[i]; + s->tagged_captures->data[w] = s->tagged_captures->data[i]; + w++; + } + } + } + s->tags->count = w; + s->tagged_captures->count = w; + return result; + } + } } @@ -919,15 +943,15 @@ static void spec_error(Builder *b, int32_t argc, const Janet *argv) { spec_onerule(b, argc, argv, RULE_ERROR); } } -static void spec_drop(Builder *b, int32_t argc, const Janet *argv) { - spec_onerule(b, argc, argv, RULE_DROP); -} static void spec_to(Builder *b, int32_t argc, const Janet *argv) { spec_onerule(b, argc, argv, RULE_TO); } static void spec_thru(Builder *b, int32_t argc, const Janet *argv) { spec_onerule(b, argc, argv, RULE_THRU); } +static void spec_drop(Builder *b, int32_t argc, const Janet *argv) { + spec_onerule(b, argc, argv, RULE_DROP); +} /* Rule of the form [rule, tag] */ static void spec_cap1(Builder *b, int32_t argc, const Janet *argv, uint32_t op) { @@ -947,6 +971,9 @@ static void spec_accumulate(Builder *b, int32_t argc, const Janet *argv) { static void spec_group(Builder *b, int32_t argc, const Janet *argv) { spec_cap1(b, argc, argv, RULE_GROUP); } +static void spec_unref(Builder *b, int32_t argc, const Janet *argv) { + spec_cap1(b, argc, argv, RULE_UNREF); +} static void spec_reference(Builder *b, int32_t argc, const Janet *argv) { peg_arity(b, argc, 1, 2); @@ -1104,6 +1131,7 @@ static const SpecialPair peg_specials[] = { {"to", spec_to}, {"uint", spec_uint_le}, {"uint-be", spec_uint_be}, + {"unref", spec_unref}, }; /* Compile a janet value into a rule and return the rule index. */ @@ -1392,6 +1420,7 @@ static void *peg_unmarshal(JanetMarshalContext *ctx) { case RULE_ACCUMULATE: case RULE_GROUP: case RULE_CAPTURE: + case RULE_UNREF: /* [rule, tag] */ if (rule[1] >= blen) goto bad; op_flags[rule[1]] |= 0x01; diff --git a/src/include/janet.h b/src/include/janet.h index 59d6a37c..a8efc545 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1841,7 +1841,8 @@ typedef enum { RULE_LENPREFIX, /* [rule_a, rule_b (repeat rule_b rule_a times)] */ RULE_READINT, /* [(signedness << 4) | (endianess << 5) | bytewidth, tag] */ RULE_LINE, /* [tag] */ - RULE_COLUMN /* [tag] */ + RULE_COLUMN, /* [tag] */ + RULE_UNREF /* [rule, tag] */ } JanetPegOpcod; typedef struct { |
