Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | 1x 1x 52x 52x 52x 52x 49x 49x 18x 137x 125x 27x 76x 70x 6x 4x 2x 52x 52x 72x 72x 70x 52x 52x 52x 2x 2x 2x 50x 52x 1x | /**
* Universidad de La Laguna
* Escuela Superior de Ingeniería y Tecnología
* Grado en Ingeniería Informática
* Procesadores de Lenguajes
*
* @author Juan Rodríguez Suárez
* @since Mar 04 2024
* @desc Contains a Scope class to analyze the scope of the program.
*/
const {
buildIdentifier,
buildVariableDeclaration,
buildVariableDeclarator,
} = require('./ast-build');
const { difference } = require('./utils.js');
/**
* @description Class to analyze the scope of the program
*/
class Scope {
constructor(parent) {
this.parent = parent;
this.initialized = new Set();
this.used = new Set();
this.letDeclarations = [];
}
add(name) {
this.initialized.add(name);
this.letDeclarations.push(buildVariableDeclarator(buildIdentifier(name)));
}
setAsInitialized(name) {
this.initialized.add(name);
}
setAsUsed(name) {
this.used.add(name);
}
has(name) {
return this.initialized.has(name);
}
buildDeclaration() {
return buildVariableDeclaration(this.letDeclarations);
}
lookup(name) {
if (this.has(name)) {
return this;
}
if (this.parent) {
return this.parent.lookup(name);
}
return null;
}
notDeclared() {
let notDeclared = difference(this.used, this.initialized);
for (let v of this.used) {
let s = this.lookup(v);
if (s) {
notDeclared.delete(v);
}
}
return notDeclared;
}
notDeclaredMessage() {
let notDeclared = this.notDeclared();
if (notDeclared.size > 0) {
return Array.from(notDeclared).
map(x => x.replace(/^[$]/, '')).
map(x => `Variable \'${x}\' not declared`).join('\n');
}
return null;
}
get length() {
return this.letDeclarations.length;
}
}
module.exports = Scope;
|