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