mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Feb 2005
Posts: 10
R
Roanoke Offline OP
Pikka bird
OP Offline
Pikka bird
R
Joined: Feb 2005
Posts: 10
Possibly the best programming function has the ability to handle multiple possibilitys in a variable.

vb script
Select Case variable
Case "PARAM"
cmd
Case "Param 2"
cmd
Case else
cmd

End select

A variant could be used for mirc.

Select Case (%variable/data) {
Case (Data) {

}
Case (Data) {

}
Case Else {

}
}

Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
My personal beleive is mircs scripting langauge must be hard enough for Khaled to maintain now, I would guess 80% or more of the bugs he has to work out are in the script processing parts (just an opion).
So based on that I dont see the need for a select case construct. it can be reproduced with IF and ELSEIF

if (%variable == data1) { ... }
elseif (%variable == data2) { ... }
elseif (%variable == data3) { ... }
else { ... }

If u need it to use drop through logic like java

var %dropthrough = $false
if (%variable == data1) { ... | %dropthrough = $true }
if (%variable == data2 || %dropthrough == $true ) { ... | %dropthrough = $true }
if (%variable == data3 || %dropthrough == $true ) { ... | %dropthrough = $false }
else { ... }

Joined: Dec 2002
Posts: 2,962
S
Hoopy frood
Offline
Hoopy frood
S
Joined: Dec 2002
Posts: 2,962
Both of those are inefficient as hell and twice as ugly. A cascading switch/case statement would be a very practical addition to the scripting language. And not that it really matters but from looking at the first screen of the bugs forum there's a 2:1 ratio of legitimate non-scripting bugs vs. legitimate scripting bugs.


Spelling mistakes, grammatical errors, and stupid comments are intentional.
Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
Oh i never said they were pretty, And Im not strictly against it, just felt it fell into the same kinda aurguement as with FOR NEXT loops, since a while loop can do the same thing, are they needed?

I didnt think it would be overly inefficient, a select case would get the initial value and compare it to each case untill matched, I guess the internal processing of each case compare over mirc having to pharse the lines its comparing might speed it up some, but it would have to be a heavyly used script to make much difference (lots of reps).

If its just cosmetics of course, then sure lets have a select case, they do make the code easier to read, then again you could build your own without much hassle. And almost the exact syntax smile

select.case %variable
if $case(data1) { ... }
if $case(data2) { ... }
if $case.else { ... }
select.end

I thought of having just $case(data1) { ... } but from memory mirc doesnt like you returning it /IF it sends the /IF as a command to the server, which is a bit of a bummer.

Joined: Feb 2005
Posts: 10
R
Roanoke Offline OP
Pikka bird
OP Offline
Pikka bird
R
Joined: Feb 2005
Posts: 10
If you look briefly at how mIRC is created you can determine how easy it is to impliment it and how much strain it will cause to a script.

Code:
   ; Information is linked simply enough. In good code the commands are created with a design for expansion.

Select Case <Variable> {

  Case (DATA)
    ; The variable set in active memory.. So by calling a variable it takes less memory...  
  Case Else
    ; The overhead and memory required for an if statement to be ran, is vertually the same as a Case statement.
    ; A few variables IE 3 will remain in memory until finish of the Case Segment.
}
    ; The code itself will look cleaner, and allow for users to understand the creators code easier.
  


I hope I have been informative. :-)

Joined: Dec 2002
Posts: 2,962
S
Hoopy frood
Offline
Hoopy frood
S
Joined: Dec 2002
Posts: 2,962
A for loop isn't really the same. The C-style for loop is precisely the same functionality as a while loop except presented in a slightly different way (and not necessarily a cleaner or prettier way). The only practical difference is that in a language like C it allows the compiler to optimize the iterating peice of code, which in other words means it would have no benefits in mIRC script. The other common type of for loop iterates over sequences, which, seeing as mIRC has no sequence types/objects, has no relevance. A select statement on the other hand provides efficiency bonuses since the condition is evaluated only once. It can be emulated with pretty much the same effect using goto, but it's a hack that has many flaws and potential pitfalls.


Spelling mistakes, grammatical errors, and stupid comments are intentional.
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
er
im stealing this trick, but using gotos can emulate switches...

Code:
alias some_switch {
goto $1
:case_one
:case_two
echo -a case 1&2
return
:case_three
}


right there... that has dropthrough logic as well, both /some_switch case_one and case_two will yield the same result

-argv


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Aug 2003
Posts: 1,831
I
Hoopy frood
Offline
Hoopy frood
I
Joined: Aug 2003
Posts: 1,831
Yeah actually using a var handles a default also.
Code:
alias some_switch {
  var %a = $$1 | goto %a
  :one
  :two
  echo -a case 1&2
  return
  :%a 
  echo -a Default
}

//some_switch one | some_switch two | some_switch notdefined

Joined: Nov 2003
Posts: 2,327
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Nov 2003
Posts: 2,327
That's a perfect workaround, but imagine checking about 20 conditions with :labels, it will become very messy.

Something like this would be much better:

Code:
alias blah {
  var %x = 12
  switch (%x) {
    case (1) {
      echo -a %x is 1
      break
    }
    case ($calc(10+1)) {
      echo -a %x is 11
      break
    }
    default { echo -a %x is %x }
  }
  ;more code can go here.
}


New username: hixxy
Joined: Dec 2002
Posts: 2,962
S
Hoopy frood
Offline
Hoopy frood
S
Joined: Dec 2002
Posts: 2,962
It's functional for basic uses but as I said in my previous post, it's a hack which has problems in certain situations.
ie.
Code:
moo {
  var %a = $1
  this line causes an error!
  goto %a
  :one
  echo -a one!
  :two
  echo -a two!
  :%a
  return
  :error
  echo -a error!
  reseterror
}


/moo blah correctly triggers the error handling code, but then try /moo error and... oh crap. Of course it's not limited to error handling, using goto in this way means that any other use of goto outside of the switch/case usage will be potentially 'hijacked' aswell. And did I mention it was ugly?


Spelling mistakes, grammatical errors, and stupid comments are intentional.
Joined: Feb 2005
Posts: 10
R
Roanoke Offline OP
Pikka bird
OP Offline
Pikka bird
R
Joined: Feb 2005
Posts: 10
I have come up with a practical way in the mean time... but it takes up 2 and a half pages of code..
Code:
  
alias SELECT {
  if ($1 = CASE) {
    STRING SET GLOBAL SELECT_CASE $2-
    return $true
  }
  if ($1 = END) {
    STRING DELETE GLOBAL SELECT_CASE
  }
}

alias CASE {
  STRING GET GLOBAL SELECT_CASE
  var %SELECT_CASE = $result
  if ($prop = CS) {
    return $iif($1- === %SELECT_CASE, return $true)
  }
  if ($prop = ISIN) {
    return $iif($1- isin %SELECT_CASE, return $true)
  }
  if ($prop = ISWM) {
    return $iif($1- iswm %SELECT_CASE, return $true)
  }
  if ($prop = ISWMCS) {
    return $iif($1- iswmcs %SELECT_CASE, return $true)
  }
  return $iif($1- = %SELECT_CASE, return $true)
}


alias STRING {
  if ($1 = SET) {
    hadd -m $2 $3 $4-
    return $TRUE
  }
  if ($1 = GET) {
    return $hget($2 , $3)
  }
  if ($1 = DELETE) {
    hdel $2 $3
    return $TRUE
  }
  if ($1 = CLEAR) {
    hdel $2
    return $TRUE
  }
  :ERROR
  echo -s $error
  reseterror
  return $FALSE
} 



The code may not be very efficiant in itself.. and lacks an ELSE statement but it does allow for special paramitors like iswm (in if statement) as well as other stuff.. like that
It allows for much prettier code and helps the Scripter to be less redundant in his/her codeing.


(Take a look)

Code:
  

SELECT CASE $1
if $case(*string*).iswm {
  echo the string is in $1
}
if $CASE(STRING).cs {
  echo the variable == string
}
SELECT END


Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
Thats script is very close to what I originally posted the example script for, but mine didnt have the $prop additions * very good idea * , but i have added it in this one. Also this one, allows for nested case statements (assuming you end the case statment with a /select.end) and supports drop through logic and case.else.


Code:
alias select.case {
  if (%select.case.hashtables.cleared != $true) {
    hfree -w select.case
    hfree -w case.select.matched
    hfree -w case.select.exit
    ; * Hashtables need to be empty per code execution, buggy scripts might leave something in them.
    ; * Also cant use -u0 or -u option on items as it doesnt function the same as with /set
  }
  set -u %select.case.hashtables.cleared $true
  var %i = $hget(select.case,0).item
  inc %i
  hadd -m select.case %i $1-
  hadd -m case.select.matched %i %case.select.matched
  hadd -m case.select.exit %i %case.select.exit
  set %case.select.matched $false
  set %case.select.exit $false
}
alias select.end {
  var %i = $hget(select.case,0).item
  set -u %case.select.matched $hget(case.select.matched,%i)
  set -u %case.select.exit $hget(case.select.exit,%i)
  hdel select.case %i
  hdel case.select.matched %i
  hdel case.select.exit %i
}
alias select.exit {
  set -u %case.select.exit $true
}  
alias case {
  if (%case.select.exit) { return $false }
  if (%case.select.matched == $true) { return $true }
  var %i = $hget(select.case,0).item
  ;
  if $istok(= == === < > >= <= // \\ & isin isincs iswm iswmcs isnum isletter ison isop ishop isvoice isreg isaop isavoice isignore isprotect != !== !=== !< !> !>= !<= !// !\\ !& !isin !isincs !iswm !iswmcs !isnum !isletter !ison !isop !ishop !isvoice !isreg !isaop !isavoice !isignore !isprotect,$prop,32) { var %prop = $prop } | else { var %prop = == }
  if ($1- [ %prop ] $hget(select.case,%i)) { set -u %case.select.matched $true | return $true }
  ;
  ; *** originaly just had this line >>>>> if ($1- == $hget(select.case,%i)) { set -u %case.select.matched $true | return $true }
  ;
  return $false
}
alias case.else {
  if (%case.select.exit) { return $false }
  if (%case.select.matched) { return $false }
  set -u %case.select.matched $true
  select.exit
  return $true
}  
;
;
; EXAMPLE BELOW
;
;
alias test {
  select.case $1
  if $case(fred) { echo -a fredo }
  if $case(dave) { echo -a davo 
    select.case $2
    if $case(1) { echo $!2 is one | select.exit }
    if $case(3) { echo $!2 is three }
    if $case(2) { echo $!2 is two or it was three if said above }
    if $case.else { echo $!2 is not one, two or three }
    select.end
  }
  if $case(greg).=== { echo -a greg the bunny shoots himself and thats the end of that. | select.exit }
  if $case(*m*).iswm { echo -a M is present }
  if $case.else  { echo -a ELSE someone else duh! }
  select.end
}


* I dont think case.else is ment to run in a drop trough is it? I set it not to. also a case.else well do a case.exit so u cant do other IF $case()'s

Joined: Feb 2005
Posts: 10
R
Roanoke Offline OP
Pikka bird
OP Offline
Pikka bird
R
Joined: Feb 2005
Posts: 10
Yeah its not but it can be ignored if you have $case($null).else which is also a hack about it but unless the (<space/data>) is in the $0- Token there is no way for MIRC to figure out how it is supposed to work...

as for the multiple case statements.. its a brilliant idea but i think it can be coded a bit better... because there is an error in your code for the CASE.ELSE statement...
It only goes to the lowest level.. .. and forgets about the ones behind it.... so you might want to fix that otherwise leave the case.else out of the statement until it is fixed...



Last edited by Roanoke; 03/03/05 05:38 PM.
Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
$case.else works on the princible two global identifiers %case.select.exit and %case.select.matched are both false, these are reset for the previous case depths current values when the /select.end of this case is encountered. As far as I can see $case.else is working fine. Could you show me an code example of this bug please.

Joined: Feb 2005
Posts: 10
R
Roanoke Offline OP
Pikka bird
OP Offline
Pikka bird
R
Joined: Feb 2005
Posts: 10
n/m i was being nittpicky.. lol


Link Copied to Clipboard