Factor out mono literal and pattern into smaller crates

This commit is contained in:
Ayaz Hafiz 2023-03-25 16:33:55 -05:00
parent 01c15c0648
commit f75248d206
No known key found for this signature in database
GPG Key ID: 0E2A37416A25EF58
5 changed files with 1858 additions and 1837 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
use super::pattern::{build_list_index_probe, store_pattern, DestructType, ListIndex, Pattern};
use crate::borrow::Ownership;
use crate::ir::{
build_list_index_probe, substitute_in_exprs_many, BranchInfo, Call, CallType,
CompiledGuardStmt, DestructType, Env, Expr, GuardStmtSpec, JoinPointId, ListIndex, Literal,
Param, Pattern, Procs, Stmt,
substitute_in_exprs_many, BranchInfo, Call, CallType, CompiledGuardStmt, Env, Expr,
GuardStmtSpec, JoinPointId, Literal, Param, Procs, Stmt,
};
use crate::layout::{
Builtin, InLayout, Layout, LayoutCache, LayoutInterner, TLLayoutInterner, TagIdIntType,
@ -1451,14 +1451,7 @@ pub(crate) fn optimize_when<'a>(
match (has_guard, should_inline) {
(false, _) => {
// Bind the fields referenced in the pattern.
branch = crate::ir::store_pattern(
env,
procs,
layout_cache,
&pattern,
cond_symbol,
branch,
);
branch = store_pattern(env, procs, layout_cache, &pattern, cond_symbol, branch);
join_params = &[];
jump_pattern_param_symbols = &[];
@ -2125,7 +2118,7 @@ fn decide_to_branching<'a>(
remainder: arena.alloc(stmt),
};
crate::ir::store_pattern(env, procs, layout_cache, &pattern, cond_symbol, join)
store_pattern(env, procs, layout_cache, &pattern, cond_symbol, join)
}
Chain {
test_chain,

View File

@ -0,0 +1,116 @@
use roc_builtins::bitcode::{FloatWidth, IntWidth};
use roc_can::expr::IntValue;
use roc_error_macros::internal_error;
use roc_module::symbol::Symbol;
use roc_std::RocDec;
use crate::layout::{Builtin, InLayout, Layout, LayoutInterner, TLLayoutInterner};
use super::pattern::Pattern;
#[derive(Debug, Clone, Copy)]
pub enum IntOrFloatValue {
Int(IntValue),
Float(f64),
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Literal<'a> {
// Literals
/// stored as raw bytes rather than a number to avoid an alignment bump
Int([u8; 16]),
/// stored as raw bytes rather than a number to avoid an alignment bump
U128([u8; 16]),
Float(f64),
/// stored as raw bytes rather than a number to avoid an alignment bump
Decimal([u8; 16]),
Str(&'a str),
/// Closed tag unions containing exactly two (0-arity) tags compile to Expr::Bool,
/// so they can (at least potentially) be emitted as 1-bit machine bools.
///
/// So [True, False] compiles to this, and so do [A, B] and [Foo, Bar].
/// However, a union like [True, False, Other Int] would not.
Bool(bool),
/// Closed tag unions containing between 3 and 256 tags (all of 0 arity)
/// compile to bytes, e.g. [Blue, Black, Red, Green, White]
Byte(u8),
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ListLiteralElement<'a> {
Literal(Literal<'a>),
Symbol(Symbol),
}
impl<'a> ListLiteralElement<'a> {
pub fn to_symbol(&self) -> Option<Symbol> {
match self {
Self::Symbol(s) => Some(*s),
_ => None,
}
}
}
pub enum NumLiteral {
Int([u8; 16], IntWidth),
U128([u8; 16]),
Float(f64, FloatWidth),
Decimal([u8; 16]),
}
impl NumLiteral {
pub fn to_expr_literal(&self) -> Literal<'static> {
match *self {
NumLiteral::Int(n, _) => Literal::Int(n),
NumLiteral::U128(n) => Literal::U128(n),
NumLiteral::Float(n, _) => Literal::Float(n),
NumLiteral::Decimal(n) => Literal::Decimal(n),
}
}
pub fn to_pattern(&self) -> Pattern<'static> {
match *self {
NumLiteral::Int(n, w) => Pattern::IntLiteral(n, w),
NumLiteral::U128(n) => Pattern::IntLiteral(n, IntWidth::U128),
NumLiteral::Float(n, w) => Pattern::FloatLiteral(f64::to_bits(n), w),
NumLiteral::Decimal(n) => Pattern::DecimalLiteral(n),
}
}
}
pub fn make_num_literal<'a>(
interner: &TLLayoutInterner<'a>,
layout: InLayout<'a>,
num_str: &str,
num_value: IntOrFloatValue,
) -> NumLiteral {
match interner.get(layout) {
Layout::Builtin(Builtin::Int(width)) => match num_value {
IntOrFloatValue::Int(IntValue::I128(n)) => NumLiteral::Int(n, width),
IntOrFloatValue::Int(IntValue::U128(n)) => NumLiteral::U128(n),
IntOrFloatValue::Float(..) => {
internal_error!("Float value where int was expected, should have been a type error")
}
},
Layout::Builtin(Builtin::Float(width)) => match num_value {
IntOrFloatValue::Float(n) => NumLiteral::Float(n, width),
IntOrFloatValue::Int(int_value) => match int_value {
IntValue::I128(n) => NumLiteral::Float(i128::from_ne_bytes(n) as f64, width),
IntValue::U128(n) => NumLiteral::Float(u128::from_ne_bytes(n) as f64, width),
},
},
Layout::Builtin(Builtin::Decimal) => {
let dec = match RocDec::from_str(num_str) {
Some(d) => d,
None => internal_error!(
"Invalid decimal for float literal = {}. This should be a type error!",
num_str
),
};
NumLiteral::Decimal(dec.to_ne_bytes())
}
layout => internal_error!(
"Found a non-num layout where a number was expected: {:?}",
layout
),
}
}

File diff suppressed because it is too large Load Diff

View File

@ -19,9 +19,4 @@ pub mod low_level;
pub mod reset_reuse;
pub mod tail_recursion;
// Temporary, while we can build up test cases and optimize the exhaustiveness checking.
// For now, following this warning's advice will lead to nasty type inference errors.
//#[allow(clippy::ptr_arg)]
pub mod decision_tree;
pub mod debug;