mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
Merge branch 'trunk' of github.com:rtfeldman/roc into wasm-recursive-tags
This commit is contained in:
commit
b1a2a3ba07
7 changed files with 92 additions and 43 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3411,6 +3411,7 @@ dependencies = [
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_mono",
|
"roc_mono",
|
||||||
|
"roc_reporting",
|
||||||
"roc_std",
|
"roc_std",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
]
|
]
|
||||||
|
|
|
@ -10,6 +10,7 @@ edition = "2018"
|
||||||
roc_collections = { path = "../collections" }
|
roc_collections = { path = "../collections" }
|
||||||
roc_module = { path = "../module" }
|
roc_module = { path = "../module" }
|
||||||
roc_builtins = { path = "../builtins" }
|
roc_builtins = { path = "../builtins" }
|
||||||
|
roc_reporting = { path = "../../reporting" }
|
||||||
roc_mono = { path = "../mono" }
|
roc_mono = { path = "../mono" }
|
||||||
roc_std = { path = "../../roc_std" }
|
roc_std = { path = "../../roc_std" }
|
||||||
morphic_lib = { path = "../../vendor/morphic_lib" }
|
morphic_lib = { path = "../../vendor/morphic_lib" }
|
||||||
|
|
|
@ -62,6 +62,7 @@ use roc_mono::ir::{
|
||||||
ModifyRc, OptLevel, ProcLayout,
|
ModifyRc, OptLevel, ProcLayout,
|
||||||
};
|
};
|
||||||
use roc_mono::layout::{Builtin, LambdaSet, Layout, LayoutIds, TagIdIntType, UnionLayout};
|
use roc_mono::layout::{Builtin, LambdaSet, Layout, LayoutIds, TagIdIntType, UnionLayout};
|
||||||
|
use roc_reporting::internal_error;
|
||||||
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
||||||
|
|
||||||
/// This is for Inkwell's FunctionValue::verify - we want to know the verification
|
/// This is for Inkwell's FunctionValue::verify - we want to know the verification
|
||||||
|
@ -5604,9 +5605,13 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
let int_type = convert::int_type_from_int_width(env, *int_width);
|
let int_type = convert::int_type_from_int_width(env, *int_width);
|
||||||
build_int_unary_op(env, arg.into_int_value(), int_type, op)
|
build_int_unary_op(env, arg.into_int_value(), int_type, op)
|
||||||
}
|
}
|
||||||
Float(float_width) => {
|
Float(float_width) => build_float_unary_op(
|
||||||
build_float_unary_op(env, arg.into_float_value(), op, *float_width)
|
env,
|
||||||
}
|
layout,
|
||||||
|
arg.into_float_value(),
|
||||||
|
op,
|
||||||
|
*float_width,
|
||||||
|
),
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!("Compiler bug: tried to run numeric operation {:?} on invalid builtin layout: ({:?})", op, arg_layout);
|
unreachable!("Compiler bug: tried to run numeric operation {:?} on invalid builtin layout: ({:?})", op, arg_layout);
|
||||||
}
|
}
|
||||||
|
@ -6983,9 +6988,10 @@ fn int_abs_with_overflow<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
fn build_float_unary_op<'a, 'ctx, 'env>(
|
fn build_float_unary_op<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
layout: &Layout<'a>,
|
||||||
arg: FloatValue<'ctx>,
|
arg: FloatValue<'ctx>,
|
||||||
op: LowLevel,
|
op: LowLevel,
|
||||||
float_width: FloatWidth,
|
float_width: FloatWidth, // arg width
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
use roc_module::low_level::LowLevel::*;
|
use roc_module::low_level::LowLevel::*;
|
||||||
|
|
||||||
|
@ -6997,7 +7003,35 @@ fn build_float_unary_op<'a, 'ctx, 'env>(
|
||||||
NumAbs => env.call_intrinsic(&LLVM_FABS[float_width], &[arg.into()]),
|
NumAbs => env.call_intrinsic(&LLVM_FABS[float_width], &[arg.into()]),
|
||||||
NumSqrtUnchecked => env.call_intrinsic(&LLVM_SQRT[float_width], &[arg.into()]),
|
NumSqrtUnchecked => env.call_intrinsic(&LLVM_SQRT[float_width], &[arg.into()]),
|
||||||
NumLogUnchecked => env.call_intrinsic(&LLVM_LOG[float_width], &[arg.into()]),
|
NumLogUnchecked => env.call_intrinsic(&LLVM_LOG[float_width], &[arg.into()]),
|
||||||
NumToFloat => arg.into(), /* Converting from Float to Float is a no-op */
|
NumToFloat => {
|
||||||
|
let return_width = match layout {
|
||||||
|
Layout::Builtin(Builtin::Float(return_width)) => *return_width,
|
||||||
|
_ => internal_error!("Layout for returning is not Float : {:?}", layout),
|
||||||
|
};
|
||||||
|
match (float_width, return_width) {
|
||||||
|
(FloatWidth::F32, FloatWidth::F32) => arg.into(),
|
||||||
|
(FloatWidth::F32, FloatWidth::F64) => bd.build_cast(
|
||||||
|
InstructionOpcode::FPExt,
|
||||||
|
arg,
|
||||||
|
env.context.f64_type(),
|
||||||
|
"f32_to_f64",
|
||||||
|
),
|
||||||
|
(FloatWidth::F64, FloatWidth::F32) => bd.build_cast(
|
||||||
|
InstructionOpcode::FPTrunc,
|
||||||
|
arg,
|
||||||
|
env.context.f32_type(),
|
||||||
|
"f64_to_f32",
|
||||||
|
),
|
||||||
|
(FloatWidth::F64, FloatWidth::F64) => arg.into(),
|
||||||
|
(FloatWidth::F128, FloatWidth::F128) => arg.into(),
|
||||||
|
(FloatWidth::F128, _) => {
|
||||||
|
unimplemented!("I cannot handle F128 with Num.toFloat yet")
|
||||||
|
}
|
||||||
|
(_, FloatWidth::F128) => {
|
||||||
|
unimplemented!("I cannot handle F128 with Num.toFloat yet")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
NumCeiling => env.builder.build_cast(
|
NumCeiling => env.builder.build_cast(
|
||||||
InstructionOpcode::FPToSI,
|
InstructionOpcode::FPToSI,
|
||||||
env.call_intrinsic(&LLVM_CEILING[float_width], &[arg.into()]),
|
env.call_intrinsic(&LLVM_CEILING[float_width], &[arg.into()]),
|
||||||
|
|
|
@ -1309,7 +1309,7 @@ fn num_to_float() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-dev"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||||
fn num_to_float_f64_to_f32() {
|
fn num_to_float_f64_to_f32() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
@ -1328,7 +1328,47 @@ fn num_to_float_f64_to_f32() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-wasm", feature = "gen-dev"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||||
|
fn num_to_float_f32_to_f32() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
|
||||||
|
arg : F32
|
||||||
|
arg = 9.0
|
||||||
|
|
||||||
|
ret : F32
|
||||||
|
ret = Num.toFloat arg
|
||||||
|
ret
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
9.0,
|
||||||
|
f32
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||||
|
fn num_to_float_f64_to_f64() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
|
||||||
|
arg : F64
|
||||||
|
arg = 9.0
|
||||||
|
|
||||||
|
ret : F64
|
||||||
|
ret = Num.toFloat arg
|
||||||
|
ret
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
9.0,
|
||||||
|
f64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||||
fn num_to_float_f32_to_f64() {
|
fn num_to_float_f32_to_f64() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::cell::Cell;
|
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
@ -23,10 +22,6 @@ use roc_mono::ir::PRETTY_PRINT_IR_SYMBOLS;
|
||||||
|
|
||||||
const TEST_WRAPPER_NAME: &str = "test_wrapper";
|
const TEST_WRAPPER_NAME: &str = "test_wrapper";
|
||||||
|
|
||||||
std::thread_local! {
|
|
||||||
static TEST_COUNTER: Cell<u32> = Cell::new(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn promote_expr_to_module(src: &str) -> String {
|
fn promote_expr_to_module(src: &str) -> String {
|
||||||
let mut buffer = String::from("app \"test\" provides [ main ] to \"./platform\"\n\nmain =\n");
|
let mut buffer = String::from("app \"test\" provides [ main ] to \"./platform\"\n\nmain =\n");
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use core::alloc::Layout;
|
use core::alloc::Layout;
|
||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::{ManuallyDrop, MaybeUninit};
|
||||||
use libc;
|
use libc;
|
||||||
use roc_std::RocStr;
|
use roc_std::RocStr;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
@ -119,13 +119,8 @@ pub extern "C" fn roc_fx_getLine() -> RocStr {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn roc_fx_putLine(line: RocStr) -> () {
|
pub extern "C" fn roc_fx_putLine(line: ManuallyDrop<RocStr>) {
|
||||||
let bytes = line.as_slice();
|
let bytes = line.as_slice();
|
||||||
let string = unsafe { std::str::from_utf8_unchecked(bytes) };
|
let string = unsafe { std::str::from_utf8_unchecked(bytes) };
|
||||||
println!("{}", string);
|
println!("{}", string);
|
||||||
|
|
||||||
// don't mess with the refcount!
|
|
||||||
core::mem::forget(line);
|
|
||||||
|
|
||||||
()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use core::alloc::Layout;
|
use core::alloc::Layout;
|
||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::{ManuallyDrop, MaybeUninit};
|
||||||
use libc;
|
use libc;
|
||||||
use roc_std::{RocList, RocStr};
|
use roc_std::{RocList, RocStr};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -141,29 +141,19 @@ pub extern "C" fn roc_fx_getChar() -> u8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn roc_fx_putLine(line: RocStr) -> () {
|
pub extern "C" fn roc_fx_putLine(line: ManuallyDrop<RocStr>) {
|
||||||
let bytes = line.as_slice();
|
let bytes = line.as_slice();
|
||||||
let string = unsafe { std::str::from_utf8_unchecked(bytes) };
|
let string = unsafe { std::str::from_utf8_unchecked(bytes) };
|
||||||
println!("{}", string);
|
println!("{}", string);
|
||||||
std::io::stdout().lock().flush();
|
std::io::stdout().lock().flush();
|
||||||
|
|
||||||
// don't mess with the refcount!
|
|
||||||
core::mem::forget(line);
|
|
||||||
|
|
||||||
()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn roc_fx_putRaw(line: RocStr) -> () {
|
pub extern "C" fn roc_fx_putRaw(line: ManuallyDrop<RocStr>) {
|
||||||
let bytes = line.as_slice();
|
let bytes = line.as_slice();
|
||||||
let string = unsafe { std::str::from_utf8_unchecked(bytes) };
|
let string = unsafe { std::str::from_utf8_unchecked(bytes) };
|
||||||
print!("{}", string);
|
print!("{}", string);
|
||||||
std::io::stdout().lock().flush();
|
std::io::stdout().lock().flush();
|
||||||
|
|
||||||
// don't mess with the refcount!
|
|
||||||
core::mem::forget(line);
|
|
||||||
|
|
||||||
()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -190,25 +180,23 @@ pub extern "C" fn roc_fx_getFileBytes(br_ptr: *mut BufReader<File>) -> RocList<u
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn roc_fx_closeFile(br_ptr: *mut BufReader<File>) -> () {
|
pub extern "C" fn roc_fx_closeFile(br_ptr: *mut BufReader<File>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
Box::from_raw(br_ptr);
|
Box::from_raw(br_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn roc_fx_openFile(name: RocStr) -> *mut BufReader<File> {
|
pub extern "C" fn roc_fx_openFile(name: ManuallyDrop<RocStr>) -> *mut BufReader<File> {
|
||||||
let f = File::open(name.as_str()).expect("Unable to open file");
|
let f = File::open(name.as_str()).expect("Unable to open file");
|
||||||
let br = BufReader::new(f);
|
let br = BufReader::new(f);
|
||||||
|
|
||||||
// don't mess with the refcount!
|
|
||||||
core::mem::forget(name);
|
|
||||||
|
|
||||||
Box::into_raw(Box::new(br))
|
Box::into_raw(Box::new(br))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn roc_fx_withFileOpen(name: RocStr, buffer: *const u8) -> () {
|
pub extern "C" fn roc_fx_withFileOpen(name: ManuallyDrop<RocStr>, buffer: *const u8) {
|
||||||
|
// TODO: figure out accepting a closure in an fx and passing data to it.
|
||||||
// let f = File::open(name.as_str()).expect("Unable to open file");
|
// let f = File::open(name.as_str()).expect("Unable to open file");
|
||||||
// let mut br = BufReader::new(f);
|
// let mut br = BufReader::new(f);
|
||||||
|
|
||||||
|
@ -216,9 +204,4 @@ pub extern "C" fn roc_fx_withFileOpen(name: RocStr, buffer: *const u8) -> () {
|
||||||
// let closure_data_ptr = buffer.offset(8);
|
// let closure_data_ptr = buffer.offset(8);
|
||||||
// call_the_closure(closure_data_ptr);
|
// call_the_closure(closure_data_ptr);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // don't mess with the refcount!
|
|
||||||
// core::mem::forget(name);
|
|
||||||
|
|
||||||
()
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue