Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
May 26, 2015 Lazy variadic not working, any alternatives? | ||||
---|---|---|---|---|
| ||||
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 ... |
May 26, 2015 Re: Lazy variadic not working, any alternatives? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tofu Ninja | On Tuesday, 26 May 2015 at 05:22:26 UTC, Tofu Ninja wrote: Actually the code seems to compile on 2.067.1 but definitely does not work as expected. Another example of Lazy variadic to show how it works... void main(string[] args) { test(a(), b(), c()); } bool a() { writeln("a"); return true; } bool b() { writeln("b"); return true; } bool c() { writeln("c"); return true; } void test(lazy bool[] c...) { for(int i = 0; i < c.length; i++) { writeln("iteration: ", i); if(c[i]) writeln("success"); } } prints... a b c iteration: 0 a b c success a b c iteration: 1 a b c success a b c iteration: 2 a b c success a b c Though because it still runs in order, maybe I can still make this work... |
May 26, 2015 Re: Lazy variadic not working, any alternatives? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tofu Ninja | On Tuesday, 26 May 2015 at 05:43:59 UTC, Tofu Ninja wrote:
> On Tuesday, 26 May 2015 at 05:22:26 UTC, Tofu Ninja wrote:
> Actually the code seems to compile on 2.067.1 but definitely does not work as expected.
> ...
I guess it stems from the fact that its "lazy (bool[])"
Wish I could do "(lazy bool)[]"
|
May 26, 2015 Re: Lazy variadic not working, any alternatives? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tofu Ninja | 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; } |
May 26, 2015 Re: Lazy variadic not working, any alternatives? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Tuesday, 26 May 2015 at 05:54:11 UTC, John Colvin wrote:
> 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;
> }
Hmmm.... this does seem to work. Does this essentially expand out to tok_and(lazy bool arg1, lazy bool arg2, ...)?
|
May 26, 2015 Re: Lazy variadic not working, any alternatives? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tofu Ninja | On 5/25/15 11:53 PM, Tofu Ninja wrote: > On Tuesday, 26 May 2015 at 05:43:59 UTC, Tofu Ninja wrote: >> On Tuesday, 26 May 2015 at 05:22:26 UTC, Tofu Ninja wrote: >> Actually the code seems to compile on 2.067.1 but definitely does not >> work as expected. >> ... > > I guess it stems from the fact that its "lazy (bool[])" > Wish I could do "(lazy bool)[]" Lazy variadic functions are clearly defined here: http://dlang.org/function.html The correct way to do it is: bool tok_and(bool delegate()[] terms ...) -Steve |
May 26, 2015 Re: Lazy variadic not working, any alternatives? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tofu Ninja | On Tuesday, 26 May 2015 at 06:04:59 UTC, Tofu Ninja wrote: > On Tuesday, 26 May 2015 at 05:54:11 UTC, John Colvin wrote: >> 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; >> } > > Hmmm.... this does seem to work. Does this essentially expand out to tok_and(lazy bool arg1, lazy bool arg2, ...)? Apparently yes, which surprised me. Storage classes and TypeTuples (or Arguments, as they are now) are a bit of a dark corner. E.g. void foo(ref int, ref int); alias A(T...) = T; static assert(is(ParameterTypeTuple!foo == A!(ParameterTypeTuple!foo))); That fails. |
Copyright © 1999-2021 by the D Language Foundation