AjGenesis y Language Workbench Competition 2011

Published on Author lopez1 Comment

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

Leave a Reply

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