Refactoreando AjLisp: un intérprete Lisp escrito en C#

Published on Author lopezLeave a comment

En estos días estuve reimplementando el núcleo de mi intérprete Lisp de código abierto AjLisp. Había escrito sobre la anterior versión en el 2008:

AjLisp: a Lisp interpreter in .NET
AjLisp: un intérprete Lisp en .NET

Es trabajo en progreso. Pueden bajar el código de:

http://code.google.com/p/ajlisp/source/browse/#svn/trunk/AjLisp

(hay otras dos implementaciones en ese repositorio, en desarrollo: AjScheme, un Lisp tipo Scheme, y AjSharpure, que intenta seguir las ideas de Clojure). Debería escribir sobre esas implementaciones. Este post es el inicial en una serie sobre AjLisp. Es una corta introducción al estado actual del proyecto.

El principal cambio en esta nueva versión: el intérprete puede manejar objetos y valores nativos. La alternativa hubiera sido apuntar a esos objetos a través de “wrappers”, alguna clase que implemente SymbolicExpression o similar. Pero elegí manejar directamente objetos nativos. Para eso, cambié las primitivas y clases relacionadas para que recibieran como argumentos objetos en vez de IExpression. Sigue habiendo una interfaz IExpression, defined como:

    public interface IExpression
    {
        object Evaluate(ValueEnvironment environment);
    }

El ValueEnvironment (planeo cambiarle el nombre a BindingEnvironment, y derivarlo de alguna interfaz tipo IBindingEnvironment) mantiene una asociación anidada de nombres y valores:

Hay un interfaz IFunction:

    public interface IFunction
    {
        object Apply(List arguments, ValueEnvironment environment);
    }

que debería ser implementada por cualquier form expression (la cabeza de una lista a evaluar).

Las dos clases principales que representan los tipos núcleo del AjLisp son identificadores y listas:

Todo el proyecto fue armado siguiendo Test-Driven Development, así que no tuve problemas en cambiar la versión anterior: tenía toda una batería de tests que me ayudó en el proceso de refactoring. Este es el estado actual de los test:

Debería escribir sobre:

– La implementación de ValueEnvironment

– Manejo de objetos nativos

– El tipo List y su evaluación

– Evaluación de Identifier

– Las primitivas implementadas

– El Lexer y el Parser

– Operaciones numéricas

– Números racionales (AjLisp puede manejar pares enteros numerador/denominador)

Ahora, luego de lo que aprendí desarrollando estos proyectos (AjLisp, AjScheme, AjSharpure), estoy escribiendo un núcleo mínimo AjCoreLisp, para mostrar cuáles son las primitivas mínimas para crear un intérprete Lisp. Armado con esa implementación, me gustaría explorar alternativas de compilación, en vez de ser sólo intérprete. Mi primer candidato es Dynamic Language Runtime. Otro podría ser la producción de código C# directo. Sería demasiado encarar esa exploración sobre un intérprete “más grande”. Primero, entonces, estudiaré sobre compilar un intérprete con menos primitivas, más condensado.

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

Leave a Reply

Your email address will not be published. Required fields are marked *