store literals in lists directly

This commit is contained in:
Folkert 2021-09-05 17:06:02 +02:00
parent 8e7aef314a
commit b97c2d5d84
13 changed files with 97 additions and 65 deletions

View file

@ -2746,6 +2746,63 @@ macro_rules! match_on_closure_argument {
}};
}
fn try_make_literal<'a>(
env: &mut Env<'a, '_>,
can_expr: &roc_can::expr::Expr,
) -> Option<Literal<'a>> {
use roc_can::expr::Expr::*;
match can_expr {
Int(_, precision, _, int) => {
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *precision, false) {
IntOrFloat::SignedIntType(_) | IntOrFloat::UnsignedIntType(_) => {
Some(Literal::Int(*int))
}
_ => unreachable!("unexpected float precision for integer"),
}
}
Float(_, precision, float_str, float) => {
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *precision, true) {
IntOrFloat::BinaryFloatType(_) => Some(Literal::Float(*float)),
IntOrFloat::DecimalFloatType => {
let dec = match RocDec::from_str(float_str) {
Some(d) => d,
None => panic!("Invalid decimal for float literal = {}. TODO: Make this a nice, user-friendly error message", float_str),
};
Some(Literal::Decimal(dec))
}
_ => unreachable!("unexpected float precision for integer"),
}
}
// TODO investigate lifetime trouble
// Str(string) => Some(Literal::Str(env.arena.alloc(string))),
Num(var, num_str, num) => {
// first figure out what kind of number this is
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *var, false) {
IntOrFloat::SignedIntType(_) | IntOrFloat::UnsignedIntType(_) => {
Some(Literal::Int((*num).into()))
}
IntOrFloat::BinaryFloatType(_) => Some(Literal::Float(*num as f64)),
IntOrFloat::DecimalFloatType => {
let dec = match RocDec::from_str(num_str) {
Some(d) => d,
None => panic!(
r"Invalid decimal for float literal = {}. TODO: Make this a nice, user-friendly error message",
num_str
),
};
Some(Literal::Decimal(dec))
}
}
}
_ => None,
}
}
pub fn with_hole<'a>(
env: &mut Env<'a, '_>,
can_expr: roc_can::expr::Expr,
@ -3442,11 +3499,19 @@ pub fn with_hole<'a>(
} => {
let mut arg_symbols = Vec::with_capacity_in(loc_elems.len(), env.arena);
let mut elements = Vec::with_capacity_in(loc_elems.len(), env.arena);
for arg_expr in loc_elems.iter() {
let symbol = possible_reuse_symbol(env, procs, &arg_expr.value);
elements.push(ListLiteralElement::Symbol(symbol));
arg_symbols.push(symbol)
let mut symbol_exprs = Vec::with_capacity_in(loc_elems.len(), env.arena);
for arg_expr in loc_elems.into_iter() {
if let Some(literal) = try_make_literal(env, &arg_expr.value) {
elements.push(ListLiteralElement::Literal(literal));
} else {
let symbol = possible_reuse_symbol(env, procs, &arg_expr.value);
elements.push(ListLiteralElement::Symbol(symbol));
arg_symbols.push(symbol);
symbol_exprs.push(arg_expr);
}
}
let arg_symbols = arg_symbols.into_bump_slice();
@ -3466,7 +3531,7 @@ pub fn with_hole<'a>(
hole,
);
let iter = loc_elems
let iter = symbol_exprs
.into_iter()
.rev()
.map(|e| (elem_var, e))

View file

@ -3,14 +3,8 @@ procedure Test.1 (Test.2, Test.3):
ret Test.2;
procedure Test.0 ():
let Test.11 = 1i64;
let Test.12 = 2i64;
let Test.13 = 3i64;
let Test.5 = Array [Test.11, Test.12, Test.13];
let Test.8 = 3i64;
let Test.9 = 2i64;
let Test.10 = 1i64;
let Test.6 = Array [Test.8, Test.9, Test.10];
let Test.5 = Array [1i64, 2i64, 3i64];
let Test.6 = Array [3i64, 2i64, 1i64];
let Test.4 = CallByName Test.1 Test.5 Test.6;
dec Test.6;
dec Test.5;

View file

@ -7,9 +7,7 @@ procedure Num.24 (#Attr.2, #Attr.3):
ret Test.5;
procedure Test.0 ():
let Test.11 = 1i64;
let Test.12 = 2i64;
let Test.1 = Array [Test.11, Test.12];
let Test.1 = Array [1i64, 2i64];
let Test.9 = 5i64;
let Test.10 = 4i64;
let Test.7 = CallByName Num.24 Test.9 Test.10;

View file

@ -1,8 +1,5 @@
procedure Test.0 ():
let Test.6 = 1i64;
let Test.7 = 3i64;
let Test.8 = 4i64;
let Test.4 = Array [Test.6, Test.7, Test.8];
let Test.4 = Array [1i64, 3i64, 4i64];
let Test.5 = 3.14f64;
let Test.3 = Struct {Test.4, Test.5};
let Test.1 = StructAtIndex 0 Test.3;

View file

@ -3,8 +3,7 @@ procedure List.5 (#Attr.2, #Attr.3):
ret Test.4;
procedure Test.0 ():
let Test.5 = 1i64;
let Test.2 = Array [Test.5];
let Test.2 = Array [1i64];
let Test.3 = 2i64;
let Test.1 = CallByName List.5 Test.2 Test.3;
ret Test.1;

View file

@ -8,8 +8,6 @@ procedure Test.1 (Test.2):
ret Test.5;
procedure Test.0 ():
let Test.8 = 1i64;
let Test.9 = 2i64;
let Test.4 = Array [Test.8, Test.9];
let Test.4 = Array [1i64, 2i64];
let Test.3 = CallByName Test.1 Test.4;
ret Test.3;

View file

@ -1,9 +1,9 @@
procedure List.4 (#Attr.2, #Attr.3, #Attr.4):
let Test.22 = lowlevel ListLen #Attr.2;
let Test.20 = lowlevel NumLt #Attr.3 Test.22;
if Test.20 then
let Test.21 = lowlevel ListSet #Attr.2 #Attr.3 #Attr.4;
ret Test.21;
let Test.19 = lowlevel ListLen #Attr.2;
let Test.17 = lowlevel NumLt #Attr.3 Test.19;
if Test.17 then
let Test.18 = lowlevel ListSet #Attr.2 #Attr.3 #Attr.4;
ret Test.18;
else
ret #Attr.2;
@ -16,23 +16,20 @@ procedure Num.24 (#Attr.2, #Attr.3):
ret Test.7;
procedure Test.1 ():
let Test.11 = 1i64;
let Test.12 = 2i64;
let Test.13 = 3i64;
let Test.10 = Array [Test.11, Test.12, Test.13];
let Test.10 = Array [1i64, 2i64, 3i64];
ret Test.10;
procedure Test.2 (Test.3):
let Test.17 = 0i64;
let Test.18 = 0i64;
let Test.16 = CallByName List.4 Test.3 Test.17 Test.18;
ret Test.16;
let Test.14 = 0i64;
let Test.15 = 0i64;
let Test.13 = CallByName List.4 Test.3 Test.14 Test.15;
ret Test.13;
procedure Test.0 ():
let Test.15 = CallByName Test.1;
let Test.14 = CallByName Test.2 Test.15;
let Test.5 = CallByName List.7 Test.14;
dec Test.14;
let Test.12 = CallByName Test.1;
let Test.11 = CallByName Test.2 Test.12;
let Test.5 = CallByName List.7 Test.11;
dec Test.11;
let Test.8 = CallByName Test.1;
let Test.6 = CallByName List.7 Test.8;
dec Test.8;

View file

@ -11,10 +11,7 @@ procedure List.3 (#Attr.2, #Attr.3):
ret Test.8;
procedure Test.1 (Test.2):
let Test.14 = 1i64;
let Test.15 = 2i64;
let Test.16 = 3i64;
let Test.6 = Array [Test.14, Test.15, Test.16];
let Test.6 = Array [1i64, 2i64, 3i64];
let Test.7 = 0i64;
let Test.5 = CallByName List.3 Test.6 Test.7;
dec Test.6;

View file

@ -11,12 +11,8 @@ procedure Num.24 (#Attr.2, #Attr.3):
ret Test.6;
procedure Test.0 ():
let Test.10 = 1i64;
let Test.11 = 2i64;
let Test.12 = 3i64;
let Test.1 = Array [Test.10, Test.11, Test.12];
let Test.9 = 1f64;
let Test.2 = Array [Test.9];
let Test.1 = Array [1i64, 2i64, 3i64];
let Test.2 = Array [1f64];
let Test.4 = CallByName List.7 Test.1;
dec Test.1;
let Test.5 = CallByName List.7 Test.2;

View file

@ -14,9 +14,6 @@ procedure Test.2 (Test.3):
ret Test.5;
procedure Test.0 ():
let Test.12 = 1i64;
let Test.13 = 2i64;
let Test.14 = 3i64;
let Test.1 = Array [Test.12, Test.13, Test.14];
let Test.1 = Array [1i64, 2i64, 3i64];
let Test.4 = CallByName Test.2 Test.1;
ret Test.4;

View file

@ -4,9 +4,6 @@ procedure Test.1 (Test.2):
ret Test.6;
procedure Test.0 ():
let Test.7 = 1i64;
let Test.8 = 2i64;
let Test.9 = 3i64;
let Test.5 = Array [Test.7, Test.8, Test.9];
let Test.5 = Array [1i64, 2i64, 3i64];
let Test.4 = CallByName Test.1 Test.5;
ret Test.4;

View file

@ -56,8 +56,6 @@ procedure Test.1 (Test.2):
jump Test.26;
procedure Test.0 ():
let Test.39 = 1i64;
let Test.40 = 2i64;
let Test.7 = Array [Test.39, Test.40];
let Test.7 = Array [1i64, 2i64];
let Test.6 = CallByName Test.1 Test.7;
ret Test.6;

View file

@ -54,7 +54,6 @@ procedure Test.1 (Test.2, Test.3, Test.4):
procedure Test.0 ():
let Test.10 = 0i64;
let Test.11 = 0i64;
let Test.40 = 1i64;
let Test.12 = Array [Test.40];
let Test.12 = Array [1i64];
let Test.9 = CallByName Test.1 Test.10 Test.11 Test.12;
ret Test.9;