use Switch; switch ($val) { case 1 { print "number 1" } case "a" { print "string a" } case [1..10,42] { print "number in list" } case (@array) { print "number in list" } case /\w+/ { print "pattern" } case qr/\w+/ { print "pattern" } case (%hash) { print "entry in hash" } case (\%hash) { print "entry in hash" } case (\&sub) { print "arg to subroutine" } else { print "previous case not true" } } #### syntax (switch (EXPR) CODE) { # eval the expr first to avoid # reevaluation at each case my $var = new_unique_symbol; code { { $var = EXPR; switch_aux($var) CODE } } } syntax (switch_aux (EXPR) { case CODE_t { CODE_c } CODE_e }) { # else is left as an excercise. code{ if(case(EXPR,CODE_t)){ CODE_c } else { switch_aux(EXPR){ CODE_e } # notice the recursion here } } } syntax (case (EXPR,INTEGER)){ code { (EXPR == INTEGER) } } syntax (case (EXPR,STRING)){ code { (EXPR eq STRING) } } syntax (case (EXPR,LIST)){ code { (grep EXPR, LIST) } } syntax (case (EXPR,REGEX)){ code { (EXPR =~ REGEX ) } } syntax (case (EXPR,HASH)){ code { (exists EXPR, HASH) } } syntax (case (EXPR,SUB)){ code { SUB(EXPR) } } #### parser = new Parse::RecDescent (q{ expression: and_expr '||' expression | and_expr and_expr: not_expr '&&' and_expr | not_expr not_expr: '!' brack_expr | brack_expr brack_expr: '(' expression ')' | identifier identifier: /[a-z]+/i }); # becomes after dropping the quoting operator q{} parser = new Parse::RecDescent( expression: and_expr '||' expression | and_expr and_expr: not_expr '&&' and_expr | not_expr not_expr: '!' brack_expr | brack_expr brack_expr: '(' expression ')' | identifier identifier: /[a-z]+/i );