aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mininix/sexp.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mininix/sexp.ml')
-rw-r--r--lib/mininix/sexp.ml160
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 @@
1open Conv
2open Core
3open Extraction
4
5exception ToSexpError of string
6
7let tag t l = Sexp.List (Sexp.Atom t :: l)
8
9let 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
22let option_to_sexp mv ~f =
23 match mv with Some v -> tag "Some" [ f v ] | None -> Sexp.Atom "None"
24
25let mode_to_sexp mode =
26 Sexp.Atom (match mode with SHALLOW -> "SHALLOW" | DEEP -> "DEEP")
27
28let rec_to_sexp r = Sexp.Atom (match r with REC -> "REC" | NONREC -> "NONREC")
29
30let 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
57let kind_to_sexp k = Sexp.Atom (match k with ABS -> "ABS" | WITH -> "WITH")
58
59let 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
99let 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
113and 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
129and 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
134let expr_res_to_sexp = function
135 | NoFuel -> Sexp.Atom "NoFuel"
136 | Res e -> tag "Res" [ option_to_sexp e ~f:expr_to_sexp ]
137
138let val_res_to_sexp = function
139 | NoFuel -> Sexp.Atom "NoFuel"
140 | Res e -> tag "Res" [ option_to_sexp e ~f:val_to_sexp ]
141
142let 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
147and sexp_of_import_forest forest =
148 Sexp.List (Sexp.Atom "deps" :: List.map forest ~f:sexp_of_import_tree)
149
150exception OfSexpError of string
151
152let 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
158and 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")