[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference iosg::all-in-1_v30

Title:*OLD* ALL-IN-1 (tm) Support Conference
Notice:Closed - See Note 4331.l to move to IOSG::ALL-IN-1
Moderator:IOSG::PYE
Created:Thu Jan 30 1992
Last Modified:Tue Jan 23 1996
Last Successful Update:Fri Jun 06 1997
Number of topics:4343
Total number of notes:18308

340.0. "Nested .IF statements" by SHALOT::NICODEM (Who told you I'm paranoid???) Thu Mar 26 1992 19:56

	OK, here's one for the script processor gurus that's had me tearing my
hair out today.  In a DO script, I have a single FOR statement that looks like:

	FOR rse DO -
	  .IF condition1 -
	    THEN -
	      .IF condition2 -
		THEN -
		  function1 -
		ELSE -
		  function2\\\\
	      function3

	That is, if 'condition1' is true, process two things: the second .IF
statement, and 'function3'.

	However, this nesting seemed to confuse the script processor, so I
changed the logic to:

	FOR rse DO -
	  .IF NOT condition1 -
	    THEN -
	      OA$NULL -
	    ELSE -
	      .IF condition2 -
		THEN -
		  function1 -
		ELSE -
		  function2\\\\
	      function3

	This still, however, did not work.  In both cases, 'function2' never got
executed, and the trace showed that ALL-IN-1 was trying to execute the command
'function2\function3' (i.e., the command dispatcher saw them both as one
function).  Reducing the four backslashes to two did, indeed, allow 'function2'
to execute; however, 'function3' then executed *all* the time, not just in the
context of the second ELSE.

	The strangest part is that I got the second example above to work... by
adding another OA$NULL:

	FOR rse DO -
	  .IF NOT condition1 -
	    THEN -
	      OA$NULL -
	    ELSE -
	      OA$NULL\\\\ -           <----------  Additional line
	      .IF condition2 -
		THEN -
		  function1 -
		ELSE -
		  function2\\\\
	      function3

	But adding that line should have made no difference at all.  It's almost
as if the first ELSE clause got confused by starting off with another .IF, and
putting the OA$NULL in "fixed" it up.  This shouldn't be necessary!

	BTW, this is V2.4; I haven't checked it on V3.0 yet.

	Any comments welcome...

	F
T.RTitleUserPersonal
Name
DateLines
340.1Continuation-sign after \\\\UTRTSC::BOSMANWe&#039;re just sugar mice in the rainFri Mar 27 1992 07:5116
    F,
    
    Maybe another problem and I don't know if it is a typo but why haven't
    you included a continuation sign after the four backslashes? The next
    example works fine for me, I get function 2 and function 3 as output.
    
    FWIW, Sjaak.
    
    FOR PROFIL WITH .USER EQS "BOSMAN" DO       -
       .IF .USER EQS "BOSMAN" THEN              -
          .IF .USER NES "BOSMAN" THEN           -
             GET OA$DISPLAY = "function 1"      -
          ELSE                                  -
             GET OA$DISPLAY = "function 2" \\\\ -
          GET OA$DISPLAY = "function 3"
    .EXIT
340.2A new meaning of the word "parsed"...SCOTTC::MARSHALLPearl-white, but slightly shop-soiledFri Mar 27 1992 12:048
Nested .IF statements are notoriously hazardous, due to the interesting way
they are "parsed".  My advice would be to avoid them: even if you get it to
work, a subsequent, seemingly innocuous, change to the code could break it.

However, in V3.0 there are new script directives .THEN and .ENDIF, which allow
conditionals to be nested more easily.

Scott
340.3More on syntax ... UTRTSC::BOSMANWe&#039;re just sugar mice in the rainFri Mar 27 1992 12:243
    Re -1: See 80 (.3)
    
    Sjaak.
340.4Maybe it's just a philosophical question, but...SHALOT::NICODEMWho told you I&#039;m paranoid???Fri Mar 27 1992 18:109
	RE: .1 -- Yes, it was a typo; there *is* a continuation marker on each
line.

	RE: .0 -- What I was most interested in was *WHY* the addition of an
OA$NULL function made the line "work"!  The only difference between my second
and third examples was that silly OA$NULL, yet it made the difference in the
operation of the line.  Why?

	F
340.5Bug in the "grammatical syntax tree"... :-)IOSG::TALLETTJust one more fix, then we can ship...Mon Mar 30 1992 11:3517
    
    	The script processor looks for lines starting with a "." and
    	treats them differently, compare these two:
    
    	.if xxx then .goto blah
    
    	and
    
    	.if xxx then oa$null \\ .goto blah
    
    	The second one is illegal (if I got the wrong number of backslashes
    	I am sorry, but I never understood them!).
    
    	I have had a similar problem with FOR loops and needed an OA$NULL.
    
    Regards,
    Paul
340.6if you only knew how dumb ALL-IN-1 was.....SHALOT::WARFORDRichard Warford @OPA DTN 393-7495Tue Mar 31 1992 02:3657
    You don't really want to hear about this do you Frank????
    It has to do with 2 things, 1 the number of times you went through the
    COMMAND dispatcher, and 2, the way a .IF is parsed.
    
    Starting with the easy one, when a .IF is encountered, ALL-IN-1 looks
    for a THEN and and ELSE to break the statement up into the clauses it
    needs. Thus in your first example the ELSE is seen as part of the 
    FIRST if, not the second. So it would only do function 2 if condition1
    were false. ALL-IN-1 isn't smart enough to know that your inside a
    second .IF and to go to the end and look backwards for the ELSE, it
    just assumes the first ELSE must go with the first .IF.
    
	FOR rse DO -
IF	  .IF condition1 -
THEN	    THEN -
	      .IF condition2 -
		THEN -
		  function1 -
ELSE		ELSE -
		  function2\\\\
	      function3

    
    Your second attempt fixes this by adding the second ELSE which
    makes things balance. BUT it has the wrong number of backslashes!
    It might look right, but its wrong. Remeber my old formula:
    backslashes = 2 (to the power of [times through COMMAND dispatcher]-1)
    
    Anything beging with a . after a THEN or an ELSE does not go back
    to the command dispatcher. So in your example 2 you will find that
    the second .IF has only been through the command dispatcher twice
    which requires 2 backslashes (2^[2-1]). But this would have been
    confusing to the FOR function. You really need to force 4 backslashes
    to make the FOR function happy. You could have fixed this via
    a .FU (thereby forcing the command dispatch to happen again). Your use
    of the OA$NULL causes it to NOT be a '.' after the THEN and so it
    goes to the command dispatcher again for the second .IF. Leaving off
    the . on the .IF use to also work, but I don't know if it still would.
    All of this is courtesy of the consistency of use of backslashes :^)
    between scripts and functions!
    
	FOR rse DO -
	  .IF NOT condition1 -
	    THEN -
    	      OA$NULL -
	    ELSE -
	      .FU .IF condition2 -
		THEN -
		  function1 -
		ELSE -
		  function2\\\\
	      function3

    
    Now I bet your more confused than you were, and wish you hadn't asked.
    
    Rick
