feat: add new Data type to prelude and allow it to unify with any user defined type

This commit is contained in:
rvcas 2022-11-14 14:42:10 -05:00 committed by Lucas
parent 123e729137
commit 3f952cdf0e
2 changed files with 52 additions and 12 deletions

View File

@ -13,13 +13,14 @@ use crate::{
IdGenerator,
};
const BYTE_ARRAY: &str = "ByteArray";
const BOOL: &str = "Bool";
const INT: &str = "Int";
const LIST: &str = "List";
const NIL: &str = "Nil";
const RESULT: &str = "Result";
const STRING: &str = "String";
pub const BYTE_ARRAY: &str = "ByteArray";
pub const BOOL: &str = "Bool";
pub const INT: &str = "Int";
pub const DATA: &str = "Data";
pub const LIST: &str = "List";
pub const NIL: &str = "Nil";
pub const RESULT: &str = "Result";
pub const STRING: &str = "String";
/// Build a prelude that can be injected
/// into a compiler pipeline
@ -46,6 +47,18 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo {
},
);
// Data
prelude.types.insert(
DATA.to_string(),
TypeConstructor {
parameters: vec![],
tipo: data(),
location: Span::empty(),
module: "".to_string(),
public: true,
},
);
// ByteArray
prelude.types.insert(
BYTE_ARRAY.to_string(),
@ -372,14 +385,12 @@ pub fn from_default_function(
DefaultFunction::UnIData => None,
DefaultFunction::UnBData => None,
DefaultFunction::EqualsData => {
let arg = generic_var(id_gen.next());
let tipo = function(vec![arg.clone(), arg], bool());
let tipo = function(vec![data(), data()], bool());
Some((tipo, 1))
}
DefaultFunction::SerialiseData => {
let tipo = function(vec![generic_var(id_gen.next())], byte_array());
let tipo = function(vec![data()], byte_array());
Some((tipo, 1))
}
@ -412,6 +423,15 @@ pub fn int() -> Arc<Type> {
})
}
pub fn data() -> Arc<Type> {
Arc::new(Type::App {
public: true,
name: DATA.to_string(),
module: "".to_string(),
args: vec![],
})
}
pub fn byte_array() -> Arc<Type> {
Arc::new(Type::App {
args: vec![],

View File

@ -12,7 +12,7 @@ use crate::{
RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition,
UnqualifiedImport, UntypedDefinition, Use, PIPE_VARIABLE,
},
builtins::{function, generic_var, unbound_var},
builtins::{self, function, generic_var, unbound_var},
tipo::fields::FieldMap,
IdGenerator,
};
@ -29,6 +29,14 @@ pub struct ScopeResetData {
local_values: HashMap<String, ValueConstructor>,
}
const EXCLUDE_DATA_UNIFY: [&str; 5] = [
builtins::INT,
builtins::BYTE_ARRAY,
builtins::STRING,
builtins::BOOL,
builtins::LIST,
];
#[derive(Debug)]
pub struct Environment<'a> {
/// Accessors defined in the current module
@ -1099,6 +1107,18 @@ impl<'a> Environment<'a> {
return Ok(());
}
if let (Type::App { name: name1, .. }, Type::App { name: name2, .. }) =
(t1.deref(), t2.deref())
{
if name1 == "Data" && !EXCLUDE_DATA_UNIFY.contains(&name2.as_str()) {
return Ok(());
}
if name2 == "Data" && !EXCLUDE_DATA_UNIFY.contains(&name1.as_str()) {
return Ok(());
}
}
// Collapse right hand side type links. Left hand side will be collapsed in the next block.
if let Type::Var { tipo } = t2.deref() {
if let TypeVar::Link { tipo } = tipo.borrow().deref() {