Dynamic Language Runtime (Parte 1) Hello World!

Published on Author lopezLeave a comment

Próximo post

Quiero compilar mis intérpretes (AjSharp, AjLisp, el nuevo AjScript), escritos en C#. Podría usar CodeDom, Reflection.Emit, Mono.Cecil, para generar código CLR/.NET. Pero ya hay una librería dedicada a implementar lenguajes dinámicos: el Dynamic Language Runtime. La tomé de

http://dlr.codeplex.com

y compilé la release version usando VS2008. Notablemente, los autores removieron la implementación de un simple lenguaje (está en la versión 0.9, como ToyScript). Necesito ayuda para enteder su funcionamiento, estructura interna y forma de uso. La documentación es técnicamente buena, pero introduce tantas partes con nombres como “Call Site” que son nuevos para mí, y algo ambiguos, así que no es evidente cómo usara; hay que investigarla con cuidado. Por ejemplo, ¿qué es un “Call Site”?. No queda claro qué hace dado su nombre.

Así que me decidí a escribir algunos code katas, experimentos cortos, para comenzar a investigar el DLR. Y como es habitual, pasar estos experimentos a post y código disponible. Afortunadamente, tengo la ayuda del libro “Pro DLR in .NET 4” de Chaur Wu. Encuentro ahí el primer ejemplo que voy a comentar.

Primer experimento: crear un simple REPL (Read-Eval-Print Loop) para un simple “Hello, World!”.

(El código de esta serie de posts queda en http://code.google.com/p/ajcodekatas/  en trunk/Dlr)

Creé un proyecto de consola, usando Visual Studio 2008 (mis intérpretes son simples, y no necesito nada de .NET 4 todavía), llamado DlrHelloWorld.

Agregué las referencias a Microsoft.Scripting.dll, Microsoft.Scripting.Code.dll, Microsoft.Dynamic.dll (curiosamente, una de las clases que voy a usar, ConsoleHost, está en esta última dll).

La primera clase:

    public class HelloScriptCode : ScriptCode
    {
        public HelloScriptCode(SourceUnit sourceUnit)
            : base(sourceUnit)
        {
        }
        public override object Run(Scope scope)
        {
            Console.WriteLine("Hello, World");
            return null;
        }
    }

Objetos de esta clase ejecutarán un simple “Hello, World”. Noten que recibe un SourceUnit, algo que tiene el código a compilar. Pero será ignorado en este primer ejemplo.

Luego, la clase que maneja al HelloScriptCode:

    public class HelloContext : LanguageContext
    {
        public HelloContext(ScriptDomainManager domainManager,
            IDictionary<string, object> options)
            : base(domainManager)
        {
        }
        public override ScriptCode CompileSourceCode(SourceUnit sourceUnit, 
            CompilerOptions options, ErrorSink errorSink)
        {
            return new HelloScriptCode(sourceUnit);
        }
    }

Su principal responsabilidad: dado un SourceUnit, producir un objeto ScriptCode.

DLR puede albergar un lenguaje, provendo un REPL. Escribí una clase que hereda de ConsoleHost:

    public class HelloConsole : ConsoleHost
    {
        protected override Type Provider
        {
            get
            {
                return typeof(HelloContext);
            }
        }
    }

El main simple es:

    class Program
    {
        static void Main(string[] args)
        {
            (new HelloConsole()).Run(args);
        }
    }

 

La salida puede ser algo repetitiva 馃槈 :

Debería estudiar y entender las piezas involucrada en este ejemplo (opciones de host, uso de source unit y language contexto, formas dinámicas de script code). Próximos pasos: investigar sobre compilar expresiones simples y comandos.

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 *