Str.concat tests and definition set up

This commit is contained in:
Chad Stearns 2020-08-15 02:45:52 -04:00
parent 27b2d10b2a
commit a81504720b
7 changed files with 68 additions and 2 deletions

View file

@ -431,6 +431,12 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
// Str module
// Str.concat : Str, Str -> Str
add_type(
Symbol::STR_CONCAT,
SolvedType::Func(vec![str_type(), str_type()], Box::new(str_type())),
);
// isEmpty : Str -> Bool
add_type(
Symbol::STR_ISEMPTY,

View file

@ -1043,8 +1043,8 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
unique_function(vec![str_type(star1)], bool_type(star2))
});
// append : Attr * Str, Attr * Str -> Attr * Str
add_type(Symbol::STR_APPEND, {
// Str.concat : Attr * Str, Attr * Str -> Attr * Str
add_type(Symbol::STR_CONCAT, {
let_tvars! { star1, star2, star3 };
unique_function(vec![str_type(star1), str_type(star2)], str_type(star3))
});

View file

@ -50,6 +50,7 @@ pub fn builtin_defs(var_store: &mut VarStore) -> MutMap<Symbol, Def> {
Symbol::BOOL_AND => bool_and,
Symbol::BOOL_OR => bool_or,
Symbol::BOOL_NOT => bool_not,
Symbol::STR_CONCAT => str_concat,
Symbol::LIST_LEN => list_len,
Symbol::LIST_GET => list_get,
Symbol::LIST_SET => list_set,
@ -619,6 +620,25 @@ fn list_reverse(symbol: Symbol, var_store: &mut VarStore) -> Def {
)
}
/// Str.concat : Str, Str -> Str
fn str_concat(symbol: Symbol, var_store: &mut VarStore) -> Def {
let str_var = var_store.fresh();
let body = RunLowLevel {
op: LowLevel::StrConcat,
args: vec![(str_var, Var(Symbol::ARG_1)), (str_var, Var(Symbol::ARG_2))],
ret_var: str_var,
};
defn(
symbol,
vec![(str_var, Symbol::ARG_1), (str_var, Symbol::ARG_2)],
var_store,
body,
str_var,
)
}
/// List.concat : List elem, List elem -> List elem
fn list_concat(symbol: Symbol, var_store: &mut VarStore) -> Def {
let list_var = var_store.fresh();

View file

@ -1560,6 +1560,16 @@ fn run_low_level<'a, 'ctx, 'env>(
use LowLevel::*;
match op {
StrConcat => {
// Str.concat : Str, Str -> Str
debug_assert_eq!(args.len(), 2);
let first_str = load_symbol(env, scope, &args[0]);
let second_str = load_symbol(env, scope, &args[1]);
str_concat(env, first_str, second_str)
}
ListLen => {
// List.len : List * -> Int
debug_assert_eq!(args.len(), 1);
@ -1785,6 +1795,14 @@ fn run_low_level<'a, 'ctx, 'env>(
}
}
fn str_concat<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
first_str: BasicValueEnum<'ctx>,
second_str: BasicValueEnum<'ctx>,
) -> BasicValueEnum<'ctx> {
first_str
}
fn build_int_binop<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
lhs: IntValue<'ctx>,

View file

@ -0,0 +1,20 @@
#[macro_use]
extern crate pretty_assertions;
#[macro_use]
extern crate indoc;
extern crate bumpalo;
extern crate inkwell;
extern crate libc;
extern crate roc_gen;
#[macro_use]
mod helpers;
#[cfg(test)]
mod gen_str {
#[test]
fn str_concat() {
assert_evals_to!("Str.concat \"a\" \"b\"", "abc", &'static str);
}
}

View file

@ -3,6 +3,7 @@
/// into an Expr when added directly by can::builtins
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum LowLevel {
StrConcat,
ListLen,
ListGetUnsafe,
ListSet,

View file

@ -652,6 +652,7 @@ define_builtins! {
1 STR_AT_STR: "@Str" // the Str.@Str private tag
2 STR_ISEMPTY: "isEmpty"
3 STR_APPEND: "append"
4 STR_CONCAT: "concat"
}
4 LIST: "List" => {
0 LIST_LIST: "List" imported // the List.List type alias