On Tuesday, 26 May 2015 at 05:22:26 UTC, Tofu Ninja wrote:
So I was writing a simple parser and I wanted a functionality that was basically "try list of tokens in order and if any of them fail, rewind input".

I tried using a lazy variadic function:

bool tok_and(lazy bool[] terms ...)
{
        auto backup = getInputLocation();
        for(int i = 0; i < terms.length; i++)
        {
                if(terms[i] == false)
                {
                        rewind(backup);
                        return false;
                }
        }
        return true;
}

But this does not work because of BUG9110
https://issues.dlang.org/show_bug.cgi?id=9110

Any one have an idea how to achieve similar functionality without a bunch of boilerplate at the call site? The lazy version would have been nice because it would have allowed for:

if(tok_and(ident(), equal(), expression())) {...}
else if(tok_and(some(), other(), grammar())) {...}
else ...

Something like this appears to work:

import std.typetuple : allSatisfy;

enum implicityConvertibleToBool(T) = is(T : bool);

bool tok_and(Args...)(lazy Args terms)
if(allSatisfy!(implicitlyConvertibleToBool, Args))
{
        auto backup = getInputLocation();
        foreach(term; terms)
        {
                if(term == false)
                {
                        rewind(backup);
                        return false;
                }
        }
        return true;
}

Reply via email to