package diffast-langs-verilog-parsing

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file context.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
(*
   Copyright 2012-2025 Codinuum Software Lab <https://codinuum.com>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*)
(* context.ml *)

[%%prepare_logger]

module Astloc = Langs_common.Astloc

module Loc = Astloc

type tag =
  | Cunknown
  | Ctoplevel
  | Cmodule_item_list
  | Cgenerate_item_list
  | Cblock_decl_stmt_list
  | Ccase_item_list
  | Ccase_inside_item_list
  | Ccellpin_list
  | Clist_of_ports
  | Cpev_expr
  | Cev_expr
  | Cexpr

let tag_to_string = function
  | Cunknown               -> "unknown"
  | Ctoplevel              -> "toplevel"
  | Cmodule_item_list      -> "module_item_list"
  | Cgenerate_item_list    -> "generate_item_list"
  | Cblock_decl_stmt_list  -> "block_decl_stmt_list"
  | Ccase_item_list        -> "case_item_list"
  | Ccase_inside_item_list -> "case_inside_item_list"
  | Ccellpin_list          -> "cellpin_list"
  | Clist_of_ports         -> "list_of_ports"
  | Cpev_expr              -> "pev_expr"
  | Cev_expr               -> "ev_expr"
  | Cexpr                  -> "expr"

type t = { tag               : tag;
	   mutable is_active : bool;
	 }

let copy_context c = { tag = c.tag; is_active = c.is_active }

let deactivate_context c = c.is_active <- false

let to_string { tag=tag; is_active=is_active } =
  Printf.sprintf "%s[%sACTIVE]" (tag_to_string tag) (if is_active then "" else "NOT ")

let unknown() = { tag=Cunknown; is_active=false; }

let toplevel() = { tag=Ctoplevel; is_active=true; }

let module_item_list() = { tag=Cmodule_item_list; is_active=true; }

let generate_item_list() = { tag=Cgenerate_item_list; is_active=true; }

let block_decl_stmt_list() = { tag=Cblock_decl_stmt_list; is_active=true; }

let case_item_list() = { tag=Ccase_item_list; is_active=true; }

let case_inside_item_list() = { tag=Ccase_inside_item_list; is_active=true; }

let cellpin_list() = { tag=Ccellpin_list; is_active=true; }

let list_of_ports() = { tag=Clist_of_ports; is_active=true; }

let pev_expr() = { tag=Cpev_expr; is_active=true; }

let ev_expr() = { tag=Cev_expr; is_active=true; }

let expr() = { tag=Cexpr; is_active=true; }


let get_tag { tag=tag; is_active=_; } = tag

let is_unknown c                = c.tag = Cunknown
let is_toplevel c               = c.tag = Ctoplevel
let is_module_item_list c       = c.tag = Cmodule_item_list
let is_generate_item_list c     = c.tag = Cgenerate_item_list
let is_block_decl_stmt_list c   = c.tag = Cblock_decl_stmt_list
let is_case_item_list c         = c.tag = Ccase_item_list
let is_case_inside_item_list c  = c.tag = Ccase_inside_item_list
let is_cellpin_list c           = c.tag = Ccellpin_list
let is_list_of_ports c          = c.tag = Clist_of_ports
let is_pev_expr c               = c.tag = Cpev_expr
let is_ev_expr c                = c.tag = Cev_expr
let is_expr c                   = c.tag = Cexpr


[%%capture_path
class stack env = object (self)
  val checkpoint_tbl = Hashtbl.create 0 (* Loc.t -> t Stack.t *)

  val mutable stack : t Stack.t = Stack.create()
  val mutable suspended = false
  val mutable push_callback       = fun _ -> ()
  val mutable pop_callback        = fun _ _ -> ()
  val mutable activate_callback   = fun _ -> ()
  val mutable deactivate_callback = fun _ -> ()


  method size = Stack.length stack

  method register_push_callback f = push_callback <- f
  method register_pop_callback f = pop_callback <- f
  method register_activate_callback f = activate_callback <- f
  method register_deactivate_callback f = deactivate_callback <- f

  method clear = Stack.clear stack

  method top = Stack.top stack


  method suspended = suspended

  method suspend =
    [%debug_log "called"];
    suspended <- true;

  method resume =
    [%debug_log "called"];
    suspended <- false;

(*
  method _force_pop n stack =
  for i = 1 to n do
  ignore (Stack.pop stack)
  done
 *)

  method checkpoint (key : Loc.t) =
    begin %debug_block
      [%debug_log "key=%s" (Loc.to_string key)];
    Stack.iter (fun c -> [%debug_log "stack: %s" (to_string c)]) stack;
    end;
(*
  if Hashtbl.mem checkpoint_tbl key then
  [%warn_log "already checkpointed: key=%s" (Loc.to_string key)];
 *)
    let copy = self#_copy_stack stack in
    Hashtbl.replace checkpoint_tbl key copy;

  method recover key =
    try
      stack <- self#_copy_stack (Hashtbl.find checkpoint_tbl key);

      begin %debug_block
	[%debug_log "key=%s" (Loc.to_string key)];
      Stack.iter (fun c -> [%debug_log "stack: %s" (to_string c)]) stack;
      end
    with
      Not_found -> [%fatal_log "stack not found: key=%s" (Loc.to_string key)]; exit 1


  method _copy_stack s =
    let copy = Stack.create() in
    let cs = ref [] in
    Stack.iter
      (fun c ->
	cs := (copy_context c) :: !cs
      ) s;
    List.iter
      (fun c ->
	Stack.push c copy
      ) !cs;
    copy


  method push c =
    if not suspended then begin

      begin %debug_block
	[%debug_log "%s" (to_string c)];
      Stack.iter (fun _c -> [%debug_log "stack: %s" (to_string _c)]) stack;
      end;

      Stack.push c stack;
      push_callback c
    end
    else
      [%debug_log "suspended"];

    env#set_context_enter_flag

  method pop = self#_pop false
  method pop_and_activate = self#_pop true

  method _pop terminates_surrounding_construct =
    if not suspended then begin

      begin %debug_block
	Stack.iter
	(fun _c ->
	  [%debug_log "stack: %s" (to_string _c)]
	) stack;
      end;

      ignore (Stack.pop stack);

      let new_top =
	try
	  Stack.top stack
	with Stack.Empty ->
	  assert false
      in
      [%debug_log "(new top: %s)" (to_string  new_top)];

      pop_callback terminates_surrounding_construct new_top
    end
    else
      [%debug_log "suspended"]

  method activate_top : unit =
    if not suspended then begin
      let c = self#top in

      if not c.is_active then
	[%debug_log "%s" (to_string c)];

      c.is_active <- true
    end;
    env#set_context_activate_flag

  method activate_top_no_delay =
    if not suspended then begin
      let c = self#top in

      if not c.is_active then
	[%debug_log "%s" (to_string c)];

      c.is_active <- true;
      activate_callback c
    end

  method deactivate_top =
    if not suspended then begin
      let c = self#top in

      if c.is_active then
	[%debug_log "%s" (to_string c)];

      c.is_active <- false
    end

  method deactivate_top_no_delay =
    if not suspended then begin
      let c = self#top in

      if c.is_active then
	[%debug_log "%s" (to_string c)];

      c.is_active <- false;
      deactivate_callback c
    end

  method top_is_active =
    let c = self#top in
    c.is_active

  method top_is_unknown =
    let c = self#top in
    is_unknown c

  method reset =
    self#clear;
    Hashtbl.clear checkpoint_tbl;
    self#push (toplevel())


  initializer
    self#reset

end (* of class Context.stack *)
]
OCaml

Innovation. Community. Security.