Skip to content

Commit

Permalink
issue pegjs#30: begin implementing ranges support. Changes in grammar…
Browse files Browse the repository at this point in the history
… and handling in passes.
  • Loading branch information
Mingun committed Sep 17, 2013
1 parent 5312e12 commit f2b2c9d
Show file tree
Hide file tree
Showing 7 changed files with 754 additions and 307 deletions.
7 changes: 6 additions & 1 deletion lib/compiler/opcodes.js
Expand Up @@ -42,5 +42,10 @@ module.exports = {
/* Failure Reporting */

SILENT_FAILS_ON: 25, // SILENT_FAILS_ON
SILENT_FAILS_OFF: 26 // SILENT_FAILS_FF
SILENT_FAILS_OFF: 26, // SILENT_FAILS_FF

/* Checking array length */

CHECK_MIN_LEN: 27, // CHECK_MIN_LEN len
CHECK_MAX_LEN: 28 // CHECK_MAX_LEN len
};
37 changes: 36 additions & 1 deletion lib/compiler/passes/generate-bytecode.js
Expand Up @@ -174,10 +174,21 @@ var utils = require("../../utils"),
* [26] SILENT_FAILS_OFF
*
* silentFails--;
*
* Checking array length
* ---------------------
*
* [27] CHECK_MIN_LEN len
*
* stack.push(len !== undefined && stack.top().length < len)
*
* [28] CHECK_MAX_LEN len
*
* stack.push(len !== undefined && stack.top().length >=len)
*/
module.exports = function(ast, options) {
var consts = [];

/// Add new constant to constant list, if it not exist, and return they index in that list.
function addConst(value) {
var index = utils.indexOf(consts, function(c) { return c === value; });

Expand Down Expand Up @@ -516,6 +527,30 @@ module.exports = function(ast, options) {
);
},

range: function(node, context) {
var emptyArrayIndex = addConst('[]');
expressionCode = generate(node.expression, {
sp: context.sp + 1,
env: { },
action: null
});

return buildSequence(
[op.PUSH, emptyArrayIndex], // var result = []
expressionCode, // var elem = expr();
buildLoop(
[op.WHILE_NOT_ERROR], // while (elem !== null) {
buildSequence(
[op.APPEND], // result.push(elem);
/*TODO: new opcode*/ // if (max !== undefined && result.length >= max) break;
expressionCode // elem = expr();
)
), // }
/*TODO: new opcode*/ // if (min !== undefined && result.length < min) result = null;
[op.POP] // return result;
);
},

rule_ref: function(node) {
return [op.RULE, utils.indexOfRuleByName(ast, node.name)];
},
Expand Down
6 changes: 4 additions & 2 deletions lib/compiler/passes/generate-javascript.js
Expand Up @@ -818,7 +818,7 @@ module.exports = function(ast, options) {
}

parts.push([
'',
' //{ Helper functions',
' function text() {',
' return input.substring(peg$reportedPos, peg$currPos);',
' }',
Expand Down Expand Up @@ -892,17 +892,19 @@ module.exports = function(ast, options) {
' }',
' }',
' }',
''
' //}'
].join('\n'));

if (options.optimize === "size") {
parts.push(indent4(generateInterpreter()));
parts.push('');
} else {
parts.push(' //{ Parse rule functions')
utils.each(ast.rules, function(rule) {
parts.push(indent4(generateRuleFunction(rule)));
parts.push('');
});
parts.push(' //}')
}

if (ast.initializer) {
Expand Down
1 change: 1 addition & 0 deletions lib/compiler/passes/report-left-recursion.js
Expand Up @@ -45,6 +45,7 @@ module.exports = function(ast) {
optional: checkExpression,
zero_or_more: checkExpression,
one_or_more: checkExpression,
range: checkExpression,

rule_ref:
function(node, appliedRules) {
Expand Down
1 change: 1 addition & 0 deletions lib/compiler/passes/report-missing-rules.js
Expand Up @@ -27,6 +27,7 @@ module.exports = function(ast) {
optional: checkExpression,
zero_or_more: checkExpression,
one_or_more: checkExpression,
range: checkExpression,

rule_ref:
function(node) {
Expand Down

0 comments on commit f2b2c9d

Please sign in to comment.