diff --git a/src/patterns.js b/src/patterns.js index a04ab3346c6ea294f5dcc971b5605f32368f81c0..f2e8dbb210c09697998fdbb1cf3b23c51d3f37c7 100644 --- a/src/patterns.js +++ b/src/patterns.js @@ -396,7 +396,7 @@ if (restMatch.success) { // match the repeat pattern on the empty array to fill in its // pattern variable in the environment - match = matchPattern(pattern, [], env, patternEnv); + match = matchPattern(pattern, [], env, patternEnv, topLevel); patternEnv = _.extend(restMatch.patternEnv, match.patternEnv); rest = restMatch.rest; break patternLoop; @@ -416,7 +416,7 @@ } } } - match = matchPattern(pattern, rest, env, patternEnv); + match = matchPattern(pattern, rest, env, patternEnv, topLevel); if (!match.success && pattern.repeat) { // a repeat can match zero tokens and still be a // "success" so break out of the inner loop and @@ -514,7 +514,7 @@ "$y" : ... } */ - function matchPattern(pattern, stx, env, patternEnv) { + function matchPattern(pattern, stx, env, patternEnv, topLevel) { var subMatch; var match, matchEnv; var rest; @@ -562,7 +562,8 @@ // initialize if we haven't done so already patternEnv[patternKey] = { level: nextLevel, - match: [subMatch.patternEnv[patternKey]] + match: [subMatch.patternEnv[patternKey]], + topLevel: topLevel }; } } else { @@ -592,7 +593,8 @@ rest = match.rest; matchEnv = { level: 0, - match: match.result + match: match.result, + topLevel: topLevel }; // push the match onto this value's slot in the environment @@ -603,7 +605,8 @@ // initialize if necessary patternEnv[pattern.value] = { level: 1, - match: [matchEnv] + match: [matchEnv], + topLevel: topLevel }; } } else { @@ -658,7 +661,7 @@ // We need to reverse the matches for any top level repeaters because // they match in reverse, and thus put their results in backwards. _.forEach(patternEnv, function(val, key) { - if (val.level && val.match) { + if (val.level && val.match && val.topLevel) { val.match.reverse(); } }); diff --git a/test/test_macro_patterns.js b/test/test_macro_patterns.js index 4ad1cbde620888b490d59c138190300baac21b70..a15cbbd397484c60f104a832459c1626a0595368 100644 --- a/test/test_macro_patterns.js +++ b/test/test_macro_patterns.js @@ -844,4 +844,14 @@ describe("macro expander", function() { expect(a).to.be(0) }) + it("should only reverse top-level repeater patterns", function() { + macro m { + rule infix { ($num ...) | } => { + $num (-) ... + } + } + + expect((3 2 1) m).to.be(0); + }) + });