[Git][monnier/typer][location-inside-source] Compute location inside the source from the given point.
Simon Génier pushed to branch location-inside-source at Stefan / Typer Commits: 87882dea by Simon Génier at 2021-09-28T17:45:35-04:00 Compute location inside the source from the given point. - - - - - 3 changed files: - src/lexer.ml - src/prelexer.ml - src/source.ml Changes: ===================================== src/lexer.ml ===================================== @@ -37,8 +37,8 @@ let unescape str = let lex_number (source : #Source.t) - (start_location : Source.Location.t) (start_point : Source.Point.t) + (doc : string) : sexp = let rec lex_exponent () = @@ -48,8 +48,8 @@ let lex_number lex_exponent () | _ - -> let source = source#slice start_point in - Float (start_location, float_of_string source) + -> let source, location = source#slice start_point doc in + Float (location, float_of_string source) in let lex_exponent_sign () = @@ -60,8 +60,8 @@ let lex_number (* TODO: error if there are no signs or digits after the 'e'? *) | _ - -> let source = source#slice start_point in - Float (start_location, float_of_string source) + -> let source, location = source#slice start_point doc in + Float (location, float_of_string source) in let rec lex_fractional () = @@ -75,8 +75,8 @@ let lex_number lex_exponent_sign () | _ - -> let source = source#slice start_point in - Float (start_location, float_of_string source) + -> let source, location = source#slice start_point doc in + Float (location, float_of_string source) in let rec lex_integer () = @@ -94,8 +94,8 @@ let lex_number lex_exponent_sign () | _ - -> let source = source#slice start_point in - Integer (start_location, Z.of_string source) + -> let source, location = source#slice start_point doc in + Integer (location, Z.of_string source) in lex_integer () @@ -105,31 +105,30 @@ let lex_symbol (token_env : token_env) (source : #Source.t) (doc : string) - (start_location : Source.Location.t) (start_point : Source.Point.t) : sexp = - let mksym start_location start_point escaped = + let mksym start_point escaped = if Source.Point.equal start_point source#point - then epsilon start_location + then epsilon (Source.Location.of_point source#file start_point doc) else - let raw_name = source#slice start_point in + let raw_name, location = source#slice start_point doc in let name = if escaped then unescape raw_name else raw_name in - hSymbol (start_location, name) + hSymbol (location, name) in - let rec loop start_location start_point prec lf (escaped : bool) = + let rec loop start_point prec lf (escaped : bool) = match source#peek with | None - -> lf (mksym start_location start_point escaped) + -> lf (mksym start_point escaped) | Some c -> (match token_env.(Char.code c) with | CKseparate - -> lf (mksym start_location start_point escaped) + -> lf (mksym start_point escaped) | CKinner prec' - -> let left = mksym start_location start_point escaped in + -> let left = mksym start_point escaped in let op_location = source#location doc in (* To be considered `inner`, an operator char needs to have @@ -151,9 +150,9 @@ let lex_symbol then fun s -> lf (Node (op, [left; s])) else fun s -> Node (op, [lf left; s]) in - loop (source#location doc) source#point prec' lf' false + loop source#point prec' lf' false else - loop start_location start_point prec lf escaped + loop start_point prec lf escaped | CKnormal -> (source#advance; @@ -165,11 +164,11 @@ let lex_symbol leading byte, so it has to count as 1 as well ;-) *) | '\\' when not is_last -> source#advance; - loop start_location start_point prec lf true + loop start_point prec lf true - | _ -> loop start_location start_point prec lf escaped)) + | _ -> loop start_point prec lf escaped)) in - loop start_location start_point 0 (fun s -> s) false + loop start_point 0 (fun s -> s) false let split_presymbol (token_env : token_env) @@ -182,7 +181,6 @@ let split_presymbol | None -> List.rev acc | Some (c) -> let start_point = source#point in - let start_location = source#location doc in let token = match c with (* A negative number literal, or a symbol starting with '-'. *) @@ -190,21 +188,21 @@ let split_presymbol -> (source#advance; match source#peek with | Some ('0' .. '9') - -> lex_number source start_location start_point + -> lex_number source start_point doc | _ - -> lex_symbol token_env source doc start_location start_point) + -> lex_symbol token_env source doc start_point) | '0' .. '9' -> (source#advance; - lex_number source start_location start_point) + lex_number source start_point doc) | _ when token_env.(Char.code c) = CKseparate -> source#advance; - let name = source#slice start_point in - hSymbol (start_location, name) + let name, location = source#slice start_point doc in + hSymbol (location, name) | _ - -> lex_symbol token_env source doc start_location start_point + -> lex_symbol token_env source doc start_point in loop (token :: acc) in ===================================== src/prelexer.ml ===================================== @@ -61,7 +61,7 @@ end (* FIXME: Handle multiline strings. *) let rec consume_until_newline (source : #Source.t) : unit = - match source#next_char with + match source#next with | None | Some ('\n') -> () | Some _ -> consume_until_newline source @@ -96,14 +96,14 @@ let prelex (source : #Source.t) : pretoken list = -> source#advance; let start_point = source#point in consume_until_newline source; - let new_doc = String.trim (source#slice start_point) in - loop ctx acc (doc ^ "\n" ^ new_doc) + let new_doc, _ = source#slice start_point "" in + loop ctx acc (doc ^ "\n" ^ String.trim new_doc) (* A string. *) | Some ('"') -> source#advance; let rec prestring chars = - match source#next_char with + match source#next with | None | Some ('\n') -> let location = source#location doc in prelexer_error location "Unterminated string"; @@ -115,7 +115,7 @@ let prelex (source : #Source.t) : pretoken list = loop ctx (pretoken :: acc) "" | Some ('\\') - -> (match source#next_char with + -> (match source#next with | None | Some ('\n') -> let location = source#location doc in prelexer_error location "Unterminated escape sequence"; @@ -155,25 +155,25 @@ let prelex (source : #Source.t) : pretoken list = let rec pretok () = match source#peek with | None | Some ('%' | '"' | '{' | '}') - -> let location = source#location doc in - let text = source#slice start_point in + -> let text, location = source#slice start_point doc in loop ctx (Pretoken (location, text) :: acc) "" | Some (c) when c <= ' ' - -> let location = source#location doc in - let text = source#slice start_point in + -> let text, location = source#slice start_point doc in source#advance; loop ctx (Pretoken (location, text) :: acc) "" | Some ('\\') -> source#advance; - (match source#next_char with + (match source#next with | Some _ -> pretok () | None - -> let location = source#location doc in + -> let error_location = source#location doc in source#advance; - let text = source#slice start_point in - prelexer_error location ("Unterminated escape sequence in: " ^ text); + let text, location = source#slice start_point doc in + prelexer_error + error_location + ("Unterminated escape sequence in: " ^ text); loop ctx (Pretoken (location, text) :: acc) "") | Some _ ===================================== src/source.ml ===================================== @@ -33,6 +33,14 @@ module Location = struct let dummy = {file = ""; line = 0; column = 0; docstr = ""} + let of_point + (file : string) + (_, line, column : Point.t) + (docstr : string) + : t = + + {file; line; column; docstr} + let to_string ({file; line; column; _} : t) : string = Printf.sprintf "%s:%d:%d" file line column @@ -81,7 +89,10 @@ object (self) Note that the source is required only to buffer the last line read and may raise an Invalid_argument if the slice extends before the start of the line. *) - method virtual slice : Point.t -> string + method slice (offset, line, column : Point.t) (docstr : string) : string * Location.t = + (self#slice_impl offset, {file; line; column; docstr}) + + method virtual private slice_impl : int -> string (* Moves the cursor forward one byte *) method advance : unit = @@ -99,7 +110,7 @@ object (self) method private virtual advance_impl : unit (* Returns the char at the cursor, then advances it forward. *) - method next_char : char option = + method next : char option = let c = self#peek in self#advance; c @@ -133,12 +144,12 @@ class source_file file_name = object (self) with | End_of_file -> None - method advance_impl = + method private advance_impl = offset <- offset + 1 method private offset = line_offset + offset - method slice (start_offset, _, _) = + method private slice_impl start_offset = let relative_start_offset = start_offset - line_offset in String.sub source_line relative_start_offset (offset - relative_start_offset) end @@ -159,11 +170,11 @@ object then Some (source.[offset]) else None - method advance_impl = + method private advance_impl = offset <- offset + 1 method private offset = offset - method slice (start_offset, _, _) = + method private slice_impl start_offset = String.sub source start_offset (offset - start_offset) end View it on GitLab: https://gitlab.com/monnier/typer/-/commit/87882dea3ad0446c118b20b7c61aa3bcb2... -- View it on GitLab: https://gitlab.com/monnier/typer/-/commit/87882dea3ad0446c118b20b7c61aa3bcb2... You're receiving this email because of your account on gitlab.com.
Afficher les réponses par date
participants (1)
-
Simon Génier (@ilovemonoids)