Skip to content

Commit d31c585

Browse files
committed
Fix handling of MF-style compiler directives, and emit related semtoks
1 parent fa0abb5 commit d31c585

19 files changed

+236
-319
lines changed

src/lsp/cobol_lsp/lsp_request.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,8 @@ let handle_hover registry (params: HoverParams.t) =
236236
| Cobol_preproc.FileCopy { copyloc = loc; _ } ->
237237
Lsp_position.is_in_lexloc params.position
238238
(Cobol_common.Srcloc.lexloc_in ~filename loc)
239-
| Cobol_preproc.Replace _ ->
239+
| Cobol_preproc.Replace _
240+
| Cobol_preproc.LexDir _ ->
240241
false
241242
end (Cobol_preproc.Trace.events pplog)
242243
in
@@ -264,6 +265,7 @@ let handle_hover registry (params: HoverParams.t) =
264265
Pretty.string_to (hover_markdown ~loc) "```%s\n%s\n```" mdlang text
265266
| Some FileCopy { status = MissingCopy _; _ }
266267
| Some Replace _
268+
| Some LexDir _
267269
| None ->
268270
None
269271
end

src/lsp/cobol_lsp/lsp_semtoks.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,8 @@ let semtoks_of_comments ~filename ?range comments = comments |>
569569
let semtoks_of_preproc_statements ~filename ?range pplog =
570570
List.rev @@ List.fold_left begin fun acc -> function
571571
| Cobol_preproc.Trace.FileCopy { copyloc = loc; _ }
572-
| Cobol_preproc.Trace.Replace { replloc = loc } ->
572+
| Cobol_preproc.Trace.Replace { replloc = loc }
573+
| Cobol_preproc.Trace.LexDir { loc; _ } ->
573574
acc_semtoks ~filename ?range TOKTYP.macro loc acc
574575
| Cobol_preproc.Trace.Replacement _ ->
575576
acc

src/lsp/cobol_preproc/preproc.ml

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ open Cobol_common.Srcloc.TYPES
1616
open Cobol_common.Srcloc.INFIX
1717
open Cobol_common.Diagnostics.TYPES
1818
open Text.TYPES
19+
open Preproc_directives (* import types of directives *)
1920

2021
module DIAGS = Cobol_common.Diagnostics
2122

@@ -126,10 +127,6 @@ let srclex_restart_on_file ?position filename =
126127

127128
(* SOURCE FORMAT *)
128129

129-
type lexing_directive =
130-
| LexDirSource:
131-
'k Src_format.source_format with_loc -> lexing_directive [@@unboxed]
132-
133130
let cdir_source_format ~dialect format =
134131
match Src_format.decypher ~dialect ~&format with
135132
| Ok (SF sf) ->
@@ -141,50 +138,6 @@ let cdir_source_format ~dialect format =
141138

142139
(* COPY/REPLACING *)
143140

144-
type copy_statement =
145-
| CDirCopy of
146-
{
147-
library: library;
148-
suppress_printing: bool;
149-
replacing: replacing with_loc list;
150-
}
151-
and replace_statement =
152-
| CDirReplace of
153-
{
154-
also: bool;
155-
replacing: replacing with_loc list;
156-
}
157-
| CDirReplaceOff of
158-
{
159-
last: bool;
160-
}
161-
and library =
162-
{
163-
libname: fileloc with_loc;
164-
cbkname: fileloc with_loc option;
165-
}
166-
and fileloc = [`Word | `Alphanum] * string
167-
and replacing =
168-
| ReplaceExact of
169-
{
170-
repl_from: pseudotext with_loc;
171-
repl_to: pseudotext with_loc;
172-
}
173-
| ReplacePartial of
174-
{
175-
repl_subst: partial_subst with_loc;
176-
repl_to: string with_loc option;
177-
}
178-
and partial_subst =
179-
{
180-
partial_subst_dir: replacing_direction;
181-
partial_subst_len: int;
182-
partial_subst_regexp: Str.regexp;
183-
}
184-
and replacing_direction = Leading | Trailing
185-
186-
(* --- Implementation of replacing operations ------------------------------- *)
187-
188141
let concat_strings = Cobol_common.Srcloc.concat_strings_with_loc
189142
let lift_textword w = TextWord ~&w &@<- w
190143

@@ -218,12 +171,6 @@ let partial_word (type k) (req: k partial_word_request) words : (k, _) result =
218171
| _, _ ->
219172
Error (DIAGS.One.error ~loc:~@words "Expected@ one@ text-word")
220173

