Glue code working

This commit is contained in:
Joshua Hoeflich 2021-08-08 11:06:10 -05:00
parent 0ca85a54fe
commit 4231b340ee
11 changed files with 251 additions and 2 deletions

View file

@ -63,6 +63,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
STR_COUNT_GRAPHEMES => str_count_graphemes,
STR_FROM_INT => str_from_int,
STR_FROM_UTF8 => str_from_utf8,
STR_FROM_UTF8_RANGE => str_from_utf8_range,
STR_TO_BYTES => str_to_bytes,
STR_FROM_FLOAT=> str_from_float,
LIST_LEN => list_len,
@ -1352,7 +1353,7 @@ fn str_from_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
)
}
/// Str.fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8Problem ]*
/// Str.fromUtf8 : List U8 -> Result Str [ BadUtf8 { byteIndex : Nat, problem : Utf8Problem } } ]*
fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
let bytes_var = var_store.fresh();
let bool_var = var_store.fresh();
@ -1455,6 +1456,111 @@ fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
ret_var,
)
}
/// Str.fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [ BadUtf8 { byteIndex : Nat, problem : Utf8Problem } } ]*
fn str_from_utf8_range(symbol: Symbol, var_store: &mut VarStore) -> Def {
let bytes_var = var_store.fresh();
let bool_var = var_store.fresh();
let arg_record_var = var_store.fresh();
let ll_record_var = var_store.fresh();
let ret_var = var_store.fresh();
// 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_3)),
loc_expr: no_region(RunLowLevel {
op: LowLevel::StrFromUtf8Range,
args: vec![(bytes_var, Var(Symbol::ARG_1)), (arg_record_var, Var(Symbol::ARG_2))],
ret_var: ll_record_var,
}),
expr_var: ll_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: ll_record_var,
ext_var: var_store.fresh(),
field: "c_isOk".into(),
field_var: var_store.fresh(),
loc_expr: Box::new(no_region(Var(Symbol::ARG_3))),
},
),
// all is good
no_region(tag(
"Ok",
// arg_2.a -> Str
vec![Access {
record_var: ll_record_var,
ext_var: var_store.fresh(),
field: "b_str".into(),
field_var: var_store.fresh(),
loc_expr: Box::new(no_region(Var(Symbol::ARG_3))),
}],
var_store,
)),
)],
final_else: Box::new(
// bad!!
no_region(tag(
"Err",
vec![tag(
"BadUtf8",
vec![
Access {
record_var: ll_record_var,
ext_var: var_store.fresh(),
field: "d_problem".into(),
field_var: var_store.fresh(),
loc_expr: Box::new(no_region(Var(Symbol::ARG_3))),
},
Access {
record_var: ll_record_var,
ext_var: var_store.fresh(),
field: "a_byteIndex".into(),
field_var: var_store.fresh(),
loc_expr: Box::new(no_region(Var(Symbol::ARG_3))),
},
],
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), (arg_record_var, Symbol::ARG_2)],
var_store,
body,
ret_var,
)
}
/// Str.toBytes : Str -> List U8
fn str_to_bytes(symbol: Symbol, var_store: &mut VarStore) -> Def {