Skip to content

Commit 5b57efa

Browse files
committed
Lisa cfg
1 parent 81518a5 commit 5b57efa

5 files changed

Lines changed: 138 additions & 0 deletions

File tree

src/cfg/cfg.ml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
open Ast
2+
3+
(* Abidefinitsioon, et pärast oma Graph mooduli defineerimist saaks ocamlgraph-ile ligi. *)
4+
module Ocamlgraph = Graph
5+
6+
module Node = Node
7+
module Edge = Edge
8+
9+
module Graph =
10+
struct
11+
module G = Ocamlgraph.Persistent.Digraph.ConcreteLabeled (Node) (Edge)
12+
include G
13+
include Ocamlgraph.Oper.P (G)
14+
end
15+
16+
17+
(** Juhtvoograaf. *)
18+
type t = {
19+
entry: Node.t; (** Sisendtipp. *)
20+
g: Graph.t; (** Graaf ise. *)
21+
exit: Node.t; (** Väljundtipp. *)
22+
}
23+
24+
(** Teisendab lause juhtvoograafiks. *)
25+
let rec of_stmt (stmt: stmt): t =
26+
match stmt with
27+
| Assign (v, e) ->
28+
let entry = Node.fresh () in
29+
let exit = Node.fresh () in
30+
let g = Graph.add_edge_e Graph.empty (entry, Assign (v, e), exit) in
31+
{entry; g; exit}
32+
| If (c, t, f) ->
33+
let t_cfg = of_stmt t in
34+
let f_cfg = of_stmt f in
35+
let entry = Node.fresh () in
36+
let exit = Node.fresh () in
37+
let g = Graph.union t_cfg.g f_cfg.g in
38+
let g = Graph.add_edge_e g (entry, Guard (c, true), t_cfg.entry) in
39+
let g = Graph.add_edge_e g (entry, Guard (c, false), f_cfg.entry) in
40+
let g = Graph.add_edge_e g (t_cfg.exit, Nop, exit) in
41+
let g = Graph.add_edge_e g (f_cfg.exit, Nop, exit) in
42+
{entry; g; exit}
43+
| Nop ->
44+
let node = Node.fresh () in
45+
let g = Graph.add_vertex Graph.empty node in
46+
{entry = node; g; exit = node}
47+
| Error ->
48+
let entry = Node.fresh () in
49+
let exit = Node.fresh () in
50+
let g = Graph.add_edge_e Graph.empty (entry, Error, exit) in
51+
{entry; g; exit}
52+
| Seq (a, b) ->
53+
let a_cfg = of_stmt a in
54+
let b_cfg = of_stmt b in
55+
let g = Graph.union a_cfg.g b_cfg.g in
56+
let g = Graph.add_edge_e g (a_cfg.exit, Nop, b_cfg.entry) in
57+
{entry = a_cfg.entry; g; exit = b_cfg.exit}
58+
| While (c, b) ->
59+
let b_cfg = of_stmt b in
60+
let entry = Node.fresh () in
61+
let exit = Node.fresh () in
62+
let g = b_cfg.g in
63+
let g = Graph.add_edge_e g (entry, Guard (c, true), b_cfg.entry) in
64+
let g = Graph.add_edge_e g (entry, Guard (c, false), exit) in
65+
let g = Graph.add_edge_e g (b_cfg.exit, Nop, entry) in
66+
{entry; g; exit}
67+
68+
69+
(** Abifunktsioonid. *)
70+
71+
(** Tagastab tipust väljuvad servad ja vastavad sihttipud. *)
72+
let succ (cfg: t) (node: Node.t): (Edge.t * Node.t) list =
73+
Graph.succ_e cfg.g node
74+
|> List.map (fun (_, edge, node') ->
75+
(edge, node')
76+
)
77+
78+
(** Tagastab tippu sisenevad servad ja vastavad lähtetipud. *)
79+
let pred (cfg: t) (node: Node.t): (Edge.t * Node.t) list =
80+
Graph.pred_e cfg.g node
81+
|> List.map (fun (node', edge, _) ->
82+
(edge, node')
83+
)
84+
85+
(** Kas tipp on Error-i kohal? *)
86+
let is_error (cfg: t) (node: Node.t): bool =
87+
succ cfg node
88+
|> List.exists (fun (edge, _) ->
89+
edge = Edge.Error
90+
)
91+
92+
(** Tagastab kõik tipud. *)
93+
let nodes (cfg: t): Node.t list =
94+
Graph.fold_vertex List.cons cfg.g []
95+
96+

src/cfg/dune

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(library
2+
(name cfg)
3+
(libraries ast ocamlgraph)
4+
(preprocess (pps ppx_deriving.std ppx_deriving_hash)))

src/cfg/edge.ml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
(** Juhtvoograafi serv. *)
2+
open Ast
3+
4+
type t =
5+
| Assign of var * expr (** Omistamine *)
6+
| Guard of expr * bool (** Valvur tõese/väära haru jaoks *)
7+
| Error (** Vea tekkimine *)
8+
| Nop (** Mitte millegi tegemine *)
9+
[@@deriving ord]
10+
11+
12+
(** Väljatrüki funktsioonid. *)
13+
14+
let pp ppf edge =
15+
match edge with
16+
| Assign (v, e) -> Format.fprintf ppf "%a = %a" pp_var v pp_expr e
17+
| Guard (e, true) -> Format.fprintf ppf "[%a]" pp_expr e
18+
| Guard (e, false) -> Format.fprintf ppf "[!(%a)]" pp_expr e
19+
| Error -> Format.pp_print_string ppf "error()"
20+
| Nop -> Format.pp_print_string ppf ""
21+
22+
let show edge = Format.asprintf "%a" pp edge
23+
24+
25+
(** ocamlgraph-i jaoks. *)
26+
let default = Nop

src/cfg/node.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type t = int [@@deriving eq, ord, hash, show]
2+
3+
let fresh =
4+
let i = ref 0 in
5+
fun () ->
6+
incr i;
7+
!i

src/cfg/node.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
(** Abstraktne juhtvoograafi tipp. *)
2+
type t [@@deriving eq, ord, hash, show]
3+
4+
(** Loob uue unikaalse tipu. *)
5+
val fresh: unit -> t

0 commit comments

Comments
 (0)