|
26 | 26 | // compiled under the same regression rule (SV/EN classification is symmetric, so a mis-split only skips). |
27 | 27 | // See those sections below. |
28 | 28 | // |
29 | | -// scala-cli run autotranslate/scratch/verify-mirror-examples.scala -- <introprog-root> |
| 29 | +// scala-cli run autotranslate/scratch/verify-mirror-examples.scala -- [introprog-root] [--list] |
| 30 | +// introprog-root repo root to scan (optional; defaults to ".") |
| 31 | +// --list also print the per-body/-transcript OK/skip breakdown for phases 1 and 2 |
30 | 32 | // (exit 0 = clean, exit 1 = at least one regression or an untranslated ratified code-string) |
31 | 33 |
|
32 | 34 | @main def verifyMirrorExamples(args: String*): Unit = |
|
69 | 71 | val texFiles = Seq("compendium", "slides").map(root / _).filter(os.exists) |
70 | 72 | .flatMap(d => os.walk(d)).filter(f => os.isFile(f) && f.ext == "tex").sortBy(_.toString) |
71 | 73 | val leaks = collection.mutable.ArrayBuffer[String]() |
| 74 | + // NB (#958.6): the per-file setup (read tex, rel, extraId, opt-out, clampRanges) recurs in the two gates below. |
| 75 | + // Kept as deliberate duplication — this is a scratch tool and the three loops differ enough (leak-check needs |
| 76 | + // no clamp/extraId) that a shared higher-order helper would add more indirection than it removes. |
72 | 77 | for f <- texFiles do |
73 | 78 | val tex = os.read(f) |
74 | 79 | def scan(body: String): Unit = |
|
102 | 107 | val extraId = CodeGlossary.overridesFor(rel) |
103 | 108 | if !CodeGlossary.isOptedOut(rel) then |
104 | 109 | val clampRanges = Latex.ifswedishRanges(tex) |
105 | | - def clamped(pos: Int): Boolean = clampRanges.exists((a, b) => pos >= a && pos < b) |
| 110 | + def clamped(pos: Int): Boolean = clampRanges.exists(r => pos >= r.start && pos < r.end) |
106 | 111 | for m <- envRe.findAllMatchIn(tex) if !clamped(m.start) do |
107 | 112 | val env = m.group(1) |
108 | 113 | val body = if env == "lstlisting" then stripLstOpt(m.group(2)) else m.group(2) |
|
112 | 117 | else if !phase1Envs(env) then nonCode += 1 // Trace/Output — not compilable Scala |
113 | 118 | else if compiles(en, "Inline.scala") then { inChecked += 1; inOk += s"$rel:${lineOf(tex, m.start)} ($env)" } |
114 | 119 | else if compiles(body, "Inline.scala") then |
115 | | - inRegressions += s"$rel ($env)" |
116 | | - println(s" INLINE REGRESSION: $rel ($env) — compiles in Swedish but NOT after rename") |
| 120 | + inRegressions += s"$rel:${lineOf(tex, m.start)} ($env)" |
| 121 | + println(s" INLINE REGRESSION: $rel:${lineOf(tex, m.start)} ($env) — compiles in Swedish but NOT after rename") |
117 | 122 | else { inSkipped += 1; inSkip += s"$rel:${lineOf(tex, m.start)} ($env)" } |
118 | 123 | println(s"\n=== inline .tex compile gate (phase 1): $inChecked ok, $inSkipped skipped (not standalone), " + |
119 | 124 | s"$replDeferred REPL deferred to phase 2, $nonCode Trace/Output not gated, ${inRegressions.size} REGRESSIONS ===") |
|
144 | 149 | case None => |
145 | 150 | val t = line.trim |
146 | 151 | val isOutput = t.isEmpty || replOutRe.findFirstMatchIn(line).isDefined || |
147 | | - t.matches("(val|var)\\s+\\w+:.*=.*") // result-echo `val x: T = …` |
| 152 | + t.matches("(?U)(val|var)\\s+\\w+:.*=.*") // result-echo `val x: T = …`; (?U) so \w |
| 153 | + // matches åäö — else `var räknaLäte:` (SV) |
| 154 | + // and `var callCount:` (EN) classify |
| 155 | + // differently, breaking SV/EN symmetry (#958) |
148 | 156 | if inInput && !isOutput then prog += line // continuation of a multi-line input |
149 | 157 | else inInput = false |
150 | 158 | prog.mkString("\n") |
|
160 | 168 | val extraId = CodeGlossary.overridesFor(rel) |
161 | 169 | if !CodeGlossary.isOptedOut(rel) then |
162 | 170 | val clampRanges = Latex.ifswedishRanges(tex) |
163 | | - def clamped(pos: Int): Boolean = clampRanges.exists((a, b) => pos >= a && pos < b) |
| 171 | + def clamped(pos: Int): Boolean = clampRanges.exists(r => pos >= r.start && pos < r.end) |
164 | 172 | for m <- envRe.findAllMatchIn(tex) if replEnvs(m.group(1)) && !clamped(m.start) do |
165 | 173 | val body = stripLstOpt(m.group(2)) // strip a leading [numbers=none] optional arg |
166 | 174 | val en = CodeGlossary.renderCodeIds(body, extraId) |
|
0 commit comments