Skip to content

Commit 19e01b7

Browse files
committed
done implement unified_ops translation
1 parent 64d4e15 commit 19e01b7

File tree

7 files changed

+86
-72
lines changed

7 files changed

+86
-72
lines changed

compiler/core/lam_convert.ml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,6 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t =
232232
| Pduprecord -> prim ~primitive:Pduprecord ~args loc
233233
| Plazyforce -> prim ~primitive:Plazyforce ~args loc
234234
| Praise _ -> prim ~primitive:Praise ~args loc
235-
| Pinfix _ -> assert false
236235
| Pobjcomp x -> prim ~primitive:(Pobjcomp x) ~args loc
237236
| Pobjorder -> prim ~primitive:Pobjorder ~args loc
238237
| Pobjmin -> prim ~primitive:Pobjmin ~args loc
@@ -476,16 +475,6 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) :
476475
| Lprim (Pimport, args, loc) ->
477476
let args = Ext_list.map args (convert_aux ~dynamic_import:true) in
478477
lam_prim ~primitive:Pimport ~args loc
479-
| Lprim (Pinfix (Inf_custom (mod_, op)), args, loc) ->
480-
let fn = Lam.var (Ident.create_persistent op) in
481-
let args = Ext_list.map args (convert_aux ~dynamic_import) in
482-
let ap_info : Lam.ap_info =
483-
{ap_loc = loc; ap_status = App_na; ap_inlined = Lambda.Default_inline}
484-
in
485-
Lam.apply fn args ap_info
486-
| Lprim (Pinfix Inf_invariant, args, loc) ->
487-
(* TODO : invariant *)
488-
assert false
489478
| Lprim (primitive, args, loc) ->
490479
let args = Ext_list.map args (convert_aux ~dynamic_import) in
491480
lam_prim ~primitive ~args loc

compiler/ml/lambda.ml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,6 @@ type immediate_or_pointer = Immediate | Pointer
175175

176176
type is_safe = Safe | Unsafe
177177

178-
type infix_info = Inf_custom of string * string | Inf_invariant
179-
180178
type primitive =
181179
| Pidentity
182180
| Pignore
@@ -200,8 +198,6 @@ type primitive =
200198
| Pccall of Primitive.description
201199
(* Exceptions *)
202200
| Praise of raise_kind
203-
(* Infix *)
204-
| Pinfix of infix_info
205201
(* object operations *)
206202
| Pobjcomp of comparison
207203
| Pobjorder

compiler/ml/lambda.mli

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,6 @@ type pointer_info =
138138
| Pt_shape_none
139139
| Pt_assertfalse
140140

141-
type infix_info = Inf_custom of string * string | Inf_invariant
142-
143141
type primitive =
144142
| Pidentity
145143
| Pignore
@@ -163,8 +161,6 @@ type primitive =
163161
| Pccall of Primitive.description
164162
(* Exceptions *)
165163
| Praise of raise_kind
166-
(* Infix *)
167-
| Pinfix of infix_info
168164
(* object primitives *)
169165
| Pobjcomp of comparison
170166
| Pobjorder

compiler/ml/printlambda.ml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,6 @@ let primitive ppf = function
125125
| Plazyforce -> fprintf ppf "force"
126126
| Pccall p -> fprintf ppf "%s" p.prim_name
127127
| Praise k -> fprintf ppf "%s" (Lambda.raise_kind k)
128-
| Pinfix (Inf_custom (mod_, op)) -> fprintf ppf "%s.%s" mod_ op
129-
| Pinfix Inf_invariant -> fprintf ppf "invariant"
130128
| Pobjcomp Ceq -> fprintf ppf "=="
131129
| Pobjcomp Cneq -> fprintf ppf "!="
132130
| Pobjcomp Clt -> fprintf ppf "<"

compiler/ml/translcore.ml

Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,30 @@ let transl_extension_constructor env path ext =
4949

