Add gen support for Nat

This commit is contained in:
Jared Ramirez 2021-01-01 17:40:47 -06:00
parent 37510e6aae
commit faa8f66b6c
9 changed files with 137 additions and 63 deletions

View file

@ -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();

View file

@ -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");

View file

@ -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(),

View file

@ -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(),

View file

@ -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!(

View file

@ -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();

View file

@ -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,
)), )),
}?; }?;

View file

@ -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: {:?}",

View file

@ -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),
}; };