Trouble with anon delegates.
BCS
ao at pathlink.com
Tue Jan 16 19:38:09 PST 2007
You might try somthing like this (warning it has been called "evil"), this
vertion dosn't work but it can actualy be made to by using structs and a
little refactoring. The basic idea is use structs with delegate as members
to build operatio trees. In this case I used it for the reduction, you'd
could using it for parsing as well.
p.s. It realy is evil, you have been warned.
// a base type for derivation
class Type{}
// a templated derived type to store things in
class TypeT(T) : Type
{
public T val;
static TypeT!(T) opCall(T v)
{
auto ret = new TypeT!(T);
ret.val = v;
return ret;
}
}
/*
Doc ::=
A:a B:b C:c = new Fig(a,b,c)
| D:d E:e = new Fig(d,e)
*/
TypeT!(Fig) delegate() Parse_Doc(inout char[] from)
{
char[] tmp;
// copy from
tmp = from;
if(auto a = Parse_A(tmp)) // try to parse an "a"
if(auto b = Parse_B(tmp)) // try to parse an "b"
if(auto c = Parse_C(tmp)) // try to parse an "c"
{ // if all's good
// update what's been parsed
from = tmp;
return &(
// make an array from the args
[cast(Type delegate())a,b,c]
// copy it (force off stack)
.dup
)
// form delegate from array
// and function literal
.function TypeT!(Fig)(Type delegate()[] args)
{
// literal calls given code
auto ret =
new Fig(
// call args for values
cast(a.typeof)args[0]().val,
cast(b.typeof)args[1]().val,
cast(b.typeof)args[2]().val);
// place in object and return
return TypeT!(ret.typeof)(ret);
};
}
// restore tmp
tmp = from;
// blah, blah, blah
if(auto d = Parse_D(tmp))
if(auto e = Parse_E(tmp))
{
from = tmp;
return &([cast(Type delegate())d,e].dup)
.function TypeT!(Fig)(Type delegate()[] args)
{
auto ret =
new Fig(
cast(d.typeof)args[0]().val,
cast(e.typeof)args[1]().val);
return TypeT!(ret.typeof)(ret);
};
}
return null;
}
/*
A ::=
"hello":v = v
*/
TypeT!(char[]) delegate() Parse_A(inout char[] from)
{
char[] tmp;
tmp=from;
// check for a "hello"
if(from[0.."hello".length] == "hello")
{
// update from
from = from["hello".length..$];
// return delegate returning "hello" in obj
return &("hello".dup).function TypeT!(char[])()
{
auto ret =
from[0.."hello".length];
return TypeT!(ret.typeof)(ret);
};
}
return null;
}
/// ........
More information about the Digitalmars-d-learn
mailing list