340.7Return of tyhe backslashes!AIMTEC::WICKS_AVote Bill&#039;n&#039;Opus for a weirder USATue Mar 31 1992 03:4318
    Rick,
    
    Only last week someone here at the CSC was asking where the "secret
    backslash formula" was defined and being too lazy to search for it
    in one of the old notes file I cheated and pulled it from the class
    you gave in Reading in June of 87 - now it lives in notes once more!
    
    there is the old saying "whenever 2 or more application programmers
    gather together then they shall recite the backslash formula
    2 to the power of number of times through the command dispatcher -1"
    
    Of course you don't need all those backslashes anymore with the new
    syntax stuff or so my old neighbour Ian told me and he's always right.
    
    Regards,
    
    Andrew.D.Wicks
                                     
340.8Frank so loves that formula - don't ya Frank!SHALOT::WARFORDRichard Warford @OPA DTN 393-7495Tue Mar 31 1992 15:466
    Talking about that formula always caused glassy eyes.... The major
    problem being most people don't know when you go though the command
    dispatcher levels.
    
    I just thought I'd pull it out to make Frank wish he hadn't asked
    his question!
340.9A different approachUTRTSC::BOSMANWe&#039;re just sugar mice in the rainTue Mar 31 1992 16:1716
    You don't even have to use backslashes if you negotiate the expression
    and jump over the clause!! This will always work!!
    
    .IF NOT (expression) THEN .GOTO else_if
    
       {IF clause when expression is true}
    
       .GOTO end_if
    .LABEL else_if   
    
       {ELSE clause when expression is false}
    
    .LABEL end_if
    
    
    Regards, Sjaak.
340.10But that would require a DO DOSHALOT::WARFORDRichard Warford @OPA DTN 393-7495Wed Apr 01 1992 04:478
    Unfortunately .-1 wouldn't work in Frank's example, because you cannot
    do .GOTOs while you are inside the FOR function!
    
    He'd haveto do a FOR x DO DO y. And DO DO's should be considered
    DON'Ts! The IO of opening and closing the file for each iteration
    can be quite time consuming.
    
    RIck
340.11FOR {condition} DO .FX DO script etc.UTRTSC::BOSMANWe&#039;re just sugar mice in the rainWed Apr 01 1992 08:570
340.12why does my brain hurt???WPOPTH::BEESONDown Under in the bottom left cornerMon Apr 06 1992 12:2321
    One point on the new .THEN...
    
    You cannot use a flow control . command (ie: .ABORT, .EXIT or .GOTO)
    from within one of these little beauties. Therefore half the time you
    have to go back to the golden oldie format and half the time that won't
    work like Frank's *SENSIBLE* example. (the second two are hard logic to
    follow and make for a maintenance nightmare.)
    
    I know I'll get yelled at but why is this sooooo hard! All I wanted to
    do is write a little script... I know I'll do it like this:
    
    	FOR {condition} DO COMMAND dcl_command_procedure
    
    then I'll be able to IF..THEN..ELSE to my hearts content. It may be
    slow but at least I'll know it works! (and the customer will buy a
    bigger box anyway!)
    
    regards,
    ajb
    
    PS: I'm not being serious, just sarcastic. ;-)
340.13Not that this makes it any clearer, but...SHALOT::NICODEMWho told you I&#039;m paranoid???Mon Apr 06 1992 18:1429
	It gets back to the fact that the argument to the THEN or ELSE clause
has to be either another script directive (e.g., .GOTO, .EXIT, .IF), or a single
command line.  The backslashes get confusing, since each pass through the
command dispatcher, backslashes are "halved" (i.e., two become one) -- just like
processing double quotes within a quoted string.

	So the "fun" is in determining just how many times this little "halving"
has been done.  That's what Rick's formula attempts to do.  The other way around
the problem, of course, is to "shield" the command line from this "backslash
biter", and make sure that it never gets processed until it's time to actually
execute the command line.  One way to do this is to use the GET OA$FUNCTION
syntax, since -- up until the time that the GET OA$FUNCTION gets executed --
its argument is merely a string... nothing more, nothing less.

	So let's suppose we're "buried" at a level that would normally require
8 backslashes:

	...
	    ELSE -
		function1\\\\\\\\ -
		function2\\\\\\\\ -
		function3

	You *could* reduce this "clutter" by doing something like:

	...
	    ELSE -
		GET OA$FUNCTION = "function1\function2\function3"