mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
compiling again
This commit is contained in:
parent
b716636db0
commit
c85cee3bc0
4 changed files with 370 additions and 128 deletions
|
@ -237,6 +237,7 @@ pub fn build_expr<'a, 'ctx, 'env>(
|
||||||
default_branch: (default_stores, default_expr),
|
default_branch: (default_stores, default_expr),
|
||||||
ret_layout,
|
ret_layout,
|
||||||
cond_layout,
|
cond_layout,
|
||||||
|
cond_symbol: _,
|
||||||
} => {
|
} => {
|
||||||
let ret_type =
|
let ret_type =
|
||||||
basic_type_from_layout(env.arena, env.context, &ret_layout, env.ptr_bytes);
|
basic_type_from_layout(env.arena, env.context, &ret_layout, env.ptr_bytes);
|
||||||
|
@ -346,6 +347,7 @@ pub fn build_expr<'a, 'ctx, 'env>(
|
||||||
.left()
|
.left()
|
||||||
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
|
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
|
||||||
}
|
}
|
||||||
|
LoadWithoutIncrement(_symbol) => todo!("implement load without increment"),
|
||||||
Load(symbol) => load_symbol(env, scope, symbol),
|
Load(symbol) => load_symbol(env, scope, symbol),
|
||||||
Str(str_literal) => {
|
Str(str_literal) => {
|
||||||
if str_literal.is_empty() {
|
if str_literal.is_empty() {
|
||||||
|
@ -718,8 +720,10 @@ pub fn build_expr<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
RunLowLevel(op, args) => run_low_level(env, layout_ids, scope, parent, *op, args),
|
RunLowLevel(op, args) => run_low_level(env, layout_ids, scope, parent, *op, args),
|
||||||
|
|
||||||
IncBefore(_, expr) => build_expr(env, layout_ids, scope, parent, expr),
|
|
||||||
DecAfter(_, expr) => build_expr(env, layout_ids, scope, parent, expr),
|
DecAfter(_, expr) => build_expr(env, layout_ids, scope, parent, expr),
|
||||||
|
|
||||||
|
Reuse(_, expr) => build_expr(env, layout_ids, scope, parent, expr),
|
||||||
|
Reset(_, expr) => build_expr(env, layout_ids, scope, parent, expr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1194,6 +1194,7 @@ fn decide_to_branching<'a>(
|
||||||
Expr::Switch {
|
Expr::Switch {
|
||||||
cond: env.arena.alloc(cond),
|
cond: env.arena.alloc(cond),
|
||||||
cond_layout,
|
cond_layout,
|
||||||
|
cond_symbol,
|
||||||
branches: branches.into_bump_slice(),
|
branches: branches.into_bump_slice(),
|
||||||
default_branch,
|
default_branch,
|
||||||
ret_layout,
|
ret_layout,
|
||||||
|
|
|
@ -288,6 +288,10 @@ pub enum Expr<'a> {
|
||||||
Load(Symbol),
|
Load(Symbol),
|
||||||
Store(&'a [(Symbol, Layout<'a>, Expr<'a>)], &'a Expr<'a>),
|
Store(&'a [(Symbol, Layout<'a>, Expr<'a>)], &'a Expr<'a>),
|
||||||
|
|
||||||
|
/// RC instructions
|
||||||
|
LoadWithoutIncrement(Symbol),
|
||||||
|
DecAfter(Symbol, &'a Expr<'a>),
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
FunctionPointer(Symbol, Layout<'a>),
|
FunctionPointer(Symbol, Layout<'a>),
|
||||||
RuntimeErrorFunction(&'a str),
|
RuntimeErrorFunction(&'a str),
|
||||||
|
@ -323,6 +327,7 @@ pub enum Expr<'a> {
|
||||||
/// This *must* be an integer, because Switch potentially compiles to a jump table.
|
/// This *must* be an integer, because Switch potentially compiles to a jump table.
|
||||||
cond: &'a Expr<'a>,
|
cond: &'a Expr<'a>,
|
||||||
cond_layout: Layout<'a>,
|
cond_layout: Layout<'a>,
|
||||||
|
cond_symbol: Symbol,
|
||||||
/// The u64 in the tuple will be compared directly to the condition Expr.
|
/// The u64 in the tuple will be compared directly to the condition Expr.
|
||||||
/// If they are equal, this branch will be taken.
|
/// If they are equal, this branch will be taken.
|
||||||
branches: &'a [(u64, Stores<'a>, Expr<'a>)],
|
branches: &'a [(u64, Stores<'a>, Expr<'a>)],
|
||||||
|
@ -352,13 +357,100 @@ pub enum Expr<'a> {
|
||||||
},
|
},
|
||||||
EmptyArray,
|
EmptyArray,
|
||||||
|
|
||||||
/// RC instructions
|
/// Reset/Reuse
|
||||||
IncBefore(Symbol, &'a Expr<'a>),
|
|
||||||
DecAfter(Symbol, &'a Expr<'a>),
|
/// Re-use Symbol in Expr
|
||||||
|
Reuse(Symbol, &'a Expr<'a>),
|
||||||
|
Reset(Symbol, &'a Expr<'a>),
|
||||||
|
|
||||||
RuntimeError(&'a str),
|
RuntimeError(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn function_r<'a>(env: &mut Env<'a, '_>, body: &'a Expr<'a>) -> &'a Expr<'a> {
|
||||||
|
use Expr::*;
|
||||||
|
|
||||||
|
match body {
|
||||||
|
Switch {
|
||||||
|
cond_symbol,
|
||||||
|
branches,
|
||||||
|
cond,
|
||||||
|
cond_layout,
|
||||||
|
default_branch,
|
||||||
|
ret_layout,
|
||||||
|
} => {
|
||||||
|
let stack_size = cond_layout.stack_size(env.pointer_size);
|
||||||
|
let mut new_branches = Vec::with_capacity_in(branches.len(), env.arena);
|
||||||
|
|
||||||
|
for (tag, stores, branch) in branches.iter() {
|
||||||
|
let new_branch = function_d(env, *cond_symbol, stack_size as _, branch);
|
||||||
|
|
||||||
|
new_branches.push((*tag, *stores, new_branch));
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_default_branch = (
|
||||||
|
default_branch.0,
|
||||||
|
&*env.arena.alloc(function_d(
|
||||||
|
env,
|
||||||
|
*cond_symbol,
|
||||||
|
stack_size as _,
|
||||||
|
default_branch.1,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
env.arena.alloc(Switch {
|
||||||
|
cond_symbol: *cond_symbol,
|
||||||
|
branches: new_branches.into_bump_slice(),
|
||||||
|
default_branch: new_default_branch,
|
||||||
|
ret_layout: ret_layout.clone(),
|
||||||
|
cond: *cond,
|
||||||
|
cond_layout: cond_layout.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Store(stores, body) => {
|
||||||
|
let new_body = function_r(env, body);
|
||||||
|
|
||||||
|
env.arena.alloc(Store(stores, new_body))
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => body,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn function_d<'a>(
|
||||||
|
env: &mut Env<'a, '_>,
|
||||||
|
z: Symbol,
|
||||||
|
stack_size: usize,
|
||||||
|
body: &'a Expr<'a>,
|
||||||
|
) -> Expr<'a> {
|
||||||
|
if let Some(reused) = function_s(env, z, stack_size, body) {
|
||||||
|
Expr::Reset(z, env.arena.alloc(reused))
|
||||||
|
} else {
|
||||||
|
body.clone()
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
match body {
|
||||||
|
Expr::Tag { .. } => Some(env.arena.alloc(Expr::Reuse(w, body))),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
fn function_s<'a>(
|
||||||
|
env: &mut Env<'a, '_>,
|
||||||
|
w: Symbol,
|
||||||
|
stack_size: usize,
|
||||||
|
body: &'a Expr<'a>,
|
||||||
|
) -> Option<&'a Expr<'a>> {
|
||||||
|
match body {
|
||||||
|
Expr::Tag { tag_layout, .. }
|
||||||
|
if tag_layout.stack_size(env.pointer_size) as usize <= stack_size =>
|
||||||
|
{
|
||||||
|
Some(env.arena.alloc(Expr::Reuse(w, body)))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum MonoProblem {
|
pub enum MonoProblem {
|
||||||
PatternProblem(crate::pattern::Error),
|
PatternProblem(crate::pattern::Error),
|
||||||
|
@ -373,7 +465,8 @@ impl<'a> Expr<'a> {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut layout_cache = LayoutCache::default();
|
let mut layout_cache = LayoutCache::default();
|
||||||
|
|
||||||
from_can(env, can_expr, procs, &mut layout_cache)
|
let result = from_can(env, can_expr, procs, &mut layout_cache);
|
||||||
|
function_r(env, env.arena.alloc(result)).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,6 +663,15 @@ fn pattern_to_when<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn decrement_refcount<'a>(env: &mut Env<'a, '_>, symbol: Symbol, expr: Expr<'a>) -> Expr<'a> {
|
||||||
|
// TODO are there any builtins that should be refcounted?
|
||||||
|
if symbol.is_builtin() {
|
||||||
|
expr
|
||||||
|
} else {
|
||||||
|
Expr::DecAfter(symbol, env.arena.alloc(expr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
fn from_can<'a>(
|
fn from_can<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
|
@ -604,7 +706,8 @@ fn from_can<'a>(
|
||||||
layout_cache,
|
layout_cache,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Expr::IncBefore(symbol, env.arena.alloc(Expr::Load(symbol)))
|
// NOTE Load will always increment the refcount
|
||||||
|
Expr::Load(symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LetRec(defs, ret_expr, _, _) => from_can_defs(env, defs, *ret_expr, layout_cache, procs),
|
LetRec(defs, ret_expr, _, _) => from_can_defs(env, defs, *ret_expr, layout_cache, procs),
|
||||||
|
@ -614,7 +717,7 @@ fn from_can<'a>(
|
||||||
|
|
||||||
// TODO is order important here?
|
// TODO is order important here?
|
||||||
for symbol in symbols {
|
for symbol in symbols {
|
||||||
result = Expr::DecAfter(symbol, env.arena.alloc(result));
|
result = decrement_refcount(env, symbol, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
|
@ -699,17 +802,35 @@ fn from_can<'a>(
|
||||||
region,
|
region,
|
||||||
loc_cond,
|
loc_cond,
|
||||||
branches,
|
branches,
|
||||||
} => from_can_when(
|
} => {
|
||||||
env,
|
let cond_symbol = if let roc_can::expr::Expr::Var(symbol) = loc_cond.value {
|
||||||
cond_var,
|
symbol
|
||||||
expr_var,
|
} else {
|
||||||
region,
|
env.unique_symbol()
|
||||||
*loc_cond,
|
};
|
||||||
branches,
|
|
||||||
layout_cache,
|
|
||||||
procs,
|
|
||||||
),
|
|
||||||
|
|
||||||
|
let mono_when = from_can_when(
|
||||||
|
env,
|
||||||
|
cond_var,
|
||||||
|
expr_var,
|
||||||
|
region,
|
||||||
|
cond_symbol,
|
||||||
|
branches,
|
||||||
|
layout_cache,
|
||||||
|
procs,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mono_cond = from_can(env, loc_cond.value, procs, layout_cache);
|
||||||
|
|
||||||
|
let cond_layout = layout_cache
|
||||||
|
.from_var(env.arena, cond_var, env.subs, env.pointer_size)
|
||||||
|
.expect("invalid cond_layout");
|
||||||
|
|
||||||
|
Expr::Store(
|
||||||
|
env.arena.alloc([(cond_symbol, cond_layout, mono_cond)]),
|
||||||
|
env.arena.alloc(mono_when),
|
||||||
|
)
|
||||||
|
}
|
||||||
If {
|
If {
|
||||||
cond_var,
|
cond_var,
|
||||||
branch_var,
|
branch_var,
|
||||||
|
@ -1203,7 +1324,7 @@ fn from_can_when<'a>(
|
||||||
cond_var: Variable,
|
cond_var: Variable,
|
||||||
expr_var: Variable,
|
expr_var: Variable,
|
||||||
region: Region,
|
region: Region,
|
||||||
loc_cond: Located<roc_can::expr::Expr>,
|
cond_symbol: Symbol,
|
||||||
mut branches: std::vec::Vec<roc_can::expr::WhenBranch>,
|
mut branches: std::vec::Vec<roc_can::expr::WhenBranch>,
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
procs: &mut Procs<'a>,
|
procs: &mut Procs<'a>,
|
||||||
|
@ -1260,9 +1381,6 @@ fn from_can_when<'a>(
|
||||||
let cond_layout = layout_cache
|
let cond_layout = layout_cache
|
||||||
.from_var(env.arena, cond_var, env.subs, env.pointer_size)
|
.from_var(env.arena, cond_var, env.subs, env.pointer_size)
|
||||||
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
||||||
let cond_symbol = env.unique_symbol();
|
|
||||||
let cond = from_can(env, loc_cond.value, procs, layout_cache);
|
|
||||||
stored.push((cond_symbol, cond_layout.clone(), cond));
|
|
||||||
|
|
||||||
// NOTE this will still store shadowed names.
|
// NOTE this will still store shadowed names.
|
||||||
// that's fine: the branch throws a runtime error anyway
|
// that's fine: the branch throws a runtime error anyway
|
||||||
|
@ -1273,7 +1391,7 @@ fn from_can_when<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
for symbol in bound_symbols {
|
for symbol in bound_symbols {
|
||||||
ret = Expr::DecAfter(symbol, env.arena.alloc(ret));
|
ret = decrement_refcount(env, symbol, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr::Store(stored.into_bump_slice(), arena.alloc(ret))
|
Expr::Store(stored.into_bump_slice(), arena.alloc(ret))
|
||||||
|
@ -1282,9 +1400,6 @@ fn from_can_when<'a>(
|
||||||
.from_var(env.arena, cond_var, env.subs, env.pointer_size)
|
.from_var(env.arena, cond_var, env.subs, env.pointer_size)
|
||||||
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
let cond = from_can(env, loc_cond.value, procs, layout_cache);
|
|
||||||
let cond_symbol = env.unique_symbol();
|
|
||||||
|
|
||||||
let mut loc_branches = std::vec::Vec::new();
|
let mut loc_branches = std::vec::Vec::new();
|
||||||
let mut opt_branches = std::vec::Vec::new();
|
let mut opt_branches = std::vec::Vec::new();
|
||||||
|
|
||||||
|
@ -1406,17 +1521,13 @@ fn from_can_when<'a>(
|
||||||
.from_var(env.arena, expr_var, env.subs, env.pointer_size)
|
.from_var(env.arena, expr_var, env.subs, env.pointer_size)
|
||||||
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
let branching = crate::decision_tree::optimize_when(
|
crate::decision_tree::optimize_when(
|
||||||
env,
|
env,
|
||||||
cond_symbol,
|
cond_symbol,
|
||||||
cond_layout.clone(),
|
cond_layout.clone(),
|
||||||
ret_layout,
|
ret_layout,
|
||||||
opt_branches,
|
opt_branches,
|
||||||
);
|
)
|
||||||
|
|
||||||
let stores = env.arena.alloc([(cond_symbol, cond_layout, cond)]);
|
|
||||||
|
|
||||||
Expr::Store(stores, env.arena.alloc(branching))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1640,7 +1751,7 @@ fn specialize<'a>(
|
||||||
|
|
||||||
// TODO does order matter here?
|
// TODO does order matter here?
|
||||||
for &symbol in pattern_symbols.iter() {
|
for &symbol in pattern_symbols.iter() {
|
||||||
specialized_body = Expr::DecAfter(symbol, env.arena.alloc(specialized_body));
|
specialized_body = decrement_refcount(env, symbol, specialized_body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset subs, so we don't get type errors when specializing for a different signature
|
// reset subs, so we don't get type errors when specializing for a different signature
|
||||||
|
|
|
@ -11,6 +11,7 @@ mod helpers;
|
||||||
mod test_mono {
|
mod test_mono {
|
||||||
use crate::helpers::{can_expr, infer_expr, test_home, CanExprOut};
|
use crate::helpers::{can_expr, infer_expr, test_home, CanExprOut};
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
use roc_module::ident::TagName;
|
||||||
use roc_module::symbol::{Interns, Symbol};
|
use roc_module::symbol::{Interns, Symbol};
|
||||||
use roc_mono::expr::Expr::{self, *};
|
use roc_mono::expr::Expr::{self, *};
|
||||||
use roc_mono::expr::Procs;
|
use roc_mono::expr::Procs;
|
||||||
|
@ -166,30 +167,33 @@ mod test_mono {
|
||||||
let home = test_home();
|
let home = test_home();
|
||||||
let gen_symbol_0 = Interns::from_index(home, 0);
|
let gen_symbol_0 = Interns::from_index(home, 0);
|
||||||
|
|
||||||
Struct(&[
|
DecAfter(
|
||||||
(
|
gen_symbol_0,
|
||||||
CallByName {
|
&Struct(&[
|
||||||
name: gen_symbol_0,
|
(
|
||||||
layout: Layout::FunctionPointer(
|
CallByName {
|
||||||
&[Layout::Builtin(Builtin::Int64)],
|
name: gen_symbol_0,
|
||||||
&Layout::Builtin(Builtin::Int64),
|
layout: Layout::FunctionPointer(
|
||||||
),
|
&[Layout::Builtin(Builtin::Int64)],
|
||||||
args: &[(Int(4), Layout::Builtin(Int64))],
|
&Layout::Builtin(Builtin::Int64),
|
||||||
},
|
),
|
||||||
Layout::Builtin(Int64),
|
args: &[(Int(4), Layout::Builtin(Int64))],
|
||||||
),
|
},
|
||||||
(
|
Layout::Builtin(Int64),
|
||||||
CallByName {
|
),
|
||||||
name: gen_symbol_0,
|
(
|
||||||
layout: Layout::FunctionPointer(
|
CallByName {
|
||||||
&[Layout::Builtin(Builtin::Float64)],
|
name: gen_symbol_0,
|
||||||
&Layout::Builtin(Builtin::Float64),
|
layout: Layout::FunctionPointer(
|
||||||
),
|
&[Layout::Builtin(Builtin::Float64)],
|
||||||
args: &[(Float(3.14), Layout::Builtin(Float64))],
|
&Layout::Builtin(Builtin::Float64),
|
||||||
},
|
),
|
||||||
Layout::Builtin(Float64),
|
args: &[(Float(3.14), Layout::Builtin(Float64))],
|
||||||
),
|
},
|
||||||
])
|
Layout::Builtin(Float64),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -299,27 +303,30 @@ mod test_mono {
|
||||||
let gen_symbol_0 = Interns::from_index(home, 1);
|
let gen_symbol_0 = Interns::from_index(home, 1);
|
||||||
let symbol_x = Interns::from_index(home, 0);
|
let symbol_x = Interns::from_index(home, 0);
|
||||||
|
|
||||||
Store(
|
DecAfter(
|
||||||
&[(
|
symbol_x,
|
||||||
symbol_x,
|
&Store(
|
||||||
Builtin(Str),
|
&[(
|
||||||
Store(
|
symbol_x,
|
||||||
&[(
|
Builtin(Str),
|
||||||
gen_symbol_0,
|
Store(
|
||||||
Layout::Builtin(layout::Builtin::Int1),
|
&[(
|
||||||
Expr::Bool(true),
|
gen_symbol_0,
|
||||||
)],
|
Layout::Builtin(layout::Builtin::Int1),
|
||||||
&Cond {
|
Expr::Bool(true),
|
||||||
cond_symbol: gen_symbol_0,
|
)],
|
||||||
branch_symbol: gen_symbol_0,
|
&Cond {
|
||||||
cond_layout: Builtin(Int1),
|
cond_symbol: gen_symbol_0,
|
||||||
pass: (&[] as &[_], &Expr::Str("bar")),
|
branch_symbol: gen_symbol_0,
|
||||||
fail: (&[] as &[_], &Expr::Str("foo")),
|
cond_layout: Builtin(Int1),
|
||||||
ret_layout: Builtin(Str),
|
pass: (&[] as &[_], &Expr::Str("bar")),
|
||||||
},
|
fail: (&[] as &[_], &Expr::Str("foo")),
|
||||||
),
|
ret_layout: Builtin(Str),
|
||||||
)],
|
},
|
||||||
&Load(symbol_x),
|
),
|
||||||
|
)],
|
||||||
|
&Load(symbol_x),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -359,27 +366,30 @@ mod test_mono {
|
||||||
let gen_symbol_0 = Interns::from_index(home, 0);
|
let gen_symbol_0 = Interns::from_index(home, 0);
|
||||||
let struct_layout = Layout::Struct(&[I64_LAYOUT, F64_LAYOUT]);
|
let struct_layout = Layout::Struct(&[I64_LAYOUT, F64_LAYOUT]);
|
||||||
|
|
||||||
CallByName {
|
DecAfter(
|
||||||
name: gen_symbol_0,
|
gen_symbol_0,
|
||||||
layout: Layout::FunctionPointer(
|
&CallByName {
|
||||||
&[struct_layout.clone()],
|
name: gen_symbol_0,
|
||||||
&struct_layout.clone(),
|
layout: Layout::FunctionPointer(
|
||||||
),
|
&[struct_layout.clone()],
|
||||||
args: &[(
|
&struct_layout.clone(),
|
||||||
Struct(&[
|
),
|
||||||
(
|
args: &[(
|
||||||
CallByName {
|
Struct(&[
|
||||||
name: gen_symbol_0,
|
(
|
||||||
layout: Layout::FunctionPointer(&[I64_LAYOUT], &I64_LAYOUT),
|
CallByName {
|
||||||
args: &[(Int(4), I64_LAYOUT)],
|
name: gen_symbol_0,
|
||||||
},
|
layout: Layout::FunctionPointer(&[I64_LAYOUT], &I64_LAYOUT),
|
||||||
I64_LAYOUT,
|
args: &[(Int(4), I64_LAYOUT)],
|
||||||
),
|
},
|
||||||
(Float(0.1), F64_LAYOUT),
|
I64_LAYOUT,
|
||||||
]),
|
),
|
||||||
struct_layout,
|
(Float(0.1), F64_LAYOUT),
|
||||||
)],
|
]),
|
||||||
}
|
struct_layout,
|
||||||
|
)],
|
||||||
|
},
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -493,7 +503,9 @@ mod test_mono {
|
||||||
|
|
||||||
let load = Load(var_x);
|
let load = Load(var_x);
|
||||||
|
|
||||||
Store(arena.alloc(stores), arena.alloc(load))
|
let store = Store(arena.alloc(stores), arena.alloc(load));
|
||||||
|
|
||||||
|
DecAfter(var_x, arena.alloc(store))
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -517,7 +529,9 @@ mod test_mono {
|
||||||
|
|
||||||
let load = Load(var_x);
|
let load = Load(var_x);
|
||||||
|
|
||||||
Store(arena.alloc(stores), arena.alloc(load))
|
let store = Store(arena.alloc(stores), arena.alloc(load));
|
||||||
|
|
||||||
|
DecAfter(var_x, arena.alloc(store))
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -543,7 +557,9 @@ mod test_mono {
|
||||||
|
|
||||||
let load = Load(var_x);
|
let load = Load(var_x);
|
||||||
|
|
||||||
Store(arena.alloc(stores), arena.alloc(load))
|
let store = Store(arena.alloc(stores), arena.alloc(load));
|
||||||
|
|
||||||
|
DecAfter(var_x, arena.alloc(store))
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -589,33 +605,143 @@ mod test_mono {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn when_on_result() {
|
// fn when_on_result() {
|
||||||
// compiles_to(
|
// compiles_to(
|
||||||
// r#"
|
// r#"
|
||||||
// when 1 is
|
// when 1 is
|
||||||
// 1 -> 12
|
// 1 -> 12
|
||||||
// _ -> 34
|
// _ -> 34
|
||||||
// "#,
|
// "#,
|
||||||
// {
|
// {
|
||||||
// use self::Builtin::*;
|
// use self::Builtin::*;
|
||||||
// use Layout::Builtin;
|
// use Layout::Builtin;
|
||||||
// let home = test_home();
|
// let home = test_home();
|
||||||
//
|
//
|
||||||
// let gen_symbol_3 = Interns::from_index(home, 3);
|
// let gen_symbol_3 = Interns::from_index(home, 3);
|
||||||
// let gen_symbol_4 = Interns::from_index(home, 4);
|
// let gen_symbol_4 = Interns::from_index(home, 4);
|
||||||
//
|
//
|
||||||
// CallByName(
|
// CallByName(
|
||||||
// gen_symbol_3,
|
// gen_symbol_3,
|
||||||
// &[(
|
// &[(
|
||||||
// Struct(&[(
|
// Struct(&[(
|
||||||
// CallByName(gen_symbol_4, &[(Int(4), Builtin(Int64))]),
|
// CallByName(gen_symbol_4, &[(Int(4), Builtin(Int64))]),
|
||||||
// Builtin(Int64),
|
// Builtin(Int64),
|
||||||
// )]),
|
// )]),
|
||||||
// Layout::Struct(&[("x".into(), Builtin(Int64))]),
|
// Layout::Struct(&[("x".into(), Builtin(Int64))]),
|
||||||
// )],
|
// )],
|
||||||
// )
|
// )
|
||||||
// },
|
// },
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn insert_reset_reuse() {
|
||||||
|
compiles_to(
|
||||||
|
r#"
|
||||||
|
when Foo 1 is
|
||||||
|
Foo _ -> Foo 1
|
||||||
|
Bar -> Foo 2
|
||||||
|
Baz -> Foo 2
|
||||||
|
a -> a
|
||||||
|
"#,
|
||||||
|
{
|
||||||
|
use self::Builtin::*;
|
||||||
|
use Layout::{Builtin, Union};
|
||||||
|
|
||||||
|
let home = test_home();
|
||||||
|
let gen_symbol_1 = Interns::from_index(home, 1);
|
||||||
|
|
||||||
|
let union_layout = Union(&[
|
||||||
|
&[Builtin(Int64)],
|
||||||
|
&[Builtin(Int64)],
|
||||||
|
&[Builtin(Int64), Builtin(Int64)],
|
||||||
|
]);
|
||||||
|
|
||||||
|
Store(
|
||||||
|
&[(
|
||||||
|
gen_symbol_1,
|
||||||
|
union_layout.clone(),
|
||||||
|
Tag {
|
||||||
|
tag_layout: union_layout.clone(),
|
||||||
|
tag_name: TagName::Global("Foo".into()),
|
||||||
|
tag_id: 2,
|
||||||
|
union_size: 3,
|
||||||
|
arguments: &[(Int(2), Builtin(Int64)), (Int(1), Builtin(Int64))],
|
||||||
|
},
|
||||||
|
)],
|
||||||
|
&Store(
|
||||||
|
&[],
|
||||||
|
&Switch {
|
||||||
|
cond: &Load(gen_symbol_1),
|
||||||
|
cond_symbol: gen_symbol_1,
|
||||||
|
branches: &[
|
||||||
|
(
|
||||||
|
2,
|
||||||
|
&[],
|
||||||
|
Reset(
|
||||||
|
gen_symbol_1,
|
||||||
|
&Reuse(
|
||||||
|
gen_symbol_1,
|
||||||
|
&Tag {
|
||||||
|
tag_layout: union_layout.clone(),
|
||||||
|
tag_name: TagName::Global("Foo".into()),
|
||||||
|
tag_id: 2,
|
||||||
|
union_size: 3,
|
||||||
|
arguments: &[
|
||||||
|
(Int(2), Builtin(Int64)),
|
||||||
|
(Int(1), Builtin(Int64)),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
&[],
|
||||||
|
Reset(
|
||||||
|
gen_symbol_1,
|
||||||
|
&Reuse(
|
||||||
|
gen_symbol_1,
|
||||||
|
&Tag {
|
||||||
|
tag_layout: union_layout.clone(),
|
||||||
|
tag_name: TagName::Global("Foo".into()),
|
||||||
|
tag_id: 2,
|
||||||
|
union_size: 3,
|
||||||
|
arguments: &[
|
||||||
|
(Int(2), Builtin(Int64)),
|
||||||
|
(Int(2), Builtin(Int64)),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
default_branch: (
|
||||||
|
&[],
|
||||||
|
&Reset(
|
||||||
|
gen_symbol_1,
|
||||||
|
&Reuse(
|
||||||
|
gen_symbol_1,
|
||||||
|
&Tag {
|
||||||
|
tag_layout: union_layout.clone(),
|
||||||
|
tag_name: TagName::Global("Foo".into()),
|
||||||
|
tag_id: 2,
|
||||||
|
union_size: 3,
|
||||||
|
arguments: &[
|
||||||
|
(Int(2), Builtin(Int64)),
|
||||||
|
(Int(2), Builtin(Int64)),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ret_layout: union_layout.clone(),
|
||||||
|
cond_layout: union_layout,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue