@@ -54,90 +54,92 @@ let is_poly {typ = ts1, ts2} = List.mem VarT ts1 || List.mem VarT ts2
5454
5555let typs = [BoolT ; IntT ; CharT ; TextT ]
5656
57+ type 'a def =
58+ | VoidD : unit def
59+ | BoolD : bool def
60+ | IntD : int def
61+ | CharD : char def
62+ | TextD : string def
63+ | VarD : const def
64+ | ProdD : 'a def * 'b def -> ('a * 'b ) def
65+
66+ let (&) l r = ProdD (l, r)
67+
68+ let rec typs_of : type a. a def -> typ list = function
69+ | VoidD -> []
70+ | BoolD -> [BoolT ]
71+ | IntD -> [IntT ]
72+ | CharD -> [CharT ]
73+ | TextD -> [TextT ]
74+ | VarD -> [VarT ]
75+ | ProdD (l , r ) -> typs_of l @ typs_of r
76+
77+ let rec inj : type a. a def -> a -> const list -> const list = function
78+ | VoidD -> fun () vs -> vs
79+ | BoolD -> fun v vs -> BoolV v :: vs
80+ | IntD -> fun v vs -> IntV v :: vs
81+ | CharD -> fun v vs -> CharV v :: vs
82+ | TextD -> fun v vs -> TextV v :: vs
83+ | VarD -> fun v vs -> v :: vs
84+ | ProdD (lD , rD ) ->
85+ let injL = inj lD and injR = inj rD in fun (l , r ) vs -> injL l (injR r vs)
86+
87+ let rec prj : type a. a def -> const list -> a * const list = function
88+ | VoidD -> fun vs -> (() , vs)
89+ | BoolD -> (function (BoolV v :: vs ) -> (v, vs) | _ -> failwith " bool" )
90+ | IntD -> (function (IntV v :: vs ) -> (v, vs) | _ -> failwith " int" )
91+ | CharD -> (function (CharV v :: vs ) -> (v, vs) | _ -> failwith " char" )
92+ | TextD -> (function (TextV v :: vs ) -> (v, vs) | _ -> failwith " text" )
93+ | VarD -> (function (v :: vs ) -> (v, vs) | _ -> failwith " var" )
94+ | ProdD (lD , rD ) ->
95+ let prjL = prj lD and prjR = prj rD in
96+ fun vs -> let (l, vs) = prjL vs in let (r, vs) = prjR vs in ((l, r), vs)
97+
98+ let def name inD outD fn = {
99+ name = name;
100+ typ = typs_of inD, typs_of outD;
101+ fn = let inj = inj outD and prj = prj inD in
102+ fun vs -> let (v, vs) = prj vs in assert (vs = [] ); inj (fn v) []
103+ }
104+
57105let funs =
58106 [
59- {name = " ==" ;
60- typ = [VarT ; VarT ], [BoolT ];
61- fn = fun [x1 ; x2 ] -> [BoolV (x1 = x2)]};
62- {name = " <>" ;
63- typ = [VarT ; VarT ], [BoolT ];
64- fn = fun [x1 ; x2 ] -> [BoolV (x1 <> x2)]};
65-
66- {name = " true" ;
67- typ = [] , [BoolT ];
68- fn = fun [] -> [BoolV (true )]};
69- {name = " false" ;
70- typ = [] , [BoolT ];
71- fn = fun [] -> [BoolV (false )]};
72-
73- {name = " Int.+" ;
74- typ = [IntT ; IntT ], [IntT ];
75- fn = fun [IntV i1 ; IntV i2 ] -> [IntV (i1 + i2)]};
76- {name = " Int.-" ;
77- typ = [IntT ; IntT ], [IntT ];
78- fn = fun [IntV i1 ; IntV i2 ] -> [IntV (i1 - i2)]};
79- {name = " Int.*" ;
80- typ = [IntT ; IntT ], [IntT ];
81- fn = fun [IntV i1 ; IntV i2 ] -> [IntV (i1 * i2)]};
82- {name = " Int./" ;
83- typ = [IntT ; IntT ], [IntT ];
84- fn = fun [IntV i1 ; IntV i2 ] -> [IntV (i1 / i2)]};
85- {name = " Int.%" ;
86- typ = [IntT ; IntT ], [IntT ];
87- fn = fun [IntV i1 ; IntV i2 ] -> [IntV (i1 mod i2)]};
88- {name = " Int.<" ;
89- typ = [IntT ; IntT ], [BoolT ];
90- fn = fun [x1 ; x2 ] -> [BoolV (x1 < x2)]};
91- {name = " Int.>" ;
92- typ = [IntT ; IntT ], [BoolT ];
93- fn = fun [x1 ; x2 ] -> [BoolV (x1 > x2)]};
94- {name = " Int.<=" ;
95- typ = [IntT ; IntT ], [BoolT ];
96- fn = fun [x1 ; x2 ] -> [BoolV (x1 < = x2)]};
97- {name = " Int.>=" ;
98- typ = [IntT ; IntT ], [BoolT ];
99- fn = fun [x1 ; x2 ] -> [BoolV (x1 > = x2)]};
100- {name = " Int.print" ;
101- typ = [IntT ], [] ;
102- fn = fun [IntV i ] -> print_int i; flush_all () ; [] };
103-
104- {name = " Char.toInt" ;
105- typ = [CharT ], [IntT ];
106- fn = fun [CharV c ] -> [IntV (Char. code c)]};
107- {name = " Char.fromInt" ;
108- typ = [IntT ], [CharT ];
109- fn = fun [IntV i ] -> [CharV (Char. chr i)]};
110- {name = " Char.print" ;
111- typ = [CharT ], [] ;
112- fn = fun [CharV c ] -> print_char c; flush_all () ; [] };
113-
114- {name = " Text.++" ;
115- typ = [TextT ; TextT ], [TextT ];
116- fn = fun [TextV t1 ; TextV t2 ] -> [TextV (t1 ^ t2)]};
117- {name = " Text.<" ;
118- typ = [TextT ; TextT ], [BoolT ];
119- fn = fun [x1 ; x2 ] -> [BoolV (x1 < x2)]};
120- {name = " Text.>" ;
121- typ = [TextT ; TextT ], [BoolT ];
122- fn = fun [x1 ; x2 ] -> [BoolV (x1 > x2)]};
123- {name = " Text.<=" ;
124- typ = [TextT ; TextT ], [BoolT ];
125- fn = fun [x1 ; x2 ] -> [BoolV (x1 < = x2)]};
126- {name = " Text.>=" ;
127- typ = [TextT ; TextT ], [BoolT ];
128- fn = fun [x1 ; x2 ] -> [BoolV (x1 > = x2)]};
129- {name = " Text.length" ;
130- typ = [TextT ], [IntT ];
131- fn = fun [TextV t ] -> [IntV (String. length t)]};
132- {name = " Text.sub" ;
133- typ = [TextT ; IntT ], [CharT ];
134- fn = fun [TextV t ; IntV i ] -> [CharV (t.[i])]};
135- {name = " Text.fromChar" ;
136- typ = [CharT ], [TextT ];
137- fn = fun [CharV c ] -> [TextV (String. make 1 c)]};
138- {name = " Text.print" ;
139- typ = [TextT ], [] ;
140- fn = fun [TextV t ] -> print_string t; flush_all () ; [] };
107+ def " ==" (VarD & VarD ) BoolD (fun (x1 , x2 ) -> x1 = x2);
108+ def " <>" (VarD & VarD ) BoolD (fun (x1 , x2 ) -> x1 <> x2);
109+
110+ def " true" VoidD BoolD (fun () -> true );
111+ def " false" VoidD BoolD (fun () -> false );
112+
113+ def " Int.+" (IntD & IntD ) IntD (fun (i1 , i2 ) -> i1 + i2);
114+ def " Int.-" (IntD & IntD ) IntD (fun (i1 , i2 ) -> i1 - i2);
115+ def " Int.*" (IntD & IntD ) IntD (fun (i1 , i2 ) -> i1 * i2);
116+ def " Int./" (IntD & IntD ) IntD (fun (i1 , i2 ) -> i1 / i2);
117+ def " Int.%" (IntD & IntD ) IntD (fun (i1 , i2 ) -> i1 mod i2);
118+
119+ def " Int.<" (IntD & IntD ) BoolD (fun (i1 , i2 ) -> i1 < i2);
120+ def " Int.>" (IntD & IntD ) BoolD (fun (i1 , i2 ) -> i1 > i2);
121+ def " Int.<=" (IntD & IntD ) BoolD (fun (i1 , i2 ) -> i1 < = i2);
122+ def " Int.>=" (IntD & IntD ) BoolD (fun (i1 , i2 ) -> i1 > = i2);
123+
124+ def " Int.print" IntD VoidD (fun i -> print_int i; flush_all () );
125+
126+ def " Char.toInt" CharD IntD Char. code;
127+ def " Char.fromInt" IntD CharD Char. chr;
128+
129+ def " Char.print" CharD VoidD (fun c -> print_char c; flush_all () );
130+
131+ def " Text.++" (TextD & TextD ) TextD (fun (t1 , t2 ) -> t1 ^ t2);
132+
133+ def " Text.<" (TextD & TextD ) BoolD (fun (i1 , i2 ) -> i1 < i2);
134+ def " Text.>" (TextD & TextD ) BoolD (fun (i1 , i2 ) -> i1 > i2);
135+ def " Text.<=" (TextD & TextD ) BoolD (fun (i1 , i2 ) -> i1 < = i2);
136+ def " Text.>=" (TextD & TextD ) BoolD (fun (i1 , i2 ) -> i1 > = i2);
137+
138+ def " Text.length" TextD IntD String. length;
139+ def " Text.sub" (TextD & IntD ) CharD (fun (t , i ) -> t.[i]);
140+ def " Text.fromChar" CharD TextD (String. make 1 );
141+
142+ def " Text.print" TextD VoidD (fun t -> print_string t; flush_all () );
141143 ]
142144
143145let fun_of_string name =
0 commit comments