[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