Skip to content

Commit

Permalink
Merge pull request #3 from op8867555/feat/tuple
Browse files Browse the repository at this point in the history
Add tuple support
  • Loading branch information
HKalbasi authored Oct 18, 2023
2 parents 87654d4 + 7ece942 commit 86a4568
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 20 deletions.
24 changes: 12 additions & 12 deletions examples/memory_management/main.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
#include <cstdint>
#include <iostream>
#include <vector>

#include "./generated.h"

// Rust values are available in the `::rust` namespace from their absolute path
// in Rust
template <typename T> using Vec = rust::std::vec::Vec<T>;
template <typename T> using Option = rust::std::option::Option<T>;
template <typename T> using BoxDyn = rust::Box<rust::Dyn<T>>;
template <typename T> using RmDyn = rust::RefMut<rust::Dyn<T>>;
using rust::crate::consume_and_panic;
using rust::crate::consume_n_times;
using rust::crate::PrintOnDrop;
using rust::crate::PrintOnDropConsumer;
using rust::crate::PrintOnDropPair;
using namespace rust::crate;

class CppPrintOnDropHolder : public PrintOnDropConsumer {
rust::Unit consume(PrintOnDrop p) override {
Expand Down Expand Up @@ -139,8 +134,7 @@ int main() {
const char *elems[3] = {"elem1", "elem2", "elem3"};
int i = 0;
auto iter = rust::std::iter::from_fn(
::rust::Box<::rust::Dyn<::rust::Fn<::rust::std::option::Option<
::rust::crate::PrintOnDrop>>>>::make_box([&] {
rust::Box<rust::Dyn<rust::Fn<Option<PrintOnDrop>>>>::make_box([&] {
if (i == 3) {
return Option<PrintOnDrop>::None();
}
Expand All @@ -149,12 +143,18 @@ int main() {
}));
std::cout << "Checkpoint 41" << std::endl;
iter.for_each(
::rust::Box<
::rust::Dyn<::rust::Fn<::rust::crate::PrintOnDrop, rust::Unit>>>::
make_box([](PrintOnDrop p) -> rust::Unit {
rust::Box<rust::Dyn<rust::Fn<PrintOnDrop, rust::Unit>>>::make_box(
[](PrintOnDrop p) -> rust::Unit {
std::cout << "Checkpoint 42" << std::endl;
return {};
}));
}
std::cout << "Checkpoint 43" << std::endl;
{
auto tuple = rust::Tuple<PrintOnDrop, int32_t, PrintOnDrop>(
PrintOnDrop(rust::Str::from_char_star("field_0")), 5,
PrintOnDrop(rust::Str::from_char_star("field_2")));
std::cout << "Checkpoint 44" << std::endl;
}
std::cout << "Checkpoint 45" << std::endl;
}
4 changes: 4 additions & 0 deletions examples/memory_management/main.zng
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ type () {
wellknown_traits(Copy);
}

type (crate::PrintOnDrop, i32, crate::PrintOnDrop) {
#layout(size = 40, align = 8);
}

type bool {
#layout(size = 1, align = 1);
wellknown_traits(Copy);
Expand Down
21 changes: 14 additions & 7 deletions examples/memory_management/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ Checkpoint 20
Checkpoint 21
PrintOnDrop(A) has been dropped
Checkpoint 22
thread '<unnamed>' panicked at 'consume_and_panic executed with value B', examples/memory_management/src/lib.rs:29:9
thread '<unnamed>' panicked at examples/memory_management/src/lib.rs:29:9:
consume_and_panic executed with value B
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
PrintOnDrop(B) has been dropped
PrintOnDrop(A) has been dropped
Expand All @@ -58,15 +59,15 @@ Checkpoint 30
PrintOnDrop(elem1) has been dropped
PrintOnDrop(elem2) has been dropped
Checkpoint 31
[main.cpp:117] PrintOnDrop(rust::Str::from_char_star("dbg_A")) = PrintOnDrop(
[main.cpp:112] PrintOnDrop(rust::Str::from_char_star("dbg_A")) = PrintOnDrop(
"dbg_A",
)
Checkpoint 32
[main.cpp:119] std::move(p1) = PrintOnDrop(
[main.cpp:114] std::move(p1) = PrintOnDrop(
"dbg_A",
)
Checkpoint 33
[main.cpp:121] p2 = PrintOnDrop(
[main.cpp:116] p2 = PrintOnDrop(
"dbg_A",
)
Checkpoint 34
Expand All @@ -80,9 +81,15 @@ Checkpoint 39
PrintOnDrop(option_A) has been dropped
Checkpoint 40
Checkpoint 41
PrintOnDrop(iter_elem) has been dropped
PrintOnDrop(iter_elem) has been dropped
PrintOnDrop(iter_elem) has been dropped
Checkpoint 42
PrintOnDrop(elem1) has been dropped
Checkpoint 42
PrintOnDrop(elem2) has been dropped
Checkpoint 42
PrintOnDrop(elem3) has been dropped
Checkpoint 43
Checkpoint 44
PrintOnDrop(field_0) has been dropped
PrintOnDrop(field_2) has been dropped
Checkpoint 45
PrintOnDrop(C) has been dropped
10 changes: 10 additions & 0 deletions zngur-generator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ impl ZngurGenerator {
}
}
}
if let RustType::Tuple(fields) = &ty_def.ty {
if !fields.is_empty() {
let rust_link_name = rust_file.add_tuple_constructor(&fields);
constructors.push(CppFnSig {
rust_link_name,
inputs: fields.iter().map(|x| x.into_cpp()).collect(),
output: ty_def.ty.into_cpp(),
});
}
}
for wellknown_trait in ty_def.wellknown_traits {
let data = rust_file.add_wellknown_trait(&ty_def.ty, wellknown_trait);
wellknown_traits.push(data);
Expand Down
29 changes: 28 additions & 1 deletion zngur-generator/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ impl IntoCpp for RustType {
if v.is_empty() {
return CppType::from("rust::Unit");
}
todo!()
CppType {
path: CppPath::from("rust::Tuple"),
generic_args: v.into_iter().map(|x| x.into_cpp()).collect(),
}
}
RustType::Dyn(tr, marker_bounds) => {
let tr_as_cpp_type = tr.into_cpp();
Expand Down Expand Up @@ -473,6 +476,30 @@ pub extern "C" fn {mangled_name}(
mangled_name
}

pub fn add_tuple_constructor(&mut self, fields: &[RustType]) -> String {
let constructor = mangle_name(&fields.iter().join("&"));
w!(
self,
r#"
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn {constructor}("#
);
for name in 0..fields.len() {
w!(self, "f_{name}: *mut u8, ");
}
w!(
self,
r#"o: *mut u8) {{ unsafe {{
::std::ptr::write(o as *mut _, ("#
);
for (name, ty) in fields.iter().enumerate() {
w!(self, "::std::ptr::read(f_{name} as *mut {ty}), ");
}
wln!(self, ")) }} }}");
constructor
}

pub fn add_constructor(
&mut self,
rust_name: &str,
Expand Down
8 changes: 8 additions & 0 deletions zngur-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,13 @@ fn rust_type<'a>(
let unit = just(Token::ParenOpen)
.then(just(Token::ParenClose))
.map(|_| ParsedRustType::Tuple(vec![]));
let tuple = parser
.clone()
.separated_by(just(Token::Comma))
.allow_trailing()
.collect::<Vec<_>>()
.delimited_by(just(Token::ParenOpen), just(Token::ParenClose))
.map(|xs| ParsedRustType::Tuple(xs));
let slice = parser
.clone()
.map(|x| ParsedRustType::Slice(Box::new(x)))
Expand All @@ -748,6 +755,7 @@ fn rust_type<'a>(
scalar
.or(boxed)
.or(unit)
.or(tuple)
.or(slice)
.or(adt)
.or(reference)
Expand Down
11 changes: 11 additions & 0 deletions zngur-parser/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ type () {
);
}

#[test]
fn parse_tuple() {
check_success(
r#"
type (i8, u8) {
#layout(size = 0, align = 1);
}
"#,
);
}

#[test]
fn typo_in_wellknown_trait() {
check_fail(
Expand Down

0 comments on commit 86a4568

Please sign in to comment.