5050 - Span fidelity: errors refer to the canonical text, not Lucid source.
5151*)
5252
53- (* ─── Character helpers ──────────────────────────────────────────────── *)
53+ (* ─── Character helpers ──────────────────────────────────────────── *)
5454
5555let is_id_char c =
5656 (c > = 'a' && c < = 'z' ) || (c > = 'A' && c < = 'Z' )
@@ -70,16 +70,7 @@ let indent_of line =
7070 while ! i < len && (line.[! i] = ' ' || line.[! i] = '\t' ) do incr i done ;
7171 ! i
7272
73- (* ─── Comment handling ───────────────────────────────────────────────── *)
74-
75- (* * Convert a leading [-- comment] to [// comment] at the original indent. *)
76- let convert_dashdash_comment line =
77- let trimmed = String. trim line in
78- if starts_with trimmed " --" then
79- let indent_len = String. length line - String. length trimmed in
80- let indent = String. sub line 0 indent_len in
81- indent ^ " //" ^ String. sub trimmed 2 (String. length trimmed - 2 )
82- else line
73+ (* ─── Comment handling ────────────────────────────────────────────── *)
8374
8475(* * Strip a trailing [-- ...] comment (respecting string literals) and
8576 return [(code_part, comment_text option)]. *)
@@ -105,7 +96,7 @@ let strip_dashdash_comment line =
10596 else (String. sub line 0 ! cut,
10697 Some (String. sub line (! cut + 2 ) (len - ! cut - 2 )))
10798
108- (* ─── Word-level keyword substitution ────────────────────────────────── *)
99+ (* ─── Word-level keyword substitution ───────────────────────────────────── *)
109100
110101let replace_word ~from_w ~to_w s =
111102 let flen = String. length from_w in
@@ -144,7 +135,7 @@ let apply_logic_subs s =
144135 let s = replace_word ~from_w: " not" ~to_w: " !" s in
145136 s
146137
147- (* ─── Module path helpers ────────────────────────────────────────────── *)
138+ (* ─── Module path helpers ────────────────────────────────────────────────── *)
148139
149140(* * [Data.Map.Strict] → [Data::Map::Strict]. *)
150141let dots_to_colons s =
@@ -156,7 +147,7 @@ let dots_to_colons s =
156147 ) s;
157148 Buffer. contents buf
158149
159- (* ─── Import translation ─────────────────────────────────────────────── *)
150+ (* ─── Import translation ───────────────────────────────────────────────────── *)
160151
161152(* * Try to transform a PureScript [import …] line. *)
162153let transform_import_line stripped =
@@ -221,7 +212,7 @@ let transform_import_line stripped =
221212 end
222213 end
223214
224- (* ─── Module declaration ─────────────────────────────────────────────── *)
215+ (* ─── Module declaration ───────────────────────────────────────────────────── *)
225216
226217(* * [module Foo where] / [module Foo (exports) where] → [module Foo;].
227218 Canonical AffineScript uses [module] as a file-level header (no
@@ -252,7 +243,7 @@ let transform_module_line stripped =
252243 Some (Printf. sprintf " module %s;" mod_path)
253244 end
254245
255- (* ─── Type signature handling ────────────────────────────────────────── *)
246+ (* ─── Type signature handling ──────────────────────────────────────────────── *)
256247
257248(* * A line of the form [name :: type ...] is a type signature. Lucid keeps
258249 it as a comment so the canonical type inferer is the source of truth.
@@ -267,7 +258,7 @@ let is_type_signature stripped =
267258 has_dcolon && len > 0
268259 && (stripped.[0 ] > = 'a' && stripped.[0 ] < = 'z' || stripped.[0 ] = '_' )
269260
270- (* ─── Data / class / instance declarations ───────────────────────────── *)
261+ (* ─── Data / class / instance declarations ───────────────────────────────────── *)
271262
272263(* * [data Foo a b = Ctor1 a | Ctor2] → [type Foo[a, b] = Ctor1(a) | Ctor2].
273264 Best-effort: parameterised constructor arguments wrapped in parens. *)
@@ -350,7 +341,7 @@ let transform_instance_decl stripped =
350341 | _ -> Some (Printf. sprintf " impl %s {" body)
351342 end
352343
353- (* ─── Function equations ─────────────────────────────────────────────── *)
344+ (* ─── Function equations ────────────────────────────────────────────────────── *)
354345
355346(* * [f x y = expr] — wrap parameters and emit canonical [fn].
356347 Returns [None] when the line isn't a recognisable equation. *)
@@ -395,7 +386,7 @@ let transform_equation stripped =
395386 end
396387 end
397388
398- (* ─── Expression-level substitutions ─────────────────────────────────── *)
389+ (* ─── Expression-level substitutions ───────────────────────────────────────────── *)
399390
400391(* * [\x -> body] / [\x y -> body] → [(x, y) => body]. *)
401392let transform_lambda_inline s =
@@ -535,11 +526,14 @@ let render_block_head head marker =
535526 head ^ " = {"
536527 | _ -> head
537528
538- (* ─── Main transformer ───────────────────────────────────────────────── *)
529+ (* ─── Main transformer ───────────────────────────────────────────────────────── *)
539530
540531let is_blank_line raw =
541- let (code, _) = strip_dashdash_comment (String. trim raw) in
542- String. trim code = " "
532+ let t = String. trim raw in
533+ if starts_with t " //" then true
534+ else
535+ let (code, _) = strip_dashdash_comment t in
536+ String. trim code = " "
543537
544538let transform_source source =
545539 let lines = Array. of_list (String. split_on_char '\n' source) in
@@ -571,8 +565,7 @@ let transform_source source =
571565 for i = 0 to n - 1 do
572566 let raw_line = lines.(i) in
573567 let ind = indent_of raw_line in
574- let line = convert_dashdash_comment raw_line in
575- let (code_part, comment_opt) = strip_dashdash_comment (String. trim line) in
568+ let (code_part, comment_opt) = strip_dashdash_comment (String. trim raw_line) in
576569 let stripped = String. trim code_part in
577570
578571 let with_comment line_text =
@@ -585,6 +578,10 @@ let transform_source source =
585578 (match comment_opt with
586579 | Some c -> Buffer. add_string out (" // " ^ String. trim c ^ " \n " )
587580 | None -> Buffer. add_char out '\n' )
581+ end else if starts_with stripped " //" || starts_with stripped " /*" then begin
582+ (* Already-canonical comment lines pass through unchanged. *)
583+ let indent_str = String. make ind ' ' in
584+ Buffer. add_string out (indent_str ^ stripped ^ " \n " )
588585 end else if is_type_signature stripped then begin
589586 (* Keep type signatures as a comment so the inferer drives types. *)
590587 let indent_str = String. make ind ' ' in
@@ -661,7 +658,7 @@ let transform_source source =
661658 done ;
662659 Buffer. contents out
663660
664- (* ─── Entry points ───────────────────────────────────────────────────── *)
661+ (* ─── Entry points ────────────────────────────────────────────────────────────── *)
665662
666663let parse_string_lucid ~file content =
667664 let canonical = transform_source content in
0 commit comments