1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
use arret_syntax::datum::Datum; use crate::ty; use crate::ty::Ty; pub fn ty_ref_for_datum<M: ty::Pm>(datum: &Datum) -> ty::Ref<M> { (match datum { Datum::Bool(_, val) => Ty::LitBool(*val), Datum::Sym(_, val) => Ty::LitSym(val.clone()), Datum::Char(_, _) => Ty::Char, Datum::Int(_, _) => Ty::Int, Datum::Float(_, _) => Ty::Float, Datum::Str(_, _) => Ty::Str, Datum::List(_, vs) => { ty::List::new_tuple(vs.iter().map(|datum| ty_ref_for_datum(datum)).collect()).into() } Datum::Vector(_, vs) => Ty::Vector(vs.iter().map(|v| ty_ref_for_datum(v)).collect()), Datum::Set(_, vs) => { let unified_type = ty::unify::unify_ty_ref_iter(vs.iter().map(|v| ty_ref_for_datum(v))); Ty::Set(Box::new(unified_type)) } Datum::Map(_, vs) => { let unified_key = ty::unify::unify_ty_ref_iter(vs.iter().map(|(k, _)| ty_ref_for_datum(k))); let unified_value = ty::unify::unify_ty_ref_iter(vs.iter().map(|(_, v)| ty_ref_for_datum(v))); ty::Map::new(unified_key, unified_value).into() } }) .into() } #[cfg(test)] mod test { use super::*; use crate::hir::poly_for_str; fn assert_poly_for_str(ty_str: &str, datum_str: &str) { use arret_syntax::parser::datum_from_str; let datum = datum_from_str(None, datum_str).unwrap(); assert_eq!(poly_for_str(ty_str), ty_ref_for_datum(&datum)); } #[test] fn trivial_types() { assert_poly_for_str("Int", "1"); assert_poly_for_str("Int", "-51"); assert_poly_for_str("Char", "\\newline"); assert_poly_for_str("Str", r#""Test string""#); } #[test] fn bool_literal() { assert_poly_for_str("true", "true"); assert_poly_for_str("false", "false"); } #[test] fn sym_literal() { assert_poly_for_str("'foo", "foo"); } #[test] fn fixed_list() { assert_poly_for_str("()", "()"); assert_poly_for_str("(List Int Int 'foo)", "(1 2 foo)"); } #[test] fn fixed_vec() { assert_poly_for_str("[]", "[]"); assert_poly_for_str("(Vector false Int 'foo)", "[false 2 foo]"); } #[test] fn fixed_set() { assert_poly_for_str("(Setof (RawU))", "#{}"); assert_poly_for_str("(Setof Bool)", "#{true false}"); } #[test] fn fixed_map() { assert_poly_for_str("(Map (RawU) (RawU))", "{}"); assert_poly_for_str("(Map Bool (RawU Int 'foo))", "{true 1, false foo}"); } }