Parse and expand numeric bounds in canonicalization pass

This commit is contained in:
ayazhafiz 2022-02-01 22:48:29 -05:00
parent 17c5fe0bff
commit a6f7579c07
113 changed files with 472 additions and 1361 deletions

View file

@ -3,8 +3,8 @@ use crate::builtins::builtin_defs_map;
use crate::def::{can_defs_with_return, Def};
use crate::env::Env;
use crate::num::{
finish_parsing_base, finish_parsing_float, finish_parsing_int, finish_parsing_int128,
float_expr_from_result, int_expr_from_result, num_expr_from_result,
finish_parsing_base, finish_parsing_float, finish_parsing_num, float_expr_from_result,
int_expr_from_result, num_expr_from_result,
};
use crate::pattern::{canonicalize_pattern, Pattern};
use crate::procedure::References;
@ -13,9 +13,9 @@ use roc_collections::all::{ImSet, MutMap, MutSet, SendMap};
use roc_module::called_via::CalledVia;
use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
use roc_module::low_level::LowLevel;
use roc_module::numeric::{FloatWidth, IntWidth, NumWidth};
use roc_module::numeric::{FloatWidth, IntWidth, NumWidth, NumericBound};
use roc_module::symbol::Symbol;
use roc_parse::ast::{self, Base, EscapedChar, StrLiteral};
use roc_parse::ast::{self, EscapedChar, StrLiteral};
use roc_parse::pattern::PatternType::*;
use roc_problem::can::{PrecedenceProblem, Problem, RuntimeError};
use roc_region::all::{Loc, Region};
@ -47,8 +47,6 @@ impl Output {
}
}
pub type NumericBound<NumWidth> = roc_module::numeric::NumericBound<NumWidth, Variable>;
#[derive(Clone, Debug, PartialEq)]
pub enum Expr {
// Literals
@ -211,23 +209,21 @@ pub fn canonicalize_expr<'a>(
use Expr::*;
let (expr, output) = match expr {
&ast::Expr::Num(str, bound) => {
&ast::Expr::Num(str) => {
let answer = num_expr_from_result(
var_store,
finish_parsing_int(str).map(|int| (str, int)),
finish_parsing_num(str).map(|result| (str, result)),
region,
bound,
env,
);
(answer, Output::default())
}
&ast::Expr::Float(str, bound) => {
&ast::Expr::Float(str) => {
let answer = float_expr_from_result(
var_store,
finish_parsing_float(str).map(|f| (str, f)),
finish_parsing_float(str).map(|(f, bound)| (str, f, bound)),
region,
bound,
env,
);
@ -799,41 +795,27 @@ pub fn canonicalize_expr<'a>(
string,
base,
is_negative,
bound,
} => {
// the minus sign is added before parsing, to get correct overflow/underflow behavior
let answer = match finish_parsing_base(string, base, is_negative) {
Ok(int) => {
Ok((int, bound)) => {
// Done in this kinda round about way with intermediate variables
// to keep borrowed values around and make this compile
let int_string = int.to_string();
let int_str = int_string.as_str();
int_expr_from_result(
var_store,
Ok((int_str, int as i128)),
Ok((int_str, int as i128, bound)),
region,
base,
bound,
env,
)
}
Err(e) => int_expr_from_result(var_store, Err(e), region, base, bound, env),
Err(e) => int_expr_from_result(var_store, Err(e), region, base, env),
};
(answer, Output::default())
}
&ast::Expr::Int(str, bound) => {
let answer = int_expr_from_result(
var_store,
finish_parsing_int128(str).map(|f| (str, f)),
region,
Base::Decimal,
bound,
env,
);
(answer, Output::default())
}
// Below this point, we shouln't see any of these nodes anymore because
// operator desugaring should have removed them!
bad_expr @ ast::Expr::ParensAround(_) => {