npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@alu0100819786/constant-folding

v2.1.1

Published

Constant Folding javascript code

Downloads

9

Readme


descripcion: Super Repositorio que contiene los archivos de la Práctica 3 además de un README.md explicando todo el proceso de desarrollo. alumno: "Gabriel Melián Hernández Alu0100819786"

npm version

Constant-Folding

El proceso de creación de nuestras funciones de constant folding, lo podremos encontrar dentro del subrepo constant-folding-module-gabriel-melian-hernandez-alu0100819786.

Partimos como base para realizar nuestro constant folding de la utilización de estraverse y su función traverse. Vamos a utilizar está función de manera que actuemos sobre los nodos hijos primero que sobre los padres, para poder realizar el constant folding de manera correcta, para ello usaremos leave a la hora de aplicar las condiciones para que se llamen a las funciones.

Partimos de una base para conseguir Constant folding, en BinaryExpressions de esta manera:

const t = espree.parse(input, { ecmaVersion: 6, loc: false });
estraverse.traverse(t, {
  leave: function (n, p) {
    if (n.type == "BinaryExpression" && 
        
      n.left.type == "Literal" && n.right.type == "Literal") { replaceByLiteral(n); }

Con este código lo que hacemos es llamar a replaceByLiteral(n) con el nodo n, cuando entremos a un nodo que sea de tipo BinaryExpression y sus hijos izquierdo y derecho sean de tipo Literal.

Una vez hemos accedido al nodo en el cual queremos llevar a cabo nuestro constant folding, lo realizamos de la siguiente manera:

function replaceByLiteral(n) {
  n.type = "Literal";

  n.value = eval(`${n.left.raw} ${n.operator} ${n.right.raw}`);
  n.raw = String(n.value);

  delete n.left;
  delete n.right;
}

Realizamos la operación que contenía la BinaryExpression inicial y renombramos n, para que ahora tenga type Literal y borramos sus hijos izquierdo y derecho.

Por otra parte y respondiendo al Challenge de esta práctica se pide que el programa sea capaz de hacer constant folding no solo para BinaryExpressions sino también para operaciones con Arrays, en CallExpressions, para esto, seguimos el mismo procedimiento que mostramos anteriormente buscando ahora un nodo que tenga tipo CallExpression además de un n.callee.property.name que caze con la operación que tratará cada función, vamos a ver un par de ejemplos:

if (n.type == "CallExpression"){
        

      if(n.callee.property.name == "join") { replaceByString(n);}
    }
    if (n.type == "CallExpression"){
        

      if(n.callee.property.name == "shift") { replaceByShift(n);}
    }

Tanto join como shift son operaciones que se realizan sobre arrays, pero aunque ambos crean nodos del tipo CallExpression, su n.callee.property.name es diferente y por ende la operación que van a realizar sobre el array también y es necesario tratarlas de forma separada, teniendo una función para cada una de ellas.

Por ejemplo en la función join:

function replaceByString(n){
  n.type = "Literal";
  var aux;
  var aux2 ="";
  aux = n.callee.object.elements.length;
  if(n.arguments[0] != null){
    for( var i = 0; i < aux ; i ++){
      if ( i == aux-1){
        aux2 = aux2 + (n.callee.object.elements[i].value);
      }
      if (i < aux-1){
        aux2 = aux2 + (n.callee.object.elements[i].value) + n.arguments[0].value;
      }
    }
  }
  if(n.arguments[0] == null){
    for( var i = 0; i < aux ; i ++){
      if ( i == aux-1){
        aux2 = aux2 + (n.callee.object.elements[i].value);
      }
      if (i < aux-1){
        aux2 = aux2 + (n.callee.object.elements[i].value) + ',';
      }
    }
  }
  
  n.value = aux2;
  delete n.callee;
  delete n.arguments;
}

Entramos al nodo y vamos a ir accediendo a cada elemento del array y lo vamos a ir colocando uno a uno en una cadena separados por una coma por defecto, o si la función join tiene argumento, sustituiremos la coma, por dicho argumento a la hora de realizar el join final. y por último borraremos el calle del nodo y sus argumentos quedandonos unicamente con el nodo padre y realizando correctamente el constant folding.

Por otra parte en la función se shift:

function replaceByShift(n){
  n.type = "Literal";

  var aux;
  aux = n.callee.object.elements[0].value;
  n.value = aux;

  delete n.callee;
}

Al igual que en el ejemplo anterior entramos al nodo seleccionado, cambios su tipo y realizamos el comportamiento que debería llevar a cabo la función shift() que es la de sacar el primer valor del array y devolverlo. Por lo que, renombramos el tipo del nodo padre a Literal y a su value le asignamos el valor del primer elemento del array original y luego borramos el array quedando solamente el nodo padre ahora de tipo Literal con el value correspondiente al resultado del constant folding.

Siguiendo este razonamiento se realiza la implementación de las demás funciones para llevar a cabo todos los ejemplos requeridos en el challenge.

Publicación e Instalación.

Para llevar a cabo la publicación de nuestro npm package lo primero que tendremos que hacer es crear un usuario y darnos de alta en npm.

Para ello vamos a acceder a su página web oficial.

npmjs.com.

Y haremos click en el botón Sign Up. Rellenamos nuestros datos:

ImageText

Tras esto nos pedirá confirmación de e-mail y además la introducción de uncódigo de contraseña de un sólo uso que nos enviarán por correo al e-mail proporcionado en el mometnod e la creación de la cuenta. Una vez verificado el e-mail, ya dispondremos de nuestra cuenta en npm y podremos publicar nuestro paquete, para ello debemos colocarnos en el repositorio que contiene nuestro paquete y abrir una terminal para primero de todo logearnos de nuevo con el comando npm login. Introducimos nuestras credenciales de acceso y ya estaríamos logeados correctamente.

Para poder publicar nuestro paquete debemos definir primero en el archivo package.json nuestro ámbito y esto lo haremos simplemente modificando las primeras líneas del mismo.

{
    "name": "@alu0100819786/constant-folding",
    "version": "0.0.1",
    "author": "alu0100819786 <[email protected]>",
    "description": "Constant Folding javascript code",

Lo que escribamos en el campo name será el ámbito con el que se publicará nuestro paquete. Una vez configurado dicho fichero solo quedará el último paso que es publicar el propio package mediante el comando npm publish --access=public. Una vez hecho esto, ya podremos venirnos a la página web de npm y veremos nuestro package publicado.

ImageText

Una vez publicado ya podremos instalarlo en cualquiera de nuestro proyectos, para ello usaremos un comando que podemos encontrar en esta misma página en el lado derecho, en el apartado install y se trata del comando npm i @alu0100819786/constant-folding.

De esta forma podemos ir a otro proyecto y ejecutar el comando. Veremos como se instala al igual que cualquier otra dependencia que tengamos en el package.json, y se incluirá dentro de la carpeta de node_modules, tal y como vemos en la siguiente imagen.

ImageText

Github Submodules:

En esta práctica se nos pide que sea realizada en tres repositorios diferentes, donde tendremos un super repo y los otros dos serán sub repos del primero. Para lograr esto nos colocamos en el super repo y una vez inicializado procedemos a usar el comando

git submodule add <repo url>

Utilizaremos, este comando dos veces, una por cada repo que tenemos y esto creará un directorio en el super repo llamado .gitmodules que tendrá la información principal de los dos sub repos.

[submodule "constant-folding-module-gabriel-melian-hernandez-alu0100819786"]
	path = constant-folding-module-gabriel-melian-hernandez-alu0100819786
	url = https://github.com/ULL-ESIT-PL-2122/constant-folding-module-gabriel-melian-hernandez-alu0100819786
[submodule "constant-folding-production-test-gabriel-melian-hernandez-alu0100819786"]
	path = constant-folding-production-test-gabriel-melian-hernandez-alu0100819786
	url = https://github.com/ULL-ESIT-PL-2122/constant-folding-production-test-gabriel-melian-hernandez-alu0100819786

Además desde que hagamos nuestro primer commit luego de añadir los sub repos y hagamos un push, se actualizará la información de nuestro super repo y aparecerán los sub repos enlazados al principal como podemos ver en la siguiente imagen.

ImageText

Coverage y Github Actions:

Para llevar a cabo nuestro coverage, al igual que en la práctica anterior haremos uso de la herramienta nyc , que nos proporcionará información trás cada ejecución de nuestro programa. También podríamos utilizar la opción de sacar los resultados en un archivo .html y mostrarlo en github pages como en la práctica anterior.

ImageText

Por otra parta para hacer uso de las Github Actions vamos a modificar el archivo nodejs.yml donde especificaremos las acciones que queremos realizar cada vez que hagamos un push o un pull request en nuestro repositorio.

steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      # Runs a single command using the runners shell
      - name: Install Dependencies
        run: npm i
        
        # Runs a set of commands using the runners shell
      - name: Run Program
        run: npm run execute
      
       # Runs a set of commands using the runners shell
      - name: Run program with coverage
        run: npm run covnyc

Uso del módulo y Pruebas de Producción.

Una vez publicado el módulo, si queremos utilizarlo en algún otro proyecto debemos añadirlo en el package.json como cualquiier otra dependencia.

 "@alu0100819786/constant-folding": "*",

Con esto conseguimos que el módulo sea accesible una vez que hayamos instalado las dependencias del proyecto con npm i. Ahora si queremos utilizarlo en nuestro proyecto bastará con agregar la siguietne línea de código:

const prueba = require ("@alu0100819786/constant-folding");

Y ahora ya podremos a través de prueba acceder a todos los métodos que están presentes en nuestro módulo, comopor ejemplo el método resolverProblema que nos realizará el constant folding de una expresión, haciendo uso de los demás métodos del módulo.

fs.readFile(inputFilename, 'utf-8', (error, datos) => {
    if(error) throw error;
    prueba.resolverProblema(datos);
});

Examples

Podemos ejecutar nuestro programa rápidamente con un input de prueba para comprobar el correcto funcionamiento del mismo.

const input = `
["a", "b", "c"].join();
["a", "b", "c"].join('@');
[1, 2, 3].length;
[1, 2, 3][2-1];
[1, 2, 3].shift();
[a, b, c].pop();
`;

donde tras ejecutar nuestro programa conseguimos las siguientes salidas:

'a,b,c';
'a@b@c';
3;
2;
1;
c;

Tests

Para llevar a cabo los test de está practica utilizaremos el archivo test.js u las herramientas mocha y chai. Y haciendo uso de los métodos definidos en la el fichero src/constant-folding.js.

describe("Constant Folding test", () => {

  for (let c of Checks) {
    it(`Test ${c.text} => ${c.result}`, () =>{
        let oldconstant = constantFolding.resolverProblema;
        constantFolding.resolverProblema = x => x;

      const t = constantFolding.resolverProblema(c.text);
      const result = eval(t);
      result.should.equal(c.result);

      constantFolding.resolverProblema = oldconstant;
    });
  }
});

Con este código y las entradas de prueba:

const Checks = [

  {text: `a=2*3`, result: 6},
  {text: `a=2*4`, result: 8},
  {text: `["a", "b", "c"].join()`, result: 'a,b,c'},
  {text:`["a", "b", "c"].join('@')`, result: 'a@b@c'},
  {text: `[1, 2, 3].length`, result: 3},
  {text: `[1, 2, 3][2-1]`, result: 2},
  {text: `[1, 2, 3].shift()`, result: 1},
  {text: `[1, 2, 3].pop()`, result: 3},
];

Conseguimos que nuestros test funcionen correctamente, tal y como podemos apreciar en la resolución por ejemplo de las tareas de Github Actions.

 Constant Folding test
    ✔ Test a=2*3 => 6
    ✔ Test a=2*4 => 8
    ✔ Test ["a", "b", "c"].join() => a,b,c
    ✔ Test ["a", "b", "c"].join('@') => a@b@c
    ✔ Test [1, 2, 3].length => 3
    ✔ Test [1, 2, 3][2-1] => 2
    ✔ Test [1, 2, 3].shift() => 1
    ✔ Test [1, 2, 3].pop() => 3


  8 passing (7ms)