Meta-programming - examples

Witold Baryluk baryluk at mpi.int.pl
Sun Feb 11 11:43:11 PST 2007


Nice ideas.

I'm also thinking on few powerful things.

Compile time XML parser:
 - configuration files:

   config.xml:
     <start><tag v="aa"></start>

   mixin(buildclasses!(xml(import("config.xml")));
   writefln(xml.start.tag.v);  // will print aa

   mixin(xpath!(xml, val, "start/tag.v"));
   writefln(val);    // "aa"

   not so usefull, but:

 - glade gui:
   mixin(glade!(xml(import("gui.glade")));
   with automatic bindings?

Compile time type safe SQL (working on it!):

  create_tables.sql:
    CREATE TABLE sale (id INT, name VARCHAR, price FLOAT);

  mixin(addtables!("create_tables.sql"));

  float p = 100.00;
  auto rows = sql!("SELECT id, name, price FROM sale WHERE price < $1").sql(p); // p MUST BE float

  foreach (r; rows) {
    writefln("%d: %s = %f", r.id, r.name, r.price); 
         // yes! p.price, not p["price"].getFloat(), or sth similiar
    char[] sid = r.id;       // error!
  }

  Note: it is very VERY complicated to parse sql select with all features in compile
  time, but i have made some progress...

Pattern matching system (like in erlang, or nemerle):
  struct Eqn {
     enum typ {
       SYMBOL, FUNC, ENVVAR, DOUBLE
     };
     union u {
       char[] s;
       F f;
       char[] var;
       double d;
     };
  }

  Eqn e = { typ: DOUBLE, u.d: 3.4 };

  mixin(match!(
       case e of
         (SYMBOL, u.s as s) =>
            writefln(\"s=%s\", s),
         (DOUBLE, u.d as d) =>
            writefln(\"d=%f\", d),
         _ =>
            writefln(\"other\");
       end."));

   or:

   int[] a = [1,6,7];

   mixin(match!(
       case %1 of
         [Head | Tail] =>
            writefln(\"do something with head %d\", Head),
            Head + self(Tail), // recursion
         [Last] =>
            writefln(\"Last\"),
            Last
         [] =>
            writefln(\"empty\"),
            0
         _ =>
            assert(false, \"error\"),
         end.", "funk(int[]) : int"));

   writefln(funk(a));     //14



There is endless posibilities to extend syntax.
We can practicly implement some small langauages in this way,
and emit D code with some templates.

This is pretty cool, but we will need even quicker compilation time, for this to be
fully useful.

Even after compiler optimalisations, IDE will have problems with parsing such things.

I think we also should have regexp functions accessible in compile time. It is painful to
parse things by hand.

-- 
Witold Baryluk



More information about the Digitalmars-d mailing list