mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
WIP
This commit is contained in:
parent
165c5d8363
commit
845e30658e
4 changed files with 176 additions and 48 deletions
|
@ -486,14 +486,74 @@ pub fn build_expr<'a, 'ctx, 'env>(
|
||||||
.build_extract_value(struct_val, index, "field_access")
|
.build_extract_value(struct_val, index, "field_access")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
AccessAtIndex { index, expr, .. } => {
|
AccessAtIndex {
|
||||||
|
index,
|
||||||
|
expr,
|
||||||
|
field_layouts,
|
||||||
|
} => {
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
|
||||||
|
let ptr_size = env.pointer_bytes;
|
||||||
|
|
||||||
|
// Determine types
|
||||||
|
// assume the descriminant is in the field layouts
|
||||||
|
let num_fields = field_layouts.len();
|
||||||
|
let mut field_types = Vec::with_capacity_in(num_fields, env.arena);
|
||||||
|
|
||||||
|
for field_layout in field_layouts.iter() {
|
||||||
|
let field_type = basic_type_from_layout(env.arena, env.context, &field_layout);
|
||||||
|
field_types.push(field_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the struct_type
|
||||||
|
let struct_type = env
|
||||||
|
.context
|
||||||
|
.struct_type(field_types.into_bump_slice(), false);
|
||||||
|
|
||||||
// Get Struct val
|
// Get Struct val
|
||||||
let struct_val = build_expr(env, &scope, parent, expr, procs).into_struct_value();
|
|
||||||
|
// we have an array of bytes, representing the structure
|
||||||
|
// let raw_bytes = build_expr(env, &scope, parent, expr, procs);
|
||||||
|
|
||||||
|
// here I'm faking the input, to make sure that the problem is here, and not
|
||||||
|
// in storing a tag in memory. stores the tag and an integer value
|
||||||
|
let array_type = env.context.i8_type().array_type(9);
|
||||||
|
let const_1: BasicValueEnum = env.context.i8_type().const_int(1, true).into();
|
||||||
|
let mut zeroes = array_type.const_zero();
|
||||||
|
|
||||||
|
// setting the first bit will toggle between Ok and Err
|
||||||
|
zeroes = builder
|
||||||
|
.build_insert_value(zeroes, const_1, 0, "")
|
||||||
|
.unwrap()
|
||||||
|
.into_array_value();
|
||||||
|
|
||||||
|
let bytes = BasicValueEnum::ArrayValue(zeroes);
|
||||||
|
|
||||||
|
// we make a pointer to the structure we want, but it will pretend
|
||||||
|
// (with the bitcast) to be a pointer to an array of bytes
|
||||||
|
let struct_pointer = builder.build_alloca(array_type, "");
|
||||||
|
|
||||||
|
builder.build_store(struct_pointer, bytes);
|
||||||
|
|
||||||
|
let argument = builder
|
||||||
|
.build_load(
|
||||||
|
builder
|
||||||
|
.build_bitcast(
|
||||||
|
struct_pointer,
|
||||||
|
struct_type.ptr_type(inkwell::AddressSpace::Generic),
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
.into_pointer_value(),
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
.into_struct_value();
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.build_extract_value(struct_val, *index as u32, "tag_field_access")
|
.build_extract_value(
|
||||||
|
argument,
|
||||||
|
*index as u32,
|
||||||
|
env.arena.alloc(format!("tag_field_access_{}_", index)),
|
||||||
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -77,6 +77,7 @@ mod test_gen {
|
||||||
// Populate Procs and Subs, and get the low-level Expr from the canonical Expr
|
// Populate Procs and Subs, and get the low-level Expr from the canonical Expr
|
||||||
let mono_expr = Expr::new(&arena, &mut subs, loc_expr.value, &mut procs, home, &mut ident_ids, POINTER_SIZE);
|
let mono_expr = Expr::new(&arena, &mut subs, loc_expr.value, &mut procs, home, &mut ident_ids, POINTER_SIZE);
|
||||||
|
|
||||||
|
dbg!(&mono_expr);
|
||||||
|
|
||||||
// Put this module's ident_ids back in the interns
|
// Put this module's ident_ids back in the interns
|
||||||
env.interns.all_ident_ids.insert(home, ident_ids);
|
env.interns.all_ident_ids.insert(home, ident_ids);
|
||||||
|
@ -148,7 +149,7 @@ mod test_gen {
|
||||||
builder.finalize();
|
builder.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.define_function(main_fn, &mut ctx).expect("declare main");
|
module.define_function(main_fn, &mut ctx).expect("crane declare main");
|
||||||
module.clear_context(&mut ctx);
|
module.clear_context(&mut ctx);
|
||||||
|
|
||||||
// Perform linking
|
// Perform linking
|
||||||
|
@ -278,7 +279,7 @@ mod test_gen {
|
||||||
builder.build_return(Some(&ret));
|
builder.build_return(Some(&ret));
|
||||||
|
|
||||||
// Uncomment this to see the module's un-optimized LLVM instruction output:
|
// Uncomment this to see the module's un-optimized LLVM instruction output:
|
||||||
// env.module.print_to_stderr();
|
env.module.print_to_stderr();
|
||||||
|
|
||||||
if main_fn.verify(true) {
|
if main_fn.verify(true) {
|
||||||
fpm.run_on(&main_fn);
|
fpm.run_on(&main_fn);
|
||||||
|
@ -1181,56 +1182,114 @@ mod test_gen {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
// #[test]
|
||||||
fn applied_tag_nothing() {
|
// fn applied_tag_nothing() {
|
||||||
assert_evals_to!(
|
// assert_evals_to!(
|
||||||
indoc!(
|
// indoc!(
|
||||||
r#"
|
// r#"
|
||||||
Maybe a : [ Just a, Nothing ]
|
// Maybe a : [ Just a, Nothing ]
|
||||||
|
//
|
||||||
|
// x : Maybe Int
|
||||||
|
// x = Nothing
|
||||||
|
//
|
||||||
|
// 0x1
|
||||||
|
// "#
|
||||||
|
// ),
|
||||||
|
// 1,
|
||||||
|
// i64
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// #[test]
|
||||||
|
// fn applied_tag_just() {
|
||||||
|
// assert_evals_to!(
|
||||||
|
// indoc!(
|
||||||
|
// r#"
|
||||||
|
// Maybe a : [ Just a, Nothing ]
|
||||||
|
//
|
||||||
|
// y : Maybe Int
|
||||||
|
// y = Just 0x4
|
||||||
|
//
|
||||||
|
// 0x1
|
||||||
|
// "#
|
||||||
|
// ),
|
||||||
|
// 1,
|
||||||
|
// i64
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// #[test]
|
||||||
|
// fn applied_tag_just_unit() {
|
||||||
|
// assert_evals_to!(
|
||||||
|
// indoc!(
|
||||||
|
// r#"
|
||||||
|
// Fruit : [ Orange, Apple, Banana ]
|
||||||
|
// Maybe a : [ Just a, Nothing ]
|
||||||
|
//
|
||||||
|
// orange : Fruit
|
||||||
|
// orange = Orange
|
||||||
|
//
|
||||||
|
// y : Maybe Fruit
|
||||||
|
// y = Just orange
|
||||||
|
//
|
||||||
|
// 0x1
|
||||||
|
// "#
|
||||||
|
// ),
|
||||||
|
// 1,
|
||||||
|
// i64
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
x : Maybe Int
|
// #[test]
|
||||||
x = Nothing
|
// fn when_on_nothing() {
|
||||||
|
// assert_evals_to!(
|
||||||
0x1
|
// indoc!(
|
||||||
"#
|
// r#"
|
||||||
),
|
// x : [ Nothing, Just Int ]
|
||||||
1,
|
// x = Nothing
|
||||||
i64
|
//
|
||||||
);
|
// when x is
|
||||||
}
|
// Nothing -> 0x0
|
||||||
|
// Just _ -> 0x1
|
||||||
#[test]
|
// "#
|
||||||
fn applied_tag_just() {
|
// ),
|
||||||
assert_evals_to!(
|
// 0,
|
||||||
indoc!(
|
// i64
|
||||||
r#"
|
// );
|
||||||
Maybe a : [ Just a, Nothing ]
|
// }
|
||||||
|
|
||||||
y : Maybe Int
|
|
||||||
y = Just 0x4
|
|
||||||
|
|
||||||
0x1
|
|
||||||
"#
|
|
||||||
),
|
|
||||||
1,
|
|
||||||
i64
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn when_on_just() {
|
||||||
|
// assert_evals_to!(
|
||||||
|
// indoc!(
|
||||||
|
// r#"
|
||||||
|
// x : [ Nothing, Just Int ]
|
||||||
|
// x = Just 42
|
||||||
|
//
|
||||||
|
// case x of
|
||||||
|
// Just v -> v
|
||||||
|
// Nothing -> 0x1
|
||||||
|
// "#
|
||||||
|
// ),
|
||||||
|
// 42,
|
||||||
|
// i64
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn when_on_result() {
|
// fn when_on_result() {
|
||||||
// assert_evals_to!(
|
// assert_evals_to!(
|
||||||
// indoc!(
|
// indoc!(
|
||||||
// r#"
|
// r#"
|
||||||
// x : Result Int Int
|
// x : Result Int Int
|
||||||
// x = Ok 42
|
// x = Err (41 + 1)
|
||||||
//
|
//
|
||||||
// when x is
|
// when x is
|
||||||
// Err _ -> 4
|
// Err _ -> 42 + 0x0
|
||||||
// Ok _ -> 0
|
// Ok v -> v
|
||||||
// "#
|
// "#
|
||||||
// ),
|
// ),
|
||||||
// 0,
|
// 42,
|
||||||
// i64
|
// i64
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -735,12 +735,17 @@ fn decide_to_branching<'a>(
|
||||||
match test {
|
match test {
|
||||||
Test::IsCtor { tag_id, .. } => {
|
Test::IsCtor { tag_id, .. } => {
|
||||||
let lhs = Expr::Byte(tag_id);
|
let lhs = Expr::Byte(tag_id);
|
||||||
let rhs = path_to_expr(
|
|
||||||
env,
|
let field_layouts = env.arena.alloc([
|
||||||
cond_symbol,
|
|
||||||
&path,
|
|
||||||
Layout::Builtin(Builtin::Byte(MutMap::default())),
|
Layout::Builtin(Builtin::Byte(MutMap::default())),
|
||||||
);
|
Layout::Builtin(Builtin::Int64),
|
||||||
|
]);
|
||||||
|
let rhs = Expr::AccessAtIndex {
|
||||||
|
index: 0,
|
||||||
|
field_layouts,
|
||||||
|
expr: env.arena.alloc(Expr::Load(cond_symbol)),
|
||||||
|
};
|
||||||
|
// let rhs = Expr::Byte(tag_id);
|
||||||
let fake = MutMap::default();
|
let fake = MutMap::default();
|
||||||
|
|
||||||
let cond = env.arena.alloc(Expr::CallByName(
|
let cond = env.arena.alloc(Expr::CallByName(
|
||||||
|
|
|
@ -897,6 +897,10 @@ fn store_pattern2<'a>(
|
||||||
|
|
||||||
let mut arg_layouts = Vec::with_capacity_in(arguments.len(), env.arena);
|
let mut arg_layouts = Vec::with_capacity_in(arguments.len(), env.arena);
|
||||||
|
|
||||||
|
if is_unwrapped != 0 {
|
||||||
|
arg_layouts.push(Layout::Builtin(Builtin::Byte(MutMap::default())));
|
||||||
|
}
|
||||||
|
|
||||||
for (_, layout) in arguments {
|
for (_, layout) in arguments {
|
||||||
arg_layouts.push(layout.clone());
|
arg_layouts.push(layout.clone());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue