Skip to content

Commit e1886c9

Browse files
committed
compiler: add support for record updates.
This closes #23, taking use one step closer to v0.1
1 parent 7595b97 commit e1886c9

File tree

4 files changed

+57
-15
lines changed

4 files changed

+57
-15
lines changed

src/compiler/ocaml_to_erlang/fun.ml

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -251,21 +251,32 @@ and mk_expression exp ~var_names ~modules ~functions ~module_name =
251251
args
252252
in
253253
Expr.apply name args
254-
(* NOTE: use `extended_expression` to provide map overrides *)
255-
| Texp_record { fields; _ } ->
256-
Expr.map
257-
( fields |> Array.to_list
258-
|> List.map (fun (field, value) ->
259-
let value =
260-
match value with
261-
| Kept _ -> Error.unsupported_feature `Record_update
262-
| Overridden (_, exp) ->
254+
| Texp_record { fields; extended_expression; _ } -> (
255+
let fields =
256+
fields |> Array.to_list
257+
|> List.filter_map (fun (field, value) ->
258+
match value with
259+
| Kept _ -> None
260+
| Overridden (_, exp) ->
261+
let value =
263262
mk_expression exp ~var_names ~modules ~functions
264263
~module_name
265-
in
266-
Expr.map_field
267-
(Expr.const (Const.atom (Atom.mk field.lbl_name)))
268-
value) )
264+
in
265+
let field =
266+
Expr.map_field
267+
(Expr.const (Const.atom (Atom.mk field.lbl_name)))
268+
value
269+
in
270+
Some field)
271+
in
272+
273+
match extended_expression with
274+
| None -> Expr.map fields
275+
| Some prior_map ->
276+
Expr.map_update
277+
(mk_expression prior_map ~var_names ~modules ~functions
278+
~module_name)
279+
fields )
269280
| Texp_field (expr, _, { lbl_name; _ }) ->
270281
let name =
271282
let m = Atom.mk "maps" |> Name.atom in

src/erlang/erl_printer.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,15 +454,15 @@ and pp_expression prefix ppf expr ~module_ =
454454
match fields with
455455
| [] -> Format.fprintf ppf "#{}"
456456
| { mf_name; mf_value; _ } :: fs -> (
457-
Format.fprintf ppf "#{ %a => " (pp_expression "" ~module_) mf_name;
457+
Format.fprintf ppf "#{ %a := " (pp_expression "" ~module_) mf_name;
458458
pp_expression "" ppf mf_value ~module_;
459459
match fs with
460460
| [] -> Format.fprintf ppf " }"
461461
| fs ->
462462
Format.fprintf ppf "\n";
463463
fs
464464
|> List.iter (fun { mf_name; mf_value; _ } ->
465-
Format.fprintf ppf "%s, %a => " padding
465+
Format.fprintf ppf "%s, %a := " padding
466466
(pp_expression "" ~module_)
467467
mf_name;
468468
pp_expression "" ppf mf_value ~module_;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type t = { x: int; y: int; z: int }
2+
3+
let f () =
4+
let a = { x=0; y=0; z=0 } in
5+
{ a with x=2; y=2 }

tests/compiler/expressions.t/run.t

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
match.ml
1111
names.ml
1212
names_primes.ml
13+
record_update.ml
1314
records.ml
1415
$ caramelc compile apply.ml
1516
File "apply.ml", line 6, characters 4-8:
@@ -587,3 +588,28 @@
587588
$ cat let_rec.erl
588589
cat: let_rec.erl: No such file or directory
589590
[1]
591+
$ caramelc compile record_update.ml
592+
Compiling record_update.erl OK
593+
$ cat record_update.erl
594+
% Source code generated with Caramel.
595+
-module(record_update).
596+
-export_type([t/0]).
597+
598+
-export([f/0]).
599+
600+
-type t() :: #{ x => integer()
601+
, y => integer()
602+
, z => integer()
603+
}.
604+
605+
-spec f() -> t().
606+
f() ->
607+
A = #{ x => 0
608+
, y => 0
609+
, z => 0
610+
},
611+
A#{ x := 2
612+
, y := 2
613+
}.
614+
615+

0 commit comments

Comments
 (0)