|
|
@ -1,13 +1,22 @@
|
|
|
|
"use strict";
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
let GrammarError = require("../../grammar-error"),
|
|
|
|
let GrammarError = require("../../grammar-error"),
|
|
|
|
objects = require("../../utils/objects"),
|
|
|
|
|
|
|
|
visitor = require("../visitor");
|
|
|
|
visitor = require("../visitor");
|
|
|
|
|
|
|
|
|
|
|
|
/* Checks that each label is defined only once within each scope. */
|
|
|
|
/* Checks that each label is defined only once within each scope. */
|
|
|
|
function reportDuplicateLabels(ast) {
|
|
|
|
function reportDuplicateLabels(ast) {
|
|
|
|
|
|
|
|
function cloneEnv(env) {
|
|
|
|
|
|
|
|
let clone = {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Object.keys(env).forEach(name => {
|
|
|
|
|
|
|
|
clone[name] = env[name];
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return clone;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function checkExpressionWithClonedEnv(node, env) {
|
|
|
|
function checkExpressionWithClonedEnv(node, env) {
|
|
|
|
check(node.expression, objects.clone(env));
|
|
|
|
check(node.expression, cloneEnv(env));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let check = visitor.build({
|
|
|
|
let check = visitor.build({
|
|
|
@ -17,7 +26,7 @@ function reportDuplicateLabels(ast) {
|
|
|
|
|
|
|
|
|
|
|
|
choice: function(node, env) {
|
|
|
|
choice: function(node, env) {
|
|
|
|
node.alternatives.forEach(alternative => {
|
|
|
|
node.alternatives.forEach(alternative => {
|
|
|
|
check(alternative, objects.clone(env));
|
|
|
|
check(alternative, cloneEnv(env));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|