POV-Ray : Newsgroups : povray.bugreports : problem with '#break' in macro Server Time
8 Nov 2024 21:15:43 EST (-0500)
  problem with '#break' in macro (Message 1 to 8 of 8)  
From: jr
Subject: problem with '#break' in macro
Date: 7 Sep 2021 05:35:00
Message: <web.613731ccc652d9685e0fed26cde94f1@news.povray.org>
hi,

the docs say "Note: As of version 3.7 the #break directive can now be used: ...
anywhere within a #macro to preliminarily terminate the macro."
<https://wiki.povray.org/content/Reference:Conditional_Directives#Index_Entry_break>

but I get an error "File 'brktst.pov' line 10: Parse Error: Invalid context for
#break", from both v3.7.0.8 and v3.8 POV-Rays.  the "scene":

#version 3.7;

global_settings {assumed_gamma 1}

#macro m_flag(f_)
  #if (!f_)
    #break
  #else
    #debug "ok.\n"
  #end
#end

m_flag(true)
m_flag(false)


regards, jr.


Post a reply to this message

From: Kenneth
Subject: Re: problem with '#break' in macro
Date: 10 Sep 2021 05:25:00
Message: <web.613b2408d2ea10ff4cef624e6e066e29@news.povray.org>
[Windows 10, using one of the v3.8.0 'experimental' builds that piggy-back on
v3.7.0]

Confirmed, when  m_flag(false).

I also tried the #for-loop example given in the docs (slightly modified)...

#declare R = seed(4711);
#for (I, 1, 10)
  #if (rand(R) < 1.1)
     #break // terminate loop early
  #else
   #debug concat(str(I,0,0), " iterations and counting\n")
  #end
#end

Same fatal error message.

It would seem that these additional uses of #break were never actually
implemented(?)...or maybe that there is some undocumented extra syntax missing.

Just guesses, of course.


Post a reply to this message

From: Kenneth
Subject: Re: problem with '#break' in macro
Date: 10 Sep 2021 06:15:00
Message: <web.613b2efed2ea10ff4cef624e6e066e29@news.povray.org>
This is more strange than I thought.

Compare these two #for-loop examples. The first is my modified version-- fatal
error; the 2nd is almost identical to the doc's example, which *does* at least
parse OK. The only difference is where the #debug(...) is placed. The 1st
version is kind of like your #macro, with the inner #else actually being used
for something; the 2nd makes no use of the #else, and successfully parses. I
have no idea as to why there should be a difference.

// [doc's version, slightly modified]
#local R = seed(4711);
#for (I, 1, 100)
  #if (rand(R) < 1.1) // always less than 1.1
       #break // terminate loop early
  #else
       #debug concat(str(I,0,0), " iterations and counting\n")
  #end
#end


// [doc's version, almost as-is]
#local R = seed(4711);
#for (I, 1, 100)
  #if (rand(R) < 1.1)
       #break // terminate loop early
  #else
  #end
       #debug concat(str(I,0,0), " iterations and counting\n")
#end


Post a reply to this message

From: William F Pokorny
Subject: Re: problem with '#break' in macro
Date: 10 Sep 2021 07:52:25
Message: <613b46f9$1@news.povray.org>
On 9/7/21 5:34 AM, jr wrote:
> hi,
> 
> the docs say "Note: As of version 3.7 the #break directive can now be used: ...
> anywhere within a #macro to preliminarily terminate the macro."
> <https://wiki.povray.org/content/Reference:Conditional_Directives#Index_Entry_break>
> 
> but I get an error "File 'brktst.pov' line 10: Parse Error: Invalid context for
> #break", from both v3.7.0.8 and v3.8 POV-Rays.  the "scene":
> 
> #version 3.7;
> 
> global_settings {assumed_gamma 1}
> 
> #macro m_flag(f_)
>    #if (!f_)
>      #break
>    #else
>      #debug "ok.\n"
>    #end
> #end
> 
> m_flag(true)
> m_flag(false)
> 

Recently sidetracked by RL and otherwise focused elsewhere code wise...

Looking quickly, I think the function Parser::Break() in the file 
parser_tokenizer.cpp needs a test to handle seeing an 'else block' after 
the 'break' in the 'if block' when the if conditional tests true.

     while ( (Cond_Stack.size() > 1) &&
             (Cond_Stack.back().Cond_Type != WHILE_COND) &&
             (Cond_Stack.back().Cond_Type != FOR_COND) &&
             (Cond_Stack.back().Cond_Type != CASE_TRUE_COND) &&
             (Cond_Stack.back().Cond_Type != INVOKING_MACRO_COND) )

should read:

     while ( (Cond_Stack.size() > 1) &&
             (Cond_Stack.back().Cond_Type != WHILE_COND) &&
             (Cond_Stack.back().Cond_Type != FOR_COND) &&
             (Cond_Stack.back().Cond_Type != ELSE_COND) &&
             (Cond_Stack.back().Cond_Type != CASE_TRUE_COND) &&
             (Cond_Stack.back().Cond_Type != INVOKING_MACRO_COND) )

The code above works with the code variations recently posted. However, 
it's admittedly a slap shot. More thought and testing needed.

My quick test as to whether on the right track was to create a scene 
file like jr's original, but with macro internals looking like:

   #if (f_)
     #debug "ok.\n"
   #else
     #debug "break.\n"
     #break
   #end

The variation above works for me in all v3.7+ versions I have in hand.

Bill P.


Post a reply to this message

From: jr
Subject: Re: problem with '#break' in macro
Date: 10 Sep 2021 10:25:00
Message: <web.613b69c3d2ea10ff5e0fed26cde94f1@news.povray.org>
hi,

William F Pokorny <ano### [at] anonymousorg> wrote:
> On 9/7/21 5:34 AM, jr wrote:
>> ...
> My quick test as to whether on the right track was to create a scene
> file like jr's original, but with macro internals looking like:
>
>    #if (f_)
>      #debug "ok.\n"
>    #else
>      #debug "break.\n"
>      #break
>    #end

the intention in the code was using 'f_' as a guard, that is I added the '#else'
only to demonstrate.


> The variation above works for me in all v3.7+ versions I have in hand.

thanking both you and "the Southern Walker" ;-) for taking a look, I think
Kenneth's code is more illustrative of the problem.


regards, jr.


Post a reply to this message

From: Kenneth
Subject: Re: problem with '#break' in macro
Date: 10 Sep 2021 11:30:00
Message: <web.613b793cd2ea10ff4cef624e6e066e29@news.povray.org>
William F Pokorny <ano### [at] anonymousorg> wrote:
>
> [source code snippet]
> The code above works with the code variations recently posted. However,
> it's admittedly a slap shot. More thought and testing needed.
>
> My quick test as to whether on the right track was to create a scene
> file like jr's original, but with macro internals looking like:
>
>    #if (f_)
>      #debug "ok.\n"
>    #else
>      #debug "break.\n"
>      #break
>    #end
>
> The variation above works for me in all v3.7+ versions I have in hand.
>

Just discovered that the following also produces the error and fails-- unless
the #debug is there. Seems that in this case, the inner #end actually *needs*
something to follow it! I tried adding #break and/or #end here and there
(guesswork!) to try and MAKE it work without the #debug, but no luck so far.

#declare R = seed(4711);
#for (I, 1, 100)
  #if (rand(R) < 1.1) // always less than 1.1
     #break // terminate loop early
  #else
  #end
  // #debug concat(str(I,0,0), " iterations and counting\n")
#end


Post a reply to this message

From: William F Pokorny
Subject: Re: problem with '#break' in macro
Date: 10 Sep 2021 12:40:04
Message: <613b8a64$1@news.povray.org>
On 9/10/21 10:20 AM, jr wrote:
> hi,
> 
> William F Pokorny <ano### [at] anonymousorg> wrote:
>> On 9/7/21 5:34 AM, jr wrote:
>>> ...
>> My quick test as to whether on the right track was to create a scene
>> file like jr's original, but with macro internals looking like:
>>
>>     #if (f_)
>>       #debug "ok.\n"
>>     #else
>>       #debug "break.\n"
>>       #break
>>     #end
> 
> the intention in the code was using 'f_' as a guard, that is I added the '#else'
> only to demonstrate.
> 
Hi. What you coded is perfectly OK. I wasn't saying anything other than 
my re-code was some confirmation the 'else' token after the break was at 
the core of the problem. Your code should work!

Bill P.


Post a reply to this message

From: William F Pokorny
Subject: Re: problem with '#break' in macro
Date: 10 Sep 2021 12:54:33
Message: <613b8dc9$1@news.povray.org>
On 9/10/21 11:26 AM, Kenneth wrote:
> William F Pokorny <ano### [at] anonymousorg> wrote:
>>
>> [source code snippets]
>>
>> The variation above works for me in all v3.7+ versions I have in hand.
>>
> 
> Just discovered that the following also produces the error and fails-- unless
> the #debug is there. Seems that in this case, the inner #end actually *needs*
> something to follow it! I tried adding #break and/or #end here and there
> (guesswork!) to try and MAKE it work without the #debug, but no luck so far.
> 
> #declare R = seed(4711);
> #for (I, 1, 100)
>    #if (rand(R) < 1.1) // always less than 1.1
>       #break // terminate loop early
>    #else
>    #end
>    // #debug concat(str(I,0,0), " iterations and counting\n")
> #end
> 
Thanks! This example a stinker - my hack doesn't fix it. I don't 
immediately see a way to handle this case. After the break it reads all 
the way to through the last '#end' in both v3.8 beta 2 and my hacked 
povr code.

In other words, by the time it's done with the work to read to the end 
of the block containing the break, the parser finds itself not inside 
any nested block from which to break.

If the #debug is not commented, it stops there and breaks from the for 
loop block.

Added your test case to the others. Unsure when I might pick up looking 
at it again.

Bill P.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.