diff options
author | Rutger Broekhoff | 2025-07-07 21:52:08 +0200 |
---|---|---|
committer | Rutger Broekhoff | 2025-07-07 21:52:08 +0200 |
commit | ba61dfd69504ec6263a9dee9931d93adeb6f3142 (patch) | |
tree | d6c9b78e50eeab24e0c1c09ab45909a6ae3fd5db /lib/mininix/sexp.ml | |
download | verified-dyn-lang-interp-ba61dfd69504ec6263a9dee9931d93adeb6f3142.tar.gz verified-dyn-lang-interp-ba61dfd69504ec6263a9dee9931d93adeb6f3142.zip |
Initialize repository
Diffstat (limited to 'lib/mininix/sexp.ml')
-rw-r--r-- | lib/mininix/sexp.ml | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/lib/mininix/sexp.ml b/lib/mininix/sexp.ml new file mode 100644 index 0000000..95da655 --- /dev/null +++ b/lib/mininix/sexp.ml | |||
@@ -0,0 +1,160 @@ | |||
1 | open Conv | ||
2 | open Core | ||
3 | open Extraction | ||
4 | |||
5 | exception ToSexpError of string | ||
6 | |||
7 | let tag t l = Sexp.List (Sexp.Atom t :: l) | ||
8 | |||
9 | let lit_to_sexp = function | ||
10 | | LitString s -> tag "LitString" [ Sexp.Atom (str s) ] | ||
11 | | LitNum (NInt n) -> | ||
12 | tag "LitNum" [ Sexp.Atom "INT"; Sexp.Atom (str (string_of_Z n)) ] | ||
13 | | LitNum (NFloat n) -> | ||
14 | tag "LitNum" | ||
15 | [ | ||
16 | Sexp.Atom "FLOAT"; | ||
17 | Sexp.Atom (Printf.sprintf "%g" (float_from_flocq n)); | ||
18 | ] | ||
19 | | LitBool b -> tag "LitBool" [ Sexp.Atom (Bool.to_string b) ] | ||
20 | | LitNull -> tag "LitNull" [] | ||
21 | |||
22 | let option_to_sexp mv ~f = | ||
23 | match mv with Some v -> tag "Some" [ f v ] | None -> Sexp.Atom "None" | ||
24 | |||
25 | let mode_to_sexp mode = | ||
26 | Sexp.Atom (match mode with SHALLOW -> "SHALLOW" | DEEP -> "DEEP") | ||
27 | |||
28 | let rec_to_sexp r = Sexp.Atom (match r with REC -> "REC" | NONREC -> "NONREC") | ||
29 | |||
30 | let binop_to_sexp op = | ||
31 | Sexp.Atom | ||
32 | (match op with | ||
33 | | UpdateAttrOp -> "UpdateAttrOp" | ||
34 | | AddOp -> "AddOp" | ||
35 | | SubOp -> "SubOp" | ||
36 | | MulOp -> "MulOp" | ||
37 | | DivOp -> "DivOp" | ||
38 | | AndOp -> "AndOp" | ||
39 | | OrOp -> "OrOp" | ||
40 | | XOrOp -> "XOrOp" | ||
41 | | RoundOp Ceil -> "Ceil" | ||
42 | | RoundOp NearestEven -> "NearestEven" | ||
43 | | RoundOp Floor -> "Floor" | ||
44 | | LtOp -> "LtOp" | ||
45 | | EqOp -> "EqOp" | ||
46 | | HasAttrOp -> "HasAttrOp" | ||
47 | | SelectAttrOp -> "SelectAttrOp" | ||
48 | | DeleteAttrOp -> "DeleteAttrOp" | ||
49 | | SingletonAttrOp -> "SingletonAttrOp" | ||
50 | | TypeOfOp -> "TypeOfOp" | ||
51 | | AppendListOp -> "AppendListOp" | ||
52 | | MatchAttrOp -> "MatchAttrOp" | ||
53 | | MatchListOp -> "MatchListOp" | ||
54 | | MatchStringOp -> "MatchStringOp" | ||
55 | | FunctionArgsOp -> "FunctionArgsOp") | ||
56 | |||
57 | let kind_to_sexp k = Sexp.Atom (match k with ABS -> "ABS" | WITH -> "WITH") | ||
58 | |||
59 | let rec expr_to_sexp = function | ||
60 | | ELit l -> tag "ELit" [ lit_to_sexp l ] | ||
61 | | EId (x, None) -> tag "EId" [ Sexp.Atom (str x) ] | ||
62 | | EId (x, Some (k, e)) -> | ||
63 | tag "EId" | ||
64 | [ Sexp.Atom (str x); tag "alt" [ kind_to_sexp k; expr_to_sexp e ] ] | ||
65 | | EAbs (x, e) -> tag "EAbs" [ Sexp.Atom (str x); expr_to_sexp e ] | ||
66 | | EAbsMatch (ms, strict, e) -> | ||
67 | tag "EAbsMatch" | ||
68 | [ | ||
69 | Sexp.Atom (if strict then "EXACT" else "LOOSE"); | ||
70 | tag "formals" | ||
71 | (matcher_fold | ||
72 | (fun x me se -> | ||
73 | Sexp.List | ||
74 | [ Sexp.Atom (str x); option_to_sexp me ~f:expr_to_sexp ] | ||
75 | :: se) | ||
76 | [] ms); | ||
77 | expr_to_sexp e; | ||
78 | ] | ||
79 | | EApp (e1, e2) -> tag "EApp" [ expr_to_sexp e1; expr_to_sexp e2 ] | ||
80 | | ELetAttr (k, e1, e2) -> | ||
81 | tag "ELetAttr" [ kind_to_sexp k; expr_to_sexp e1; expr_to_sexp e2 ] | ||
82 | | ESeq (mode, e1, e2) -> | ||
83 | tag "ESeq" [ mode_to_sexp mode; expr_to_sexp e1; expr_to_sexp e2 ] | ||
84 | | EAttr bs -> | ||
85 | tag "EAttr" | ||
86 | (attr_set_fold | ||
87 | (fun x (Attr (r, e)) se -> | ||
88 | Sexp.List [ Sexp.Atom (str x); rec_to_sexp r; expr_to_sexp e ] | ||
89 | :: se) | ||
90 | [] bs) | ||
91 | | EList es -> | ||
92 | tag "EList" | ||
93 | (Internal.List.fold_right (fun e se -> expr_to_sexp e :: se) [] es) | ||
94 | | EBinOp (op, e1, e2) -> | ||
95 | tag "EBinOp" [ binop_to_sexp op; expr_to_sexp e1; expr_to_sexp e2 ] | ||
96 | | EIf (e1, e2, e3) -> | ||
97 | tag "EIf" [ expr_to_sexp e1; expr_to_sexp e2; expr_to_sexp e3 ] | ||
98 | |||
99 | let rec val_to_sexp = function | ||
100 | | VLit l -> tag "VLit" [ lit_to_sexp l ] | ||
101 | | VClo _ -> tag "VClo" [] | ||
102 | | VCloMatch _ -> tag "VCloMatch" [] | ||
103 | | VAttr bs -> | ||
104 | tag "VAttr" | ||
105 | (Extraction.thunk_map_fold | ||
106 | (fun x t bs' -> | ||
107 | Sexp.List [ Sexp.Atom (str x); thunk_to_sexp t ] :: bs') | ||
108 | [] bs) | ||
109 | | VList ts -> | ||
110 | tag "VList" | ||
111 | (Internal.List.fold_right (fun t st -> thunk_to_sexp t :: st) [] ts) | ||
112 | |||
113 | and env_to_sexp env = | ||
114 | tag "Env" | ||
115 | (Extraction.env_fold | ||
116 | (fun x (k, t) envs -> | ||
117 | Sexp.List | ||
118 | [ | ||
119 | Sexp.Atom (str x); | ||
120 | Sexp.Atom | ||
121 | (match k with | ||
122 | | Extraction.ABS -> "ABS" | ||
123 | | Extraction.WITH -> "WITH"); | ||
124 | thunk_to_sexp t; | ||
125 | ] | ||
126 | :: envs) | ||
127 | [] env) | ||
128 | |||
129 | and thunk_to_sexp = function | ||
130 | | Thunk _ -> tag "Thunk" [ Sexp.Atom "DELAYED" ] | ||
131 | | Indirect _ -> tag "Thunk" [ Sexp.Atom "INDIRECT" ] | ||
132 | | Forced v -> tag "Thunk" [ Sexp.Atom "FORCED"; val_to_sexp v ] | ||
133 | |||
134 | let expr_res_to_sexp = function | ||
135 | | NoFuel -> Sexp.Atom "NoFuel" | ||
136 | | Res e -> tag "Res" [ option_to_sexp e ~f:expr_to_sexp ] | ||
137 | |||
138 | let val_res_to_sexp = function | ||
139 | | NoFuel -> Sexp.Atom "NoFuel" | ||
140 | | Res e -> tag "Res" [ option_to_sexp e ~f:val_to_sexp ] | ||
141 | |||
142 | let rec (sexp_of_import_tree : Import.tree -> Sexp.t) = function | ||
143 | | { filename; deps = [] } -> Sexp.Atom filename | ||
144 | | { filename; deps } -> | ||
145 | Sexp.List [ Sexp.Atom filename; sexp_of_import_forest deps ] | ||
146 | |||
147 | and sexp_of_import_forest forest = | ||
148 | Sexp.List (Sexp.Atom "deps" :: List.map forest ~f:sexp_of_import_tree) | ||
149 | |||
150 | exception OfSexpError of string | ||
151 | |||
152 | let rec import_tree_of_sexp : Sexp.t -> Import.tree = function | ||
153 | | Sexp.Atom filename -> { filename; deps = [] } | ||
154 | | Sexp.List [ Sexp.Atom filename; deps ] -> | ||
155 | { filename; deps = import_forest_of_sexp deps } | ||
156 | | _ -> raise (OfSexpError "Could not parse import tree") | ||
157 | |||
158 | and import_forest_of_sexp = function | ||
159 | | Sexp.List (Sexp.Atom "deps" :: deps) -> List.map ~f:import_tree_of_sexp deps | ||
160 | | _ -> raise (OfSexpError "Could not parse import forest") | ||