|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Is it possible to start a loop in a macro using a variable name passed into the
macro?
I think not, but maybe it's one of those #write #read workaround things.
Like so:
#macro Loop (_Var, _Begin, _End, _Step)
#for (_Var, _Begin, _End, _Step)
....
#end
#end
Along the same lines, is it possible to assign an image_map file type to a
variable
like png, jpeg, etc. ?
Post a reply to this message
|
|
| |
| |
|
|
From: clipka
Subject: Re: passing variable to macro for use in #for statement
Date: 19 Sep 2018 13:57:47
Message: <5ba28e1b$1@news.povray.org>
|
|
|
| |
| |
|
|
Am 19.09.2018 um 17:58 schrieb Bald Eagle:
> Is it possible to start a loop in a macro using a variable name passed into the
> macro?
>
> I think not, but maybe it's one of those #write #read workaround things.
>
> Like so:
> #macro Loop (_Var, _Begin, _End, _Step)
> #for (_Var, _Begin, _End, _Step)
> ....
> #end
> #end
That depends on what you actually want to achieve.
If you actually want to pass the /name/ of an identifier into the macro
(presumably as a string), you're pretty much out of luck.(*)
Theoretically you could probably use:
#macro Loop (VarName, Begin, End, Step)
#for (Parse_String(VarName), Begin, End, Step)
...
#end
#end
Loop("Fnord",0,10,2)
but then the loop will actually use the macro-local variable `Fnord`,
not some global variable.
If however you just pass the variable itself (rather than its name),
then the following should work fine:
#macro Loop (Var, Begin, End, Step)
#for (Var, Begin, End, Step)
...
#end
#end
#local Fnord = 42;
Loop(Fnord,0,10,2)
#debug concat("Fnord is now ", str(Fnord,0,0), "\n")
In this case, the macro-local name `Var` is used as an alias for the
"more global" variable named `Fnord`, and the for loop should use
exactly that same variable.
(* As of v3.8.0-alpha, another approach /may/ be viable; I haven't
tested it, and it may or may not work:
#macro Loop (VarName, Begin, End, Step)
#for (global[VarName], Begin, End, Step)
...
#end
#end
#declare Fnord = 42;
Loop("Fnord",0,10,2)
#debug concat("Fnord is now ", str(Fnord,0,0), "\n")
If this works, it's because along with the introduction of dictionaries,
two pseudo-dictionaries have been added, `global` and `local`, which
allow access to the global and "most local" variables, respectively,
using dictionary-style syntax.
The caveat is that `#for` is specifically designed to use a local
variable as the loop counter, and it may gag on this construct. )
> Along the same lines, is it possible to assign an image_map file type to a
> variable
> like png, jpeg, etc. ?
Only using the `Parse_String` approach (or an equivalent homebrew
`#write`/`#include` workaround; as a matter of fact that's how the
`Parse_String` macro works behind the scenes):
#declare Format = "png";
image_map { Parse_String(Format) "foo.png" }
In the case of `image_map` it's probably easier and cleaner to use the
filename extension to convey the type information.
Also reasonably clean would be the following construct:
#macro FormatKeyword(Format)
#if (Format = "png")
png
#elif (Format = "jpeg")
jpeg
....
#end
#end
#declare Format = "png";
image_map { FormatKeyword(Format) "foo.png" }
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
clipka <ano### [at] anonymousorg> wrote:
> If however you just pass the variable itself (rather than its name),
> then the following should work fine:
>
> #macro Loop (Var, Begin, End, Step)
> #for (Var, Begin, End, Step)
> ...
> #end
> #end
> #local Fnord = 42;
> Loop(Fnord,0,10,2)
> #debug concat("Fnord is now ", str(Fnord,0,0), "\n")
Hmmm. yes, that will work just fine.... in most cases...
Though I'm trying to only /initiate/ a loop with the macro - so the #end of the
for loop is what I need to avoid at the present.
I have not yet figured out if there's a syntax trick that's possible.
like so:
Loop(Fnord,0,10,2)
[loop contents NOT in macro]
#end
> Also reasonably clean would be the following construct:
>
> #macro FormatKeyword(Format)
> #if (Format = "png")
> png
> #elif (Format = "jpeg")
> jpeg
> ....
> #end
> #end
>
> #declare Format = "png";
> image_map { FormatKeyword(Format) "foo.png" }
Right - o. That'll be great. Especially since I can just use a string
function to look at the extension of the filename and avoid the declare
altogether. :)
Post a reply to this message
|
|
| |
| |
|
|
From: clipka
Subject: Re: passing variable to macro for use in #for statement
Date: 20 Sep 2018 11:00:09
Message: <5ba3b5f9$1@news.povray.org>
|
|
|
| |
| |
|
|
Am 20.09.2018 um 16:09 schrieb Bald Eagle:
> Though I'm trying to only /initiate/ a loop with the macro - so the #end of the
> for loop is what I need to avoid at the present.
> I have not yet figured out if there's a syntax trick that's possible.
Can't do such a thing. The `#end` directives in a macro must always be
balanced - otherwise, how would the parser be able to figure out where
the macro ends.
>> #declare Format = "png";
>> image_map { FormatKeyword(Format) "foo.png" }
>
> Right - o. That'll be great. Especially since I can just use a string
> function to look at the extension of the filename and avoid the declare
> altogether. :)
If the file type can already be inferred from the extension, Why not let
POV-Ray do that job? Just leave out the file format keyword, like so:
image_map { "foo.png" }
and Bob's your uncle.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
clipka <ano### [at] anonymousorg> wrote:
> Am 19.09.2018 um 17:58 schrieb Bald Eagle:
> > Along the same lines, is it possible to assign an image_map file type
> > to a variable-- like png, jpeg, etc. ?
>
> ...reasonably clean would be the following construct:
>
> #macro FormatKeyword(Format)
> #if (Format = "png")
> png
> #elif (Format = "jpeg")
> jpeg
> ....
> #end
> #end
>
> #declare Format = "png";
> image_map { FormatKeyword(Format) "foo.png" }
Hey, that's GREAT! I struggled with this idea years ago, and had to use some
ugly kludges to get this result. Using a macro didn't occur to me (I probably
thought it wouldn't work.) Thanks, it's a really nice construct.
This would be the (longer) way that I would write such a macro (just for
visual/mental clarity):
#macro FormatKeyword(Format)
#if (Format = "png")
png
#else
#if(Format = "jpeg")
jpeg
#else
#if(Format = "bmp")
bmp
#else
#end
#end
#end
#end // of macro
#declare Format = "png";
box{0,1
pigment{
image_map{FormatKeyword(Format) "crater demo as PNG.png" interpolate 2}
.... which works very nicely.
A couple of questions/observations, though: The docs say two things at
"3.3.2.6.1 The if...else...end Directives" (in v3.7.1 beta 9's help file--
although I haven't yet checked the online wiki):
"...an optional #elseif clause is now supported."
and
"NOTE: Nesting directives in the following manner has been known to cause
problems during the parse phase.
#if( #if(yes) yes #end ) #end
"
The even shorter keyword #elif (for #elseif) is not mentioned there (even
though it works); and, its keyword 'color' in scsne code looks like a
'non'-keyword. Should both of those little errors be fixed?
More importantly, I've never had a problem using nested #if's (when including
all of the #else keywords, anyway.) I *think* my macro is a good demonstration
of what the docs mean by nested #ifs as explained there(?) So are the new
keywords #elseif and #elif designed to eliminate any *possible* nested-#ifs
problems (along with being 'shorthand' versions of such constructs)? Just
curious.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
"Kenneth" <kdw### [at] gmailcom> wrote:
>
> More importantly, I've never had a problem using nested #if's (when including
> all of the #else keywords, anyway.) I *think* my macro is a good demonstration
> of what the docs mean by nested #ifs as explained there(?)
Hmm, I see now that my macro's nested #if's and the docs' example are different
animals.
The docs'
#if( #if(yes) yes #end ) #end
clause is trying to construct a boolean "yes" within its inner #if (for use
within the outer #if?), which is rather odd-- and different from my macro's
straightforward use of nested #if's.
Post a reply to this message
|
|
| |
| |
|
|
From: clipka
Subject: Re: passing variable to macro for use in #for statement
Date: 20 Sep 2018 15:58:03
Message: <5ba3fbcb@news.povray.org>
|
|
|
| |
| |
|
|
Am 20.09.2018 um 20:56 schrieb Kenneth:
>> #macro FormatKeyword(Format)
>> #if (Format = "png")
>> png
>> #elif (Format = "jpeg")
>> jpeg
>> ....
>> #end
>> #end
...
> A couple of questions/observations, though: The docs say two things at
> "3.3.2.6.1 The if...else...end Directives" (in v3.7.1 beta 9's help file--
> although I haven't yet checked the online wiki):
>
> "...an optional #elseif clause is now supported."
Whoops, my bad: It's `#elseif`. The construct isn't too uncommon in
programming languages, but the languages can't agree on whether it
should be `elseif`, `elsif` or `elif` (or a variation thereof as the
programming language's meta-structure permits, such as POV-Ray's `#elseif`).
Examples of Elseif-Languages:
- Ada
- POV-Ray SDL
- Visual Basic
Examples of Elsif-Languages:
- Perl
- Ruby
Examples of Elif-Languages:
- C/C++ Preprocessor
- Python
- Unix shell scripts
> The even shorter keyword #elif (for #elseif) is not mentioned there (even
> though it works); and, its keyword 'color' in scsne code looks like a
> 'non'-keyword. Should both of those little errors be fixed?
Actually, no, it doesn't work: That's a mirage. If you examine it more
carefully, you'll find that the construct only behaves as expected if
both the `#if` condition and `#elif` conditionoid happen to be false;
because in that case the bogus `#elif` statement will simply be skipped.
If the `#if` condition happens to be true, the parser will parse the
`#if` branch and then crash right into the `#elif` like a brick wall,
and if the `#elif` conditionoid happens to be true, the parser will
still skip over it and enter the `#else` branch.
> More importantly, I've never had a problem using nested #if's (when including
> all of the #else keywords, anyway.) I *think* my macro is a good demonstration
> of what the docs mean by nested #ifs as explained there(?) So are the new
> keywords #elseif and #elif designed to eliminate any *possible* nested-#ifs
> problems (along with being 'shorthand' versions of such constructs)? Just
> curious.
Properly nested `#if` statements are not a problem. The problem
described in the docs specifically relates to nesting an `#if` in the
/condition/ of an enclosing `#if`.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
clipka <ano### [at] anonymousorg> wrote:
> Am 20.09.2018 um 20:56 schrieb Kenneth:
>
> > The even shorter keyword #elif (for #elseif) is not mentioned there (even
> > though it works)...
>
> Actually, no, it doesn't work: That's a mirage. If you examine it more
> carefully, you'll find that the construct only behaves as expected if...
Oh, sorry. I didn't thoroughly test the #elif keyword; I used your macro
construct as-is (basically), and it just *happened* to work in my case, or
appeared to.
Caveats noted!!
Post a reply to this message
|
|
| |
| |
|
|
From: clipka
Subject: Re: passing variable to macro for use in #for statement
Date: 20 Sep 2018 17:25:36
Message: <5ba41050$1@news.povray.org>
|
|
|
| |
| |
|
|
Am 20.09.2018 um 22:43 schrieb Kenneth:
> clipka <ano### [at] anonymousorg> wrote:
>> Am 20.09.2018 um 20:56 schrieb Kenneth:
>
>>
>>> The even shorter keyword #elif (for #elseif) is not mentioned there (even
>>> though it works)...
>>
>> Actually, no, it doesn't work: That's a mirage. If you examine it more
>> carefully, you'll find that the construct only behaves as expected if...
>
> Oh, sorry. I didn't thoroughly test the #elif keyword; I used your macro
> construct as-is (basically), and it just *happened* to work in my case, or
> appeared to.
Yeah, been there, done that. When you mentioned that both `#elseif` and
`#elif` seemed to work, I was like "huh? I'm not sure which of the two I
implemented, but I'm pretty darn sure I didn't implement both" - did a
short test myself, and lo and behold - `#elif` didn't produce an error.
So yeah, `#elif` must be what I had implemented, and I must have screwed
up the docs, accidently communicating it as `#elseif`...
Just for funsies and because I always love to double-check even if I
/know/ the results [hah!], let's just replace `#elif` with `#elseif` to
prove my point...
... huh? That didn't produce an error either; did I /really/ implement
both alternatives? Wow, clever me...
... um, wait, WTF?! Didn't that scene behave differently with `#elif`?!
Now I'm officially puzz...
... D'OH! - yeah, THAT is what's happening...
I love the smell of truth dawning on me.
Post a reply to this message
|
|
| |
| |
|
|
From: dick balaska
Subject: Re: passing variable to macro for use in #for statement
Date: 21 Sep 2018 00:51:03
Message: <5ba478b7$1@news.povray.org>
|
|
|
| |
| |
|
|
On 09/20/2018 02:56 PM, Kenneth wrote:
>
> This would be the (longer) way that I would write such a macro (just for
> visual/mental clarity):
>
> #macro FormatKeyword(Format)
> #if (Format = "png")
> png
> #else
> #if(Format = "jpeg")
> jpeg
> #else
> #if(Format = "bmp")
> bmp
> #else
> #end
> #end
> #end
> #end // of macro
>
I would write:
#macro FormatKeyword(Format)
#if (Format = "png") png #end
#if (Format = "jpeg") jpeg #end
#if (Format = "bmp") bmp #end
#end
--
dik
Rendered 1024 of 921600 pixels (0%)
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|