La semana pasada, gracias a @pmolinam, encontré
Language Workbench Competition 2011
Molina me había enviado la información el año pasado pero no recordaba la competición. Hace unos días fue mencionada en InfoQ:
Language Workbench Competition 2011 Submissions
Pueden leer la lista de tareas en:
http://www.languageworkbenches.net/LWCTask-1.0.pdf
No estoy seguro que AjGenesis pueda calificar como un Language Workbench: está más orientado a ser una herramienta de generación de código y texto desde un modelo de libre definición. No tiene integración con una IDE, prefiere ser flexible e independiente del lenguaje y tecnología. No crea ni produce ningún DSL (Domain-Specific Language): en cambio, tiene un modelo de libre definición que puede ser usado de muchas maneras, para describir los conceptos que tengamos que modelar, sin tener adosado un DSL en particular. @pmolinam me preguntó por Twitter si yo podría completar las tareas usando AjGenesis, mi herramienta de código abierto. Mi respuesta: Sí!
Entonces, algunos mensajes aparecieron en Twitter:
El lunes pasado, comencé a escribir la Fase 0, puntos 0.1 y 0.2. El ejemplo que estoy construyendo está en el trunk de AjGenesis trunk, en:
http://ajgenesis.codeplex.com/SourceControl/list/changesets
en el directorio examples/Lcw2011
El primer punto 0.1 es:
0.1 Simple (structural) DSL without any fancy expression language or such. Build a simple data definition language to define entities with properties. Properties have a name and a type. It should be possible to use primitive types for properties, as well as other Entities.
entity Person {
string name
string firstname
date bithdate
Car ownedCar
}
entity Car {
string make
string model
}
Escribí un simple Project.txt (noten que estoy usando el modelo textual en lugar del XML, ver Modelos para AjGenesis; Models for AjGenesis y Modelo textual para generación de código con AjGenesis; Textual model for Code Generation in AjGenesis ).
Project Lwc2011
Entities
Entity Person
Properties
Property Name Type="Text"
Property FirstName Type="Text"
Property BirthDate Type="Date"
Property OwnedCar Type="Car"
End Properties
End Entity
Entity Car
Properties
Property Make Type="Text"
Property Model Type="Text"
End Properties
End Entity
End Entities
End Project
La Fase 0-0.2:
0.2 Code generation to GPL such as Java, C#, C++ or XML Generate Java Beans (or some equivalent data structure in C#, Scala, etc.) with setters, getters and fields for the properties.
Usando lo que escribí para Armando una aplicacación usando AjGenesis (Parte 4); Building An Application using AjGenesis (Part 4), creé los comandos:
GenerateCSharp.cmd
GenerateJava.cmd
GenerateVbNet.cmd
Estoy usando modelos adicionales para describir la tecnología. Por ejemplo, esto es el modelo de tecnología VbNet:
<Technology>
<Name>VbNet</Name>
</Technology>
Simple! Esta vez, estoy usando el modelo XML (en memoria, tanto el modelo textual como el de XML terminan siendo manejados de la misma forma: la diferencia es sólo cuestión de serialización).
Vean el GenerateCSharp.cmd:
AjGenesis.Console Project\Project.txt Project\Technologies\CSharp.xml Tasks\Complete.ajg Tasks\Generate.ajg
Esto carga en memoria el modelo de Project.txt, el correspondiente modelo de tecnología, lee y ejecuta la tarea Complete.ajg, y lee y ejecuta la tarea Generate.ajg. El Complete.ajg (ver el mencionado post Armando una aplicacación usando AjGenesis (Parte 4); Building An Application using AjGenesis (Part 4)) se usa para completar el modelo: una cosa que hace es traducir los tipos abstractos como “Text” a los correspondientes tipos en el lenguaje final elegido, como “string” en C#, o “String” en Java.
El Generate.ajg toma el modelo enriquedo y genera el código para cada entidad, usando templates. Este es el template pare C#::
// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com)
namespace ${Project.CSharp.Namespace} {
public class ${Entity.Name}
{
<#
for each Property in Entity.Properties
#>
public ${Property.CSharp.Type} ${Property.Name} { get; set; }
<#
end for
#>
}
}
El código generado para la entidad Person:
// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com)
namespace Lwc2011 {
public class Person
{
public string Name { get; set; }
public string FirstName { get; set; }
public DateTime BirthDate { get; set; }
public Car OwnedCar { get; set; }
}
}
Próximos pasos: completar las tareas 0.3, 0.4, y pasar a resolver la Fase 1. Podría completar el trabajo en dos semanas. Seguiré publicando avances en posts.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez