expand aliases from the very beginning

This commit is contained in:
Folkert 2020-10-29 22:30:54 +01:00
parent a0c8915678
commit 2478ae05b1
2 changed files with 274 additions and 175 deletions

View File

@ -1,7 +1,11 @@
use roc_collections::all::{default_hasher, MutMap, MutSet};
use roc_module::ident::TagName;
use roc_module::symbol::Symbol;
use roc_region::all::{Located, Region};
use roc_region::all::Region;
use roc_types::builtin_aliases::{
bool_type, float_type, int_type, list_type, map_type, num_type, ordering_type, result_type,
set_type, str_type,
};
use roc_types::solved_types::{BuiltinAlias, SolvedType};
use roc_types::subs::VarId;
use std::collections::HashMap;
@ -24,7 +28,7 @@ pub fn standard_stdlib() -> StdLib {
StdLib {
mode: Mode::Standard,
types: types(),
aliases: aliases(),
aliases: roc_types::builtin_aliases::aliases(),
applies: vec![
Symbol::LIST_LIST,
Symbol::SET_SET,
@ -46,121 +50,11 @@ const TVAR3: VarId = VarId::from_u32(3);
const TVAR4: VarId = VarId::from_u32(4);
const TOP_LEVEL_CLOSURE_VAR: VarId = VarId::from_u32(5);
pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
let mut aliases = HashMap::with_capacity_and_hasher(NUM_BUILTIN_IMPORTS, default_hasher());
let mut add_alias = |symbol, alias| {
debug_assert!(
!aliases.contains_key(&symbol),
"Duplicate alias definition for {:?}",
symbol
);
// TODO instead of using Region::zero for all of these,
// instead use the Region where they were defined in their
// source .roc files! This can give nicer error messages.
aliases.insert(symbol, alias);
};
let single_private_tag = |symbol, targs| {
SolvedType::TagUnion(
vec![(TagName::Private(symbol), targs)],
Box::new(SolvedType::EmptyTagUnion),
)
};
// Num range : [ @Num range ]
add_alias(
Symbol::NUM_NUM,
BuiltinAlias {
region: Region::zero(),
vars: vec![Located::at(Region::zero(), "range".into())],
typ: single_private_tag(Symbol::NUM_AT_NUM, vec![flex(TVAR1)]),
},
);
// Integer : [ @Integer ]
add_alias(
Symbol::NUM_INTEGER,
BuiltinAlias {
region: Region::zero(),
vars: Vec::new(),
typ: single_private_tag(Symbol::NUM_AT_INTEGER, Vec::new()),
},
);
// Int : Num Integer
add_alias(
Symbol::NUM_INT,
BuiltinAlias {
region: Region::zero(),
vars: Vec::new(),
typ: SolvedType::Apply(
Symbol::NUM_NUM,
vec![SolvedType::Apply(Symbol::NUM_INTEGER, Vec::new())],
),
},
);
// FloatingPoint : [ @FloatingPoint ]
add_alias(
Symbol::NUM_FLOATINGPOINT,
BuiltinAlias {
region: Region::zero(),
vars: Vec::new(),
typ: single_private_tag(Symbol::NUM_AT_FLOATINGPOINT, Vec::new()),
},
);
// Float : Num FloatingPoint
add_alias(
Symbol::NUM_FLOAT,
BuiltinAlias {
region: Region::zero(),
vars: Vec::new(),
typ: SolvedType::Apply(
Symbol::NUM_NUM,
vec![SolvedType::Apply(Symbol::NUM_FLOATINGPOINT, Vec::new())],
),
},
);
// Bool : [ True, False ]
add_alias(
Symbol::BOOL_BOOL,
BuiltinAlias {
region: Region::zero(),
vars: Vec::new(),
typ: SolvedType::TagUnion(
vec![
(TagName::Global("True".into()), Vec::new()),
(TagName::Global("False".into()), Vec::new()),
],
Box::new(SolvedType::EmptyTagUnion),
),
},
);
// Result a e : [ Ok a, Err e ]
add_alias(
Symbol::RESULT_RESULT,
BuiltinAlias {
region: Region::zero(),
vars: vec![
Located::at(Region::zero(), "a".into()),
Located::at(Region::zero(), "e".into()),
],
typ: SolvedType::TagUnion(
vec![
(TagName::Global("Ok".into()), vec![flex(TVAR1)]),
(TagName::Global("Err".into()), vec![flex(TVAR2)]),
],
Box::new(SolvedType::EmptyTagUnion),
),
},
);
aliases
fn single_private_tag(symbol: Symbol, type_arguments: Vec<SolvedType>) -> SolvedType {
SolvedType::TagUnion(
vec![(TagName::Private(symbol), type_arguments)],
Box::new(SolvedType::EmptyTagUnion),
)
}
pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
@ -782,61 +676,3 @@ fn top_level_function(arguments: Vec<SolvedType>, ret: Box<SolvedType>) -> Solve
fn closure(arguments: Vec<SolvedType>, closure_var: VarId, ret: Box<SolvedType>) -> SolvedType {
SolvedType::Func(arguments, Box::new(SolvedType::Flex(closure_var)), ret)
}
#[inline(always)]
fn float_type() -> SolvedType {
SolvedType::Apply(Symbol::NUM_FLOAT, Vec::new())
}
#[inline(always)]
fn int_type() -> SolvedType {
SolvedType::Apply(Symbol::NUM_INT, Vec::new())
}
#[inline(always)]
fn bool_type() -> SolvedType {
SolvedType::Apply(Symbol::BOOL_BOOL, Vec::new())
}
#[inline(always)]
fn ordering_type() -> SolvedType {
// [ LT, EQ, GT ]
SolvedType::TagUnion(
vec![
(TagName::Global("GT".into()), vec![]),
(TagName::Global("EQ".into()), vec![]),
(TagName::Global("LT".into()), vec![]),
],
Box::new(SolvedType::EmptyTagUnion),
)
}
#[inline(always)]
fn str_type() -> SolvedType {
SolvedType::Apply(Symbol::STR_STR, Vec::new())
}
#[inline(always)]
fn num_type(a: SolvedType) -> SolvedType {
SolvedType::Apply(Symbol::NUM_NUM, vec![a])
}
#[inline(always)]
fn result_type(a: SolvedType, e: SolvedType) -> SolvedType {
SolvedType::Apply(Symbol::RESULT_RESULT, vec![a, e])
}
#[inline(always)]
fn list_type(a: SolvedType) -> SolvedType {
SolvedType::Apply(Symbol::LIST_LIST, vec![a])
}
#[inline(always)]
fn set_type(a: SolvedType) -> SolvedType {
SolvedType::Apply(Symbol::SET_SET, vec![a])
}
#[inline(always)]
fn map_type(key: SolvedType, value: SolvedType) -> SolvedType {
SolvedType::Apply(Symbol::MAP_MAP, vec![key, value])
}

View File

@ -0,0 +1,263 @@
use crate::solved_types::{BuiltinAlias, SolvedType};
use crate::subs::VarId;
use roc_collections::all::{default_hasher, MutMap};
use roc_module::ident::TagName;
use roc_module::symbol::Symbol;
use roc_region::all::{Located, Region};
use std::collections::HashMap;
const NUM_BUILTIN_IMPORTS: usize = 8;
/// These can be shared between definitions, they will get instantiated when converted to Type
const TVAR1: VarId = VarId::from_u32(1);
const TVAR2: VarId = VarId::from_u32(2);
pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
let mut aliases = HashMap::with_capacity_and_hasher(NUM_BUILTIN_IMPORTS, default_hasher());
let mut add_alias = |symbol, alias| {
debug_assert!(
!aliases.contains_key(&symbol),
"Duplicate alias definition for {:?}",
symbol
);
// TODO instead of using Region::zero for all of these,
// instead use the Region where they were defined in their
// source .roc files! This can give nicer error messages.
aliases.insert(symbol, alias);
};
// Num range : [ @Num range ]
add_alias(
Symbol::NUM_NUM,
BuiltinAlias {
region: Region::zero(),
vars: vec![Located::at(Region::zero(), "range".into())],
typ: num_alias_content(flex(TVAR1)),
},
);
// Integer : [ @Integer ]
add_alias(
Symbol::NUM_INTEGER,
BuiltinAlias {
region: Region::zero(),
vars: Vec::new(),
typ: integer_alias_content(),
},
);
// Int : Num Integer
add_alias(
Symbol::NUM_INT,
BuiltinAlias {
region: Region::zero(),
vars: Vec::new(),
typ: int_alias_content(),
},
);
// FloatingPoint : [ @FloatingPoint ]
add_alias(
Symbol::NUM_FLOATINGPOINT,
BuiltinAlias {
region: Region::zero(),
vars: Vec::new(),
typ: floatingpoint_alias_content(),
},
);
// Float : Num FloatingPoint
add_alias(
Symbol::NUM_FLOAT,
BuiltinAlias {
region: Region::zero(),
vars: Vec::new(),
typ: float_alias_content(),
},
);
// Bool : [ True, False ]
add_alias(
Symbol::BOOL_BOOL,
BuiltinAlias {
region: Region::zero(),
vars: Vec::new(),
typ: bool_alias_content(),
},
);
// Result a e : [ Ok a, Err e ]
add_alias(
Symbol::RESULT_RESULT,
BuiltinAlias {
region: Region::zero(),
vars: vec![
Located::at(Region::zero(), "ok".into()),
Located::at(Region::zero(), "err".into()),
],
typ: result_alias_content(flex(TVAR1), flex(TVAR2)),
},
);
aliases
}
#[inline(always)]
pub fn flex(tvar: VarId) -> SolvedType {
SolvedType::Flex(tvar)
}
#[inline(always)]
pub fn num_type(range: SolvedType) -> SolvedType {
SolvedType::Alias(
Symbol::NUM_NUM,
vec![("range".into(), range.clone())],
Box::new(num_alias_content(range)),
)
}
#[inline(always)]
fn num_alias_content(range: SolvedType) -> SolvedType {
single_private_tag(Symbol::NUM_AT_NUM, vec![range])
}
// FLOATING POINT
#[inline(always)]
pub fn floatingpoint_type() -> SolvedType {
SolvedType::Alias(
Symbol::NUM_FLOATINGPOINT,
Vec::new(),
Box::new(floatingpoint_alias_content()),
)
}
#[inline(always)]
fn floatingpoint_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_FLOATINGPOINT, Vec::new())
}
// FLOAT
#[inline(always)]
pub fn float_type() -> SolvedType {
SolvedType::Alias(
Symbol::NUM_FLOAT,
Vec::new(),
Box::new(float_alias_content()),
)
}
#[inline(always)]
fn float_alias_content() -> SolvedType {
num_type(floatingpoint_type())
}
// INT
#[inline(always)]
pub fn int_type() -> SolvedType {
SolvedType::Alias(Symbol::NUM_INT, Vec::new(), Box::new(int_alias_content()))
}
#[inline(always)]
fn int_alias_content() -> SolvedType {
num_type(integer_type())
}
// INTEGER
#[inline(always)]
pub fn integer_type() -> SolvedType {
SolvedType::Alias(
Symbol::NUM_INTEGER,
Vec::new(),
Box::new(integer_alias_content()),
)
}
#[inline(always)]
fn integer_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_INTEGER, Vec::new())
}
#[inline(always)]
pub fn bool_type() -> SolvedType {
SolvedType::Alias(
Symbol::BOOL_BOOL,
Vec::new(),
Box::new(bool_alias_content()),
)
}
fn bool_alias_content() -> SolvedType {
SolvedType::TagUnion(
vec![
(TagName::Global("False".into()), vec![]),
(TagName::Global("True".into()), vec![]),
],
Box::new(SolvedType::EmptyTagUnion),
)
}
#[inline(always)]
pub fn ordering_type() -> SolvedType {
// [ LT, EQ, GT ]
SolvedType::TagUnion(
vec![
(TagName::Global("GT".into()), vec![]),
(TagName::Global("EQ".into()), vec![]),
(TagName::Global("LT".into()), vec![]),
],
Box::new(SolvedType::EmptyTagUnion),
)
}
#[inline(always)]
pub fn result_type(a: SolvedType, e: SolvedType) -> SolvedType {
SolvedType::Alias(
Symbol::RESULT_RESULT,
vec![("ok".into(), a.clone()), ("err".into(), e.clone())],
Box::new(result_alias_content(a, e)),
)
}
#[inline(always)]
fn result_alias_content(a: SolvedType, e: SolvedType) -> SolvedType {
SolvedType::TagUnion(
vec![
(TagName::Global("Ok".into()), vec![a]),
(TagName::Global("Err".into()), vec![e]),
],
Box::new(SolvedType::EmptyTagUnion),
)
}
#[inline(always)]
pub fn list_type(a: SolvedType) -> SolvedType {
SolvedType::Apply(Symbol::LIST_LIST, vec![a])
}
#[inline(always)]
pub fn str_type() -> SolvedType {
SolvedType::Apply(Symbol::STR_STR, Vec::new())
}
#[inline(always)]
pub fn set_type(a: SolvedType) -> SolvedType {
SolvedType::Apply(Symbol::SET_SET, vec![a])
}
#[inline(always)]
pub fn map_type(key: SolvedType, value: SolvedType) -> SolvedType {
SolvedType::Apply(Symbol::MAP_MAP, vec![key, value])
}
fn single_private_tag(symbol: Symbol, type_arguments: Vec<SolvedType>) -> SolvedType {
SolvedType::TagUnion(
vec![(TagName::Private(symbol), type_arguments)],
Box::new(SolvedType::EmptyTagUnion),
)
}