AjBasic: un intérprete Basic de código abierto

Mi proyecto de generación de código AjGenesis usa un lenguaje interpretado para ejecutar tareas y expandir plantillas. El lenguaje fue bautizado AjBasic. Lo puede ver usado en todos los ejemplos que escribí para AjGenesis (más información en los posts de AjGenesis). Hace unos años, había separado el códgio del intérprete del proyecto madre, pero nunca lo había publicado. Este fin de semana, estuve refactorizando el código, y ahora, el resultado de ese trabajo está publicado en:

http://code.google.com/p/ajbasic/

En mi opinión, Google Code es fácil de manejar. Al contrario de SourceForge y CodePlex, usa Subversion como repositorio de código. Uso el cliente Tortoise SVN para enviar los cambios. La gente de Google es gentil: pude crear varios proyectos, por ahora esta es la lista:

http://code.google.com/p/ajlisp (en buena forma, se pude comenzar a investigar)
http://code.google.com/p/ajtalk (todavía en su infancia)

Más información en:

AjLisp- un intérprete Lisp en .NET
AjTalk- un intérprete tipo Smalltalk

La Solución

 La solución AjBasicWithTests se compone de los proyectos:

AjBasic: implementa el compilador y el tokenizador. El tokenizer separa el texto entrante en tokens. El compilador arma árboles abstractos a evaluar, desde esa entrada.

AjInterpreter: Un nuevo proyecto, no presente en el AjGenesis original. Contiene toto el soporte del árbol abstracto, sus nodos, el ambiente (environment) donde se almaceman los valores, y un evaluador de los programas. El manejo de objetos .NET, y de objetos dinámicos, están en este proyecto. Mi intención es continuar usando este proyecto para soportar otros lenguajes interpretados.

AjBasic.Console: Una simple consola para probar el intérprete.

AjBasic.GUI: Un simple (y feo) WinForm para probar el intérprete.

AjBasic.Test: Algunos tests, usando NUnit (hay otra solución AjBasic que no incluye el proyecto de tests)

Todos los proyectos están escritos usando Visual Basic .NET. La solución fue compilada usando Visual Studio 2005. La consola y el proyecto GUI podrían ser usados como base, explican cómo usar el intérprete desde nuestra propia aplicación.

Hay varios puntos para discutir sobre la implemetación: merecerian otros posts. Por ahora,  exploremos algunas de las principales características del proyecto, en su estado actual. Luego, escribiré una lista de ideas a explorar en futuras versiones.

Como mencioné, el lenguaje nació para soportar la generación de código desde AjGenesis. Yo lo diseñé para manejar objetos .NET nativos, así como objetos dinámicos. Pero ¿qué es un objeto dinámico? Es un objeto que no tiene clase asociada, pero que puede ser expandido con nuevas propiedades (el ejemplo más cercano que podría mencionar ahora, son los objetos Javascript).

Así, podemos escribir código como:

a.FirstName = "Adam" a.LastName = "Doe" a.Age = 800

No tenemos que declarar la variable. Podemos crear el objeto y agregar la propiedad FirstName en un comando (esta creación automática de objeto no está soportada en AjGenesis, aún, pero se puede crear un objeto del tipo DynamicObject con new).

Podemos probar la existencia de una propiedad:

if a.LastName then ' it has a LastName not nothing else ... end if


Si la variable a no tiene valor asignado, o si no tiene la propiedad LastName, la condición de arriba es evaluada a falso. Podemos preguntar por algo como foo.bar.anything y no se levanta una exception. El valor del resultado sería Nothing, que es evaluado y tomado por falso en una condición.


Los Tests


La solución no fue desarrollado usando TDD (Test-driven development). Escribí los tests despues del código, solo para estar seguro que la funcionalidad principal estuviera bien implementado, cumpliendo con lo que esperaba de cada método. No usé nombres descriptivos para los tests, pero me fueron muy útiles cuando encaré la refactorización de la solución completa:



Podemos probar el lenguaje desde la consola AjBasic.Console:



y desde el WinForm AjBasic.GUI



Ninguno de los dos es la “qué aplicación, que bruta…”, pero funcionan…. ;-)


Próximos Pasos


Hay varias ideas volando cerca de la neurona que me queda, y tengo que poner orden en mi cabeza. Algunos puntos, para que queden escritos:


- Ahora que el núcleo del intérprete está separado del compilador basic, me gustaría escribir AjSharp, un intérprete con sintaxis C#. Entonces, podría ser agregado a AjGenesis, para escribir plantillas y tareas en ese lenguaje, que puede resultar más agradable para los programadores C#.


- Agregar soporte de clases dinámicas y prototipos.


- Refactorizar los tests


- Escribir un manual mínimo, explicando el lenguaje y sus características


- Extender el lenguaje para soportar valores “delayed” y “delayed evaluation” (quizás paralelismo).


- La forma internal del intérprete podrías ser reescrita en Java


- La opción de escribir un AST (Abstract Syntax Tree) que se acople al soporte de DLR (Dynamic Language Runtime) no me atrae, podría llevar mucho trabajo. Pero podría ser interesante para aprender sobre el soporte de DLR en .NET.


- Usar el lenguaje como base para la programación de agentees distribuidos (un punto ambicioso, que merece mayor evaluación).


Como es costumbre, me divertí mucho escribiendo este software.


Nos leemos!


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

This entry was posted in 1389, 6145, 8596. Bookmark the permalink.

2 Responses to AjBasic: un intérprete Basic de código abierto

  1. Jorge says:

    Esta bastante bueno, intente agregar un “Imports ” que me sirvio para ensamblados locales en directorio bin, pero para ensamblados de la GAC – nada. Trate de llamar metodos estaticos como Math.Log(n) y tampoco funcionó. Alguna sugerencia? Gracias!

  2. lopez says:

    Hola Jorge!

    Gracias por probarlo… Hmmm… lo de la GAC tengo que estudiarlo.

    Lo de metodo estatico, deberia funcionar con System.Math.Log(n)

    (no tiene busqueda de tipo por nombre parcial)

    Nos leemos!

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>