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 ProjectLa 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.cmdEstoy 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