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
);