5050
(* Translation of primitives *)
5151

52-
(*
53-
type sargs = (Asttypes.arg_label * Parsetree.expression) list
54-
55-
let translate_unified_application (env : Env.t) (prim : Primitive.description)
56-
(sargs : sargs) : Lambda.primitive option =
57-
(* TODO *)
58-
None
59-
*)
52+
let translate_unified_ops (prim : Primitive.description) (env : Env.t)
53+
(lhs_type : type_expr) : Lambda.primitive option =
54+
(* lhs_type is already unified in type-level *)
55+
let entry = Hashtbl.find_opt Unified_ops.index_by_name prim.prim_name in
56+
match entry with
57+
| Some {specialization} -> (
58+
match specialization with
59+
| {int}
60+
when is_base_type env lhs_type Predef.path_int
61+
|| is_base_type env lhs_type Predef.path_char
62+
|| maybe_pointer_type env lhs_type = Immediate ->
63+
Some int
64+
| {float = Some float} when is_base_type env lhs_type Predef.path_float ->
65+
Some float
66+
| {bigint = Some bigint} when is_base_type env lhs_type Predef.path_bigint
67+
->
68+
Some bigint
69+
| {string = Some string} when is_base_type env lhs_type Predef.path_string
70+
->
71+
Some string
72+
| {bool = Some bool} when is_base_type env lhs_type Predef.path_bool ->
73+
Some bool
74+
| {int} -> Some int)
75+
| _ -> None
6076

6177
type specialized = {
6278
objcomp: Lambda.primitive;
@@ -403,12 +419,21 @@ let specialize_comparison
403419
raise Not_found if primitive is unknown *)
404420

405421
let specialize_primitive p env ty (* ~has_constant_constructor *) =
406-
try
407-
let table = Hashtbl.find comparisons_table p.prim_name in
408-
match is_function_type env ty with
409-
| Some (lhs, _rhs) -> specialize_comparison table env lhs
410-
| None -> table.objcomp
411-
with Not_found -> find_primitive p.prim_name
422+
let fn_expr = is_function_type env ty in
423+
let unified =
424+
match fn_expr with
425+
| Some (lhs, _) -> translate_unified_ops p env lhs
426+
| None -> None
427+
in
428+
match unified with
429+
| Some primitive -> primitive
430+
| None -> (
431+
try
432+
let table = Hashtbl.find comparisons_table p.prim_name in
433+
match fn_expr with
434+
| Some (lhs, _rhs) -> specialize_comparison table env lhs
435+
| None -> table.objcomp
436+
with Not_found -> find_primitive p.prim_name)
412437

413438
(* Eta-expand a primitive *)
414439

@@ -467,32 +492,44 @@ let transl_primitive loc p env ty =
467492

