Skip to content

Support stack_ fun #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions lib/Ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,20 @@ module Exp = struct
true
| _ -> false

let is_uminus_constant {pconst_desc; _} =
match pconst_desc with
| Pconst_integer (n, _) | Pconst_float (n, _) ->
Char.(String.get n 0 = '-')
| Pconst_unboxed_integer (s, _, _) | Pconst_unboxed_float (s, _, _) -> (
match s with Negative -> true | Positive -> false )
| _ -> false

let is_uminus_op {Location.txt; _} =
match txt with "~-" | "~-." -> true | _ -> false

let is_uplus_op {Location.txt; _} =
match txt with "~+" | "~+." -> true | _ -> false

(* Jane Street: This is meant to be true if the expression can be parsed by
the [simple_expr] production in the parser.

Expand All @@ -200,18 +214,17 @@ module Exp = struct
let rec is_simple_in_parser exp =
match exp.pexp_desc with
| Pexp_indexop_access {pia_rhs= None; _}
|Pexp_new _ | Pexp_object _ | Pexp_ident _ | Pexp_constant _
|Pexp_new _ | Pexp_object _ | Pexp_ident _
|Pexp_construct (_, None)
|Pexp_variant (_, None)
|Pexp_override _ | Pexp_open _ | Pexp_extension _ | Pexp_hole
|Pexp_record _ | Pexp_record_unboxed_product _ | Pexp_array _
|Pexp_list _ | Pexp_list_comprehension _ | Pexp_array_comprehension _
|Pexp_unboxed_tuple _ ->
true
| Pexp_prefix (_, e)
|Pexp_field (e, _)
|Pexp_unboxed_field (e, _)
|Pexp_send (e, _) ->
| Pexp_constant c -> not (is_uminus_constant c)
| Pexp_prefix (op, _) -> not (is_uminus_op op || is_uplus_op op)
| Pexp_field (e, _) | Pexp_unboxed_field (e, _) | Pexp_send (e, _) ->
is_simple_in_parser e
| Pexp_infix ({txt; _}, e1, e2) ->
String.length txt > 0
Expand Down Expand Up @@ -2493,16 +2506,12 @@ end = struct
~test:extension_local ) ->
true
| ( Exp {pexp_desc= Pexp_stack _; _}
, { pexp_desc=
( Pexp_apply _ | Pexp_fun _ | Pexp_function _ | Pexp_lazy _
| Pexp_new _ | Pexp_tuple _
| Pexp_construct (_, Some _)
| Pexp_cons _ | Pexp_infix _ | Pexp_prefix _ | Pexp_stack _
| Pexp_let _ | Pexp_letop _ | Pexp_letopen _ | Pexp_letmodule _
| Pexp_send _ | Pexp_setfield _ | Pexp_ifthenelse _
| Pexp_variant (_, Some _) )
; _ } ) ->
true
, {pexp_desc= Pexp_fun _ | Pexp_function _ | Pexp_construct _; _} ) ->
false
| Exp {pexp_desc= Pexp_stack _; _}, expr
when Exp.is_simple_in_parser expr ->
false
| Exp {pexp_desc= Pexp_stack _; _}, _ -> true
| ( Exp {pexp_desc= Pexp_apply _ | Pexp_construct _; _}
, {pexp_desc= Pexp_stack _; _} ) ->
true
Expand Down
Empty file.
43 changes: 24 additions & 19 deletions test/passing/tests/stack-erased.ml.js-ref
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
(* These tests from the campiler test suite *)

