From 512139eaffd537fa4c2df6dca295abb625dd75c4 Mon Sep 17 00:00:00 2001 From: Michael Mikonos <127171689+mknos@users.noreply.github.com> Date: Tue, 26 Mar 2024 20:40:14 +0800 Subject: [PATCH] bc: array name versus digits (#523) * bc: array name versus digits * Array names are allowed to contain numeric digits but cannot start with a digit: ary2 is valid but 2ary is not * Assigning then fetching an array value didn't work as expected * I got a hint when adding debug statement to the =P instruction: "name[[]] idx[] varName[ary2[]1] at bc.y line 982, line 2." * The regex did not match because varName is "ary2[]1"; the regex expected that a digit would only be found after the "[]" substring * Make the code more correct by splitting on "[]" to get the array name "ary2" and the index of "1" * varName string is built earlier by the P instruction %perl bc -d # before patch ary2[0] = 1 instruction: N, 0 instruction: N, 1 instruction: P, ary2 instruction: =P ary2[0] instruction: N, 0 instruction: p, ary2 0 * bc: fix implicit print * When looping, setting $return=1 in =v instruction caused the loop to terminate early * Example input: for (i=1; i<10; i++) print i * Instead, take a hint from FOR-COND instruction and set $return=3 for suppressing print * This allows the simple statement "x=1" to not print * Apply the same to =P instruction, where the $return=1 code was copied from * no implicit print for "break" * Set $return=1 in BREAK instruction to match RETURN * In a loop with nested break, this stops the break from printing 0 * Example input: for ( v=0; v<5; v++) { print v; if (v>2) break }; print "\n" --- bin/bc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/bin/bc b/bin/bc index 400713a6..6874240f 100755 --- a/bin/bc +++ b/bin/bc @@ -2519,15 +2519,14 @@ sub exec_stmt $sym_table{$varName} = { type => 'var', value => $value }; push(@ope_stack, $value); - $return = 1; # do not print result + $return = 3; # do not print result next INSTR; } elsif($_ eq '=P') { my $varName = pop(@ope_stack); my $value = pop(@ope_stack); - my ($name, $idx) = ($varName =~ /([a-z]+)\[\](\d+)/); - + my ($name, $idx) = split /\[\]/, $varName, 2; $name .= '[]'; unless (defined($sym_table{$name}) and $sym_table{$name}{'type'} eq 'array') @@ -2538,7 +2537,7 @@ sub exec_stmt $sym_table{$name}{'value'}[$idx] = { type => 'var', value => $value }; push(@ope_stack, $value); - $return = 1; # do not print result + $return = 3; # do not print result next INSTR; } elsif($_ eq 'IF') { @@ -2731,7 +2730,7 @@ sub exec_stmt # debug {"breaking.\n"}; - $return = 2; + $return = 1; push(@ope_stack, 0); last INSTR;