221-
type partial_replacing =
222-
{
223-
repl_dir: replacing_direction;
224-
repl_strict: bool;
225-
}
226-
227174
let partial_subst (k: partial_replacing) ({ payload = pat; _ } as repl_from) =
228175
{ partial_subst_dir = k.repl_dir;
229176
partial_subst_len = String.length pat;

src/lsp/cobol_preproc/preproc.mli

Lines changed: 69 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -15,107 +15,27 @@ open Cobol_common.Srcloc.TYPES
1515
open Cobol_common.Diagnostics.TYPES
1616
open Text.TYPES
1717

18+
(** {1 Source text lexer} *)
19+
1820
type 'k srclexer = 'k Src_lexing.state * Lexing.lexbuf
1921
and any_srclexer =
2022
| Plx: 'k srclexer -> any_srclexer [@@unboxed]
2123

22-
(* --- Compiler Directives -------------------------------------------------- *)
23-
24-
(* SOURCE FORMAT *)
25-
26-
type lexing_directive =
27-
| LexDirSource:
28-
'k Src_format.source_format with_loc -> lexing_directive [@@unboxed]
29-
30-
(* COPY/REPLACING *)
31-
32-
type copy_statement =
33-
| CDirCopy of
34-
{
35-
library: library;
36-
suppress_printing: bool;
37-
replacing: replacing with_loc list;
38-
}
39-
and replace_statement =
40-
| CDirReplace of
41-
{
42-
also: bool;
43-
replacing: replacing with_loc list;
44-
}
45-
| CDirReplaceOff of
46-
{
47-
last: bool;
48-
}
49-
and library =
50-
{
51-
libname: fileloc with_loc;
52-
cbkname: fileloc with_loc option;
53-
}
54-
and fileloc = [`Word | `Alphanum] * string
55-
and replacing
56-
57-
type (_, _) repl_attempt =
58-
| OnPartText: ([`NoReplacement | `MissingText],
59-
partial_text_repl_result) repl_attempt
60-
| OnFullText: ([`NoReplacement],
61-
text * Preproc_trace.log) repl_attempt
62-
and partial_text_repl_result =
63-
(text * Preproc_trace.log,
64-
[`MissingText of text * Preproc_trace.log * text]) result
65-
66-
module type ENTRY_POINTS = sig
67-
type 'x entry
68-
val replace_statement: replace_statement with_diags with_loc entry
69-
val lexing_directive: lexing_directive option with_diags with_loc entry
70-
val copy_statement: copy_statement with_diags with_loc entry
71-
end
72-
73-
module type PPPARSER = sig
74-
exception Error
75-
76-
(* The incremental API. *)
77-
module MenhirInterpreter: MenhirLib.IncrementalEngine.INCREMENTAL_ENGINE
78-
with type token = Preproc_tokens.token
79-
80-
(* The entry point(s) to the incremental API. *)
81-
module Incremental: ENTRY_POINTS with type
82-
'x entry := Lexing.position -> 'x MenhirInterpreter.checkpoint
83-
end
84-
85-
type partial_replacing =
86-
{
87-
repl_dir: replacing_direction;
88-
repl_strict: bool;
89-
}
90-
and replacing_direction = Leading | Trailing
91-
92-
val replacing
93-
: ?partial:partial_replacing
94-
-> pseudotext with_loc
95-
-> pseudotext with_loc
96-
-> replacing option with_diags
97-
val apply_replacing
98-
: (_, 'a) repl_attempt
99-
-> replacing with_loc list
100-
-> Preproc_trace.log
101-
-> text
102-
-> 'a
103-
104-
(** {3 Source format} *)
24+
(** {2 Source format} *)
10525

10626
val source_format
10727
: any_srclexer
10828
-> Src_format.any
10929
val cdir_source_format
11030
: dialect: Cobol_config.dialect
11131
-> string with_loc
112-
-> lexing_directive option with_diags
32+
-> Preproc_directives.lexing_directive option with_diags
11333
val with_source_format
11434
: 'k Src_format.source_format with_loc
11535
-> any_srclexer
11636
-> any_srclexer
11737

118-
(** {3 Instantiation} *)
38+
(** {2 Instantiation} *)
11939

12040
val srclex_from_file
12141
: source_format: Src_format.any
@@ -132,7 +52,7 @@ val srclex_from_channel
13252
-> in_channel
13353
-> any_srclexer
13454

135-
(** {3 Resetting the input} *)
55+
(** {2 Resetting the input} *)
13656

13757
(** Note: the functions below assume [position] corresponds to the begining of
13858
the input.} *)
@@ -153,7 +73,7 @@ val srclex_restart_on_channel
15373
-> any_srclexer
15474
-> any_srclexer
15575

156-
(** {3 Queries} *)
76+
(** {2 Queries} *)
15777

15878
val srclex_diags
15979
: any_srclexer
@@ -167,12 +87,46 @@ val srclex_comments
16787
val srclex_newline_cnums
16888
: any_srclexer
16989
-> int list
90+
val next_source_line
91+
: any_srclexer
92+
-> any_srclexer * text
93+
val fold_source_lines
94+
: any_srclexer
95+
-> (text -> 'a -> 'a)
96+
-> 'a
97+
-> 'a
98+
val print_source_lines
99+
: Format.formatter
100+
-> any_srclexer
101+
-> unit
170102

171-
val next_source_line: any_srclexer -> any_srclexer * text
172-
val fold_source_lines: any_srclexer -> (text -> 'a -> 'a) -> 'a -> 'a
173-
val print_source_lines: Format.formatter -> any_srclexer -> unit
103+
(** {1 Compiler Directives} *)
174104

175-
(* --- *)
105+
val replacing
106+
: ?partial: Preproc_directives.partial_replacing
107+
-> pseudotext with_loc
108+
-> pseudotext with_loc
109+
-> Preproc_directives.replacing option with_diags
110+
111+
type (_, _) repl_attempt =
112+
| OnPartText: ([`NoReplacement | `MissingText],
113+
partial_text_repl_result) repl_attempt
114+
| OnFullText: ([`NoReplacement],
115+
text * Preproc_trace.log) repl_attempt
116+
and partial_text_repl_result =
117+
(text * Preproc_trace.log,
118+
[`MissingText of text * Preproc_trace.log * text]) result
119+
val apply_replacing
120+
: (_, 'a) repl_attempt
121+
-> Preproc_directives.replacing with_loc list
122+
-> Preproc_trace.log
123+
-> text
124+
-> 'a
125+
126+
(** {1 Preprocessor state}
127+
128+
This state is used to track some preprocessing-related divisions, like the
129+
`CONTROL DIVISION` in the GCOS dialect. *)
176130

177131
type state
178132

@@ -198,3 +152,27 @@ val find_preproc_phrase
198152
-> text
199153
-> (preproc_phrase * state,
200154
[> `MissingPeriod | `MissingText | `NoneFound ]) result
155+
156+
(** {1 Parsing statements and directives} *)
157+
158+
module type ENTRY_POINTS = sig
159+
type 'x entry
160+
val replace_statement
161+
: Preproc_directives.replace_statement with_diags with_loc entry
162+
val lexing_directive
163+
: Preproc_directives.lexing_directive option with_diags with_loc entry
164+
val copy_statement
165+
: Preproc_directives.copy_statement with_diags with_loc entry
166+
end
167+
168+
module type PPPARSER = sig
169+
exception Error
170+
171+
(* The incremental API. *)
172+
module MenhirInterpreter: MenhirLib.IncrementalEngine.INCREMENTAL_ENGINE
173+
with type token = Preproc_tokens.token
174+
175+
(* The entry point(s) to the incremental API. *)
176+
module Incremental: ENTRY_POINTS with type
177+
'x entry := Lexing.position -> 'x MenhirInterpreter.checkpoint
178+
end
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
(**************************************************************************)
2+
(* *)
3+
(* SuperBOL OSS Studio *)
4+
(* *)
5+
(* Copyright (c) 2022-2023 OCamlPro SAS *)
6+
(* *)
7+
(* All rights reserved. *)
8+
(* This source code is licensed under the GNU Affero General Public *)
9+
(* License version 3 found in the LICENSE.md file in the root directory *)
10+
(* of this source tree. *)
11+
(* *)
12+
(**************************************************************************)
13+
14+
open Cobol_common.Srcloc.TYPES
15+
open Text.TYPES
16+
17+
type lexing_directive =
18+
| LexDirSource:
19+
'k Src_format.source_format with_loc -> lexing_directive [@@unboxed]
20+
21+
type copy_statement =
22+
| CDirCopy of
23+
{
24+
library: library;
25+
suppress_printing: bool;
26+
replacing: replacing with_loc list;
27+
}
28+
and replace_statement =
29+
| CDirReplace of
30+
{
31+
also: bool;
32+
replacing: replacing with_loc list;
33+
}
34+
| CDirReplaceOff of
35+
{
36+
last: bool;
37+
}
38+
and library =
39+
{
40+
libname: fileloc with_loc;
41+
cbkname: fileloc with_loc option;
42+
}
43+
and fileloc = [`Word | `Alphanum] * string
44+
and replacing =
45+
| ReplaceExact of
46+
{
47+
repl_from: pseudotext with_loc;
48+
repl_to: pseudotext with_loc;
49+
}
50+
| ReplacePartial of
51+
{
52+
repl_subst: partial_subst with_loc;
53+
repl_to: string with_loc option;
54+
}
55+
and partial_subst =
56+
{
57+
partial_subst_dir: replacing_direction;
58+
partial_subst_len: int;
59+
partial_subst_regexp: Str.regexp;
60+
}
61+
and replacing_direction = Leading | Trailing
62+
63+
type partial_replacing =
64+
{
65+
repl_dir: replacing_direction;
66+
repl_strict: bool;
67+
}

0 commit comments

Comments
 (0)