Skip to content

Commit 7b76ff1

Browse files
committed
Lots of updates
1 parent c14a65f commit 7b76ff1

File tree

11 files changed

+147
-160
lines changed

11 files changed

+147
-160
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ keywords = ["ocaml", "rust", "ffi"]
77
repository = "https://github.com/zshipko/ocaml-rs"
88
license = "ISC"
99
description = "OCaml bindings for Rust"
10-
documentation = "https://docs.rs/raml"
10+
documentation = "https://docs.rs/ocaml"
1111

1212
[dependencies]

LICENSE.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ISC License
2+
3+
Copyright (c) 2018, Zach Shipko
4+
5+
Permission to use, copy, modify, and/or distribute this software for any
6+
purpose with or without fee is hereby granted, provided that the above
7+
copyright notice and this permission notice appear in all copies.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
# ocaml-rs - OCaml FFI for Rust
22

3-
NOTE: `ocmal-rs` is based on [raml v0.1](https://crates.io/crates/raml) with the goal of creating an even higher-level interface.
4-
5-
Direct OCaml bindings without ever leaving Rust - no C stubs!
6-
7-
Please see the example in `examples` for the Rust code in `rust` for the Rust code that OCaml code will call and the `ocaml` directory for the OCaml code that calls the Rust code.
3+
NOTE: `ocaml-rs` is based on [raml v0.1](https://crates.io/crates/raml) with the goal of creating a higher-level interface.
84

95
```rust
106
caml!(ml_beef, |parameter|, <local>, {
@@ -15,7 +11,9 @@ caml!(ml_beef, |parameter|, <local>, {
1511
} -> local);
1612
```
1713

18-
The macro takes care of _automatically_ declaring `CAMLparam` et. al, as well as `CAMLlocal` and `CAMLreturn`.
14+
The macro takes care of _automatically_ declaring `CAMLparam` et. al, as well as `CAMLlocal` and `CAMLreturn`
15+
16+
For a working example see `./examples/rust` and `./examples/ocaml`
1917

2018
### Documentation
2119

examples/ocaml/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ pretty: test
1818
cd ../rust && cargo rustc $(ARGS)
1919

2020
clean:
21-
rm test *.o *.cm*
22-
rm -rf _build
21+
rm -rf _build test
2322
cd ../rust && cargo clean
2423

2524
.PHONY: build clean pretty

examples/ocaml/test.ml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@ external send_tuple : (int * int) -> int = "ml_send_tuple"
44
external new_tuple : unit -> (int * int * int) = "ml_new_tuple"
55
external new_array : unit -> int array = "ml_new_array"
66
external new_list : unit -> int list = "ml_new_list"
7+
external testing_callback : int -> int -> unit = "ml_testing_callback"
78

89
let f x = x land 0x0000ffff
910

11+
let print_testing a b =
12+
Printf.printf "testing: %d %d\n" a b
13+
14+
let _ =
15+
Callback.register "print_testing" print_testing
1016

1117
let _ =
1218
let string = "string thing" in
@@ -23,4 +29,5 @@ let _ =
2329
let arr = new_array () in
2430
Array.iter (Printf.printf "%d\n") arr;
2531
let lst = new_list () in
26-
List.iter (Printf.printf "%d\n") lst
32+
List.iter (Printf.printf "%d\n") lst;
33+
testing_callback 5 10

examples/rust/src/lib.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ caml!(ml_send_int, |v|, <l>, {
1212
caml!(ml_send_two, |v, v2|, {
1313
println!("local root addr: {:p} caml_local_roots: {:#?}, v: {:?}", &memory::caml_local_roots, memory::caml_local_roots, v.value());
1414
let x = v.int_val();
15+
println!("string tag: {}", v2.tag() as u8);
1516
let string = ocaml::Str::from(v2);
1617
println!("got 0x{:x}, {}", x, string.as_str());
18+
1719
});
1820

1921
caml!(ml_send_tuple, |t|, <dest>, {
@@ -24,26 +26,23 @@ caml!(ml_send_tuple, |t|, <dest>, {
2426
} -> dest);
2527

2628
caml!(ml_new_tuple, |_unit|, <dest>, {
27-
let tuple = ocaml::Tuple::from((Value::int(0), Value::int(1), Value::int(2)));
29+
let tuple = ocaml::Tuple::from(vec![Value::int(0), Value::int(1), Value::int(2)]);
2830
dest = Value::from(tuple);
2931
} -> dest);
3032

3133
caml!(ml_new_array, |_unit|, <dest>, {
32-
let mut arr = ocaml::Array::new(5);
33-
34-
for i in 0..5 {
35-
arr.set(i, Value::int(i as i32)).unwrap();
36-
}
37-
38-
dest = Value::from(arr)
34+
let x: Vec<Value> = (0..5).map(|x| Value::int(x)).collect();
35+
dest = ocaml::Array::from(x).into();
3936
} -> dest);
4037

4138
caml!(ml_new_list, |_unit|, <dest>, {
42-
let mut list = ocaml::List::new();
39+
let x: Vec<Value> = (0..5).map(|x| Value::int(x)).collect();
40+
dest = ocaml::List::from(x).into();
41+
} -> dest);
4342

44-
for i in 0..5 {
45-
list.append(Value::int(i));
46-
}
43+
caml!(ml_testing_callback, |a, b|, {
44+
let f = ocaml::named_value("print_testing")
45+
.expect("print_testing not registered");
4746

48-
dest = ocaml::Value::from(list)
49-
} -> dest);
47+
f.call_n(vec![a, b]);
48+
});

src/core/lib.rs

Lines changed: 0 additions & 117 deletions
This file was deleted.

src/core/mlvalues.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,27 @@ pub type Mark = Uintnat;
3636
///
3737
pub struct Header {}
3838

39+
pub const VALUE_SIZE: isize = ::std::mem::size_of::<Value>() as isize;
40+
41+
/// #ifdef ARCH_BIG_ENDIAN
42+
/// #define Tag_val(val) (((unsigned char *) (val)) [-1])
43+
/// #else
44+
/// #define Tag_val(val) (((unsigned char *) (val)) [-sizeof(value)])
45+
/// #endif
46+
#[cfg(target_endian = "big")]
47+
#[macro_export]
48+
macro_rules! tag_val {
49+
($x:expr) => (*(($x as *const u8).offset(-1)));
50+
($x:ident) => (*(($x as *const u8).offset(-1)));
51+
}
52+
53+
#[cfg(target_endian = "little")]
54+
#[macro_export]
55+
macro_rules! tag_val {
56+
($x:expr) => (*(($x as *const u8).offset(-$crate::core::mlvalues::VALUE_SIZE)));
57+
($x:ident) => (*(($x as *const u8).offset(-$crate::core::mlvalues::VALUE_SIZE)));
58+
}
59+
3960
#[macro_export]
4061
/// `(((intnat)(x) << 1) + 1)`
4162
macro_rules! val_long {

src/tag.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ pub enum Tag {
2727
}
2828

2929
impl Tag {
30-
pub fn new(i: u32) -> Tag {
31-
match i {
30+
pub fn new(i: u8) -> Tag {
31+
match i as u32 {
3232
Forward_tag => Tag::Forward,
3333
Infix_tag => Tag::Infix,
3434
Object_tag => Tag::Object,

src/types.rs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,14 @@ impl From<Tuple> for Value {
1717
}
1818
}
1919

20-
impl From<(Value, Value)> for Tuple {
21-
fn from(t: (Value, Value)) -> Tuple {
22-
let mut dst = Tuple::new(2);
23-
let (a, b) = t;
24-
let _ = dst.set(0, a);
25-
let _ = dst.set(1, b);
26-
dst
27-
}
28-
}
20+
impl <R: AsRef<[Value]>> From<R> for Tuple {
21+
fn from(t: R) -> Tuple {
22+
let mut dst = Tuple::new(t.as_ref().len());
23+
24+
for (n, item) in t.as_ref().iter().enumerate() {
25+
let _ = dst.set(n, item.clone());
26+
}
2927

30-
impl From<(Value, Value, Value)> for Tuple {
31-
fn from(t: (Value, Value, Value)) -> Tuple {
32-
let mut dst = Tuple::new(3);
33-
let (a, b, c) = t;
34-
let _ = dst.set(0, a);
35-
let _ = dst.set(1, b);
36-
let _ = dst.set(2, c);
3728
dst
3829
}
3930
}
@@ -76,6 +67,18 @@ impl From<Array> for Value {
7667
}
7768
}
7869

70+
impl <R: AsRef<[Value]>> From<R> for Array {
71+
fn from(t: R) -> Array {
72+
let mut dst = Array::new(t.as_ref().len());
73+
74+
for (n, item) in t.as_ref().iter().enumerate() {
75+
let _ = dst.set(n, item.clone());
76+
}
77+
78+
dst
79+
}
80+
}
81+
7982
impl From<Value> for Array {
8083
fn from(v: Value) -> Array {
8184
if !v.is_block() {
@@ -127,6 +130,18 @@ impl From<List> for Value {
127130
}
128131
}
129132

133+
impl <R: AsRef<[Value]>> From<R> for List {
134+
fn from(t: R) -> List {
135+
let mut dst = List::new();
136+
137+
for item in t.as_ref().iter().rev() {
138+
let _ = dst.push_hd(item.clone());
139+
}
140+
141+
dst
142+
}
143+
}
144+
130145
impl List {
131146
pub fn new() -> List {
132147
List(Value::new(empty_list()), 0)
@@ -136,7 +151,7 @@ impl List {
136151
self.1
137152
}
138153

139-
pub fn append(&mut self, v: Value) {
154+
pub fn push_hd(&mut self, v: Value) {
140155
unsafe {
141156
let tmp = alloc::caml_alloc(2, 0);
142157
memory::store_field(tmp, 0, v.0);

0 commit comments

Comments
 (0)