468493
let transl_primitive_application loc prim env ty args =
469494
let prim_name = prim.prim_name in
470-
try
495+
let unified =
471496
match args with
472-
| [arg1; _]
473-
when is_base_type env arg1.exp_type Predef.path_bool
474-
&& Hashtbl.mem comparisons_table prim_name ->
475-
(Hashtbl.find comparisons_table prim_name).boolcomp
476-
| _ ->
477-
let has_constant_constructor =
478-
match args with
479-
| [_; {exp_desc = Texp_construct (_, {cstr_tag = Cstr_constant _}, _)}]
480-
| [{exp_desc = Texp_construct (_, {cstr_tag = Cstr_constant _}, _)}; _]
481-
| [_; {exp_desc = Texp_variant (_, None)}]
482-
| [{exp_desc = Texp_variant (_, None)}; _] ->
483-
true
484-
| _ -> false
485-
in
486-
if has_constant_constructor then
487-
match Hashtbl.find_opt comparisons_table prim_name with
488-
| Some table when table.simplify_constant_constructor -> table.intcomp
489-
| Some _ | None -> specialize_primitive prim env ty
490-
(* ~has_constant_constructor*)
491-
else specialize_primitive prim env ty
492-
with Not_found ->
493-
if String.length prim_name > 0 && prim_name.[0] = '%' then
494-
raise (Error (loc, Unknown_builtin_primitive prim_name));
495-
Pccall prim
497+
| [arg1] | [arg1; _] -> translate_unified_ops prim env arg1.exp_type
498+
| _ -> None
499+
in
500+
match unified with
501+
| Some primitive -> primitive
502+
| None -> (
503+
try
504+
match args with
505+
| [arg1; _]
506+
when is_base_type env arg1.exp_type Predef.path_bool
507+
&& Hashtbl.mem comparisons_table prim_name ->
508+
(Hashtbl.find comparisons_table prim_name).boolcomp
509+
| _ ->
510+
let has_constant_constructor =
511+
match args with
512+
| [
513+
_; {exp_desc = Texp_construct (_, {cstr_tag = Cstr_constant _}, _)};
514+
]
515+
| [
516+
{exp_desc = Texp_construct (_, {cstr_tag = Cstr_constant _}, _)}; _;
517+
]
518+
| [_; {exp_desc = Texp_variant (_, None)}]
519+
| [{exp_desc = Texp_variant (_, None)}; _] ->
520+
true
521+
| _ -> false
522+
in
523+
if has_constant_constructor then
524+
match Hashtbl.find_opt comparisons_table prim_name with
525+
| Some table when table.simplify_constant_constructor -> table.intcomp
526+
| Some _ | None -> specialize_primitive prim env ty
527+
(* ~has_constant_constructor*)
528+
else specialize_primitive prim env ty
529+
with Not_found ->
530+
if String.length prim_name > 0 && prim_name.[0] = '%' then
531+
raise (Error (loc, Unknown_builtin_primitive prim_name));
532+
Pccall prim)
496533

497534
(* To propagate structured constants *)
498535

compiler/ml/typecore.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,7 +2458,7 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp
24582458
in
24592459
let type_clash_context = type_clash_context_from_function sexp sfunct in
24602460
let args, ty_res, fully_applied =
2461-
match translate_unified_application env funct sargs with
2461+
match translate_unified_ops env funct sargs with
24622462
| Some (targs, result_type) -> (targs, result_type, true)
24632463
| None -> type_application ?type_clash_context uncurried env funct sargs
24642464
in
@@ -3563,7 +3563,7 @@ and is_automatic_curried_application env funct =
35633563
| Tarrow _ -> true
35643564
| _ -> false
35653565
3566-
and translate_unified_application (env : Env.t) (funct : Typedtree.expression)
3566+
and translate_unified_ops (env : Env.t) (funct : Typedtree.expression)
35673567
(sargs : sargs) : (targs * Types.type_expr) option =
35683568
match funct.exp_desc with
35693569
| Texp_ident (path, _, _) -> (

compiler/ml/unified_ops.ml

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ open Misc
2424
2525
Since these are simple ad-hoc translations for primitive applications, we cannot use the result type defined in other contexts.
2626
So falling back to int type is the simplest behavior that ensures backwards compatibility.
27+
28+
Actual implementations of translation are colocated into core modules
29+
30+
You can find it in:
31+
- Type-level : ml/typecore.ml
32+
- IR-level : ml/translcore.ml
33+
34+
With function name "translate_unified_ops"
2735
*)
2836

2937
type form = Unary | Binary
@@ -81,13 +89,3 @@ let index_by_path =
8189

8290
let index_by_name =
8391
entries |> Array.map (fun entry -> (entry.name, entry)) |> create_hashtable
84-
85-
(*
86-
Actual implementations of translation are colocated into core modules
87-
88-
You can find it in:
89-
- Type-level : ml/typecore.ml
90-
- IR-level : ml/translcore.ml
91-
92-
With function name "translate_unified_application"
93-
*)

0 commit comments

Comments
 (0)