aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/peg.c35
-rw-r--r--src/include/janet.h3
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 {