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; |