Lexer and parser generators using CTFE

F i L witte2008 at gmail.com
Sun May 27 13:15:08 PDT 2012


I'm not sure I follow all the details of what Andrei's suggesting 
and what's being talked about here, this parser/lexer stuff is 
still very new to me, so this may be a bit off-topic. However, I 
thought I'd weigh in on something I was very impressed with about 
the Nimrod language's direct AST access/manipulation.

Nim has a "template" which is very much like D's mixin templates, 
example:

   # Nim
   template foo(b:string) =
     var bar = b

   block main:
     foo("test")
     assert(bar == "test")

and the equivalent in...

   // D
   mixin template foo(string b) {
     auto bar = b;
   }

   void main() {
     mixin foo("test");
     assert(bar == "test");
   }

which is all very straight forward stuff, the cool part comes 
with Nim's macro's. Nim has a two unique types: expr & stmt 
(expression & statement). They're direct AST structures which can 
be passed to template/macro procedures and arbitrarily mutated. 
Example:

   macro foo(s:stmt): stmt =
     result = newNimNode(nnkStmtList)
     for i in 1 .. s.len-1:
       var str = s[i].toStrLit()
       result.add(newCall("echo", str))

   block main:
     foo:
       bar
       baz

the above code prints:
"
   bar
   baz
"

**Some notes: result is what's returned, and the reason you can 
use "foo" with a statement body is because any macro/template 
who's last parameter is type 'stmt' can be called with block 
semantics; similar to how UFCS works with the first parameter.**

The above *might* look like the following in D:

   macro foo(ASTNode[] stmts...) {
     ASTNode[] result;
     foreach (s; stmts) {
       auto str = s.toASTString();
       result ~= new ASTCall!"writeln"(str);
     }
     return result;
   }

   void main() {
     foo {
       bar;
       baz;
     }
   }

This kind of direct AST manipulation + body semantics opens the 
doors for a lot of cool things. If you read through Nim's lib 
documentation you'll notice many of the "language" features are 
actually just Library procedures in the defaultly included system 
module. Which is great because contributions to the *language* 
can be made very easily. Also, the infrastructure to read/write 
AST is no-doubt immensely useful for IDE support and other such 
dev tools.

I'm not a huge fan of everything in Nimrod, but this is something 
they definitely got right, and I think D could gain from their 
experience.


More information about the Digitalmars-d mailing list