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