mIRC Home    About    Download    Register    News    Help

Print Thread
#26170 26/05/03 06:48 PM
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
OP Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
Apparently mIRC has some issues when parsing a complex if statement. The statement I have is:
if (!(%i == %len || (%i > 1 && $iscsptg(%p)))) { ..... }

mIRC says:
* /if: invalid format

Well, mIRC is the only one that seems to agree with that analysis. When I use that same line of code (variables/identifiers changed) in C, and in php, and in perl it works fine, no syntax errors.

So why does mIRC seem to think that format is invalid? The parenthesis match up, etc.

Yes I could just rewrite the if statement to get it to work the way I need it to. Using De Morgan's laws I can rewrite it as:

if (%i != %len && !(%i > 1 && $iscsptg(%p))) { ..... }

And then it works perfectly. But like I said it's not an issue of "how can I make this work" it's an issue of "why does mIRC seem to think this shouldn't work"

Joined: Dec 2002
Posts: 39
L
Ameglian cow
Offline
Ameglian cow
L
Joined: Dec 2002
Posts: 39
yes, same problem here. mIRC 6.03, WINDOWS XP
mm I think mIRC does not like !(%a == b) comparison...
I tried // if ((3 != 4)) { echo -a blah | else echo -a bloh } and worked fine
but when i tried with (!(3 == 4)) it echoed nothing

Last edited by Larra; 26/05/03 07:44 PM.
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
OP Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
Yea that appears to be the problem, but it does allow it on sub-expressions, like I said, if (%i != %len && !(%i > 1 && $iscsptg(%p))) { ..... } that works fine, even though it has a !(....), it seems to just not like it when the entire expression is negated, which imho is a bug.

Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
Somebody has to read the help file more carefully. Where does it say that you can use the ! mark for subexpressions?
Help file:
The ! not prefix
You can use the ! prefix in front of variables and identifiers in an if-then-else statement to negate a value. The following statements are equivalent.

if (%x == $null) echo x has no value

if (!%x) echo x has no value


There is no bug here. If you want proof, try this:
Code:
//if (1 != 2 && !(3 > 4 && $upper(0))) { echo -s works: $ifmatch }
It does nothing.

What mirc does when it sees the && !(3 > 4 part is consider "!(3" a literal string, so the > operator does a string comparison. You can see that more clearly from the following example:
Code:
//if (1 != 2 && !(3 != 4 || 0)) { echo -s works: $ifmatch }


Another example:
Code:
//if (1 != 2 && !(3 != 4 && 0)) { echo -s works: $ifmatch }
Can you guess what mirc does here? After treating "!(3" as a string and finds out it is not equal to 4, it moves on the next comparison: it considers "0)" the entire subexpression after the last && operator. Of course, it is true, since the string "0)" is definitely not $null or zero. So $ifmatch gets filled with it.


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
OP Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
Well then this further proves my point of "mIRC needs a new parsing engine." In the sense of expression parsing, I am using it in front of an identifier, in front of the identifier $true or the identifier $false, because that is what the subexpression of a boolean operation should evaluate to. You may see a subexpression being negated as being different than putting it directly in front of an identifier, but programatically and mathematically it is equivilent. Like I said, it can be done in a different way, but let me ask, how many people here are familiar with De Morgan's Laws of logical equivilence? That is,
!(a && b) == (!a || !b)
!(a || b) == (!a && !b)
I'm sure the majority of scripters have never heard of these laws. It makes it harder to code things when you know you want !(a && b) and you have to think, what other way can I write this without using a not operation on a subexpression? It can be especially difficult if you are unfamiliar with the formulas that allow you to do it. Imho, regardless of whether it is a "bug" it is still a flaw.

Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
I suppose it depends greatly on how you're use to thinking. Also, I believe that you end up wasting more resources than its worth when you try and negate an entire group of || conditions. Example.

if (!$true) || (!$false) || (!$false) { }
mIRC will stop evaluating when it hits the second condition, because it knows it already succeeded. the third condition is never evaluated.

if !($true && $false && $false) { }
In this example, all three conditions MUST be evaluated in order to determine the negated result, no matter how redundant the third condition is.

Just as we don't speak in double-negatives, it's usually good to avoid coding in double negatives aswell. There are times when it is appropriate to use a double-negative, but just about as common as to use one in speech.

- Raccoon


Well. At least I won lunch.
Good philosophy, see good in bad, I like!
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
OP Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
Well yes and no, in an && expression, as soon as you hit something that evaluates to false, the entire expression evaluates to false; thats just the definition of an and operation. So in your example, if !($true && $false && $false), it would (or rather should), just evaluate the first $true and then the $false, then stop, negate that, and have an overall value of $true. The third argument is irrelevant. $false && $false == $false, $false && $true == $false, so no matter what that last argument is, the expression will still evaluate to false, so it should not be checked, and in most languages it is not, I don't know for a fact how mIRC internally does it. And as for speaking in double negatives, it is very common in both English and in programming, the phrase "not unlike" translates to "like," for example. You are right, for simple expressions, it is rather easy to translate it but for example:

if (!(!(a && b) || !(c && d)) || !(a && e))
becomes:
if ((a && b && c && d) || (!a || !e))
[and I may have done the math wrong, it is midnight...]

Would the final result be obvious to you looking at the original? You are right, the latter is much more simplistic, and much faster, but often the work involved in translating A to B makes it easier to just let the parser do it for you.

Joined: Feb 2003
Posts: 307
T
Fjord artisan
Offline
Fjord artisan
T
Joined: Feb 2003
Posts: 307
alwais close eache statement like if ((..) || (...) && (...)) {}
its faster and bugless

in your case try like this
if (!(%i == %len) || (%i > 1 && $iscsptg(%p))) { ..... }


Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
OP Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
Well the line you pasted doesn't even come close to doing what I want, and even if it did, it still doesn't work in mIRC, a ! is not supported in front of a subexpression.

Joined: Apr 2003
Posts: 426
Fjord artisan
Offline
Fjord artisan
Joined: Apr 2003
Posts: 426
codemaster is quite correct.


--------
mIRC - fun for all the family (except grandma and grandpa)

Link Copied to Clipboard