my %function = ( sumsq => sub { my \$sum = 0; foreach(@_) { \$sum += \$_*\$_; } return \$sum; }, # sum of squares sqrt => sub { return sqrt shift; }, ); #### if(/\G((?i:[a-z]\w*))\s*\(/gc) { # function '(' my \$function = \$1; \$function{\$function} or die sprintf "Undefined function '\$function' called at: \"%s\"", where(); my @arg; unless(/\G\s*(?=\))/gc) { while(1){ my(\$value) = parse_expr() or die sprintf "Expression expected at: \"%s\"", where(); push @arg, \$value; /\G\s*,/gc or last; } } /\G\s+/gc; /\G\)/gc or die sprintf "Parse error: ')' expected at: \"%s\"", where(); trace(sprintf "function '\$function' called with %d argument%s", scalar @arg, @arg==1 ? "" : "s"); return \$function{\$function}->(@arg); } #### Line 29 "·sumsq(3,2+2)*sqrt(36)" Line 29 "sumsq(·3,2+2)*sqrt(36)" Line 31 "sumsq(3·,2+2)*sqrt(36)" value=3 Line 29 "sumsq(3,·2+2)*sqrt(36)" Line 31 "sumsq(3,2·+2)*sqrt(36)" value=2 Line 36 "sumsq(3,2+·2)*sqrt(36)" op=+ Line 29 "sumsq(3,2+·2)*sqrt(36)" Line 31 "sumsq(3,2+2·)*sqrt(36)" value=2 Line 43 "sumsq(3,2+2·)*sqrt(36)" popping 2 + Line 45 "sumsq(3,2+2·)*sqrt(36)" result = 4 Line 85 "sumsq(3,2+2)·*sqrt(36)" function 'sumsq' called with 2 arguments Line 31 "sumsq(3,2+2)·*sqrt(36)" value=25 Line 36 "sumsq(3,2+2)*·sqrt(36)" op=* Line 29 "sumsq(3,2+2)*·sqrt(36)" Line 29 "sumsq(3,2+2)*sqrt(·36)" Line 31 "sumsq(3,2+2)*sqrt(36·)" value=36 Line 85 "sumsq(3,2+2)*sqrt(36)·" function 'sqrt' called with 1 argument Line 31 "sumsq(3,2+2)*sqrt(36)·" value=6 Line 43 "sumsq(3,2+2)*sqrt(36)·" popping 25 * Line 45 "sumsq(3,2+2)*sqrt(36)·" result = 150 150 Stack: This value is never affected