From b809cd022ceecae51b0e9b80818b72b4fb300bac Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 22 Sep 2013 19:40:18 +0600 Subject: [PATCH] #30: add support for delimiter. --- README.md | 6 +++++- lib/compiler/passes/generate-bytecode.js | 24 ++++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f007afaaa..7924a88da 100644 --- a/README.md +++ b/README.md @@ -293,7 +293,7 @@ expression as many times as possible. Try to match the expression. If the match succeeds, return its match result, otherwise return an empty string. -#### *expression* |count|
*expression* |min..max| +#### *expression* |count|
*expression* |count,delimiter|
*expression* |min..max|
*expression* |min..max,delimiter| Match exact `count` repetitions of `expression`. If the match succeeds, return their match results in an array. @@ -306,6 +306,10 @@ be omitted. If `min` omitted, then suppose to `0`. If `max` is omitted, then suppose to infinity. `expression |..|` equivalently `expression |0..|` and `expression *`. `expression |1..|` equivalently `expression +`. +Optionally, you can specify delimiter as rule reference or arbitrary rule +expression. Delimiter must appear between elements in parsed input. Results +of delimiter expression will be dropped. + `count`, `min` and `max` must be positive integers. #### & *expression* diff --git a/lib/compiler/passes/generate-bytecode.js b/lib/compiler/passes/generate-bytecode.js index a2d3fa04b..a438fe492 100644 --- a/lib/compiler/passes/generate-bytecode.js +++ b/lib/compiler/passes/generate-bytecode.js @@ -546,17 +546,33 @@ module.exports = function(ast, options) { var emptyArrayIndex = addConst('[]'); var nullIndex = addConst('null'); // expressionCode put result on stack - expressionCode = generate(node.expression, { + var expressionCode = generate(node.expression, { sp: context.sp + 1, env: { }, action: null }); - /*minIndex = generate(node.min, { + var expressionCode2 = node.delimiter ? + buildSequence( + generate(node.delimiter, { + sp: context.sp + 1, + env: { }, + action: null + }), // item = delim(); + buildCondition( + [op.IF_NOT_ERROR], // if (item != null) + buildSequence( + op.POP, + expressionCode // item = expr() + ), + [] + ) + ) : expressionCode; + /*var minIndex = generate(node.min, { sp: context.sp + 1, env: { }, action: null }); - maxIndex = generate(node.max, { + var maxIndex = generate(node.max, { sp: context.sp + 1, env: { }, action: null @@ -577,7 +593,7 @@ module.exports = function(ast, options) { [op.IF_ARRLEN_MAX], // stack:[ [elem...] ] // push `null` - this break loop on next iteration. [op.PUSH, nullIndex], // elem = null; stack:[ [elem...], null ] - expressionCode // } else { + expressionCode2 // } else { ) // elem = expr(); stack:[ [elem...], elem ] ) // } ), // } stack:[ [elem...], elem ]