Desde Lenguajes de Infijo a EVM usando Nearley.js

Descripción

Usando Nearley.js describa un lenguaje de programación sencillo (Sintáxis convencional a la Lua/C/BASIC/…). Las acciones semánticas deben retornar ASTs que puedan ser usados por su intérprete del lenguaje Egg.

En el repositorio fun-lang puede encontrar un ejemplo que contiene un pequeño lenguaje escrito en Nearley.js y que se corresponden con la lista de YouTube de Toby Ho Make your ow Language.

Mi consejo es que parta de este repo y modifique el AST producido para que sea el que hemos usado en el lenguaje Egg.

He escrito un pequeño módulo npm moo-ignore que es un wrapper alrededor de moo que es compatible con Nearley.js y provee la forma de ignorar tokens. Puede usarlo para facilitar la escritura de esta práctica.

Requisitos

El lenguaje debe tener:

  • Declaraciones (aunque no tiene que ser necesariamente tipeado). Esto es, deberían poder declararse objetos como variables, constantes y funciones
  • Sentencias if,
  • condiciones como a <= b,
  • asignaciones,
  • Alguna forma de bucle,
  • funciones y llamadas a funciones,
  • Arrays,
    • Acceso a los elementos de un array y
    • Asignación a los elementos de un array.

Gramáticas de Ejemplo

De mas simple a mas complejas:

Fun-Lang

En el repositorio fun-lang puede encontrar un ejemplo que contiene un pequeño lenguaje escrito en Nearley.js y que se corresponden con la lista de YouTube de Toby Ho Make your ow Language.

Tini-C

Escrita en C usando un PDR:

  • Tiny-C
    • Un subconjunto hiper-minimal de C con un compilador y una VM escritas en C.
    • Contiene un lexer
    • Un parser PDR que construye un AST
    • Un generador de código para una VM
    • Un intérprete para la VM

Tiny-BASIC

Gramática en la Wikipedia:

Niklaus Wirth PL/0

Lua

Lua es un lenguaje profesional y sin embargo tiene una gramática bastante sencilla. Otra razón para animarse con este lenguaje es que ya tiene una gramática de la que partir en el directorio de ejemplos de Nearley.js:

Puede partir de este código y simplificarlo para que no lleve tanto trabajo.

Este es un fragmento de programa en Lua:

function maximum (a)
  local mi = 1          -- maximum index
  local m = a[mi]       -- maximum value
  for i,val in ipairs(a) do
    if val > m then
      mi = i
      m = val
    end
  end
  return m, mi
end

print(maximum({8,10,23,12,5}))     --> 23   3

Para saber más sobre Lua consulte:

Mini Pascal en Python

ANSI C Grammar in Parse::Eyapp

Aqui tiene una gramática del lenguaje C escrita en Parse::Eyapp, una herramienta de generación de analizadores sintácticos para el lenguaje Perl que desarrollé hace muchos años:

Pascal

JavaScript

Python

Ruby

Java

Infix program examples

Sigue un ejemplo de como podría ser su lenguaje:

begin
    # array is an egg function that returns an array
    let result = call array(2, 3, 4, 5);

    # print is also egg function
    call print(result);

    # We can also access array properties
    call print("Array length: " + result.length);

    # And call array methods
    let string = call result.join(" ~ ");
    call print(string);

    # We can use array map method by passing an anonymous function as argument
    let doubles = call result.map(func(x, i, a) begin
            x * 2
    end);
    call print(doubles)
end

Y el resultado de una ejecución del anterior programa

bin/infix2egg.js --run examples/arrays.inf
[ 2, 3, 4, 5 ]
Array length: 4
2 ~ 3 ~ 4 ~ 5
[ 4, 6, 8, 10 ]

Use su módulo Egg

Como tenemos publicado en github-registry nuestro intérprete egg lo usaremos en nuestro compilador del lenguaje infijo que hemos diseñado para interpretar los ASTs

Rúbrica

Incidencias para el Project Board para la práctica

Desde Lenguajes de Infijo a EVM usando Nearley.js

  • El lenguaje tiene al menos:

    1. Declaraciones (aunque no tiene que ser necesariamente tipeado). Esto es, deberían poder declararse objetos como variables, constantes y funciones

    2. Sentencias if,

    3. Condiciones como a <= b,

    4. Asignaciones,

    5. Alguna forma de bucle,

    6. Funciones y llamadas a funciones,

    7. Arrays, - Acceso a los elementos de un array y - Asignación a los elementos de un array.

    8. A valorar: La expresividad y potencia del lenguaje

  • Se ha hecho un análisis léxico separado y limpio

  • Retorna ASTs Egg correctos

  • Se pueden ejecutar los .evm generados fácilmente

  • Opcional: se traduce a JS fácilmente