[DGD] A small parse_string toy

bart at wotf.org bart at wotf.org
Fri Feb 27 21:59:18 CET 2009


So I was playing around a bit with Dworkin's lpc grammar for parse string, and
ended up showing to myself that parsing an lpc variant to something more dgd
friendly isn't all that hard.

see http://wotf.org/happycode.c

Its just a little proof of concept, and needs a fair bit of work to be more
then a toy, but I thought others might find it fun to play with, and hopefully
improve upon.

The code should be rather lib agnostic except maybe for using a function int
pointerp(mixed arg) which tests the type of its argument to be T_ARRAY

On my own lib, I hooked it into what is called the 'vcompiler' (a way to let
'user' objects provide code to compile_object() for parts of the directory
tree) so that it automatically gets called when files in ~aidil/vobj are compiled.

This is a little copy paste from my mud session while testing it.

aidil at wotf-devel:/players/aidil/vobj> more testobj
"/players/aidil/vobj/testobj.c"
private mixed * filter(mixed * arr, function f, mixed extra...) {
  mixed * result;
  int pos;

  result = ({ });
  for( pos = 0; pos < sizeof(arr); pos++ ) {
    if(fcall(f, arr[pos], extra)) {
      result += arr[pos..pos];
    }
  }
  return result;
}

int * test( ) {
  int * arr;

  arr = ({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });

  return filter( arr, (: return ($1 > 2 && $1 < 7); :) );
}

aidil at wotf-devel:/players/aidil/vobj> cc -v2 testobj
DGD lpc compiler frontend 1.0, (C) 2003 WOTF
---------- starting compiler ----------
* compiling /players/aidil/vobj/testobj.c
+     inheriting /system/lib/auto.c
= finished with /players/aidil/vobj/testobj.c
---------- compiler finished ----------
cc: recompiled /players/aidil/vobj/testobj.c in 49681 ticks.
aidil at wotf-devel:/players/aidil/vobj> call testobj test
Function defined by /players/aidil/vobj/testobj
Array of size 4:
({ 3, 4, 5, 6 })
aidil at wotf-devel:/players/aidil/vobj> props testobj
Listing properties on ~aidil/vobj/testobj:
"vcode"  ({ "private mixed fcall(mixed * fp, mixed arg...) { return
call_other(fp[0], fp[1], arg...); }", "mixed __anon_fun0
    ( mixed arg ... ) { return ( arg [ 0 ] > 2 && arg [ 0 ] < 7 ) ; } private
mixed * filter ( mixed * arr , mixed * f ,
    mixed extra ... ) { mixed * result ; int pos ; result = ( { } ) ; for (
pos = 0 ; pos < sizeof ( arr ) ; pos ++ ) { { if
    ( fcall ( f , arr [ pos ] , extra ) ) { result += arr [ pos .. pos ] ; } }
} return result ; } int * test ( ) { int *
    arr ; arr = ( { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ) ; return filter
( arr , ({ this_object() , "__anon_fun0" }) )
    ; }" })


Challanges for you:
- Preserve linebreaks and keep a mapping between source and intermediate line
numbers for runtime error reporting
- Add a preprocessor
- Improve parse error reporting (heh)

:)

Oh, and a more serious implementation would probably use something else for
representing function pointers and anonymous functions (what I do here is a
bit of a hack, but it doesn't require much in the way of lib support), allow
for compiling anonymous functions on-the-fly and such, but hey, this is the
result of a few hours of fiddling with how to use parse_string to parse one
language variant into another.

Bart.
--
Created with Open WebMail at http://www.bartsplace.net/
Read my weblog at http://soapbox.bartsplace.net/




More information about the DGD mailing list