Archive for the 'SimpleLisp' Category

Resoluciones del Nuevo Mes: Enero 2015

Saturday, January 3rd, 2015

Un nuevo año comienza. Pero para mí, sigue siendo el mes la unidad de “nuevas resoluciones”: me parece así que es más útil, flexible y alcanzable. Tiempo de revisar las resoluciones del mes pasado,  y plantear las nuevas:

– Agregar características distribuidas a AjErl, el intérprete tipo Erlang en C# [parcial] ver repo
– Mejorar ClojSharp [completo] ver repo
– Mejorar SimpleLisp [completo] ver repo
– Generación de Código con AjGenesis para Node [pendiente]
– Comenzar Basic Script Language en C# [completo] ver repo

Adicionalmente, estuve trabajando en:

– Mejorar ScalaSharp [completo] ver repo
– Primeras operaciones del emulador Chip8 en JavaScript [completo] ver repo
– Escribir ejemplos de Clojure (con Ring, Compojure) [completo] ver repo
– Trabajar en proyecto Liqueed [completo] ver repo
– Mejorar AjScript [completo] ver repo

Las resoluciones para el nuevo mes:

– Continuar con características distribuidas de AjErl, intérprete tipo Erlang en C#
– Mejorar ClojSharp
– Mejorar ScalaSharp
– Mejorar emulador Chip8 en JavaScript
– Generar código con AjGenesis para Node
– Mejorar Basic Script Language para C#
– Escribir posts de JavaScript e Inteligencia Artificial

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

SimpleLisp (2) Compilando Valores y Variables Lisp a JavaScript

Tuesday, December 9th, 2014

Anterior Post

Veamos algo de la implementación del proyecto

https://github.com/ajlopez/SimpleLisp

el compilador de Lisp a JavaScript, escrito en JavaScript, siguiendo el flujo de trabajo de TDD (Test-Driven Development). Todo es “trabajo en progreso” así que lo explico hoy es la implementación actual, de este día, que puede ir cambiando a medida que se vayan implementando nuevos casos de uso.

Tomé la decisión de que cada símbolo de Lisp sea una variable de JavaScript. Así que la compilación de un símbolo queda expresada en este test:

exports['compile symbol'] = function (test) {
    test.equal(sl.compile('a'), 'a');
}

El sl es módulo SimpleLisp que ya tengo cargado con require, al principio de los tests. Este test de arriba lo tomé de test/compile.js

Un entero y un string se compilan a valores naturales en JavaScript:

exports['compile integer'] = function (test) {
    test.equal(sl.compile('42'), '42');
}

exports['compile string'] = function (test) {
    test.equal(sl.compile('"foo"'), '"foo"');
}

También se compilan a valores naturales sus valores “quoted”:

exports['compile quoted integer'] = function (test) {
    test.equal(sl.compile("'42"), '42');
}

exports['compile quoted string'] = function (test) {
    test.equal(sl.compile("'\"foo\""), '"foo"');
}

Decidí tratar a nil como el null de JavaScript. Los valores booleanos se compilan tal cual:

exports['compile nil'] = function (test) {
    test.equal(sl.compile('nil'), 'null');
}

exports['compile booleans'] = function (test) {
    test.strictEqual(sl.compile('false'), 'false');
    test.strictEqual(sl.compile('true'), 'true');
}

¿Pero qué pasa si hay que compilar una serie de expresiones Lisp? Armo una función anónima, la invoco sin parámetros, y devuelvo el valor de la última expresión:

exports['compile two symbols'] = function (test) {
    test.equal(sl.compile('a b'), '(function () { a; return b; })()');
}

Próximos temas: compilación de una lista y de valores quoted más complejos.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

SimpleLisp (1) Compilando Lisp a JavaScript

Monday, November 24th, 2014

Siguiente Post

Ya varias veces implementé un intérprete Lisp, en C#, en Java, en JavaScript. Ver proyectos

https://github.com/ajlopez/AjLisp
https://github.com/ajlopez/AjLispJava
https://github.com/ajlopez/AjLispJs

Siempre es bueno implementar Lisp. Es un lenguaje simple, sencillo, poderoso, con funciones como ciudadanos de primera clase, y con el “twist” de implementar: algunas funciones que no evalúan de antemano sus argumentos, y macros.

Pero esta vez quiero implementar un compiladr Lisp. Es decir, algo que traslade al lenguaje anfitrión el programa Lisp. He elegido JavaScript como lenguaje anfitrión, y también como lenguaje de compilación: JavaScript mismo es el encargado de leer y traducir código Lisp a JavaScript. Pueden ver mi avance en

https://github.com/ajlopez/SimpleLisp

Como es costumbre, todo armado siguiendo el flujo de trabajo de TDD (Test-Driven Development), y sin tener todo el diseño de antemano, simplemente va surgiendo con los pequeños casos de uso que voy incorporando. Como es mi primer compilador Lisp, estoy aprendiendo nuevas formas de implementar el lenguaje. Algo vi en los últimos años al toparme con Clojure, que compila a Java, a CLR y a JavaScript. Lo que veo que tengo que implementar es:

Símbolos: identificadores por nombre, con valor asociado. Los estoy compilando a variables de JavaScript. En SimpleLisp, un símbolo puede quedar definido para el tope del programa, para un bloque let, o como argumento de una función. Entonces, depende del caso, lo paso a una variable tope de JavaScript (o al menos, tope en el módulo que estoy armando en compilación), a una variable local, o a un argumento con nombre.

Funciones: traducir una función normal de Lisp a una función normal de JavaScript. Lo único diferente es que las funciones de Lisp siempre devuelven en un valor, los “comandos” son siempre expresiones, como en Ruby. Una lista a evaluar en SimpleLisp la compilo a una llamada a función simple en JavaScript.

Special Forms: Su implementación es novedosa para mí. Ahora que tengo que compilar, no interpretar, cada vez que me topo con un una lista cuya cabeza es un if, un do, un let, etc…  voy y la compilo de forma especial a JavaScript. Un (if … ) de SimpleLisp queda transformado en un if de JavaScript (es un poco más complicado, porque el if de SimpleLisp tiene que devolver un valor, es una expresión, mientras que un if de JavaScript es un comando; ya veremos en futuro post la implementación que adopté).

Macros: De nuevo, al tener que compilar, puedo adoptar una implementación nueva: expandir la macro AL MOMENTO DE COMPILAR. Veremos hasta donde puedo llegar con este camino. Una consecuencia que veo: no puedo pasar una macro como valor funcional como argumento de otra función. Justamente, lo que pasa en Clojure: las macros no son valores funcionales, son “trucos” que se expande en tiempo de compilación.

Y como en otras implementaciones, agrego acceso a invocar JavaScript nativo desde SimpleLisp. Mi idea es poder escribir un sitio Node.js/Express con SimpleLisp.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez