Skip to content

Commit

Permalink
add a built in capitalize function
Browse files Browse the repository at this point in the history
  • Loading branch information
bobzhang committed Apr 24, 2017
1 parent c0ad5b9 commit 2d5a450
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 3 deletions.
18 changes: 18 additions & 0 deletions README.md
Expand Up @@ -358,6 +358,24 @@ because 123z does not form a valid identifier.

`CONCAT(a,b)` is roughly equivalent to `a##b` in cpp syntax.

CAPITALIZE
---------------

`CAPITALIZE()` is a predefined macro that takes one argument,
removes any leading and trailing whitespace, reduces each internal
whitespace sequence to a single space character and produces
a valid OCaml identifer with first character.

For example,
```ocaml
#define EVENT(n,ty) external CONCAT(on,CAPITALIZE(n)) : ty = STRINGIFY(n) [@@bs.val]
EVENT(exit, unit -> unit)
```
is expanded into:

```ocaml
external onExit : unit -> unit = "exit" [@@bs.val]
```

Stringification
---------------
Expand Down
29 changes: 27 additions & 2 deletions cppo_eval.ml
Expand Up @@ -23,6 +23,13 @@ let builtins = [
`Ident (dummy_loc, "y", None))],
env)
);
"CAPITALIZE", (fun env ->
`Defun (dummy_loc, "CAPITALIZE",
["x"],
[`Capitalize (`Ident (dummy_loc, "x", None))],
env)
);

]

let is_reserved s =
Expand Down Expand Up @@ -84,7 +91,11 @@ let trim_and_compact_string s =
let buf = Buffer.create (String.length s) in
trim_and_compact buf s;
Buffer.contents buf

let trim_compact_and_capitalize_string s =
let buf = Buffer.create (String.length s) in
trim_and_compact buf s;
String.capitalize (Buffer.contents buf)

let is_ident s =
let len = String.length s in
len > 0
Expand Down Expand Up @@ -442,7 +453,7 @@ let rec include_file g loc rel_file env =
and expand_list ?(top = false) g env l =
List.fold_left (expand_node ~top g) env l

and expand_node ?(top = false) g env0 x =
and expand_node ?(top = false) g env0 (x : node) =
match x with
`Ident (loc, name, opt_args) ->

Expand Down Expand Up @@ -610,6 +621,20 @@ and expand_node ?(top = false) g env0 x =
g.enable_loc := enable_loc0;
env0

| `Capitalize (x : node) ->
let enable_loc0 = !(g.enable_loc) in
g.enable_loc := false;
let buf0 = g.buf in
let local_buf = Buffer.create 100 in
g.buf <- local_buf;
ignore (expand_node g env0 x);
let xs = Buffer.contents local_buf in
let s = trim_compact_and_capitalize_string xs in
(* stringify buf0 (Buffer.contents local_buf); *)
Buffer.add_string buf0 s ;
g.buf <- buf0;
g.enable_loc := enable_loc0;
env0
| `Concat (x, y) ->
let enable_loc0 = !(g.enable_loc) in
g.enable_loc := false;
Expand Down
1 change: 1 addition & 0 deletions cppo_types.ml
Expand Up @@ -58,6 +58,7 @@ and node =
| `Text of (loc * bool * string) (* bool is true for space tokens *)
| `Seq of node list
| `Stringify of node
| `Capitalize of node
| `Concat of (node * node)
| `Line of (loc * string option * int)
| `Current_line of loc
Expand Down
5 changes: 4 additions & 1 deletion test/Makefile
@@ -1,4 +1,4 @@
TESTS = ext comments cond tuple paren_arg unmatched version
TESTS = ext comments cond tuple paren_arg unmatched version capital
.PHONY: all clean $(TESTS)

all: $(TESTS)
Expand Down Expand Up @@ -36,5 +36,8 @@ unmatched:
version:
../cppo -V X:123.05.2-alpha.1+foo-2.1 version.cppo > version.out

capital:
../cppo $@.cppo > $@.out
diff -u $@.ref $@.out
clean:
rm -f *~ *.out
6 changes: 6 additions & 0 deletions test/capital.cppo
@@ -0,0 +1,6 @@


#define EVENT(n,ty) external CONCAT(on,CAPITALIZE(n)) : ty = STRINGIFY(n) [@@bs.val]


EVENT(exit, unit -> unit)
6 changes: 6 additions & 0 deletions test/capital.ref
@@ -0,0 +1,6 @@




# 6 "capital.cppo"
external onExit : unit -> unit = "exit" [@@bs.val]

0 comments on commit 2d5a450

Please sign in to comment.