Skip to content

Add BS JS Playground reason support #3976

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 16 commits into from
Nov 25, 2019
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
56 changes: 56 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,62 @@ load the data. Right now we don't provide any instructions inside here yet, but
[here's how the official ReasonML playground did
it](https://github.com/reasonml/reasonml.github.io/blob/source/website/setupSomeArtifacts.js#L65).

## Upgrading the Reason version within BuckleScript

Each BuckleScript release is coupled to a specific Reason syntax version, which currently needs to be updated manually once in a while.

It's important that we need to update two specific files:

- `jscomp/main/refmt_api.ml`: Contains the programmatic interface for the refmt syntax converter (responsible for transforming Reason string code to an OCaml AST) -> Only used in the BuckleScript JS Playground
- `lib/4.06.1/refmt_main3.ml`: The refmt binary used within BuckleScript itself. The `3` corresponds to the corresponding major version of refmt -> Used to build the vendored `refmt`, aka. `bsrefmt`

Both files are generated by using the `jscomp/bin/bspack.exe` binary (which is also built automatically when you build the compiler inside this repository) on the refmt parser. In more detail, `bspack.exe` resolves all dependencies of one specific `.ml` input file, puts them in the right order and copies all the source code with the target input file in one huge `.ml` bundle.

So the two files mentioned above, `refmt_api.ml` and `refmt_main3.ml`, are bspacked within the Reason repository and then checked into the BuckleScript repository (we call this `vendoring` or `snapshotting`).
Here are the instructions on building your own Reason snapshots (make sure you to have everything set up for building the playground bundle first, as mentioned above):

```
# Let's go up one level and clone Reason in a sibling directory next to your `bucklescript` repo
cd ..
git clone https://github.com/facebook/reason

cd reason

# You should already have created this switch by now, see playground build setup instructions in "Contributing to the BS Playground Bundle"
opam switch 4.06.1
opam pin add -y reason .
opam pin add -y rtop .

# Let's do the bspacking process for refmt_api.ml and refmt_binary.ml
cd bspacks

# Initial setup of certain dependencies before we can bspack everthing in one file
./downloadSomeDependencies.sh

# bspack and compile the files
BSPACK_EXE=/path/to/bucklescript/jscomp/bin/bspack.exe ./reason_bspack406.sh
```

Now copy the files to bucklescript and do a rebuild to verify the changes:

```
# still in reason/bspacks directory
cp build/refmt_api.ml ../../bucklescript/jscomp/main/refmt_api.ml
cp build/refmt_binary.ml ../../bucklescript/lib/4.06.1/refmt_main3.ml

# Build the whole compiler
node scripts/ninja.js config && node scripts/ninja.js build

# Build the playground
BS_PLAYGROUND=../playground node scripts/repl.js
```

You should now have the newest `refmt` binary for the actual compiler, and for the playground, a new `playground/exports.js` file with the new Reason version included.

**Important:** Always verify that the updated Reason version is in sync in the
`refmt.exe` and the playground bundle. Use `lib/bsrefmt --version` and for the
playground API `window.reason.version` (not final) to get the bundled
version.

## Contributing to the Documentation

Expand Down
27 changes: 0 additions & 27 deletions jscomp/README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,5 @@
Hello! This is the main directory for BuckleScript. `jscomp` is just a name that mirrors OCaml's own `bytecomp` and `asmcomp` (bytecode compilation and native compilation logic respectively). For building it, please see [CONTRIBUTING.md](../CONTRIBUTING.md).

Extra info:

## Rebuilding the browser-based playground

For best results, you probably want to complete the full [Setup](../CONTRIBUTING.md#setup) before following the below guidelines.

### Get `js_of_ocaml` from the normal switch

```
opam switch 4.02.3
eval `opam config env`
opam install js_of_ocaml
which js_of_ocaml # symlink this into your $PATH, maybe /usr/local/bin or something
```

### Do everything else from the bucklescript switch

You need to have [bucklescript-playground](https://github.com/BuckleScript/bucklescript-playground) cloned next to the Bucklescript directory for the following to work.

```
opam switch 4.02.3+buckle-master
eval `opam config env`
opam install camlp4 ocp-ocamlres
(node scripts/buildocaml.js)
(cd jscomp && BS_RELEASE_BUILD=true BS_PLAYGROUND=../../bucklescript-playground node repl.js)
```

## Sub directories

### [stdlib](./stdlib)
Expand Down
10 changes: 5 additions & 5 deletions jscomp/core/js_cmj_datasets.ml

Large diffs are not rendered by default.

39 changes: 39 additions & 0 deletions jscomp/main/jsoo_common.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module Js = struct
module Unsafe = struct
type any
external inject : 'a -> any = "%identity"
external get : 'a -> 'b -> 'c = "caml_js_get"
external set : 'a -> 'b -> 'c -> unit = "caml_js_set"
external pure_js_expr : string -> 'a = "caml_pure_js_expr"
let global = pure_js_expr "joo_global_object"
type obj
external obj : (string * any) array -> obj = "caml_js_object"
end
type (-'a, +'b) meth_callback
type 'a callback = (unit, 'a) meth_callback
external wrap_callback : ('a -> 'b) -> ('c, 'a -> 'b) meth_callback = "caml_js_wrap_callback"
external wrap_meth_callback : ('a -> 'b) -> ('a, 'b) meth_callback = "caml_js_wrap_meth_callback"
type + 'a t
type js_string
external string : string -> js_string t = "caml_js_from_string"
external to_string : js_string t -> string = "caml_js_to_string"
external create_file : js_string t -> js_string t -> unit = "caml_create_file"
external to_bytestring : js_string t -> string = "caml_js_to_byte_string"
end

let mk_js_error (loc: Location.t) (msg: string) =
let (file,line,startchar) = Location.get_pos_info loc.Location.loc_start in
let (file,endline,endchar) = Location.get_pos_info loc.Location.loc_end in
Js.Unsafe.(obj
[|
"js_error_msg",
inject @@ Js.string (Printf.sprintf "Line %d, %d:\n %s" line startchar msg);
"row" , inject (line - 1);
"column" , inject startchar;
"endRow" , inject (endline - 1);
"endColumn" , inject endchar;
"text" , inject @@ Js.string msg;
"type" , inject @@ Js.string "error"
|]
)

35 changes: 35 additions & 0 deletions jscomp/main/jsoo_common.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(**
This module is shared between different JSOO / Playground based modules
*)
module Js :
sig
module Unsafe :
sig
type any
external inject : 'a -> any = "%identity"
external get : 'a -> 'b -> 'c = "caml_js_get"
external set : 'a -> 'b -> 'c -> unit = "caml_js_set"
external pure_js_expr : string -> 'a = "caml_pure_js_expr"
val global : 'a
type obj
external obj : (string * any) array -> obj = "caml_js_object"
end
type (-'a, +'b) meth_callback
type 'a callback = (unit, 'a) meth_callback
external wrap_callback : ('a -> 'b) -> ('c, 'a -> 'b) meth_callback
= "caml_js_wrap_callback"
external wrap_meth_callback : ('a -> 'b) -> ('a, 'b) meth_callback
= "caml_js_wrap_meth_callback"
type +'a t
type js_string
external string : string -> js_string t = "caml_js_from_string"
external to_string : js_string t -> string = "caml_js_to_string"
external create_file : js_string t -> js_string t -> unit
= "caml_create_file"
external to_bytestring : js_string t -> string = "caml_js_to_byte_string"
end

(*
Creates a Js Error object for given location with and a certain error message
*)
val mk_js_error : Location.t -> string -> Js.Unsafe.obj
40 changes: 2 additions & 38 deletions jscomp/main/jsoo_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)

(** *)
module Js = struct
module Unsafe = struct
type any
external inject : 'a -> any = "%identity"
external get : 'a -> 'b -> 'c = "caml_js_get"
external set : 'a -> 'b -> 'c -> unit = "caml_js_set"
external pure_js_expr : string -> 'a = "caml_pure_js_expr"
let global = pure_js_expr "joo_global_object"
type obj
external obj : (string * any) array -> obj = "caml_js_object"
end
type (-'a, +'b) meth_callback
type 'a callback = (unit, 'a) meth_callback
external wrap_callback : ('a -> 'b) -> ('c, 'a -> 'b) meth_callback = "caml_js_wrap_callback"
external wrap_meth_callback : ('a -> 'b) -> ('a, 'b) meth_callback = "caml_js_wrap_meth_callback"
type + 'a t
type js_string
external string : string -> js_string t = "caml_js_from_string"
external to_string : js_string t -> string = "caml_js_to_string"
external create_file : js_string t -> js_string t -> unit = "caml_create_file"
external to_bytestring : js_string t -> string = "caml_js_to_byte_string"
end

module Js = Jsoo_common.Js

(*
Error:
Expand Down Expand Up @@ -127,21 +105,7 @@ let implementation ~use_super_errors ?(react_ppx_version=V3) prefix impl str :
begin match error_of_exn e with
| Some error ->
Location.report_error Format.err_formatter error;
let (file,line,startchar) = Location.get_pos_info error.loc.loc_start in
let (file,endline,endchar) = Location.get_pos_info error.loc.loc_end in
Js.Unsafe.(obj
[|
"js_error_msg",
inject @@ Js.string (Printf.sprintf "Line %d, %d:\n %s" line startchar error.msg);
"row" , inject (line - 1);
"column" , inject startchar;
"endRow" , inject (endline - 1);
"endColumn" , inject endchar;
"text" , inject @@ Js.string error.msg;
"type" , inject @@ Js.string "error"
|]
);

Jsoo_common.mk_js_error error.loc error.msg
| None ->
Js.Unsafe.(obj [|
"js_error_msg" , inject @@ Js.string (Printexc.to_string e)
Expand Down
Loading