reimplement Result

This commit is contained in:
Folkert 2022-02-23 17:52:13 +01:00
parent 410426f059
commit d1d7cfef44
No known key found for this signature in database
GPG Key ID: 1F17F6FFD112B97C
7 changed files with 155 additions and 6 deletions

View File

@ -160,6 +160,53 @@ pub fn pre_constrain_imports(
});
}
None => {
if module_id == home {
continue;
}
if module_id == ModuleId::RESULT {
let region = Region::zero(); // TODO this should be the region where this symbol was declared in its home module. Look that up!
let loc_symbol = Loc {
value: symbol,
region,
};
match exposed_types.get(&module_id) {
Some(ExposedModuleTypes::Valid(solved_types, new_aliases)) => {
// If the exposed value was invalid (e.g. it didn't have
// a corresponding definition), it won't have an entry
// in solved_types
if let Some(solved_type) = solved_types.get(&symbol) {
// TODO should this be a union?
for (k, v) in new_aliases.clone() {
imported_aliases.insert(k, v);
}
imported_symbols.push(Import {
loc_symbol,
solved_type: solved_type.clone(),
});
}
}
Some(ExposedModuleTypes::Invalid) => {
// If that module was invalid, use True constraints
// for everything imported from it.
imported_symbols.push(Import {
loc_symbol,
solved_type: SolvedType::Erroneous(Problem::InvalidModule),
});
}
None => {
panic!(
"Could not find module {:?} in exposed_types {:?}",
module_id, exposed_types
);
}
}
continue;
}
let is_valid_alias = stdlib.applies.contains(&symbol)
// This wasn't a builtin value or Apply; maybe it was a builtin alias.
|| roc_types::builtin_aliases::aliases().contains_key(&symbol);

View File

@ -74,6 +74,8 @@ macro_rules! log {
($($arg:tt)*) => (if SHOW_MESSAGE_LOG { println!($($arg)*); } else {})
}
const BUILTIN_MODULES: &[(ModuleId, &[ModuleId])] = &[(ModuleId::RESULT, &[])];
/// Struct storing various intermediate stages by their ModuleId
#[derive(Debug, Default)]
struct ModuleCache<'a> {
@ -2259,8 +2261,105 @@ fn load_module<'a>(
arc_shorthands: Arc<Mutex<MutMap<&'a str, PackageName<'a>>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> {
use PackageQualified::*;
let module_start_time = SystemTime::now();
dbg!(&module_name);
match module_name.as_inner().as_str() {
"Result" => {
let parse_start = SystemTime::now();
let parse_header_duration = parse_start.elapsed().unwrap();
// Insert the first entries for this module's timings
let mut module_timing = ModuleTiming::new(module_start_time);
module_timing.read_roc_file = Default::default();
module_timing.parse_header = parse_header_duration;
let filename = PathBuf::from("Result.roc");
const EXPOSES: &[Loc<ExposedName>] = &[
Loc::at_zero(ExposedName::new("Result")),
Loc::at_zero(ExposedName::new("isOk")),
Loc::at_zero(ExposedName::new("isErr")),
Loc::at_zero(ExposedName::new("map")),
Loc::at_zero(ExposedName::new("mapErr")),
Loc::at_zero(ExposedName::new("after")),
Loc::at_zero(ExposedName::new("withDefault")),
];
let imports = &[];
let info = HeaderInfo {
loc_name: Loc {
region: Region::zero(),
value: ModuleNameEnum::Interface(roc_parse::header::ModuleName::new("Result")),
},
filename,
is_root_module: false,
opt_shorthand: None,
packages: &[],
exposes: &EXPOSES,
imports,
extra: HeaderFor::Interface,
};
let src_bytes = r#"
Result ok err : [ Ok ok, Err err ]
isOk : Result ok err -> Bool
isOk = \result ->
when result is
Ok _ -> True
Err _ -> False
isErr : Result ok err -> Bool
isErr = \result ->
when result is
Ok _ -> False
Err _ -> True
withDefault : Result ok err, ok -> ok
withDefault = \result, default ->
when result is
Ok value -> value
Err _ -> default
map : Result a err, (a -> b) -> Result b err
map = \result, transform ->
when result is
Ok v -> Ok (transform v)
Err e -> Err e
mapErr : Result ok a, (a -> b) -> Result ok b
mapErr = \result, transform ->
when result is
Ok v -> Ok v
Err e -> Err (transform e)
after : Result a err, (a -> Result b err) -> Result b err
after = \result, transform ->
when result is
Ok v -> transform v
Err e -> Err e
"#;
let parse_state = roc_parse::state::State::new(src_bytes.as_bytes());
return Ok(send_header(
info,
parse_state,
module_ids,
ident_ids_by_module,
module_timing,
));
}
_ => {
// fall through
}
}
let (filename, opt_shorthand) = module_name_to_path(src_dir, module_name, arc_shorthands);
load_filename(

View File

@ -1143,7 +1143,7 @@ define_builtins! {
57 LIST_SORT_DESC_COMPARE: "#sortDescCompare"
}
5 RESULT: "Result" => {
0 RESULT_RESULT: "Result" imported // the Result.Result type alias
0 RESULT_RESULT: "Result" // the Result.Result type alias
1 RESULT_OK: "Ok" imported // Result.Result a e = [ Ok a, Err e ]
// NB: not strictly needed; used for finding global tag names in error suggestions
2 RESULT_ERR: "Err" imported // Result.Result a e = [ Ok a, Err e ]

View File

@ -1108,7 +1108,8 @@ impl<'a, 'i> Env<'a, 'i> {
}
pub fn is_imported_symbol(&self, symbol: Symbol) -> bool {
symbol.module_id() != self.home && !symbol.is_builtin()
// symbol.module_id() != self.home && !symbol.is_builtin()
symbol.module_id() != self.home
}
}

View File

@ -88,7 +88,7 @@ impl<'a> From<ExposedName<'a>> for &'a str {
}
impl<'a> ExposedName<'a> {
pub fn new(name: &'a str) -> Self {
pub const fn new(name: &'a str) -> Self {
ExposedName(name)
}

View File

@ -279,16 +279,16 @@ pub struct Loc<T> {
}
impl<T> Loc<T> {
pub fn new(start: u32, end: u32, value: T) -> Loc<T> {
pub const fn new(start: u32, end: u32, value: T) -> Loc<T> {
let region = Region::new(Position::new(start), Position::new(end));
Loc { region, value }
}
pub fn at(region: Region, value: T) -> Loc<T> {
pub const fn at(region: Region, value: T) -> Loc<T> {
Loc { region, value }
}
pub fn at_zero(value: T) -> Loc<T> {
pub const fn at_zero(value: T) -> Loc<T> {
let region = Region::zero();
Loc { region, value }
}

View File

@ -319,6 +319,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
},
);
/*
// Result ok err : [ Ok ok, Err err ]
add_alias(
Symbol::RESULT_RESULT,
@ -331,6 +332,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
typ: result_alias_content(flex(TVAR1), flex(TVAR2)),
},
);
*/
// Utf8ByteProblem : [ InvalidStartByte, UnexpectedEndOfSequence, ExpectedContinuation, OverlongEncoding, CodepointTooLarge, EncodesSurrogateHalf ]
add_alias(