package js_of_ocaml-compiler

  1. Overview
  2. Docs
Compiler from OCaml bytecode to JavaScript

Install

Dune Dependency

Authors

Maintainers

Sources

js_of_ocaml-5.9.0.tbz
sha256=daf2c7811df906fe4a8e59cd6973ccf0bdbe4a7d0e1f1fd17c9584bd0b438594
sha512=67d8f647e453f3855aff556afee0ce4524a7833852343f90271ee7c540e40c3dead0fc728acb667fcf7df69068a7c9521db809d2d0dfa5a1a0b31d0f1b60d566

doc/src/js_of_ocaml-compiler/macro.ml.html

Source file macro.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
(* Js_of_ocaml compiler
 * http://www.ocsigen.org/js_of_ocaml/
 * Copyright (C) 2019 Ty Overby, Jane Street Group LLC
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, with linking exception;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *)

open! Stdlib

type m =
  | Replace
  | Count of int ref

class macro_mapper ~flags =
  object (m)
    inherit Js_traverse.map as super

    method expression x =
      let module J = Javascript in
      match x with
      | J.ECall (J.EVar (J.S { name = Utf8 name; _ }), (ANormal | ANullish), args, _) -> (
          match name, args with
          | "FLAG", [ J.Arg (J.EStr (Utf8 s)) ] -> (
              match flags with
              | Replace ->
                  let i = if Config.Flag.find s then Targetint.one else Targetint.zero in
                  J.ENum (J.Num.of_targetint i)
              | Count count ->
                  incr count;
                  super#expression x)
          | "BLOCK", J.Arg (J.ENum tag) :: (_ :: _ as args)
            when List.for_all args ~f:(function
                     | J.Arg _ -> true
                     | J.ArgSpread _ -> false) ->
              let tag = Targetint.to_int_exn (J.Num.to_targetint tag) in
              let args =
                List.map args ~f:(function
                    | J.Arg e -> J.Element (m#expression e)
                    | J.ArgSpread _ -> assert false)
              in
              Mlvalue.Block.make ~tag ~args
          | "TAG", [ J.Arg e ] -> Mlvalue.Block.tag (m#expression e)
          | "LENGTH", [ J.Arg e ] -> Mlvalue.Array.length (m#expression e)
          | "FIELD", [ J.Arg e; J.Arg (J.ENum n) ] ->
              let idx = Targetint.to_int_exn (J.Num.to_targetint n) in
              Mlvalue.Block.field (m#expression e) idx
          | "FIELD", [ _; J.Arg (J.EUn (J.Neg, _)) ] ->
              failwith "Negative field indexes are not allowed"
          | "ISBLOCK", [ J.Arg e ] -> Mlvalue.is_block (m#expression e)
          | (("BLOCK" | "TAG" | "LENGTH" | "FIELD" | "ISBLOCK" | "FLAG") as name), _ ->
              failwith
                (Format.sprintf "macro %s called with inappropriate arguments" name)
          | _ -> super#expression x)
      | _ -> super#expression x
  end

let f ~flags js =
  let count = ref 0 in
  let flags =
    match flags with
    | true -> Replace
    | false -> Count count
  in
  let trav = new macro_mapper ~flags in
  let js = trav#program js in
  js, !count > 0
OCaml

Innovation. Community. Security.