CLazy interpreter and compiler
12 January 2009 (programming language lisp) (1 comment)CLazy is my toy functional programming language featuring a Lisp-like syntax, lazy evaluation, and not much else at the moment. To get a taste of it, here's the definition of map in CLazy, using pattern matching:
(deftype list (t) nil (cons t (list t))) (defun map (f nil) nil) (defun map (f (cons x xs)) (cons (f x) (map f xs)))
I've written the interpreter (in Lisp) back in November, and now I had this idea of writing a compiler. This compiler, instead of generating e.g. x86 assembly code, generates C# which is then compiled into .NET IL.
To do the actual code generation, instead of outright outputting text, the compiler (also written in Lisp) generates an s-expr representation of C# code. For example, the code generated for the type list, as defined above, is represented as the following:
(class ("List" :extends (instantiate-generic (dot "CLazy" "Runtime" "ConstructorTag") (dot "List" "Kcons"))) (enum ("KCons" :visibility :public) "NIL" "CONS") (empty-line) (constructor (:visibility :public :formals ((var ("kcons" :type "Kcons"))) :delegated-constructor (base "kcons"))) (empty-line) (procedure ("Nil" :visibility :public :staticp t :type "List") (return (new "List" (dot "Kcons" "NIL")))) (empty-line) (procedure ("Cons" :visibility :public :staticp t :type "List") (return (new "List" (dot "Kcons" "CONS")))))
Which is then coverted to the usual, plain-text representation of C# code by a separate un-parser, yielding the following piece of code readable by C# compilers:
class List: CLazy.Runtime.ConstructorTag<List.Kcons> { public enum Kcons { NIL, CONS } public List (Kcons kcons): base (kcons) { } public static List Nil () { return new List (Kcons.NIL); } public static List Cons () { return new List (Kcons.CONS); } }
The actual function application code is simply a compiled instance for the given function of the generic graph reduction algorithm that the interpreter uses internally, e.g. the following is the C# code generated from the second definition of map:
private static bool Reduce_2 (CLazy.Runtime.Node node) { CLazy.Runtime.Node actual_f; CLazy.Runtime.Node actual_x; CLazy.Runtime.Node actual_xs; actual_f = node.children[0]; var P_0 = node.children[1]; ReduceExprToCons (P_0); if (!(object.Equals (P_0.objPayload, ID.List.Cons ()))) { return false; } actual_x = P_0.children[0]; actual_xs = P_0.children[1]; var R_0 = new CLazy.Runtime.Node (ID.List.Cons ()); var R_1 = new CLazy.Runtime.Node (new CLazy.LangID.Apply ()); R_1.Add (actual_f); R_1.Add (actual_x); R_0.Add (R_1); var R_2 = new CLazy.Runtime.Node (new CLazy.LangID.Apply ()); var R_3 = new CLazy.Runtime.Node (new CLazy.ID.Map ()); R_2.Add (R_3); R_2.Add (actual_f); R_2.Add (actual_xs); R_0.Add (R_2); node.Overwrite (R_0); return true; }
Encsé 2009-01-13 09:21:48
Good job! Congrats! Don't you want to come up with a tasks for gekko in CLisp? That would be great I think... ;)