mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
Revise CLI example
This commit is contained in:
parent
b944798fda
commit
659966c878
7 changed files with 258 additions and 38 deletions
|
@ -1,50 +1,124 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use roc_std::alloca;
|
||||
use roc_std::RocCallResult;
|
||||
use roc_std::RocList;
|
||||
use roc_std::RocStr;
|
||||
use std::alloc::Layout;
|
||||
use std::time::SystemTime;
|
||||
|
||||
extern "C" {
|
||||
#[link_name = "roc__mainForHost_1_exposed"]
|
||||
fn quicksort(list: RocList<i64>, output: &mut RocCallResult<RocList<i64>>) -> ();
|
||||
fn roc_main(output: *mut u8) -> ();
|
||||
|
||||
#[link_name = "roc__mainForHost_1_size"]
|
||||
fn roc_main_size() -> i64;
|
||||
|
||||
#[link_name = "roc__mainForHost_1_Fx_caller"]
|
||||
fn call_Fx(
|
||||
flags: &(),
|
||||
function_pointer: *const u8,
|
||||
closure_data: *const u8,
|
||||
output: *mut u8,
|
||||
) -> ();
|
||||
|
||||
#[link_name = "roc__mainForHost_1_Fx_size"]
|
||||
fn size_Fx() -> i64;
|
||||
|
||||
#[link_name = "roc__mainForHost_1_Fx_result_size"]
|
||||
fn size_Fx_result() -> i64;
|
||||
}
|
||||
|
||||
const NUM_NUMS: usize = 100;
|
||||
#[no_mangle]
|
||||
pub fn roc_fx_putLine(line: RocStr) -> () {
|
||||
let bytes = line.as_slice();
|
||||
let string = unsafe { std::str::from_utf8_unchecked(bytes) };
|
||||
println!("{}", string);
|
||||
|
||||
()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn roc_fx_getLine() -> RocStr {
|
||||
use std::io::{self, BufRead};
|
||||
|
||||
let stdin = io::stdin();
|
||||
let line1 = stdin.lock().lines().next().unwrap().unwrap();
|
||||
|
||||
RocStr::from_slice_with_capacity(line1.as_bytes(), line1.len())
|
||||
}
|
||||
|
||||
unsafe fn call_the_closure(function_pointer: *const u8, closure_data_ptr: *const u8) -> i64 {
|
||||
let size = size_Fx_result() as usize;
|
||||
|
||||
alloca::with_stack_bytes(size, |buffer| {
|
||||
let buffer: *mut std::ffi::c_void = buffer;
|
||||
let buffer: *mut u8 = buffer as *mut u8;
|
||||
|
||||
call_Fx(
|
||||
&(),
|
||||
function_pointer,
|
||||
closure_data_ptr as *const u8,
|
||||
buffer as *mut u8,
|
||||
);
|
||||
|
||||
let output = &*(buffer as *mut RocCallResult<()>);
|
||||
|
||||
match output.into() {
|
||||
Ok(_) => 0,
|
||||
Err(e) => panic!("failed with {}", e),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn rust_main() -> isize {
|
||||
let nums: RocList<i64> = {
|
||||
let mut nums = Vec::with_capacity(NUM_NUMS);
|
||||
|
||||
for index in 0..nums.capacity() {
|
||||
let num = index as i64 % 12;
|
||||
|
||||
nums.push(num);
|
||||
}
|
||||
|
||||
RocList::from_slice(&nums)
|
||||
};
|
||||
|
||||
println!("Running Roc quicksort on {} numbers...", nums.len());
|
||||
println!("Running Roc closure");
|
||||
let start_time = SystemTime::now();
|
||||
|
||||
let size = unsafe { roc_main_size() } as usize;
|
||||
let layout = Layout::array::<u8>(size).unwrap();
|
||||
let answer = unsafe {
|
||||
use std::mem::MaybeUninit;
|
||||
let mut output = MaybeUninit::uninit();
|
||||
// TODO if this is 1024B or less, put it in a global scratch buffer
|
||||
let buffer = std::alloc::alloc(layout);
|
||||
|
||||
quicksort(nums, &mut *output.as_mut_ptr());
|
||||
roc_main(buffer);
|
||||
|
||||
match output.assume_init().into() {
|
||||
Ok(value) => value,
|
||||
Err(msg) => panic!("roc failed with message {}", msg),
|
||||
let output = &*(buffer as *mut RocCallResult<()>);
|
||||
|
||||
match output.into() {
|
||||
Ok(()) => {
|
||||
let function_pointer = {
|
||||
// this is a pointer to the location where the function pointer is stored
|
||||
// we pass just the function pointer
|
||||
let temp = buffer.offset(8) as *const i64;
|
||||
|
||||
(*temp) as *const u8
|
||||
};
|
||||
|
||||
let closure_data_ptr = buffer.offset(16);
|
||||
|
||||
let result =
|
||||
call_the_closure(function_pointer as *const u8, closure_data_ptr as *const u8);
|
||||
|
||||
std::alloc::dealloc(buffer, layout);
|
||||
|
||||
result
|
||||
}
|
||||
Err(msg) => {
|
||||
std::alloc::dealloc(buffer, layout);
|
||||
|
||||
panic!("Roc failed with message: {}", msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let end_time = SystemTime::now();
|
||||
let duration = end_time.duration_since(start_time).unwrap();
|
||||
|
||||
println!(
|
||||
"Roc quicksort took {:.4} ms to compute this answer: {:?}",
|
||||
"Roc closure took {:.4} ms to compute this answer: {:?}",
|
||||
duration.as_secs_f64() * 1000.0,
|
||||
// truncate the answer, so stdout is not swamped
|
||||
&answer.as_slice()[0..20]
|
||||
answer
|
||||
);
|
||||
|
||||
// Exit code
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue