Finish first pass of Str.fromUtf8

This commit is contained in:
Jared Ramirez 2021-02-07 16:18:34 -08:00
parent 815f633a58
commit f3d9c2f2bb
12 changed files with 591 additions and 159 deletions

View file

@ -1379,20 +1379,104 @@ fn str_from_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
/// Str.fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8Problem ]*
fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
let bytes_var = var_store.fresh();
let str_var = var_store.fresh();
let bool_var = var_store.fresh();
let record_var = var_store.fresh();
let ret_var = var_store.fresh();
let body = RunLowLevel {
op: LowLevel::StrFromUtf8,
args: vec![(bytes_var, Var(Symbol::ARG_1))],
ret_var: str_var,
// let arg_2 = RunLowLevel FromUtf8 arg_1
//
// arg_2 :
// { a : Bool -- isOk
// , b : String -- result_str
// , c : Nat -- problem_byte_index
// , d : I8 -- problem_code
// }
//
// if arg_2.a then
// # all is well
// Ok arg_2.str
// else
// # problem
// Err (BadUtf8 { byteIndex: arg_2.byteIndex, problem : arg_2.problem })
let def = crate::def::Def {
loc_pattern: no_region(Pattern::Identifier(Symbol::ARG_2)),
loc_expr: no_region(RunLowLevel {
op: LowLevel::StrFromUtf8,
args: vec![(bytes_var, Var(Symbol::ARG_1))],
ret_var: record_var,
}),
expr_var: record_var,
pattern_vars: SendMap::default(),
annotation: None,
};
let cont = If {
branch_var: ret_var,
cond_var: bool_var,
branches: vec![(
// if-condition
no_region(
// arg_2.c -> Bool
Access {
record_var,
ext_var: var_store.fresh(),
field: "isOk".into(),
field_var: var_store.fresh(),
loc_expr: Box::new(no_region(Var(Symbol::ARG_2))),
},
),
// all is good
no_region(tag(
"Ok",
// arg_2.a -> Str
vec![Access {
record_var,
ext_var: var_store.fresh(),
field: "str".into(),
field_var: var_store.fresh(),
loc_expr: Box::new(no_region(Var(Symbol::ARG_2))),
}],
var_store,
)),
)],
final_else: Box::new(
// bad!!
no_region(tag(
"Err",
vec![tag(
"BadUtf8",
vec![
Access {
record_var,
ext_var: var_store.fresh(),
field: "problem".into(),
field_var: var_store.fresh(),
loc_expr: Box::new(no_region(Var(Symbol::ARG_2))),
},
Access {
record_var,
ext_var: var_store.fresh(),
field: "byteIndex".into(),
field_var: var_store.fresh(),
loc_expr: Box::new(no_region(Var(Symbol::ARG_2))),
},
],
var_store,
)],
var_store,
)),
),
};
let body = LetNonRec(Box::new(def), Box::new(no_region(cont)), ret_var);
defn(
symbol,
vec![(bytes_var, Symbol::ARG_1)],
var_store,
body,
str_var,
ret_var,
)
}
@ -2277,6 +2361,18 @@ fn tag(name: &'static str, args: Vec<Expr>, var_store: &mut VarStore) -> Expr {
}
}
// #[inline(always)]
// fn record(fields: Vec<(Lowercase, Field)>, var_store: &mut VarStore) -> Expr {
// let mut send_map = SendMap::default();
// for (k, v) in fields {
// send_map.insert(k, v);
// }
// Expr::Record {
// record_var: var_store.fresh(),
// fields: send_map,
// }
// }
#[inline(always)]
fn defn(
fn_name: Symbol,