# $segs{$seg}{Feats}{$feat}{Fixed} position, for Fixed only
# $segs{$seg}{FeatMap}[]{Abstract} as from ours.m4
# $segs{$seg}{FeatMap}[]{Concrete} as in ours.wiring, for safety:movpos.c
-# $segs{$seg}{FeatMap}[]{Used}
+# $segs{$seg}{FeatMap}[]{UsedAbstract}
+# $segs{$seg}{FeatMap}[]{UsedConcrete}
# $segs{$seg}{Inter}{Seg} ) calculated
# $segs{$seg}{Inter}{Map} ) in writeout
$mistakes++;
}
+sub movfeatposmap ($$$$$) {
+ my ($subspecr, $segr, $entfrom, $entto, $call) = @_;
+ my $featmap= $segr->{FeatMap};
+ return unless $featmap;
+
+ foreach my $mapent (@$featmap) {
+ next unless
+ $$subspecr =~ s/
+ (?<! [A-Za-z] ) $mapent->{$entfrom} (?! \d )
+ /$mapent->{$entto}/x;
+ $mapent->{"Used$entfrom"}++;
+ $call->($mapent);
+ }
+}
+
+sub movfeatposmap_checks () {
+ foreach my $seg (keys %segs) {
+ my $segr= $segs{$seg};
+ my $featmap= $segr->{FeatMap};
+ next unless $featmap;
+ foreach my $mapent (@$featmap) {
+ foreach my $chk (qw(Abstract Concrete)) {
+ next if $mapent->{"Used$chk"};
+ endmistake("movfeatposmap entry $seg $mapent->{Abstract}".
+ " $mapent->{Concrete} unused for \L$chk lookup");
+ last;
+ }
+ }
+ }
+}
+
sub line_endwiring () {
my (@ns,$seg,$subspec,$dist);
my ($segr,@subsegil,$feat,$pos,$featr,$combpos,%featposwant);
return;
}
$segr= $segs{$seg};
+ my $desc= $seg;
+ if (defined $subspec) {
+ $desc .= "/$subspec";
+ movfeatposmap(\$subspec, $segr, Abstract, Concrete, sub {
+ my ($mapent) = @_;
+ $desc .= "[$mapent->{Concrete}]";
+ });
+ }
@subsegil= defined $subspec ? $subspec =~ m/([A-Za-z]+)(\d+)/g : ();
while (@subsegil) {
($feat,$pos,@subsegil) = @subsegil;
$pi.= sprintf("%s%d", $feat,
($comb / $featv->{Weight}) % $featv->{Posns});
}
+ my $pi_abstr= $pi;
+ movfeatposmap(\$pi_abstr, $segr, Concrete, Abstract, sub { });
+ $pi_abstr =~
o("$delim\n");
my $dist= $segr->{Dist}[$comb];
o(sprintf " { %-7s%4d, { ",
- '"'.$pi.'",',
+ '"'.$pi_abstr.'",',
defined($dist) ? $dist : 1);
for ($end=0; $end<2; $end++) {
o(", ") if $end;
redaction();
writeout();
writeasm();
+movfeatposmap_checks();
exit 1 if $mistakes;