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... ;)