mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Add gen support for Nat
This commit is contained in:
parent
37510e6aae
commit
faa8f66b6c
9 changed files with 137 additions and 63 deletions
|
@ -29,6 +29,7 @@ pub fn build_file(
|
||||||
) -> Result<PathBuf, LoadingProblem> {
|
) -> Result<PathBuf, LoadingProblem> {
|
||||||
let compilation_start = SystemTime::now();
|
let compilation_start = SystemTime::now();
|
||||||
let arena = Bump::new();
|
let arena = Bump::new();
|
||||||
|
let ptr_bytes = target.pointer_width().unwrap().bytes() as u32;
|
||||||
|
|
||||||
// Step 1: compile the app and generate the .o file
|
// Step 1: compile the app and generate the .o file
|
||||||
let subs_by_module = MutMap::default();
|
let subs_by_module = MutMap::default();
|
||||||
|
@ -44,6 +45,7 @@ pub fn build_file(
|
||||||
stdlib,
|
stdlib,
|
||||||
src_dir.as_path(),
|
src_dir.as_path(),
|
||||||
subs_by_module,
|
subs_by_module,
|
||||||
|
ptr_bytes,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let path_to_platform = loaded.platform_path.clone();
|
let path_to_platform = loaded.platform_path.clone();
|
||||||
|
|
|
@ -35,6 +35,8 @@ pub fn gen_and_eval(src: &[u8], target: Triple, opt_level: OptLevel) -> Result<R
|
||||||
|
|
||||||
let module_src = promote_expr_to_module(src_str);
|
let module_src = promote_expr_to_module(src_str);
|
||||||
|
|
||||||
|
let ptr_bytes = target.pointer_width().unwrap().bytes() as u32;
|
||||||
|
|
||||||
let exposed_types = MutMap::default();
|
let exposed_types = MutMap::default();
|
||||||
let loaded = roc_load::file::load_and_monomorphize_from_str(
|
let loaded = roc_load::file::load_and_monomorphize_from_str(
|
||||||
&arena,
|
&arena,
|
||||||
|
@ -43,6 +45,7 @@ pub fn gen_and_eval(src: &[u8], target: Triple, opt_level: OptLevel) -> Result<R
|
||||||
stdlib,
|
stdlib,
|
||||||
src_dir,
|
src_dir,
|
||||||
exposed_types,
|
exposed_types,
|
||||||
|
ptr_bytes,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut loaded = loaded.expect("failed to load module");
|
let mut loaded = loaded.expect("failed to load module");
|
||||||
|
|
|
@ -483,8 +483,9 @@ pub fn build_exp_literal<'a, 'ctx, 'env>(
|
||||||
use roc_mono::ir::Literal::*;
|
use roc_mono::ir::Literal::*;
|
||||||
|
|
||||||
match literal {
|
match literal {
|
||||||
Int(int) =>
|
Int(int) =>
|
||||||
(match layout {
|
(match layout {
|
||||||
|
Layout::Builtin(Builtin::Usize) => ptr_int(env.context, env.ptr_bytes),
|
||||||
Layout::Builtin(Builtin::Int128) => env.context.i128_type(), /* TODO file an issue: you can't currently have an int literal bigger than 64 bits long, and also (as we see here), you can't currently have (at least in Inkwell) a when-branch with an i128 literal in its pattren */
|
Layout::Builtin(Builtin::Int128) => env.context.i128_type(), /* TODO file an issue: you can't currently have an int literal bigger than 64 bits long, and also (as we see here), you can't currently have (at least in Inkwell) a when-branch with an i128 literal in its pattren */
|
||||||
Layout::Builtin(Builtin::Int64) => env.context.i64_type(),
|
Layout::Builtin(Builtin::Int64) => env.context.i64_type(),
|
||||||
Layout::Builtin(Builtin::Int32) => env.context.i32_type(),
|
Layout::Builtin(Builtin::Int32) => env.context.i32_type(),
|
||||||
|
@ -1312,7 +1313,6 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
Let(first_symbol, first_expr, first_layout, mut cont) => {
|
Let(first_symbol, first_expr, first_layout, mut cont) => {
|
||||||
let mut queue = Vec::new_in(env.arena);
|
let mut queue = Vec::new_in(env.arena);
|
||||||
|
|
||||||
|
|
||||||
queue.push((first_symbol, first_expr, first_layout));
|
queue.push((first_symbol, first_expr, first_layout));
|
||||||
|
|
||||||
while let Let(symbol, expr, layout, new_cont) = cont {
|
while let Let(symbol, expr, layout, new_cont) = cont {
|
||||||
|
@ -1742,8 +1742,11 @@ fn build_switch_ir<'a, 'ctx, 'env>(
|
||||||
//
|
//
|
||||||
// they either need to all be i8, or i64
|
// they either need to all be i8, or i64
|
||||||
let int_val = match cond_layout {
|
let int_val = match cond_layout {
|
||||||
Layout::Builtin(Builtin::Int128) => context.i128_type().const_int(*int as u64, false), /* TODO file an issue: you can't currently have an int literal bigger than 64 bits long, and also (as we see here), you can't currently have (at least in Inkwell) a when-branch with an i128 literal in its pattren */
|
Layout::Builtin(Builtin::Usize) => {
|
||||||
|
ptr_int(env.context, env.ptr_bytes).const_int(*int as u64, false)
|
||||||
|
}
|
||||||
Layout::Builtin(Builtin::Int64) => context.i64_type().const_int(*int as u64, false),
|
Layout::Builtin(Builtin::Int64) => context.i64_type().const_int(*int as u64, false),
|
||||||
|
Layout::Builtin(Builtin::Int128) => context.i128_type().const_int(*int as u64, false), /* TODO file an issue: you can't currently have an int literal bigger than 64 bits long, and also (as we see here), you can't currently have (at least in Inkwell) a when-branch with an i128 literal in its pattren */
|
||||||
Layout::Builtin(Builtin::Int32) => context.i32_type().const_int(*int as u64, false),
|
Layout::Builtin(Builtin::Int32) => context.i32_type().const_int(*int as u64, false),
|
||||||
Layout::Builtin(Builtin::Int16) => context.i16_type().const_int(*int as u64, false),
|
Layout::Builtin(Builtin::Int16) => context.i16_type().const_int(*int as u64, false),
|
||||||
Layout::Builtin(Builtin::Int8) => context.i8_type().const_int(*int as u64, false),
|
Layout::Builtin(Builtin::Int8) => context.i8_type().const_int(*int as u64, false),
|
||||||
|
@ -2933,7 +2936,7 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
use roc_mono::layout::Builtin::*;
|
use roc_mono::layout::Builtin::*;
|
||||||
|
|
||||||
match arg_builtin {
|
match arg_builtin {
|
||||||
Int128 | Int64 | Int32 | Int16 | Int8 => {
|
Usize | Int128 | Int64 | Int32 | Int16 | Int8 => {
|
||||||
build_int_unary_op(env, arg.into_int_value(), arg_builtin, op)
|
build_int_unary_op(env, arg.into_int_value(), arg_builtin, op)
|
||||||
}
|
}
|
||||||
Float128 | Float64 | Float32 | Float16 => {
|
Float128 | Float64 | Float32 | Float16 => {
|
||||||
|
@ -2971,7 +2974,7 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
let tag_lt = env.context.i8_type().const_int(2 as u64, false);
|
let tag_lt = env.context.i8_type().const_int(2 as u64, false);
|
||||||
|
|
||||||
match lhs_builtin {
|
match lhs_builtin {
|
||||||
Int128 | Int64 | Int32 | Int16 | Int8 => {
|
Usize | Int128 | Int64 | Int32 | Int16 | Int8 => {
|
||||||
let are_equal = env.builder.build_int_compare(
|
let are_equal = env.builder.build_int_compare(
|
||||||
IntPredicate::EQ,
|
IntPredicate::EQ,
|
||||||
lhs_arg.into_int_value(),
|
lhs_arg.into_int_value(),
|
||||||
|
@ -3395,7 +3398,7 @@ pub fn build_num_binop<'a, 'ctx, 'env>(
|
||||||
use roc_mono::layout::Builtin::*;
|
use roc_mono::layout::Builtin::*;
|
||||||
|
|
||||||
match lhs_builtin {
|
match lhs_builtin {
|
||||||
Int128 | Int64 | Int32 | Int16 | Int8 => build_int_binop(
|
Usize | Int128 | Int64 | Int32 | Int16 | Int8 => build_int_binop(
|
||||||
env,
|
env,
|
||||||
parent,
|
parent,
|
||||||
lhs_arg.into_int_value(),
|
lhs_arg.into_int_value(),
|
||||||
|
|
|
@ -165,6 +165,7 @@ pub fn basic_type_from_builtin<'ctx>(
|
||||||
Int16 => context.i16_type().as_basic_type_enum(),
|
Int16 => context.i16_type().as_basic_type_enum(),
|
||||||
Int8 => context.i8_type().as_basic_type_enum(),
|
Int8 => context.i8_type().as_basic_type_enum(),
|
||||||
Int1 => context.bool_type().as_basic_type_enum(),
|
Int1 => context.bool_type().as_basic_type_enum(),
|
||||||
|
Usize => ptr_int(context, ptr_bytes).as_basic_type_enum(),
|
||||||
Float128 => context.f128_type().as_basic_type_enum(),
|
Float128 => context.f128_type().as_basic_type_enum(),
|
||||||
Float64 => context.f64_type().as_basic_type_enum(),
|
Float64 => context.f64_type().as_basic_type_enum(),
|
||||||
Float32 => context.f32_type().as_basic_type_enum(),
|
Float32 => context.f32_type().as_basic_type_enum(),
|
||||||
|
|
|
@ -15,6 +15,22 @@ mod helpers;
|
||||||
mod gen_num {
|
mod gen_num {
|
||||||
use roc_std::RocOrder;
|
use roc_std::RocOrder;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn nat_alias() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
i : Nat
|
||||||
|
i = 1
|
||||||
|
|
||||||
|
i
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
1,
|
||||||
|
usize
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn i128_signed_int_alias() {
|
fn i128_signed_int_alias() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
|
|
|
@ -41,6 +41,9 @@ pub fn helper<'a>(
|
||||||
module_src = &temp;
|
module_src = &temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let target = target_lexicon::Triple::host();
|
||||||
|
let ptr_bytes = target.pointer_width().unwrap().bytes() as u32;
|
||||||
|
|
||||||
let exposed_types = MutMap::default();
|
let exposed_types = MutMap::default();
|
||||||
let loaded = roc_load::file::load_and_monomorphize_from_str(
|
let loaded = roc_load::file::load_and_monomorphize_from_str(
|
||||||
arena,
|
arena,
|
||||||
|
@ -49,6 +52,7 @@ pub fn helper<'a>(
|
||||||
stdlib,
|
stdlib,
|
||||||
src_dir,
|
src_dir,
|
||||||
exposed_types,
|
exposed_types,
|
||||||
|
ptr_bytes,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut loaded = loaded.expect("failed to load module");
|
let mut loaded = loaded.expect("failed to load module");
|
||||||
|
@ -73,9 +77,6 @@ pub fn helper<'a>(
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let target = target_lexicon::Triple::host();
|
|
||||||
let ptr_bytes = target.pointer_width().unwrap().bytes() as u32;
|
|
||||||
|
|
||||||
let mut lines = Vec::new();
|
let mut lines = Vec::new();
|
||||||
// errors whose reporting we delay (so we can see that code gen generates runtime errors)
|
// errors whose reporting we delay (so we can see that code gen generates runtime errors)
|
||||||
let mut delayed_errors = Vec::new();
|
let mut delayed_errors = Vec::new();
|
||||||
|
|
|
@ -947,6 +947,7 @@ pub fn load_and_typecheck(
|
||||||
stdlib: StdLib,
|
stdlib: StdLib,
|
||||||
src_dir: &Path,
|
src_dir: &Path,
|
||||||
exposed_types: SubsByModule,
|
exposed_types: SubsByModule,
|
||||||
|
ptr_bytes: u32,
|
||||||
) -> Result<LoadedModule, LoadingProblem> {
|
) -> Result<LoadedModule, LoadingProblem> {
|
||||||
use LoadResult::*;
|
use LoadResult::*;
|
||||||
|
|
||||||
|
@ -959,6 +960,7 @@ pub fn load_and_typecheck(
|
||||||
src_dir,
|
src_dir,
|
||||||
exposed_types,
|
exposed_types,
|
||||||
Phase::SolveTypes,
|
Phase::SolveTypes,
|
||||||
|
ptr_bytes,
|
||||||
)? {
|
)? {
|
||||||
Monomorphized(_) => unreachable!(""),
|
Monomorphized(_) => unreachable!(""),
|
||||||
TypeChecked(module) => Ok(module),
|
TypeChecked(module) => Ok(module),
|
||||||
|
@ -971,6 +973,7 @@ pub fn load_and_monomorphize<'a>(
|
||||||
stdlib: StdLib,
|
stdlib: StdLib,
|
||||||
src_dir: &Path,
|
src_dir: &Path,
|
||||||
exposed_types: SubsByModule,
|
exposed_types: SubsByModule,
|
||||||
|
ptr_bytes: u32,
|
||||||
) -> Result<MonomorphizedModule<'a>, LoadingProblem> {
|
) -> Result<MonomorphizedModule<'a>, LoadingProblem> {
|
||||||
use LoadResult::*;
|
use LoadResult::*;
|
||||||
|
|
||||||
|
@ -983,6 +986,7 @@ pub fn load_and_monomorphize<'a>(
|
||||||
src_dir,
|
src_dir,
|
||||||
exposed_types,
|
exposed_types,
|
||||||
Phase::MakeSpecializations,
|
Phase::MakeSpecializations,
|
||||||
|
ptr_bytes,
|
||||||
)? {
|
)? {
|
||||||
Monomorphized(module) => Ok(module),
|
Monomorphized(module) => Ok(module),
|
||||||
TypeChecked(_) => unreachable!(""),
|
TypeChecked(_) => unreachable!(""),
|
||||||
|
@ -996,6 +1000,7 @@ pub fn load_and_monomorphize_from_str<'a>(
|
||||||
stdlib: StdLib,
|
stdlib: StdLib,
|
||||||
src_dir: &Path,
|
src_dir: &Path,
|
||||||
exposed_types: SubsByModule,
|
exposed_types: SubsByModule,
|
||||||
|
ptr_bytes: u32,
|
||||||
) -> Result<MonomorphizedModule<'a>, LoadingProblem> {
|
) -> Result<MonomorphizedModule<'a>, LoadingProblem> {
|
||||||
use LoadResult::*;
|
use LoadResult::*;
|
||||||
|
|
||||||
|
@ -1008,6 +1013,7 @@ pub fn load_and_monomorphize_from_str<'a>(
|
||||||
src_dir,
|
src_dir,
|
||||||
exposed_types,
|
exposed_types,
|
||||||
Phase::MakeSpecializations,
|
Phase::MakeSpecializations,
|
||||||
|
ptr_bytes,
|
||||||
)? {
|
)? {
|
||||||
Monomorphized(module) => Ok(module),
|
Monomorphized(module) => Ok(module),
|
||||||
TypeChecked(_) => unreachable!(""),
|
TypeChecked(_) => unreachable!(""),
|
||||||
|
@ -1144,6 +1150,7 @@ fn load<'a>(
|
||||||
src_dir: &Path,
|
src_dir: &Path,
|
||||||
exposed_types: SubsByModule,
|
exposed_types: SubsByModule,
|
||||||
goal_phase: Phase,
|
goal_phase: Phase,
|
||||||
|
ptr_bytes: u32,
|
||||||
) -> Result<LoadResult<'a>, LoadingProblem>
|
) -> Result<LoadResult<'a>, LoadingProblem>
|
||||||
where
|
where
|
||||||
{
|
{
|
||||||
|
@ -1259,8 +1266,14 @@ where
|
||||||
// added. In that case, do nothing, and keep waiting
|
// added. In that case, do nothing, and keep waiting
|
||||||
// until we receive a Shutdown message.
|
// until we receive a Shutdown message.
|
||||||
if let Some(task) = find_task(&worker, injector, stealers) {
|
if let Some(task) = find_task(&worker, injector, stealers) {
|
||||||
run_task(task, worker_arena, src_dir, msg_tx.clone())
|
run_task(
|
||||||
.expect("Msg channel closed unexpectedly.");
|
task,
|
||||||
|
worker_arena,
|
||||||
|
src_dir,
|
||||||
|
msg_tx.clone(),
|
||||||
|
ptr_bytes,
|
||||||
|
)
|
||||||
|
.expect("Msg channel closed unexpectedly.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3341,6 +3354,7 @@ fn make_specializations<'a>(
|
||||||
mut layout_cache: LayoutCache<'a>,
|
mut layout_cache: LayoutCache<'a>,
|
||||||
specializations_we_must_make: ExternalSpecializations,
|
specializations_we_must_make: ExternalSpecializations,
|
||||||
mut module_timing: ModuleTiming,
|
mut module_timing: ModuleTiming,
|
||||||
|
ptr_bytes: u32,
|
||||||
) -> Msg<'a> {
|
) -> Msg<'a> {
|
||||||
let make_specializations_start = SystemTime::now();
|
let make_specializations_start = SystemTime::now();
|
||||||
let mut mono_problems = Vec::new();
|
let mut mono_problems = Vec::new();
|
||||||
|
@ -3351,6 +3365,7 @@ fn make_specializations<'a>(
|
||||||
subs: &mut subs,
|
subs: &mut subs,
|
||||||
home,
|
home,
|
||||||
ident_ids: &mut ident_ids,
|
ident_ids: &mut ident_ids,
|
||||||
|
ptr_bytes,
|
||||||
};
|
};
|
||||||
|
|
||||||
procs
|
procs
|
||||||
|
@ -3396,6 +3411,7 @@ fn build_pending_specializations<'a>(
|
||||||
decls: Vec<Declaration>,
|
decls: Vec<Declaration>,
|
||||||
mut module_timing: ModuleTiming,
|
mut module_timing: ModuleTiming,
|
||||||
mut layout_cache: LayoutCache<'a>,
|
mut layout_cache: LayoutCache<'a>,
|
||||||
|
ptr_bytes: u32,
|
||||||
// TODO remove
|
// TODO remove
|
||||||
exposed_to_host: MutMap<Symbol, Variable>,
|
exposed_to_host: MutMap<Symbol, Variable>,
|
||||||
) -> Msg<'a> {
|
) -> Msg<'a> {
|
||||||
|
@ -3410,6 +3426,7 @@ fn build_pending_specializations<'a>(
|
||||||
subs: &mut subs,
|
subs: &mut subs,
|
||||||
home,
|
home,
|
||||||
ident_ids: &mut ident_ids,
|
ident_ids: &mut ident_ids,
|
||||||
|
ptr_bytes,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add modules' decls to Procs
|
// Add modules' decls to Procs
|
||||||
|
@ -3613,6 +3630,7 @@ fn run_task<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
src_dir: &Path,
|
src_dir: &Path,
|
||||||
msg_tx: MsgSender<'a>,
|
msg_tx: MsgSender<'a>,
|
||||||
|
ptr_bytes: u32,
|
||||||
) -> Result<(), LoadingProblem> {
|
) -> Result<(), LoadingProblem> {
|
||||||
use BuildTask::*;
|
use BuildTask::*;
|
||||||
|
|
||||||
|
@ -3685,6 +3703,7 @@ fn run_task<'a>(
|
||||||
decls,
|
decls,
|
||||||
module_timing,
|
module_timing,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
|
ptr_bytes,
|
||||||
exposed_to_host,
|
exposed_to_host,
|
||||||
)),
|
)),
|
||||||
MakeSpecializations {
|
MakeSpecializations {
|
||||||
|
@ -3704,6 +3723,7 @@ fn run_task<'a>(
|
||||||
layout_cache,
|
layout_cache,
|
||||||
specializations_we_must_make,
|
specializations_we_must_make,
|
||||||
module_timing,
|
module_timing,
|
||||||
|
ptr_bytes,
|
||||||
)),
|
)),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
|
|
@ -691,6 +691,7 @@ pub struct Env<'a, 'i> {
|
||||||
pub problems: &'i mut std::vec::Vec<MonoProblem>,
|
pub problems: &'i mut std::vec::Vec<MonoProblem>,
|
||||||
pub home: ModuleId,
|
pub home: ModuleId,
|
||||||
pub ident_ids: &'i mut IdentIds,
|
pub ident_ids: &'i mut IdentIds,
|
||||||
|
pub ptr_bytes: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'i> Env<'a, 'i> {
|
impl<'a, 'i> Env<'a, 'i> {
|
||||||
|
@ -2288,37 +2289,41 @@ pub fn with_hole<'a>(
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
|
|
||||||
match can_expr {
|
match can_expr {
|
||||||
Int(_, precision, num) => match num_argument_to_int_or_float(env.subs, precision, false) {
|
Int(_, precision, num) => {
|
||||||
IntOrFloat::SignedIntType(precision) => Stmt::Let(
|
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, precision, false) {
|
||||||
assigned,
|
IntOrFloat::SignedIntType(precision) => Stmt::Let(
|
||||||
Expr::Literal(Literal::Int(num)),
|
assigned,
|
||||||
Layout::Builtin(int_precision_to_builtin(precision)),
|
Expr::Literal(Literal::Int(num)),
|
||||||
hole,
|
Layout::Builtin(int_precision_to_builtin(precision)),
|
||||||
),
|
hole,
|
||||||
IntOrFloat::UnsignedIntType(precision) => Stmt::Let(
|
),
|
||||||
assigned,
|
IntOrFloat::UnsignedIntType(precision) => Stmt::Let(
|
||||||
Expr::Literal(Literal::Int(num)),
|
assigned,
|
||||||
Layout::Builtin(int_precision_to_builtin(precision)),
|
Expr::Literal(Literal::Int(num)),
|
||||||
hole,
|
Layout::Builtin(int_precision_to_builtin(precision)),
|
||||||
),
|
hole,
|
||||||
_ => unreachable!("unexpected float precision for integer"),
|
),
|
||||||
},
|
_ => unreachable!("unexpected float precision for integer"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Float(_, precision, num) => match num_argument_to_int_or_float(env.subs, precision, true) {
|
Float(_, precision, num) => {
|
||||||
IntOrFloat::BinaryFloatType(precision) => Stmt::Let(
|
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, precision, true) {
|
||||||
assigned,
|
IntOrFloat::BinaryFloatType(precision) => Stmt::Let(
|
||||||
Expr::Literal(Literal::Float(num as f64)),
|
assigned,
|
||||||
Layout::Builtin(float_precision_to_builtin(precision)),
|
Expr::Literal(Literal::Float(num as f64)),
|
||||||
hole,
|
Layout::Builtin(float_precision_to_builtin(precision)),
|
||||||
),
|
hole,
|
||||||
IntOrFloat::DecimalFloatType(precision) => Stmt::Let(
|
),
|
||||||
assigned,
|
IntOrFloat::DecimalFloatType(precision) => Stmt::Let(
|
||||||
Expr::Literal(Literal::Float(num as f64)),
|
assigned,
|
||||||
Layout::Builtin(float_precision_to_builtin(precision)),
|
Expr::Literal(Literal::Float(num as f64)),
|
||||||
hole,
|
Layout::Builtin(float_precision_to_builtin(precision)),
|
||||||
),
|
hole,
|
||||||
_ => unreachable!("unexpected float precision for integer"),
|
),
|
||||||
},
|
_ => unreachable!("unexpected float precision for integer"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Str(string) => Stmt::Let(
|
Str(string) => Stmt::Let(
|
||||||
assigned,
|
assigned,
|
||||||
|
@ -2327,7 +2332,7 @@ pub fn with_hole<'a>(
|
||||||
hole,
|
hole,
|
||||||
),
|
),
|
||||||
|
|
||||||
Num(var, num) => match num_argument_to_int_or_float(env.subs, var, false) {
|
Num(var, num) => match num_argument_to_int_or_float(env.subs, env.ptr_bytes, var, false) {
|
||||||
IntOrFloat::SignedIntType(precision) => Stmt::Let(
|
IntOrFloat::SignedIntType(precision) => Stmt::Let(
|
||||||
assigned,
|
assigned,
|
||||||
Expr::Literal(Literal::Int(num)),
|
Expr::Literal(Literal::Int(num)),
|
||||||
|
@ -5612,12 +5617,14 @@ fn from_can_pattern_help<'a>(
|
||||||
// TODO preserve malformed problem information here?
|
// TODO preserve malformed problem information here?
|
||||||
Err(RuntimeError::UnsupportedPattern(*region))
|
Err(RuntimeError::UnsupportedPattern(*region))
|
||||||
}
|
}
|
||||||
NumLiteral(var, num) => match num_argument_to_int_or_float(env.subs, *var, false) {
|
NumLiteral(var, num) => {
|
||||||
IntOrFloat::SignedIntType(_) => Ok(Pattern::IntLiteral(*var, *num)),
|
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *var, false) {
|
||||||
IntOrFloat::UnsignedIntType(_) => Ok(Pattern::IntLiteral(*var, *num)),
|
IntOrFloat::SignedIntType(_) => Ok(Pattern::IntLiteral(*var, *num)),
|
||||||
IntOrFloat::BinaryFloatType(_) => Ok(Pattern::FloatLiteral(*var, *num as u64)),
|
IntOrFloat::UnsignedIntType(_) => Ok(Pattern::IntLiteral(*var, *num)),
|
||||||
IntOrFloat::DecimalFloatType(_) => Ok(Pattern::FloatLiteral(*var, *num as u64)),
|
IntOrFloat::BinaryFloatType(_) => Ok(Pattern::FloatLiteral(*var, *num as u64)),
|
||||||
},
|
IntOrFloat::DecimalFloatType(_) => Ok(Pattern::FloatLiteral(*var, *num as u64)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AppliedTag {
|
AppliedTag {
|
||||||
whole_var,
|
whole_var,
|
||||||
|
@ -5705,13 +5712,11 @@ fn from_can_pattern_help<'a>(
|
||||||
let mut arguments = arguments.clone();
|
let mut arguments = arguments.clone();
|
||||||
|
|
||||||
arguments.sort_by(|arg1, arg2| {
|
arguments.sort_by(|arg1, arg2| {
|
||||||
let ptr_bytes = 8;
|
|
||||||
|
|
||||||
let layout1 = layout_cache.from_var(env.arena, arg1.0, env.subs).unwrap();
|
let layout1 = layout_cache.from_var(env.arena, arg1.0, env.subs).unwrap();
|
||||||
let layout2 = layout_cache.from_var(env.arena, arg2.0, env.subs).unwrap();
|
let layout2 = layout_cache.from_var(env.arena, arg2.0, env.subs).unwrap();
|
||||||
|
|
||||||
let size1 = layout1.alignment_bytes(ptr_bytes);
|
let size1 = layout1.alignment_bytes(env.ptr_bytes);
|
||||||
let size2 = layout2.alignment_bytes(ptr_bytes);
|
let size2 = layout2.alignment_bytes(env.ptr_bytes);
|
||||||
|
|
||||||
size2.cmp(&size1)
|
size2.cmp(&size1)
|
||||||
});
|
});
|
||||||
|
@ -5762,13 +5767,11 @@ fn from_can_pattern_help<'a>(
|
||||||
let mut arguments = arguments.clone();
|
let mut arguments = arguments.clone();
|
||||||
|
|
||||||
arguments.sort_by(|arg1, arg2| {
|
arguments.sort_by(|arg1, arg2| {
|
||||||
let ptr_bytes = 8;
|
|
||||||
|
|
||||||
let layout1 = layout_cache.from_var(env.arena, arg1.0, env.subs).unwrap();
|
let layout1 = layout_cache.from_var(env.arena, arg1.0, env.subs).unwrap();
|
||||||
let layout2 = layout_cache.from_var(env.arena, arg2.0, env.subs).unwrap();
|
let layout2 = layout_cache.from_var(env.arena, arg2.0, env.subs).unwrap();
|
||||||
|
|
||||||
let size1 = layout1.alignment_bytes(ptr_bytes);
|
let size1 = layout1.alignment_bytes(env.ptr_bytes);
|
||||||
let size2 = layout2.alignment_bytes(ptr_bytes);
|
let size2 = layout2.alignment_bytes(env.ptr_bytes);
|
||||||
|
|
||||||
size2.cmp(&size1)
|
size2.cmp(&size1)
|
||||||
});
|
});
|
||||||
|
@ -6033,6 +6036,7 @@ fn int_precision_to_builtin(precision: IntPrecision) -> Builtin<'static> {
|
||||||
/// Given the `a` in `Num a`, determines whether it's an int or a float
|
/// Given the `a` in `Num a`, determines whether it's an int or a float
|
||||||
pub fn num_argument_to_int_or_float(
|
pub fn num_argument_to_int_or_float(
|
||||||
subs: &Subs,
|
subs: &Subs,
|
||||||
|
ptr_bytes: u32,
|
||||||
var: Variable,
|
var: Variable,
|
||||||
known_to_be_float: bool,
|
known_to_be_float: bool,
|
||||||
) -> IntOrFloat {
|
) -> IntOrFloat {
|
||||||
|
@ -6044,7 +6048,7 @@ pub fn num_argument_to_int_or_float(
|
||||||
debug_assert!(args.len() == 1);
|
debug_assert!(args.len() == 1);
|
||||||
|
|
||||||
// Recurse on the second argument
|
// Recurse on the second argument
|
||||||
num_argument_to_int_or_float(subs, args[0].1, false)
|
num_argument_to_int_or_float(subs, ptr_bytes, args[0].1, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
Content::Alias(Symbol::NUM_I128, _, _)
|
Content::Alias(Symbol::NUM_I128, _, _)
|
||||||
|
@ -6102,13 +6106,13 @@ pub fn num_argument_to_int_or_float(
|
||||||
debug_assert!(attr_args.len() == 2);
|
debug_assert!(attr_args.len() == 2);
|
||||||
|
|
||||||
// Recurse on the second argument
|
// Recurse on the second argument
|
||||||
num_argument_to_int_or_float(subs, attr_args[1], false)
|
num_argument_to_int_or_float(subs, ptr_bytes, attr_args[1], false)
|
||||||
}
|
}
|
||||||
Content::Alias(Symbol::NUM_FLOATINGPOINT, args, _) => {
|
Content::Alias(Symbol::NUM_FLOATINGPOINT, args, _) => {
|
||||||
debug_assert!(args.len() == 1);
|
debug_assert!(args.len() == 1);
|
||||||
|
|
||||||
// Recurse on the second argument
|
// Recurse on the second argument
|
||||||
num_argument_to_int_or_float(subs, args[0].1, true)
|
num_argument_to_int_or_float(subs, ptr_bytes, args[0].1, true)
|
||||||
}
|
}
|
||||||
Content::Alias(Symbol::NUM_FLOAT, _, _) // We default FloatingPoint to F64
|
Content::Alias(Symbol::NUM_FLOAT, _, _) // We default FloatingPoint to F64
|
||||||
| Content::Alias(Symbol::NUM_F64, _, _)
|
| Content::Alias(Symbol::NUM_F64, _, _)
|
||||||
|
@ -6121,6 +6125,20 @@ pub fn num_argument_to_int_or_float(
|
||||||
| Content::Alias(Symbol::NUM_AT_BINARY32, _, _) => {
|
| Content::Alias(Symbol::NUM_AT_BINARY32, _, _) => {
|
||||||
IntOrFloat::BinaryFloatType(FloatPrecision::F32)
|
IntOrFloat::BinaryFloatType(FloatPrecision::F32)
|
||||||
}
|
}
|
||||||
|
Content::Alias(Symbol::NUM_NAT, _, _)
|
||||||
|
| Content::Alias(Symbol::NUM_NATURAL, _, _)
|
||||||
|
| Content::Alias(Symbol::NUM_AT_NATURAL, _, _) => {
|
||||||
|
match ptr_bytes {
|
||||||
|
1 => IntOrFloat::UnsignedIntType(IntPrecision::I8),
|
||||||
|
2 => IntOrFloat::UnsignedIntType(IntPrecision::I16),
|
||||||
|
4 => IntOrFloat::UnsignedIntType(IntPrecision::I32),
|
||||||
|
8 => IntOrFloat::UnsignedIntType(IntPrecision::I64),
|
||||||
|
_ => panic!(
|
||||||
|
"Invalid target for Num type arguement: Roc does't support compiling to {}-bit systems.",
|
||||||
|
ptr_bytes * 8
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
other => {
|
other => {
|
||||||
panic!(
|
panic!(
|
||||||
"Unrecognized Num type argument for var {:?} with Content: {:?}",
|
"Unrecognized Num type argument for var {:?} with Content: {:?}",
|
||||||
|
|
|
@ -313,6 +313,7 @@ pub enum Builtin<'a> {
|
||||||
Int16,
|
Int16,
|
||||||
Int8,
|
Int8,
|
||||||
Int1,
|
Int1,
|
||||||
|
Usize,
|
||||||
Float128,
|
Float128,
|
||||||
Float64,
|
Float64,
|
||||||
Float32,
|
Float32,
|
||||||
|
@ -707,6 +708,7 @@ impl<'a> Builtin<'a> {
|
||||||
const I16_SIZE: u32 = std::mem::size_of::<i16>() as u32;
|
const I16_SIZE: u32 = std::mem::size_of::<i16>() as u32;
|
||||||
const I8_SIZE: u32 = std::mem::size_of::<i8>() as u32;
|
const I8_SIZE: u32 = std::mem::size_of::<i8>() as u32;
|
||||||
const I1_SIZE: u32 = std::mem::size_of::<bool>() as u32;
|
const I1_SIZE: u32 = std::mem::size_of::<bool>() as u32;
|
||||||
|
const USIZE_SIZE: u32 = std::mem::size_of::<usize>() as u32;
|
||||||
const F128_SIZE: u32 = 16;
|
const F128_SIZE: u32 = 16;
|
||||||
const F64_SIZE: u32 = std::mem::size_of::<f64>() as u32;
|
const F64_SIZE: u32 = std::mem::size_of::<f64>() as u32;
|
||||||
const F32_SIZE: u32 = std::mem::size_of::<f32>() as u32;
|
const F32_SIZE: u32 = std::mem::size_of::<f32>() as u32;
|
||||||
|
@ -735,6 +737,7 @@ impl<'a> Builtin<'a> {
|
||||||
Int16 => Builtin::I16_SIZE,
|
Int16 => Builtin::I16_SIZE,
|
||||||
Int8 => Builtin::I8_SIZE,
|
Int8 => Builtin::I8_SIZE,
|
||||||
Int1 => Builtin::I1_SIZE,
|
Int1 => Builtin::I1_SIZE,
|
||||||
|
Usize => Builtin::USIZE_SIZE,
|
||||||
Float128 => Builtin::F128_SIZE,
|
Float128 => Builtin::F128_SIZE,
|
||||||
Float64 => Builtin::F64_SIZE,
|
Float64 => Builtin::F64_SIZE,
|
||||||
Float32 => Builtin::F32_SIZE,
|
Float32 => Builtin::F32_SIZE,
|
||||||
|
@ -760,6 +763,7 @@ impl<'a> Builtin<'a> {
|
||||||
Int16 => align_of::<i16>() as u32,
|
Int16 => align_of::<i16>() as u32,
|
||||||
Int8 => align_of::<i8>() as u32,
|
Int8 => align_of::<i8>() as u32,
|
||||||
Int1 => align_of::<bool>() as u32,
|
Int1 => align_of::<bool>() as u32,
|
||||||
|
Usize => align_of::<usize>() as u32,
|
||||||
Float128 => align_of::<i128>() as u32,
|
Float128 => align_of::<i128>() as u32,
|
||||||
Float64 => align_of::<f64>() as u32,
|
Float64 => align_of::<f64>() as u32,
|
||||||
Float32 => align_of::<f32>() as u32,
|
Float32 => align_of::<f32>() as u32,
|
||||||
|
@ -775,7 +779,7 @@ impl<'a> Builtin<'a> {
|
||||||
use Builtin::*;
|
use Builtin::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Float128 | Float64 | Float32
|
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize | Float128 | Float64 | Float32
|
||||||
| Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => true,
|
| Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => true,
|
||||||
Str | Dict(_, _) | Set(_) | List(_, _) => false,
|
Str | Dict(_, _) | Set(_) | List(_, _) => false,
|
||||||
}
|
}
|
||||||
|
@ -786,7 +790,7 @@ impl<'a> Builtin<'a> {
|
||||||
use Builtin::*;
|
use Builtin::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Float128 | Float64 | Float32
|
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize | Float128 | Float64 | Float32
|
||||||
| Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => false,
|
| Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => false,
|
||||||
List(mode, element_layout) => match mode {
|
List(mode, element_layout) => match mode {
|
||||||
MemoryMode::Refcounted => true,
|
MemoryMode::Refcounted => true,
|
||||||
|
@ -811,6 +815,11 @@ fn layout_from_flat_type<'a>(
|
||||||
Apply(symbol, args) => {
|
Apply(symbol, args) => {
|
||||||
match symbol {
|
match symbol {
|
||||||
// Ints
|
// Ints
|
||||||
|
Symbol::NUM_NAT => {
|
||||||
|
debug_assert_eq!(args.len(), 0);
|
||||||
|
Ok(Layout::Builtin(Builtin::Usize))
|
||||||
|
}
|
||||||
|
|
||||||
Symbol::NUM_I128 => {
|
Symbol::NUM_I128 => {
|
||||||
debug_assert_eq!(args.len(), 0);
|
debug_assert_eq!(args.len(), 0);
|
||||||
Ok(Layout::Builtin(Builtin::Int128))
|
Ok(Layout::Builtin(Builtin::Int128))
|
||||||
|
@ -832,7 +841,6 @@ fn layout_from_flat_type<'a>(
|
||||||
Ok(Layout::Builtin(Builtin::Int8))
|
Ok(Layout::Builtin(Builtin::Int8))
|
||||||
}
|
}
|
||||||
|
|
||||||
// I think unsigned and signed use the same layout
|
|
||||||
Symbol::NUM_U128 => {
|
Symbol::NUM_U128 => {
|
||||||
debug_assert_eq!(args.len(), 0);
|
debug_assert_eq!(args.len(), 0);
|
||||||
Ok(Layout::Builtin(Builtin::Int128))
|
Ok(Layout::Builtin(Builtin::Int128))
|
||||||
|
@ -1358,6 +1366,8 @@ fn layout_from_num_content<'a>(content: Content) -> Result<Layout<'a>, LayoutPro
|
||||||
}
|
}
|
||||||
Structure(Apply(symbol, args)) => match symbol {
|
Structure(Apply(symbol, args)) => match symbol {
|
||||||
// Ints
|
// Ints
|
||||||
|
Symbol::NUM_NAT => Ok(Layout::Builtin(Builtin::Usize)),
|
||||||
|
|
||||||
Symbol::NUM_INTEGER => Ok(Layout::Builtin(Builtin::Int64)),
|
Symbol::NUM_INTEGER => Ok(Layout::Builtin(Builtin::Int64)),
|
||||||
Symbol::NUM_I128 => Ok(Layout::Builtin(Builtin::Int128)),
|
Symbol::NUM_I128 => Ok(Layout::Builtin(Builtin::Int128)),
|
||||||
Symbol::NUM_I64 => Ok(Layout::Builtin(Builtin::Int64)),
|
Symbol::NUM_I64 => Ok(Layout::Builtin(Builtin::Int64)),
|
||||||
|
@ -1365,7 +1375,6 @@ fn layout_from_num_content<'a>(content: Content) -> Result<Layout<'a>, LayoutPro
|
||||||
Symbol::NUM_I16 => Ok(Layout::Builtin(Builtin::Int16)),
|
Symbol::NUM_I16 => Ok(Layout::Builtin(Builtin::Int16)),
|
||||||
Symbol::NUM_I8 => Ok(Layout::Builtin(Builtin::Int8)),
|
Symbol::NUM_I8 => Ok(Layout::Builtin(Builtin::Int8)),
|
||||||
|
|
||||||
// I think unsigned and signed use the same layout
|
|
||||||
Symbol::NUM_U128 => Ok(Layout::Builtin(Builtin::Int128)),
|
Symbol::NUM_U128 => Ok(Layout::Builtin(Builtin::Int128)),
|
||||||
Symbol::NUM_U64 => Ok(Layout::Builtin(Builtin::Int64)),
|
Symbol::NUM_U64 => Ok(Layout::Builtin(Builtin::Int64)),
|
||||||
Symbol::NUM_U32 => Ok(Layout::Builtin(Builtin::Int32)),
|
Symbol::NUM_U32 => Ok(Layout::Builtin(Builtin::Int32)),
|
||||||
|
@ -1430,6 +1439,7 @@ fn unwrap_num_tag<'a>(subs: &Subs, var: Variable) -> Result<Layout<'a>, LayoutPr
|
||||||
Symbol::NUM_UNSIGNED32 => Builtin::Int32,
|
Symbol::NUM_UNSIGNED32 => Builtin::Int32,
|
||||||
Symbol::NUM_UNSIGNED16 => Builtin::Int16,
|
Symbol::NUM_UNSIGNED16 => Builtin::Int16,
|
||||||
Symbol::NUM_UNSIGNED8 => Builtin::Int8,
|
Symbol::NUM_UNSIGNED8 => Builtin::Int8,
|
||||||
|
Symbol::NUM_NATURAL => Builtin::Usize,
|
||||||
_ => unreachable!("not a valid int variant: {:?} {:?}", symbol, args),
|
_ => unreachable!("not a valid int variant: {:?} {:?}", symbol, args),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue