5 our ($mistakes, $currentline);
11 # $segs{$seg}{FeatCount} does not include Fixed
12 # $segs{$seg}{Feats}{$pt}{Kind} Point or Fixed
13 # $segs{$seg}{Feats}{$pt}{Weight} ) for Point only
14 # $segs{$seg}{Feats}{$pt}{Posns} ) for Point only
15 # $segs{$seg}{Feats}{$pt}{BoOb} ) for Point only
16 # $segs{$seg}{Feats}{$pt}{Fixed} position, for Fixed only
19 # $segs{$seg}{Ends}[$combpos][$end] = [ $node,$side ]
20 # $segs{$seg}{Dist}[$combpos]
23 # $nodes{$node}[$side]{Seg}
25 our ($mode,$invertible);
30 mistake("first input line does not determine phase");
34 our (%syntaxerror_once);
35 return if exists $syntaxerror_once{$mode};
36 $syntaxerror_once{$mode}= 1;
37 mistake("syntax error");
43 print STDERR "ditching $m\n";
46 sub begin_points () { }
48 my ($seg,$pt,@boob,$bodef);
49 m,^\s+(\w+)/([A-Za-z]+)\s+((\d+)\.\d+)\s+(\d*\.\d+)$, or
51 ($seg,$pt,$boob[0],$bodef,$boob[1])=($1,$2,$3,$4,$5);
52 $boob[1] =~ s/^\./$bodef./;
53 mistake("unknown wiring for $seg in $seg/$pt") unless exists $segs{$seg};
54 mistake("duplicate wiring for $seg/$pt") if exists $segs{$seg}{Feats}{$pt};
55 $segs{$seg}{Feats}{$pt}= {
57 Weight => $segs{$seg}{Posns},
59 BoOb => [ map { pa_boob($_) } @boob ]
61 $segs{$seg}{Posns} *= 2;
62 $segs{$seg}{FeatCount}++;
65 sub begin_fixed () { }
68 m,^\s+(\w+)/([A-Za-z]+)(\d+)$, or return syntaxerror();
69 ($seg,$pt,$pos)=($1,$2,$3);
70 mistake("unknown wiring for $seg in $seg/$pt") unless exists $segs{$seg};
71 mistake("duplicate fixed $seg/$pt") if exists $segs{$seg}{Feats}{$pt};
72 $segs{$seg}{Feats}{$pt}= {
78 sub begin_segment () { }
81 m/^\s+(\w+)\s+(\d+\.\d+)$/ or return syntaxerror();
83 mistake("duplicate topology for $seg") if exists $segs{$seg};
85 BoOb => pa_boob($boob),
93 sub begin_endwiring () {
98 print STDERR "mistake: $m\n in $mode, \`$currentline'\n";
102 sub line_endwiring () {
103 my (@ns,$seg,$subspec,$dist);
104 my ($segr,@subsegil,$feat,$pos,$featr,$combpos,%featposwant);
105 my ($end,$node,$side,$nsr,$endposr);
106 m,^\s*segment\s+(\w+\.\d+)\s+(\w+\.\d+)\s+(\w+)(?:/((?:[A-Za-z]+\d+)+)\*\d+)?\s+([0-9.]+)$, or return syntaxerror();
107 ($ns[0],$ns[1],$seg,$subspec,$dist)=($1,$2,$3,$4,$5);
108 if (!exists $segs{$seg}) {
109 ditch("unwired $seg$subspec");
113 @subsegil= defined $subspec ? $subspec =~ m/([A-Za-z]+)(\d+)/g : ();
115 ($feat,$pos,@subsegil) = @subsegil;
116 if (!exists $segr->{Feats}{$feat}) {
117 mistake("no wiring for $seg/$feat");
120 $featr= $segr->{Feats}{$feat};
121 if (exists $featr->{Fixed}) {
122 if ($pos != $featr->{Fixed}) {
123 ditch("fixed-elsewise $seg$subspec");
127 mistake("position $seg/$feat$pos exceeds wiring")
128 unless $pos < $featr->{Posns};
129 $featposwant{$feat}= $pos;
133 for $feat (keys %{ $segr->{Feats} }) {
134 $featr= $segr->{Feats}{$feat};
135 next if exists $featr->{Fixed};
136 mistake("wiring $seg/$feat not covered by $seg/$subspec")
137 if !exists $featposwant{$feat};
138 $combpos += $featposwant{$feat} * $featr->{Weight};
140 mistake("duplicate topology for $seg/$subspec")
141 if defined $segs{$seg}{Dist}[$combpos];
142 $segs{$seg}{Dist}[$combpos]= $dist;
143 for ($end=0; $end<2; $end++) {
144 $ns[$end] =~ m/^([a-z]\w+)\.([01])$/;
145 ($node,$side)=($1,$2);
146 $nsr= $nodes{$node}[$side];
147 if (!exists $nsr->{Seg}) {
149 } elsif ($seg ne $nsr->{Seg}) {
150 mistake("topology for $node.$side both $seg and $nsr->{Seg}");
152 $endposr= $segr->{Ends}[$combpos];
153 die "$seg $combpos ?" if defined $endposr && @$endposr;
154 $endposr->[$end]= [ $node, $side ];
159 print STDOUT $_[0] or die $!;
164 if ($boob !~ m/^([1-9]\d*|0)\.([1-9]\d*|0)$/) {
165 mistake("invalid board object $boob");
168 return sprintf "%d,%2d", $1,$2;
184 if (m/^(invertible|vanilla|points|fixed|endwiring)$/) {
186 $invertible= ($mode eq 'invertible');
187 $mode= 'segment' if $mode =~ m/^(?:vanilla|invertible)$/;
198 $p =~ s/\d{1,6}/ sprintf "%06d%d",$&,$& /ge;
203 my (@segs,$segn,$seg,$segr,$pt,$ptv, $delim);
204 my ($comb,$pi,$feat,$featr,$end);
205 o("/* autogenerated - do not edit */\n\n".
206 "#include \"safety.h\"\n\n");
208 for $seg (sort { nummap($a) cmp nummap($b) } keys %segs) {
209 $segs{$seg}{Num}= @segs;
212 foreach $seg (@segs) {
214 next unless $segr->{FeatCount};
215 o("static const MovFeatInfo mfi_${seg}[]= {");
217 for $pt (keys %{ $segr->{Feats} }) {
218 $ptv= $segr->{Feats}{$pt};
219 next if exists $ptv->{Fixed};
221 o(" { \"$seg/$pt\", $ptv->{Posns}, $ptv->{Weight} }");
225 o("static const SegPosCombInfo spci_${seg}[]= {");
227 for ($comb=0; $comb < $segr->{Posns}; $comb++) {
229 foreach $feat (keys %{ $segr->{Feats} }) {
230 $featr= $segr->{Feats}{$feat};
231 next if exists $featr->{Fixed};
232 $pi.= sprintf("%s%d", $feat,
233 ($comb / $featr->{Weight}) % $featr->{Posns});
238 for ($end=0; $end<2; $end++) {
239 $other= $segs{$seg}{Ends}[$combpos][$end];
241 if (defined $other) {
242 ($node,$side) = @$other;
244 o(sprintf "/*%5s.%d %-6s*/ %d,%3d",
256 o("static const SegmentInfo info_segments[".scalar(@segs)."]= {");
258 foreach $seg (@segs) {
261 o(sprintf " { %-7s %d, %2d,%-9s %3d,%-10s %-6s }",
262 "\"$seg\",", $segr->{Inv},
263 $segr->{FeatCount}, ($segr->{FeatCount} ? "mfi_$seg," : '0,'),
264 $segr->{Posns}, ($segr->{FeatCount} ? "spci_$seg," : '0,'),