let f = ref (stack_ (fun x -> x))
let f = ref (stack_ fun x -> x)
let f = ref (stack_ (2, 3))
let f = ignore_local (stack_ (2, 3))
let f = ref (stack_ Foo)
let f = ref (stack_ (Bar 42))
let f = ignore_local (stack_ (Bar 42))
let f = ref (stack_ Bar 42)
let f = ignore_local (stack_ Bar 42)
let f = ref (stack_ `Foo)
let f = ref (stack_ (`Bar 42))
let f = ignore_local (stack_ (`Bar 42))
Expand All @@ -21,15 +21,15 @@ let f () = stack_ (3, 5)
let f () = exclave_ stack_ (3, 5)

let f () =
let g = stack_ (fun x -> x) in
let g = stack_ fun x -> x in
g 42
;;

let f () = (stack_ (fun x -> x)) 42
let f () = (stack_ fun x -> x) 42
let f () = List.length (stack_ [ 1; 2; 3 ])
let f () = stack_ [ i for i = 0 to 9 ]
let f () = stack_ [| i for i = 0 to 9 |]
let f () = stack_ (new cla)
let f () = stack_ new cla

class foo cla =
object
Expand Down Expand Up @@ -72,16 +72,16 @@ let mk () =
let f =
ref
(stack_
(function
| x -> x))
function
| x -> x)
;;

let f =
ref
(stack_
(function
| x -> x
| y -> y))
function
| x -> x
| y -> y)
;;

let f =
Expand All @@ -91,13 +91,13 @@ let f =
(stack_
(* 3 *)
(* 4 *)
(function
(* 5 *)
(* 6 *)
| x -> x))
function
(* 5 *)
(* 6 *)
| x -> x)
;;

let x = stack_ (stack_ (2, stack_ "hello"), ~x:(stack_ (Foo x)))
let x = stack_ (stack_ (2, stack_ "hello"), ~x:(stack_ Foo x))

let x =
(* 1 *)
Expand All @@ -108,7 +108,7 @@ let x =
~x:(stack_
(* 11 *)
(* 12 *)
(Foo x)) )
Foo x) )
;;

(* Constructor precedence *)
Expand All @@ -126,14 +126,19 @@ let x = stack_ (~x:1, ~y:2)

let x = stack_ (x + y)
let x = stack_ (-x)
let x = stack_ (stack_ (Foo x))
let x = stack_ (-42)
let x = stack_ (+x)
let x = stack_ 42
let x = stack_ (- (-x))
let x = stack_ 42
let x = stack_ (stack_ Foo x)

let x =
stack_
(let y = 1 in
Some y)
;;

let x = stack_ (c#x)
let x = stack_ c#x
let x = stack_ (r.x <- x)
let x = stack_ (if x then y else z)
10 changes: 10 additions & 0 deletions test/passing/tests/stack-erased.ml.ref
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ let x = x + y

let x = -x

let x = -42

let x = +x

let x = 42

let x = - (-x)

let x = 42

let x = Foo x

let x =
Expand Down
11 changes: 11 additions & 0 deletions test/passing/tests/stack.ml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ let x = stack_ (x + y)

let x = stack_ (-x)

let x = stack_ (-42)

let x = stack_ (+x)

let x = stack_ (+42)

let x = stack_ (-(-x))

let x = stack_ (-(-42))


let x = stack_ (stack_ (Foo x))

let x = stack_ (let y = 1 in Some y)
Expand Down
Empty file added test/passing/tests/stack.ml.err
Empty file.
43 changes: 24 additions & 19 deletions test/passing/tests/stack.ml.js-ref
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
(* These tests from the campiler test suite *)

let f = ref (stack_ (fun x -> x))
let f = ref (stack_ fun x -> x)
let f = ref (stack_ (2, 3))
let f = ignore_local (stack_ (2, 3))
let f = ref (stack_ Foo)
let f = ref (stack_ (Bar 42))
let f = ignore_local (stack_ (Bar 42))
let f = ref (stack_ Bar 42)
let f = ignore_local (stack_ Bar 42)
let f = ref (stack_ `Foo)
let f = ref (stack_ (`Bar 42))
let f = ignore_local (stack_ (`Bar 42))
Expand All @@ -21,15 +21,15 @@ let f () = stack_ (3, 5)
let f () = exclave_ stack_ (3, 5)

let f () =
let g = stack_ (fun x -> x) in
let g = stack_ fun x -> x in
g 42
;;

let f () = (stack_ (fun x -> x)) 42
let f () = (stack_ fun x -> x) 42
let f () = List.length (stack_ [ 1; 2; 3 ])
let f () = stack_ [ i for i = 0 to 9 ]
let f () = stack_ [| i for i = 0 to 9 |]
let f () = stack_ (new cla)
let f () = stack_ new cla

class foo cla =
object
Expand Down Expand Up @@ -72,16 +72,16 @@ let mk () =
let f =
ref
(stack_
(function
| x -> x))
function
| x -> x)
;;

let f =
ref
(stack_
(function
| x -> x
| y -> y))
function
| x -> x
| y -> y)
;;

let f =
Expand All @@ -91,13 +91,13 @@ let f =
(stack_
(* 3 *)
(* 4 *)
(function
(* 5 *)
(* 6 *)
| x -> x))
function
(* 5 *)
(* 6 *)
| x -> x)
;;

let x = stack_ (stack_ (2, stack_ "hello"), ~x:(stack_ (Foo x)))
let x = stack_ (stack_ (2, stack_ "hello"), ~x:(stack_ Foo x))

let x =
(* 1 *)
Expand All @@ -108,7 +108,7 @@ let x =
~x:(stack_
(* 11 *)
(* 12 *)
(Foo x)) )
Foo x) )
;;

(* Constructor precedence *)
Expand All @@ -126,14 +126,19 @@ let x = stack_ (~x:1, ~y:2)

let x = stack_ (x + y)
let x = stack_ (-x)
let x = stack_ (stack_ (Foo x))
let x = stack_ (-42)
let x = stack_ (+x)
let x = stack_ 42
let x = stack_ (- (-x))
let x = stack_ 42
let x = stack_ (stack_ Foo x)

let x =
stack_
(let y = 1 in
Some y)
;;

let x = stack_ (c#x)
let x = stack_ c#x
let x = stack_ (r.x <- x)
let x = stack_ (if x then y else z)
Loading
Loading