package acgtk
Abstract Categorial Grammar development toolkit
Install
Dune Dependency
Authors
Maintainers
Sources
acg-2.1.0-20240219.tar.gz
sha512=5d380a947658fb1201895cb4cb449b1f60f54914c563e85181d628a89f045c1dd7b5b2226bb7865dd090f87caa9187e0ea6c7a4ee3dc3dda340d404c4e76c7c2
doc/src/acgtk.utilsLib/error.ml.html
Source file error.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
type pos = Lexing.position * Lexing.position let dummy_pos = (Lexing.dummy_pos, Lexing.dummy_pos) exception AcgtkError of string * (Format.formatter -> unit) * (pos option) let base_prompt = "ACGtk> " let cont_prompt = "... " module type ERROR_MANAGER = sig type t val kind : string val pp : Format.formatter -> t -> unit end module type ERROR_HANDLER = sig type manager val emit : ?loc:pos -> manager -> 'a end module ErrorManager (E : ERROR_MANAGER) = struct type manager = E.t let emit ?loc e = raise (AcgtkError (E.kind, (fun fmt -> E.pp fmt e), loc)) end let set_position lexbuf loc = let () = Sedlexing.set_position lexbuf loc in let () = Sedlexing.set_filename lexbuf loc.Lexing.pos_fname in () let quote_position (p1, p2) = ({ p1 with Lexing.pos_cnum = p1.Lexing.pos_cnum + 1 }, { p2 with Lexing.pos_cnum = p2.Lexing.pos_cnum - 1 }) let underlined_red_pp s = Fmt.(styled `Red (styled `Underline string)) s let unicode_sub_str str s_byte uni_chars = let buff = Buffer.create 128 in let rec unicode_sub_str_rec s_byte uni_chars = if uni_chars = 0 then (Buffer.contents buff, s_byte) else let u = (Uchar.utf_decode_uchar ((String.get_utf_8_uchar str s_byte))) in let () = Buffer.add_utf_8_uchar buff u in let (str, k) = (unicode_sub_str_rec (s_byte + (Uchar.utf_8_byte_length u)) (uni_chars - 1)) in (str, k) in unicode_sub_str_rec s_byte uni_chars let color_error_pp start_c end_c fmt str = let (s1, s2_start_byte) = unicode_sub_str str 0 start_c in let (s2, s3_start_byte) = unicode_sub_str str s2_start_byte (end_c - start_c) in let s3 = String.sub str s3_start_byte (String.length str - s3_start_byte) in Format.fprintf fmt "%s%s%a%s" base_prompt s1 underlined_red_pp s2 s3 let underline_error str (l1, l2) = let line_num = String.fold_left (fun i c -> if c = '\n' then i + 1 else i) 1 str in let () = ANSITerminal.move_cursor 0 (-line_num) in Logs.app (fun m -> m "%a" (color_error_pp l1.Lexing.pos_cnum l2.Lexing.pos_cnum) str) let compute_comment_for_location (pos1, pos2) = let line2 = pos2.Lexing.pos_lnum in let col2 = pos2.Lexing.pos_cnum - pos2.Lexing.pos_bol in let pos1 = pos1 in let line1 = pos1.Lexing.pos_lnum in let col1 = pos1.Lexing.pos_cnum - pos1.Lexing.pos_bol in let msg = if line1 = line2 then if col1 = col2 then Printf.sprintf "line %d, character %d" line2 col2 else Printf.sprintf "line %d, characters %d-%d" line2 col1 col2 else Printf.sprintf "line %d, character %d to line %d, character %d" line1 col1 line2 col2 in match pos1.Lexing.pos_fname with | "" -> msg | "<stdin>" -> Printf.sprintf "file <stdin>, %s" msg | fname -> Printf.sprintf "file \"%s\", %s" fname msg let pp_text fmt text = let words = String.split_on_char ' ' text in match words with | w :: words -> let () = Format.fprintf fmt "%s" w in List.iter (fun w -> Format.fprintf fmt "@ %s" w) words | _ -> () let print_error e str = match e with | AcgtkError (kind, ppf, Some (l1, l2)) -> let () = match str with | Some str -> if l1.Lexing.pos_fname = "" && l2.Lexing.pos_fname = "" then underline_error str (l1, l2) | None -> () in let loc_string = compute_comment_for_location (l1, l2) in Logs.err (fun m -> m "@[@[<h>%s error:@;@[%a:@]@]@;@[%t.@]@]" kind pp_text loc_string ppf) | AcgtkError (kind, ppf, None) -> Logs.err (fun m -> m "%s error:@;@[<4>@[%t.@]@]" kind ppf) | Failure s -> Logs.err (fun m -> m "Bug,@ please@ report:@ failure:@ %a" pp_text s) | Assert_failure (file, line, col) -> Logs.err (fun m -> m "Bug,@ please@ report:@ assertion@ failed@ at@ %s:%i:%i" file line col) | e -> let bt = (Printexc.get_backtrace ()) in if bt = "" then Logs.err (fun m -> m "Bug,@ please@ report:@ uncaught@ exception@ \"%s\"@ (run@ with@ \"-d\"@ to@ see@ backtrace)" (Printexc.to_string e)) else Logs.err (fun m -> m "Bug,@ please@ report:@ uncaught@ exception@ \"%s\"\nBACKTRACE:\n%a" (Printexc.to_string e) pp_text bt) let print_error_fatal e str = let () = print_error e str in exit 1 let rec list_to_string l = match l with | [] -> "nothing" | [ s ] -> Printf.sprintf "\"%s\"" s | [ s1 ; s2 ] -> Printf.sprintf "\"%s\" or \"%s\"" s1 s2 | s :: l -> Printf.sprintf "\"%s\", %s" s (list_to_string l)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>