mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
Frac+Approx --> Float
This commit is contained in:
parent
695d1eb467
commit
04595a9e71
11 changed files with 112 additions and 207 deletions
|
@ -13,8 +13,7 @@ use self::PatternType::*;
|
|||
pub enum Expr {
|
||||
// Literals
|
||||
Int(i64),
|
||||
Frac(i64, i64),
|
||||
Approx(f64),
|
||||
Float(f64),
|
||||
EmptyStr,
|
||||
Str(String),
|
||||
Char(char),
|
||||
|
@ -72,8 +71,8 @@ pub enum Problem {
|
|||
pub enum Pattern {
|
||||
Identifier(Symbol),
|
||||
Variant(Symbol, Option<Vec<Located<Pattern>>>),
|
||||
Integer(i64),
|
||||
Fraction(i64, i64),
|
||||
IntLiteral(i64),
|
||||
FloatLiteral(f64),
|
||||
ExactString(String),
|
||||
EmptyRecordLiteral,
|
||||
Underscore,
|
||||
|
@ -303,8 +302,7 @@ fn canonicalize(
|
|||
|
||||
let (expr, output) = match loc_expr.value {
|
||||
expr::Expr::Int(num) => ( Int(num), Output::new() ),
|
||||
expr::Expr::Frac(numerator, denominator) => ( Frac(numerator, denominator), Output::new()),
|
||||
expr::Expr::Approx(num) => ( Approx(num), Output::new()),
|
||||
expr::Expr::Float(num) => ( Float(num), Output::new() ),
|
||||
expr::Expr::EmptyRecord => ( EmptyRecord, Output::new()),
|
||||
expr::Expr::Str(string) => ( Str(string), Output::new()),
|
||||
expr::Expr::Char(ch) => ( Char(ch), Output::new()),
|
||||
|
@ -577,7 +575,6 @@ fn canonicalize(
|
|||
// Store the referenced locals in the refs_by_assignment map, so we can later figure out
|
||||
// which assigned names reference each other.
|
||||
for (ident, (symbol, region)) in idents_from_patterns(std::iter::once(&loc_pattern), &scope) {
|
||||
println!("* * * symbol: {:?}, is_closure_defn: {:?}", symbol, renamed_closure_assignment);
|
||||
let refs =
|
||||
// Functions' references don't count in assignments.
|
||||
// See 3d5a2560057d7f25813112dfa5309956c0f9e6a9 and its
|
||||
|
@ -1024,7 +1021,7 @@ fn add_idents_from_pattern(
|
|||
}
|
||||
}
|
||||
},
|
||||
&Integer(_) | &Fraction(_, _) | &ExactString(_)
|
||||
&IntLiteral(_) | &FloatLiteral(_) | &ExactString(_)
|
||||
| &EmptyRecordLiteral | &Underscore => ()
|
||||
}
|
||||
}
|
||||
|
@ -1042,7 +1039,7 @@ fn remove_idents(
|
|||
remove_idents(loc_arg.value, idents);
|
||||
}
|
||||
},
|
||||
Variant(_, None) | Integer(_) | Fraction(_, _) | ExactString(_)
|
||||
Variant(_, None) | IntLiteral(_) | FloatLiteral(_) | ExactString(_)
|
||||
| EmptyRecordLiteral | Underscore => {}
|
||||
}
|
||||
}
|
||||
|
@ -1234,16 +1231,16 @@ fn canonicalize_pattern(
|
|||
}
|
||||
},
|
||||
|
||||
&Integer(ref num) => {
|
||||
&IntLiteral(ref num) => {
|
||||
match pattern_type {
|
||||
CaseBranch => Pattern::Integer(*num),
|
||||
CaseBranch => Pattern::IntLiteral(*num),
|
||||
ptype @ Assignment | ptype @ FunctionArg => unsupported_pattern(env, *ptype, ®ion, &loc_pattern.value)
|
||||
}
|
||||
},
|
||||
|
||||
&Fraction(ref numerator, ref denominator) => {
|
||||
&FloatLiteral(ref num) => {
|
||||
match pattern_type {
|
||||
CaseBranch => Pattern::Fraction(*numerator, *denominator),
|
||||
CaseBranch => Pattern::FloatLiteral(*num),
|
||||
ptype @ Assignment | ptype @ FunctionArg => unsupported_pattern(env, *ptype, ®ion, &loc_pattern.value)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -28,9 +28,8 @@ pub fn constrain(
|
|||
let region = loc_expr.region;
|
||||
|
||||
match loc_expr.value {
|
||||
Int(_) => { Eq(num(subs.mk_flex_var()), expected, region) },
|
||||
Frac(_, _) => { fractional(subs, expected, region) },
|
||||
Approx(_) => { fractional(subs, expected, region) },
|
||||
Int(_) => { int_literal(subs, expected, region) },
|
||||
Float(_) => { float_literal(subs, expected, region) },
|
||||
Str(_) => { Eq(string(), expected, region) },
|
||||
EmptyStr => { Eq(string(), expected, region) },
|
||||
InterpolatedStr(pairs, _) => {
|
||||
|
@ -337,33 +336,43 @@ fn list(loc_elems: Vec<Located<Expr>>, bound_vars: &BoundTypeVars, subs: &mut Su
|
|||
And(constraints)
|
||||
}
|
||||
|
||||
fn fractional(subs: &mut Subs, expected: Expected<Type>, region: Region) -> Constraint {
|
||||
// We'll make a Num var1 and a Fractional var2,
|
||||
// and then add a constraint that var1 needs to equal Fractional var2
|
||||
let num_var = subs.mk_flex_var(); // Num var1
|
||||
let fractional_var = subs.mk_flex_var(); // Fractional var2
|
||||
let fractional_type =
|
||||
Type::Apply(
|
||||
"Num".to_string(),
|
||||
"Fractional".to_string(),
|
||||
vec![Type::Variable(fractional_var)]
|
||||
);
|
||||
let num_var_type = Type::Variable(num_var);
|
||||
let num_type =
|
||||
Type::Apply(
|
||||
"Num".to_string(),
|
||||
"Num".to_string(),
|
||||
vec![num_var_type.clone()]
|
||||
);
|
||||
let expected_fractional =
|
||||
ForReason(Reason::FractionalLiteral, fractional_type, region.clone());
|
||||
#[inline(always)]
|
||||
fn int_literal(subs: &mut Subs, expected: Expected<Type>, region: Region) -> Constraint {
|
||||
let typ = number_literal_type("Int", "Integer");
|
||||
let reason = Reason::IntLiteral;
|
||||
|
||||
num_literal(typ, reason, subs, expected, region)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn float_literal(subs: &mut Subs, expected: Expected<Type>, region: Region) -> Constraint {
|
||||
let typ = number_literal_type("Float", "FloatingPoint");
|
||||
let reason = Reason::FloatLiteral;
|
||||
|
||||
num_literal(typ, reason, subs, expected, region)
|
||||
}
|
||||
|
||||
|
||||
#[inline(always)]
|
||||
fn num_literal(literal_type: Type, reason: Reason, subs: &mut Subs, expected: Expected<Type>, region: Region) -> Constraint {
|
||||
let num_var = subs.mk_flex_var();
|
||||
let num_type = Variable(num_var);
|
||||
let expected_literal = ForReason(reason, literal_type, region.clone());
|
||||
|
||||
And(vec![
|
||||
Eq(num_type, expected, region.clone()),
|
||||
Eq(num_var_type, expected_fractional, region),
|
||||
Eq(num_type.clone(), expected_literal, region.clone()),
|
||||
Eq(num_type, expected, region.clone())
|
||||
])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn number_literal_type(module_name: &str, type_name: &str) -> Type {
|
||||
builtin_type("Num", "Num",
|
||||
vec![builtin_type(module_name, type_name, Vec::new())]
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn builtin_type(module_name: &str, type_name: &str, args: Vec<Type>) -> Type {
|
||||
Type::Apply(module_name.to_string(), type_name.to_string(), args)
|
||||
}
|
||||
|
|
|
@ -6,8 +6,7 @@ use std::fmt;
|
|||
pub enum Expr {
|
||||
// Literals
|
||||
Int(i64),
|
||||
Frac(i64, i64),
|
||||
Approx(f64),
|
||||
Float(f64),
|
||||
EmptyStr,
|
||||
Str(String),
|
||||
Char(char),
|
||||
|
@ -99,8 +98,8 @@ impl fmt::Display for VariantName {
|
|||
pub enum Pattern {
|
||||
Identifier(String),
|
||||
Variant(Located<VariantName>, Option<Vec<Located<Pattern>>>),
|
||||
Integer(i64),
|
||||
Fraction(i64, i64),
|
||||
IntLiteral(i64),
|
||||
FloatLiteral(f64),
|
||||
ExactString(String),
|
||||
EmptyRecordLiteral,
|
||||
Underscore,
|
||||
|
@ -115,7 +114,7 @@ impl Expr {
|
|||
let transformed = transform(self);
|
||||
|
||||
match transformed {
|
||||
Int(_) | Frac(_, _) | Approx(_) | EmptyStr | Str(_) | Char(_) | Var(_) | EmptyRecord | InterpolatedStr(_, _) | EmptyList => transformed,
|
||||
Int(_) | Float(_) | EmptyStr | Str(_) | Char(_) | Var(_) | EmptyRecord | InterpolatedStr(_, _) | EmptyList => transformed,
|
||||
List(elems) => {
|
||||
let new_elems =
|
||||
elems.into_iter()
|
||||
|
|
113
src/parse.rs
113
src/parse.rs
|
@ -199,9 +199,6 @@ parser! {
|
|||
string_literal(),
|
||||
int_or_frac_literal(),
|
||||
negative_int_or_frac_literal(),
|
||||
char('~').with(
|
||||
negative_approx_literal().or(approx_literal())
|
||||
),
|
||||
char_literal(),
|
||||
if_expr(min_indent),
|
||||
case_expr(min_indent),
|
||||
|
@ -895,68 +892,6 @@ where I: Stream<Item = char, Position = IndentablePosition>,
|
|||
)
|
||||
}
|
||||
|
||||
pub fn negative_approx_literal<I>() -> impl Parser<Input = I, Output = Expr>
|
||||
where I: Stream<Item = char, Position = IndentablePosition>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>
|
||||
{
|
||||
char('-')
|
||||
.with(digits_before_decimal())
|
||||
.and(optional(char('.').with(digits_after_decimal())))
|
||||
.then(|(int_digits, decimals): (Vec<char>, Option<Vec<char>>)| {
|
||||
// TODO check length of digits and make sure not to overflow
|
||||
let int_str: String = int_digits.into_iter().collect();
|
||||
|
||||
match decimals {
|
||||
Some(nums) => {
|
||||
let decimal_str: String = nums.into_iter().collect();
|
||||
|
||||
match format!("-{}.{}", int_str, decimal_str).parse::<f64>() {
|
||||
Ok(float) => {
|
||||
value(Expr::Approx(float)).right()
|
||||
},
|
||||
Err(_) => {
|
||||
unexpected_any("looked like a negative number literal but was actually malformed identifier").left()
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
unexpected_any("negative number literal with ~ but without the decimal point that ~ number literals require").left()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn approx_literal<I>() -> impl Parser<Input = I, Output = Expr>
|
||||
where I: Stream<Item = char, Position = IndentablePosition>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>
|
||||
{
|
||||
digits_before_decimal()
|
||||
.and(optional(char('.').with(digits_after_decimal())))
|
||||
.then(|(int_digits, decimals): (Vec<char>, Option<Vec<char>>)| {
|
||||
// TODO check length of digits and make sure not to overflow
|
||||
let int_str: String = int_digits.into_iter().collect();
|
||||
|
||||
match decimals {
|
||||
Some(nums) => {
|
||||
let decimal_str: String = nums.into_iter().collect();
|
||||
|
||||
match format!("{}.{}", int_str, decimal_str).parse::<f64>() {
|
||||
Ok(float) => {
|
||||
value(Expr::Approx(float)).right()
|
||||
},
|
||||
Err(_) => {
|
||||
unexpected_any("looked like a negative number literal but was actually malformed identifier").left()
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
unexpected_any("negative number literal with ~ but without the decimal point that ~ number literals require").left()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
pub fn negative_int_or_frac_literal<I>() -> impl Parser<Input = I, Output = Expr>
|
||||
where I: Stream<Item = char, Position = IndentablePosition>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>
|
||||
|
@ -978,21 +913,15 @@ where I: Stream<Item = char, Position = IndentablePosition>,
|
|||
(Ok(int_val), None) => {
|
||||
value(Expr::Int(-int_val as i64)).right()
|
||||
},
|
||||
(Ok(int_val), Some(nums)) => {
|
||||
(Ok(_), Some(nums)) => {
|
||||
let decimal_str: String = nums.into_iter().collect();
|
||||
// calculate numerator and denominator
|
||||
// e.g. 123.45 == 12345 / 100
|
||||
let denom = (10 as i64).pow(decimal_str.len() as u32);
|
||||
|
||||
match decimal_str.parse::<u32>() {
|
||||
Ok(decimal) => {
|
||||
// Only the numerator may ever be signed!
|
||||
let numerator = (int_val * denom) + (decimal as i64);
|
||||
|
||||
value(Expr::Frac(-numerator, denom)).right()
|
||||
match format!("{}.{}", int_str, decimal_str).parse::<f64>() {
|
||||
Ok(float) => {
|
||||
value(Expr::Float(-float)).right()
|
||||
},
|
||||
Err(_) => {
|
||||
unexpected_any("non-digit characters after decimal point in a negative number literal").left()
|
||||
unexpected_any("looked like a negative Float literal but was actually malformed identifier").left()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1020,16 +949,10 @@ where I: Stream<Item = char, Position = IndentablePosition>,
|
|||
},
|
||||
(Ok(int_val), Some(nums)) => {
|
||||
let decimal_str: String = nums.into_iter().collect();
|
||||
// calculate numerator and denominator
|
||||
// e.g. 123.45 == 12345 / 100
|
||||
let denom = (10 as i64).pow(decimal_str.len() as u32);
|
||||
|
||||
match decimal_str.parse::<u32>() {
|
||||
Ok(decimal) => {
|
||||
// Only the numerator may ever be signed!
|
||||
let numerator = (int_val * denom) + (decimal as i64);
|
||||
|
||||
value(Expr::Frac(numerator, denom)).right()
|
||||
match format!("{}.{}", int_str, decimal_str).parse::<f64>() {
|
||||
Ok(float) => {
|
||||
value(Expr::Float(float)).right()
|
||||
},
|
||||
Err(_) => {
|
||||
unexpected_any("non-digit characters after decimal point in a number literal").left()
|
||||
|
@ -1087,27 +1010,17 @@ where I: Stream<Item = char, Position = IndentablePosition>,
|
|||
match ( int_str.parse::<i64>(), decimals ) {
|
||||
(Ok(int_val), None) => {
|
||||
if is_positive {
|
||||
value(Pattern::Integer(int_val as i64)).right()
|
||||
value(Pattern::IntLiteral(int_val as i64)).right()
|
||||
} else {
|
||||
value(Pattern::Integer(-int_val as i64)).right()
|
||||
value(Pattern::IntLiteral(-int_val as i64)).right()
|
||||
}
|
||||
},
|
||||
(Ok(int_val), Some(nums)) => {
|
||||
let decimal_str: String = nums.into_iter().collect();
|
||||
// calculate numerator and denominator
|
||||
// e.g. 123.45 == 12345 / 100
|
||||
let denom = (10 as i64).pow(decimal_str.len() as u32);
|
||||
|
||||
match decimal_str.parse::<u32>() {
|
||||
Ok(decimal) => {
|
||||
// Only the numerator may ever be signed.
|
||||
let numerator = (int_val * denom) + (decimal as i64);
|
||||
|
||||
if is_positive {
|
||||
value(Pattern::Fraction(numerator, denom)).right()
|
||||
} else {
|
||||
value(Pattern::Fraction(-numerator, denom)).right()
|
||||
}
|
||||
match format!("{}.{}", int_str, decimal_str).parse::<f64>() {
|
||||
Ok(float) => {
|
||||
value(Pattern::FloatLiteral(float)).right()
|
||||
},
|
||||
Err(_) => {
|
||||
unexpected_any("non-digit characters after decimal point in a number literal").left()
|
||||
|
|
|
@ -22,7 +22,7 @@ use types::Type::{self, *};
|
|||
type Env = ImMap<Symbol, Variable>;
|
||||
|
||||
pub fn solve(env: &Env, subs: &mut Subs, constraint: Constraint) {
|
||||
println!("\nSolving:\n\n\t{:?}\n\n", constraint);
|
||||
// println!("\nSolving:\n\n\t{:?}\n\n", constraint);
|
||||
match constraint {
|
||||
True => (),
|
||||
Eq(typ, expected_type, region) => {
|
||||
|
|
|
@ -151,6 +151,6 @@ pub enum FlatType {
|
|||
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
|
||||
pub enum Builtin {
|
||||
Str, Int, Frac, Approx,
|
||||
Str, Int, Float,
|
||||
EmptyRecord,
|
||||
}
|
||||
|
|
|
@ -75,7 +75,8 @@ pub enum Reason {
|
|||
NamedFnCall(String /* function name */, u8 /* arity */),
|
||||
OperatorArg(Operator, ArgSide),
|
||||
OperatorRet(Operator),
|
||||
FractionalLiteral,
|
||||
FloatLiteral,
|
||||
IntLiteral,
|
||||
InterpolatedStringVar,
|
||||
ElemInList,
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ pub fn unify(subs: &mut Subs, left: &Descriptor, right: &Descriptor) -> Descript
|
|||
}
|
||||
};
|
||||
|
||||
println!("\nUnifying:\n\n\t{:?}\n\n\t{:?}\n\n\t-----\n\n\t{:?}\n\n", left.content, right.content, answer.content);
|
||||
// println!("\nUnifying:\n\n\t{:?}\n\n\t{:?}\n\n\t-----\n\n\t{:?}\n\n", left.content, right.content, answer.content);
|
||||
|
||||
answer
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ pub fn zero_loc_expr(expr: Expr) -> Expr {
|
|||
use roc::expr::Expr::*;
|
||||
|
||||
match expr {
|
||||
Int(_) | Frac(_, _) | Approx(_) | EmptyStr | Str(_) | Char(_) | Var(_) | EmptyRecord | EmptyList => expr,
|
||||
Int(_) | Float(_) | EmptyStr | Str(_) | Char(_) | Var(_) | EmptyRecord | EmptyList => expr,
|
||||
InterpolatedStr(pairs, string) => InterpolatedStr(pairs.into_iter().map(|( prefix, ident )| ( prefix, zero_loc(ident))).collect(), string),
|
||||
List(elems) => {
|
||||
let zeroed_elems =
|
||||
|
@ -78,7 +78,7 @@ pub fn zero_loc_pattern(loc_pattern: Located<Pattern>) -> Located<Pattern> {
|
|||
let pattern = loc_pattern.value;
|
||||
|
||||
match pattern {
|
||||
Identifier(_) | Integer(_) | Fraction(_, _) | ExactString(_) | EmptyRecordLiteral | Underscore => loc(pattern),
|
||||
Identifier(_) | IntLiteral(_) | FloatLiteral(_) | ExactString(_) | EmptyRecordLiteral | Underscore => loc(pattern),
|
||||
Variant(loc_name, None) =>
|
||||
loc(Variant(loc(loc_name.value), None)),
|
||||
Variant(loc_name, Some(opt_located_patterns)) =>
|
||||
|
|
|
@ -74,12 +74,12 @@ mod test_infer {
|
|||
|
||||
#[test]
|
||||
fn int_literal() {
|
||||
infer_eq("5", "Num.Num *");
|
||||
infer_eq("5", "Int");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fractional_literal() {
|
||||
infer_eq("0.5", "Num.Num (Num.Fractional *)");
|
||||
infer_eq("0.5", "Float");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -112,7 +112,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
[]
|
||||
"#),
|
||||
"List.List *"
|
||||
"List *"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
[[]]
|
||||
"#),
|
||||
"List.List (List.List *)"
|
||||
"List (List *)"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
[[[]]]
|
||||
"#),
|
||||
"List.List (List.List (List.List *))"
|
||||
"List (List (List *))"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -142,47 +142,47 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
[ [], [ [] ] ]
|
||||
"#),
|
||||
"List.List (List.List (List.List *))"
|
||||
"List (List (List *))"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_of_one_num() {
|
||||
fn list_of_one_int() {
|
||||
infer_eq(
|
||||
indoc!(r#"
|
||||
[42]
|
||||
"#),
|
||||
"List.List (Num.Num *)"
|
||||
"List Int"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn triple_nested_num_list() {
|
||||
fn triple_nested_int_list() {
|
||||
infer_eq(
|
||||
indoc!(r#"
|
||||
[[[ 5 ]]]
|
||||
"#),
|
||||
"List.List (List.List (List.List (Num.Num *)))"
|
||||
"List (List (List Int))"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_of_nums() {
|
||||
fn list_of_ints() {
|
||||
infer_eq(
|
||||
indoc!(r#"
|
||||
[ 1, 2, 3 ]
|
||||
"#),
|
||||
"List.List (Num.Num *)"
|
||||
"List Int"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_list_of_nums() {
|
||||
fn nested_list_of_ints() {
|
||||
infer_eq(
|
||||
indoc!(r#"
|
||||
[ [ 1 ], [ 2, 3 ] ]
|
||||
"#),
|
||||
"List.List (List.List (Num.Num *))"
|
||||
"List (List Int)"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
[ "cowabunga" ]
|
||||
"#),
|
||||
"List.List String.String"
|
||||
"List String.String"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
[[[ "foo" ]]]
|
||||
"#),
|
||||
"List.List (List.List (List.List String.String))"
|
||||
"List (List (List String.String))"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
[ "foo", "bar" ]
|
||||
"#),
|
||||
"List.List String.String"
|
||||
"List String.String"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
[ "foo", 5 ]
|
||||
"#),
|
||||
"List.List <type mismatch>"
|
||||
"List <type mismatch>"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
[ [ "foo", 5 ] ]
|
||||
"#),
|
||||
"List.List (List.List <type mismatch>)"
|
||||
"List (List <type mismatch>)"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
[ [ 1 ], [ [] ] ]
|
||||
"#),
|
||||
"List.List (List.List <type mismatch>)"
|
||||
"List (List <type mismatch>)"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -276,12 +276,12 @@ mod test_infer {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn two_arg_return_num() {
|
||||
fn two_arg_return_int() {
|
||||
infer_eq(
|
||||
indoc!(r#"
|
||||
\_ _ -> 42
|
||||
"#),
|
||||
"*, * -> Num.Num *"
|
||||
"*, * -> Int"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -341,7 +341,7 @@ mod test_infer {
|
|||
|
||||
func
|
||||
"#),
|
||||
"*, * -> Num.Num *"
|
||||
"*, * -> Int"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ mod test_infer {
|
|||
|
||||
c
|
||||
"#),
|
||||
"Num.Num *"
|
||||
"Int"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ mod test_infer {
|
|||
|
||||
alwaysFive "stuff"
|
||||
"#),
|
||||
"Num.Num *"
|
||||
"Int"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -423,7 +423,7 @@ mod test_infer {
|
|||
|
||||
enlist 5
|
||||
"#),
|
||||
"List.List (Num.Num *)"
|
||||
"List Int"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -474,7 +474,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
\l r -> l / r
|
||||
"#),
|
||||
"Num.Num Float.FloatingPoint, Num.Num Float.FloatingPoint -> Num.Num Float.FloatingPoint"
|
||||
"Float, Float -> Float"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -484,7 +484,7 @@ mod test_infer {
|
|||
indoc!(r#"
|
||||
1 / 2
|
||||
"#),
|
||||
"Num.Num Float.FloatingPoint"
|
||||
"Float"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -494,7 +494,7 @@ mod test_infer {
|
|||
// indoc!(r#"
|
||||
// 1 + 2
|
||||
// "#),
|
||||
// "Num.Num *"
|
||||
// "Num *"
|
||||
// );
|
||||
// }
|
||||
|
||||
|
|
|
@ -295,18 +295,14 @@ mod test_parse {
|
|||
|
||||
// // NUMBER LITERALS
|
||||
|
||||
fn expect_parsed_approx<'a>(expected: f64, actual: &str) {
|
||||
assert_eq!(Ok((Approx(expected), "".to_string())), parse_without_loc(actual));
|
||||
fn expect_parsed_float<'a>(expected: f64, actual: &str) {
|
||||
assert_eq!(Ok((Float(expected), "".to_string())), parse_without_loc(actual));
|
||||
}
|
||||
|
||||
fn expect_parsed_int<'a>(expected: i64, actual: &str) {
|
||||
assert_eq!(Ok((Int(expected), "".to_string())), parse_without_loc(actual));
|
||||
}
|
||||
|
||||
fn expect_parsed_ratio<'a>(expected_numerator: i64, expected_denominator: i64, actual: &str) {
|
||||
assert_eq!(Ok((Frac(expected_numerator, expected_denominator), "".to_string())), parse_without_loc(actual));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positive_int() {
|
||||
expect_parsed_int(1234, "1234");
|
||||
|
@ -318,25 +314,15 @@ mod test_parse {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn positive_approx() {
|
||||
expect_parsed_approx(123.4, "~123.4");
|
||||
fn positive_float() {
|
||||
expect_parsed_float(123.45, "123.45");
|
||||
expect_parsed_float(42.00, "42.00");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn negative_approx() {
|
||||
expect_parsed_approx(-123.4, "~-123.4");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positive_frac() {
|
||||
expect_parsed_ratio(12345, 100, "123.45");
|
||||
expect_parsed_ratio(4200, 100, "42.00");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn negative_ratio() {
|
||||
expect_parsed_ratio(-1234567, 1000, "-1234.567");
|
||||
expect_parsed_ratio(-1920, 10, "-192.0");
|
||||
fn negative_float() {
|
||||
expect_parsed_float(-1234.567, "-1234.567");
|
||||
expect_parsed_float(-192.0, "-192.0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -347,10 +333,10 @@ mod test_parse {
|
|||
|
||||
#[test]
|
||||
fn fracs_with_spaces() {
|
||||
expect_parsed_ratio(-1234567, 1000, "-1_23_4.567");
|
||||
expect_parsed_ratio(-1920, 10, "-19_2.0");
|
||||
expect_parsed_ratio(12345, 100, "1_2_3.45");
|
||||
expect_parsed_ratio(4200, 100, "4_2.00");
|
||||
expect_parsed_float(-1234.567, "-1_23_4.567");
|
||||
expect_parsed_float(-192.0, "-19_2.0");
|
||||
expect_parsed_float(123.45, "1_2_3.45");
|
||||
expect_parsed_float(42.00, "4_2.00");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -910,7 +896,7 @@ mod test_parse {
|
|||
Case(
|
||||
loc_box(Int(1)),
|
||||
vec![
|
||||
( loc(Integer(2)), loc(Int(3)) ),
|
||||
( loc(IntLiteral(2)), loc(Int(3)) ),
|
||||
]
|
||||
),
|
||||
"".to_string()
|
||||
|
@ -958,8 +944,8 @@ mod test_parse {
|
|||
Case(
|
||||
loc_box(Int(0)),
|
||||
vec![
|
||||
( loc(Integer(2)), loc(call_by_name("foo", vec![loc(Int(9))])) ),
|
||||
( loc(Integer(1)), loc(call_by_name("bar", vec![loc(Int(8))])) ),
|
||||
( loc(IntLiteral(2)), loc(call_by_name("foo", vec![loc(Int(9))])) ),
|
||||
( loc(IntLiteral(1)), loc(call_by_name("bar", vec![loc(Int(8))])) ),
|
||||
]
|
||||
),
|
||||
"".to_string()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue