Right: the real cause of the second bug is similar to what I thought it was - when it sees a float, the regex engine first checks to see if it is an integer by trying the substitution:
s/^(-?\d+)(?!\.)// The problem is that when, say, 10000.0 gets fed to this, and fails to match, the regex engine starts to back up, until it sucessfully matches (and erases) 1000, leaving 0.0 to be parsed on the next iteration of the loop, and hence producing incorrect output. The best way that I've been able to think of to fix this is to swap the order of the integer and float comparisons, so that any floats get matched before we get to the above; if anyone else can think of a better way, or some reason why this won't work, I'd be glad to hear it. Correct(?) patch enclosed below - note that it replaces the one sent earlier, which should be ignored. Simon --- Optimizer.pm.old Mon Jan 21 18:12:16 2002 +++ Optimizer.pm Mon Jan 21 18:44:05 2002 @@ -53,20 +53,20 @@ # Collect arbitrary parameters # while(/\S/) { - if(s/^([a-zA-Z][a-zA-Z0-9]+)//) { # global label + if(s/^([INSP]\d+\b)//) { # Register name + push @{$line->{parameter}},{type=>'register',value=>$1}; + } + elsif(s/^([a-zA-Z][a-zA-Z0-9]+)//) { # global label push @{$line->{parameter}},{type=>'label_global',value=>$1}; } elsif(s/^(\$\w+)//) { # local label push @{$line->{parameter}},{type=>'label_local',value=>$1}; } - elsif(s/^([INSP]\d+\b)//) { # Register name - push @{$line->{parameter}},{type=>'register',value=>$1}; + elsif(s/^(-?\d+\.\d+)//) { # float + push @{$line->{parameter}},{type=>'constant_n',value=>$1}; } elsif(s/^(-?\d+)(?!\.)//) { # integer push @{$line->{parameter}},{type=>'constant_i',value=>$1}; - } - elsif(s/^(-?\d+\.\d+)//) { # float - push @{$line->{parameter}},{type=>'constant_n',value=>$1}; } elsif(s/^("(?:[^\\"]|(?:\\(?>["tnr\\])))*")// or # single-quoted string s/^('(?:[^\\']|(?:\\(?>['tnr\\])))*')//) { # double-quoted string