mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
call changes in mono
This commit is contained in:
parent
6bc0cf33a5
commit
0893aa7369
5 changed files with 346 additions and 295 deletions
|
@ -334,14 +334,21 @@ impl<'a> BorrowInfState<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
FunctionCall {
|
||||
Call(crate::ir::Call {
|
||||
call_type,
|
||||
args,
|
||||
arg_layouts,
|
||||
..
|
||||
arguments,
|
||||
}) => {
|
||||
use crate::ir::CallType::*;
|
||||
|
||||
match call_type {
|
||||
ByName {
|
||||
name, arg_layouts, ..
|
||||
}
|
||||
| ByPointer {
|
||||
name, arg_layouts, ..
|
||||
} => {
|
||||
// get the borrow signature of the applied function
|
||||
let ps = match self.param_map.get_symbol(call_type.get_inner()) {
|
||||
let ps = match self.param_map.get_symbol(*name) {
|
||||
Some(slice) => slice,
|
||||
None => Vec::from_iter_in(
|
||||
arg_layouts.iter().cloned().map(|layout| Param {
|
||||
|
@ -358,19 +365,19 @@ impl<'a> BorrowInfState<'a> {
|
|||
self.own_var(z);
|
||||
|
||||
// if the function exects an owned argument (ps), the argument must be owned (args)
|
||||
self.own_args_using_params(args, ps);
|
||||
self.own_args_using_params(arguments, ps);
|
||||
}
|
||||
|
||||
RunLowLevel(op, args) => {
|
||||
LowLevel { op } => {
|
||||
// very unsure what demand RunLowLevel should place upon its arguments
|
||||
self.own_var(z);
|
||||
|
||||
let ps = lowlevel_borrow_signature(self.arena, *op);
|
||||
|
||||
self.own_args_using_bools(args, ps);
|
||||
self.own_args_using_bools(arguments, ps);
|
||||
}
|
||||
|
||||
ForeignCall { arguments, .. } => {
|
||||
Foreign { .. } => {
|
||||
// very unsure what demand ForeignCall should place upon its arguments
|
||||
self.own_var(z);
|
||||
|
||||
|
@ -378,30 +385,41 @@ impl<'a> BorrowInfState<'a> {
|
|||
|
||||
self.own_args_using_bools(arguments, ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Literal(_) | FunctionPointer(_, _) | RuntimeErrorFunction(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn preserve_tail_call(&mut self, x: Symbol, v: &Expr<'a>, b: &Stmt<'a>) {
|
||||
if let (
|
||||
Expr::FunctionCall {
|
||||
call_type,
|
||||
args: ys,
|
||||
match (v, b) {
|
||||
(
|
||||
Expr::Call(crate::ir::Call {
|
||||
call_type: crate::ir::CallType::ByName { name: g, .. },
|
||||
arguments: ys,
|
||||
..
|
||||
},
|
||||
}),
|
||||
Stmt::Ret(z),
|
||||
) = (v, b)
|
||||
{
|
||||
let g = call_type.get_inner();
|
||||
if self.current_proc == g && x == *z {
|
||||
)
|
||||
| (
|
||||
Expr::Call(crate::ir::Call {
|
||||
call_type: crate::ir::CallType::ByPointer { name: g, .. },
|
||||
arguments: ys,
|
||||
..
|
||||
}),
|
||||
Stmt::Ret(z),
|
||||
) => {
|
||||
if self.current_proc == *g && x == *z {
|
||||
// anonymous functions (for which the ps may not be known)
|
||||
// can never be tail-recursive, so this is fine
|
||||
if let Some(ps) = self.param_map.get_symbol(g) {
|
||||
if let Some(ps) = self.param_map.get_symbol(*g) {
|
||||
self.own_params_using_args(ys, ps)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_param_set(&mut self, ps: &[Param<'a>]) {
|
||||
|
|
|
@ -1277,7 +1277,10 @@ fn compile_test<'a>(
|
|||
ret_layout,
|
||||
);
|
||||
|
||||
let test = Expr::RunLowLevel(LowLevel::Eq, arena.alloc([lhs, rhs]));
|
||||
let test = Expr::Call(crate::ir::Call {
|
||||
call_type: crate::ir::CallType::LowLevel { op: LowLevel::Eq },
|
||||
arguments: arena.alloc([lhs, rhs]),
|
||||
});
|
||||
|
||||
// write to the test symbol
|
||||
cond = Stmt::Let(
|
||||
|
|
|
@ -88,10 +88,10 @@ pub fn occuring_variables_expr(expr: &Expr<'_>, result: &mut MutSet<Symbol>) {
|
|||
result.insert(*symbol);
|
||||
}
|
||||
|
||||
FunctionCall { args, .. } => {
|
||||
Call(crate::ir::Call { arguments, .. }) => {
|
||||
// NOTE thouth the function name does occur, it is a static constant in the program
|
||||
// for liveness, it should not be included here.
|
||||
result.extend(args.iter().copied());
|
||||
result.extend(arguments.iter().copied());
|
||||
}
|
||||
|
||||
Tag { arguments, .. }
|
||||
|
@ -110,12 +110,6 @@ pub fn occuring_variables_expr(expr: &Expr<'_>, result: &mut MutSet<Symbol>) {
|
|||
Reset(x) => {
|
||||
result.insert(*x);
|
||||
}
|
||||
RunLowLevel(_, args) => {
|
||||
result.extend(args.iter());
|
||||
}
|
||||
ForeignCall { arguments, .. } => {
|
||||
result.extend(arguments.iter());
|
||||
}
|
||||
|
||||
EmptyArray | RuntimeErrorFunction(_) | Literal(_) => {}
|
||||
}
|
||||
|
@ -447,28 +441,36 @@ impl<'a> Context<'a> {
|
|||
self.arena.alloc(Stmt::Let(z, v, l, b))
|
||||
}
|
||||
|
||||
RunLowLevel(op, args) => {
|
||||
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, op);
|
||||
let b = self.add_dec_after_lowlevel(args, ps, b, b_live_vars);
|
||||
Call(crate::ir::Call {
|
||||
ref call_type,
|
||||
arguments,
|
||||
}) => {
|
||||
use crate::ir::CallType::*;
|
||||
|
||||
self.arena.alloc(Stmt::Let(z, v, l, b))
|
||||
}
|
||||
|
||||
ForeignCall { arguments, .. } => {
|
||||
let ps = crate::borrow::foreign_borrow_signature(self.arena, arguments.len());
|
||||
match &call_type {
|
||||
LowLevel { op } => {
|
||||
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
|
||||
let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars);
|
||||
|
||||
self.arena.alloc(Stmt::Let(z, v, l, b))
|
||||
&*self.arena.alloc(Stmt::Let(z, v, l, b))
|
||||
}
|
||||
|
||||
FunctionCall {
|
||||
args: ys,
|
||||
arg_layouts,
|
||||
call_type,
|
||||
..
|
||||
Foreign { .. } => {
|
||||
let ps =
|
||||
crate::borrow::foreign_borrow_signature(self.arena, arguments.len());
|
||||
let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars);
|
||||
|
||||
&*self.arena.alloc(Stmt::Let(z, v, l, b))
|
||||
}
|
||||
|
||||
ByName {
|
||||
name, arg_layouts, ..
|
||||
}
|
||||
| ByPointer {
|
||||
name, arg_layouts, ..
|
||||
} => {
|
||||
// get the borrow signature
|
||||
let ps = match self.param_map.get_symbol(call_type.get_inner()) {
|
||||
let ps = match self.param_map.get_symbol(*name) {
|
||||
Some(slice) => slice,
|
||||
None => Vec::from_iter_in(
|
||||
arg_layouts.iter().cloned().map(|layout| Param {
|
||||
|
@ -481,10 +483,12 @@ impl<'a> Context<'a> {
|
|||
.into_bump_slice(),
|
||||
};
|
||||
|
||||
let b = self.add_dec_after_application(ys, ps, b, b_live_vars);
|
||||
let b = self.add_dec_after_application(arguments, ps, b, b_live_vars);
|
||||
let b = self.arena.alloc(Stmt::Let(z, v, l, b));
|
||||
|
||||
self.add_inc_before(ys, ps, b, b_live_vars)
|
||||
self.add_inc_before(arguments, ps, b, b_live_vars)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EmptyArray
|
||||
|
@ -510,7 +514,7 @@ impl<'a> Context<'a> {
|
|||
// is this value a constant?
|
||||
// TODO do function pointers also fall into this category?
|
||||
let persistent = match expr {
|
||||
Expr::FunctionCall { args, .. } => args.is_empty(),
|
||||
Expr::Call(crate::ir::Call { arguments, .. }) => arguments.is_empty(),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
|
|
@ -785,20 +785,6 @@ pub enum Literal<'a> {
|
|||
/// compile to bytes, e.g. [ Blue, Black, Red, Green, White ]
|
||||
Byte(u8),
|
||||
}
|
||||
#[derive(Clone, Debug, PartialEq, Copy)]
|
||||
pub enum CallType {
|
||||
ByName(Symbol),
|
||||
ByPointer(Symbol),
|
||||
}
|
||||
|
||||
impl CallType {
|
||||
pub fn get_inner(&self) -> Symbol {
|
||||
match self {
|
||||
CallType::ByName(s) => *s,
|
||||
CallType::ByPointer(s) => *s,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum Wrapped {
|
||||
|
@ -838,25 +824,98 @@ impl Wrapped {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Call<'a> {
|
||||
pub call_type: CallType<'a>,
|
||||
pub arguments: &'a [Symbol],
|
||||
}
|
||||
|
||||
impl<'a> Call<'a> {
|
||||
pub fn to_doc<'b, D, A>(&'b self, alloc: &'b D) -> DocBuilder<'b, D, A>
|
||||
where
|
||||
D: DocAllocator<'b, A>,
|
||||
D::Doc: Clone,
|
||||
A: Clone,
|
||||
{
|
||||
use CallType::*;
|
||||
|
||||
let arguments = self.arguments;
|
||||
|
||||
match self.call_type {
|
||||
CallType::ByName { name, .. } => {
|
||||
let it = std::iter::once(name)
|
||||
.chain(arguments.iter().copied())
|
||||
.map(|s| symbol_to_doc(alloc, s));
|
||||
|
||||
alloc.text("CallByName ").append(alloc.intersperse(it, " "))
|
||||
}
|
||||
CallType::ByPointer { name, .. } => {
|
||||
let it = std::iter::once(name)
|
||||
.chain(arguments.iter().copied())
|
||||
.map(|s| symbol_to_doc(alloc, s));
|
||||
|
||||
alloc
|
||||
.text("CallByPointer ")
|
||||
.append(alloc.intersperse(it, " "))
|
||||
}
|
||||
LowLevel { op: lowlevel } => {
|
||||
let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s));
|
||||
|
||||
alloc
|
||||
.text(format!("lowlevel {:?} ", lowlevel))
|
||||
.append(alloc.intersperse(it, " "))
|
||||
}
|
||||
Foreign {
|
||||
foreign_symbol: ref foreign_symbol,
|
||||
..
|
||||
} => {
|
||||
let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s));
|
||||
|
||||
alloc
|
||||
.text(format!("foreign {:?} ", foreign_symbol.as_str()))
|
||||
.append(alloc.intersperse(it, " "))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum CallType<'a> {
|
||||
ByName {
|
||||
name: Symbol,
|
||||
|
||||
full_layout: Layout<'a>,
|
||||
ret_layout: Layout<'a>,
|
||||
arg_layouts: &'a [Layout<'a>],
|
||||
},
|
||||
ByPointer {
|
||||
name: Symbol,
|
||||
|
||||
full_layout: Layout<'a>,
|
||||
ret_layout: Layout<'a>,
|
||||
arg_layouts: &'a [Layout<'a>],
|
||||
},
|
||||
Foreign {
|
||||
foreign_symbol: ForeignSymbol,
|
||||
ret_layout: Layout<'a>,
|
||||
},
|
||||
LowLevel {
|
||||
op: LowLevel,
|
||||
},
|
||||
}
|
||||
|
||||
// x = f a b c; S
|
||||
//
|
||||
//
|
||||
// invoke x = f a b c in S else Unreachable
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Expr<'a> {
|
||||
Literal(Literal<'a>),
|
||||
|
||||
// Functions
|
||||
FunctionPointer(Symbol, Layout<'a>),
|
||||
FunctionCall {
|
||||
call_type: CallType,
|
||||
full_layout: Layout<'a>,
|
||||
ret_layout: Layout<'a>,
|
||||
arg_layouts: &'a [Layout<'a>],
|
||||
args: &'a [Symbol],
|
||||
},
|
||||
RunLowLevel(LowLevel, &'a [Symbol]),
|
||||
ForeignCall {
|
||||
foreign_symbol: ForeignSymbol,
|
||||
arguments: &'a [Symbol],
|
||||
ret_layout: Layout<'a>,
|
||||
},
|
||||
Call(Call<'a>),
|
||||
|
||||
Tag {
|
||||
tag_layout: Layout<'a>,
|
||||
|
@ -957,44 +1016,8 @@ impl<'a> Expr<'a> {
|
|||
.text("FunctionPointer ")
|
||||
.append(symbol_to_doc(alloc, *symbol)),
|
||||
|
||||
FunctionCall {
|
||||
call_type, args, ..
|
||||
} => match call_type {
|
||||
CallType::ByName(name) => {
|
||||
let it = std::iter::once(name)
|
||||
.chain(args.iter())
|
||||
.map(|s| symbol_to_doc(alloc, *s));
|
||||
Call(call) => call.to_doc(alloc),
|
||||
|
||||
alloc.text("CallByName ").append(alloc.intersperse(it, " "))
|
||||
}
|
||||
CallType::ByPointer(name) => {
|
||||
let it = std::iter::once(name)
|
||||
.chain(args.iter())
|
||||
.map(|s| symbol_to_doc(alloc, *s));
|
||||
|
||||
alloc
|
||||
.text("CallByPointer ")
|
||||
.append(alloc.intersperse(it, " "))
|
||||
}
|
||||
},
|
||||
RunLowLevel(lowlevel, args) => {
|
||||
let it = args.iter().map(|s| symbol_to_doc(alloc, *s));
|
||||
|
||||
alloc
|
||||
.text(format!("lowlevel {:?} ", lowlevel))
|
||||
.append(alloc.intersperse(it, " "))
|
||||
}
|
||||
ForeignCall {
|
||||
foreign_symbol,
|
||||
arguments,
|
||||
..
|
||||
} => {
|
||||
let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s));
|
||||
|
||||
alloc
|
||||
.text(format!("foreign {:?} ", foreign_symbol.as_str()))
|
||||
.append(alloc.intersperse(it, " "))
|
||||
}
|
||||
Tag {
|
||||
tag_name,
|
||||
arguments,
|
||||
|
@ -3509,13 +3532,15 @@ pub fn with_hole<'a>(
|
|||
// build the call
|
||||
result = Stmt::Let(
|
||||
assigned,
|
||||
Expr::FunctionCall {
|
||||
call_type: CallType::ByPointer(closure_function_symbol),
|
||||
Expr::Call(self::Call {
|
||||
call_type: CallType::ByPointer {
|
||||
name: closure_function_symbol,
|
||||
full_layout: function_ptr_layout.clone(),
|
||||
ret_layout: ret_layout.clone(),
|
||||
args: arg_symbols,
|
||||
arg_layouts,
|
||||
},
|
||||
arguments: arg_symbols,
|
||||
}),
|
||||
ret_layout,
|
||||
arena.alloc(hole),
|
||||
);
|
||||
|
@ -3556,13 +3581,15 @@ pub fn with_hole<'a>(
|
|||
} else {
|
||||
result = Stmt::Let(
|
||||
assigned,
|
||||
Expr::FunctionCall {
|
||||
call_type: CallType::ByPointer(function_symbol),
|
||||
Expr::Call(self::Call {
|
||||
call_type: CallType::ByPointer {
|
||||
name: function_symbol,
|
||||
full_layout,
|
||||
ret_layout: ret_layout.clone(),
|
||||
args: arg_symbols,
|
||||
arg_layouts,
|
||||
},
|
||||
arguments: arg_symbols,
|
||||
}),
|
||||
ret_layout,
|
||||
arena.alloc(hole),
|
||||
);
|
||||
|
@ -3573,13 +3600,15 @@ pub fn with_hole<'a>(
|
|||
|
||||
result = Stmt::Let(
|
||||
assigned,
|
||||
Expr::FunctionCall {
|
||||
call_type: CallType::ByPointer(function_symbol),
|
||||
Expr::Call(self::Call {
|
||||
call_type: CallType::ByPointer {
|
||||
name: function_symbol,
|
||||
full_layout,
|
||||
ret_layout: ret_layout.clone(),
|
||||
args: arg_symbols,
|
||||
arg_layouts,
|
||||
},
|
||||
arguments: arg_symbols,
|
||||
}),
|
||||
ret_layout,
|
||||
arena.alloc(hole),
|
||||
);
|
||||
|
@ -3620,11 +3649,13 @@ pub fn with_hole<'a>(
|
|||
|
||||
let result = Stmt::Let(
|
||||
assigned,
|
||||
Expr::ForeignCall {
|
||||
Expr::Call(self::Call {
|
||||
call_type: CallType::Foreign {
|
||||
foreign_symbol,
|
||||
arguments: arg_symbols,
|
||||
ret_layout: layout.clone(),
|
||||
},
|
||||
arguments: arg_symbols,
|
||||
}),
|
||||
layout,
|
||||
hole,
|
||||
);
|
||||
|
@ -3666,7 +3697,15 @@ pub fn with_hole<'a>(
|
|||
}
|
||||
};
|
||||
|
||||
let result = Stmt::Let(assigned, Expr::RunLowLevel(op, arg_symbols), layout, hole);
|
||||
let result = Stmt::Let(
|
||||
assigned,
|
||||
Expr::Call(self::Call {
|
||||
call_type: CallType::LowLevel { op },
|
||||
arguments: arg_symbols,
|
||||
}),
|
||||
layout,
|
||||
hole,
|
||||
);
|
||||
|
||||
let iter = args
|
||||
.into_iter()
|
||||
|
@ -4455,72 +4494,37 @@ fn substitute_in_expr<'a>(
|
|||
match expr {
|
||||
Literal(_) | FunctionPointer(_, _) | EmptyArray | RuntimeErrorFunction(_) => None,
|
||||
|
||||
FunctionCall {
|
||||
Call(self::Call {
|
||||
call_type,
|
||||
args,
|
||||
arguments,
|
||||
}) => {
|
||||
let opt_call_type = match call_type {
|
||||
CallType::ByName {
|
||||
name,
|
||||
arg_layouts,
|
||||
ret_layout,
|
||||
full_layout,
|
||||
} => {
|
||||
let opt_call_type = match call_type {
|
||||
CallType::ByName(s) => substitute(subs, *s).map(CallType::ByName),
|
||||
CallType::ByPointer(s) => substitute(subs, *s).map(CallType::ByPointer),
|
||||
};
|
||||
|
||||
let mut did_change = false;
|
||||
let new_args = Vec::from_iter_in(
|
||||
args.iter().map(|s| match substitute(subs, *s) {
|
||||
None => *s,
|
||||
Some(s) => {
|
||||
did_change = true;
|
||||
s
|
||||
}
|
||||
}),
|
||||
arena,
|
||||
);
|
||||
|
||||
if did_change || opt_call_type.is_some() {
|
||||
let call_type = opt_call_type.unwrap_or(*call_type);
|
||||
|
||||
let args = new_args.into_bump_slice();
|
||||
|
||||
Some(FunctionCall {
|
||||
call_type,
|
||||
args,
|
||||
arg_layouts: *arg_layouts,
|
||||
} => substitute(subs, *name).map(|new| CallType::ByName {
|
||||
name: new,
|
||||
arg_layouts,
|
||||
ret_layout: ret_layout.clone(),
|
||||
full_layout: full_layout.clone(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
RunLowLevel(op, args) => {
|
||||
let mut did_change = false;
|
||||
let new_args = Vec::from_iter_in(
|
||||
args.iter().map(|s| match substitute(subs, *s) {
|
||||
None => *s,
|
||||
Some(s) => {
|
||||
did_change = true;
|
||||
s
|
||||
}
|
||||
}),
|
||||
arena,
|
||||
);
|
||||
|
||||
if did_change {
|
||||
let args = new_args.into_bump_slice();
|
||||
|
||||
Some(RunLowLevel(*op, args))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
ForeignCall {
|
||||
foreign_symbol,
|
||||
arguments,
|
||||
CallType::ByPointer {
|
||||
name,
|
||||
arg_layouts,
|
||||
ret_layout,
|
||||
} => {
|
||||
full_layout,
|
||||
} => substitute(subs, *name).map(|new| CallType::ByPointer {
|
||||
name: new,
|
||||
arg_layouts,
|
||||
ret_layout: ret_layout.clone(),
|
||||
full_layout: full_layout.clone(),
|
||||
}),
|
||||
CallType::Foreign { .. } => None,
|
||||
CallType::LowLevel { .. } => None,
|
||||
};
|
||||
|
||||
let mut did_change = false;
|
||||
let new_args = Vec::from_iter_in(
|
||||
arguments.iter().map(|s| match substitute(subs, *s) {
|
||||
|
@ -4533,14 +4537,15 @@ fn substitute_in_expr<'a>(
|
|||
arena,
|
||||
);
|
||||
|
||||
if did_change {
|
||||
let args = new_args.into_bump_slice();
|
||||
if did_change || opt_call_type.is_some() {
|
||||
let call_type = opt_call_type.unwrap_or_else(|| call_type.clone());
|
||||
|
||||
Some(ForeignCall {
|
||||
foreign_symbol: foreign_symbol.clone(),
|
||||
arguments: args,
|
||||
ret_layout: ret_layout.clone(),
|
||||
})
|
||||
let arguments = new_args.into_bump_slice();
|
||||
|
||||
Some(Expr::Call(self::Call {
|
||||
call_type,
|
||||
arguments,
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -5211,13 +5216,15 @@ fn call_by_name<'a>(
|
|||
"see call_by_name for background (scroll down a bit)"
|
||||
);
|
||||
|
||||
let call = Expr::FunctionCall {
|
||||
call_type: CallType::ByName(proc_name),
|
||||
let call = Expr::Call(self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: ret_layout.clone(),
|
||||
full_layout: full_layout.clone(),
|
||||
arg_layouts,
|
||||
args: field_symbols,
|
||||
};
|
||||
},
|
||||
arguments: field_symbols,
|
||||
});
|
||||
|
||||
let result = Stmt::Let(assigned, call, ret_layout.clone(), hole);
|
||||
|
||||
|
@ -5259,13 +5266,16 @@ fn call_by_name<'a>(
|
|||
field_symbols.len(),
|
||||
"see call_by_name for background (scroll down a bit)"
|
||||
);
|
||||
let call = Expr::FunctionCall {
|
||||
call_type: CallType::ByName(proc_name),
|
||||
|
||||
let call = Expr::Call(self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: ret_layout.clone(),
|
||||
full_layout: full_layout.clone(),
|
||||
arg_layouts,
|
||||
args: field_symbols,
|
||||
};
|
||||
},
|
||||
arguments: field_symbols,
|
||||
});
|
||||
|
||||
let iter = loc_args.into_iter().rev().zip(field_symbols.iter().rev());
|
||||
|
||||
|
@ -5319,13 +5329,19 @@ fn call_by_name<'a>(
|
|||
// and we have to fix it here.
|
||||
match full_layout {
|
||||
Layout::Closure(_, closure_layout, _) => {
|
||||
let call = Expr::FunctionCall {
|
||||
call_type: CallType::ByName(proc_name),
|
||||
ret_layout: function_layout.result.clone(),
|
||||
full_layout: function_layout.full.clone(),
|
||||
let call = Expr::Call(self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: function_layout
|
||||
.result
|
||||
.clone(),
|
||||
full_layout: function_layout
|
||||
.full
|
||||
.clone(),
|
||||
arg_layouts: function_layout.arguments,
|
||||
args: field_symbols,
|
||||
};
|
||||
},
|
||||
arguments: field_symbols,
|
||||
});
|
||||
|
||||
// in the case of a closure specifically, we
|
||||
// have to create a custom layout, to make sure
|
||||
|
@ -5346,13 +5362,19 @@ fn call_by_name<'a>(
|
|||
)
|
||||
}
|
||||
_ => {
|
||||
let call = Expr::FunctionCall {
|
||||
call_type: CallType::ByName(proc_name),
|
||||
ret_layout: function_layout.result.clone(),
|
||||
full_layout: function_layout.full.clone(),
|
||||
let call = Expr::Call(self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: function_layout
|
||||
.result
|
||||
.clone(),
|
||||
full_layout: function_layout
|
||||
.full
|
||||
.clone(),
|
||||
arg_layouts: function_layout.arguments,
|
||||
args: field_symbols,
|
||||
};
|
||||
},
|
||||
arguments: field_symbols,
|
||||
});
|
||||
|
||||
Stmt::Let(
|
||||
assigned,
|
||||
|
@ -5368,13 +5390,15 @@ fn call_by_name<'a>(
|
|||
field_symbols.len(),
|
||||
"scroll up a bit for background"
|
||||
);
|
||||
let call = Expr::FunctionCall {
|
||||
call_type: CallType::ByName(proc_name),
|
||||
let call = Expr::Call(self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: function_layout.result.clone(),
|
||||
full_layout: function_layout.full,
|
||||
full_layout: function_layout.full.clone(),
|
||||
arg_layouts: function_layout.arguments,
|
||||
args: field_symbols,
|
||||
};
|
||||
},
|
||||
arguments: field_symbols,
|
||||
});
|
||||
|
||||
let iter = loc_args
|
||||
.into_iter()
|
||||
|
@ -5420,13 +5444,15 @@ fn call_by_name<'a>(
|
|||
"scroll up a bit for background"
|
||||
);
|
||||
|
||||
let call = Expr::FunctionCall {
|
||||
call_type: CallType::ByName(proc_name),
|
||||
let call = Expr::Call(self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: ret_layout.clone(),
|
||||
full_layout: full_layout.clone(),
|
||||
arg_layouts,
|
||||
args: field_symbols,
|
||||
};
|
||||
},
|
||||
arguments: field_symbols,
|
||||
});
|
||||
|
||||
let iter =
|
||||
loc_args.into_iter().rev().zip(field_symbols.iter().rev());
|
||||
|
|
|
@ -75,17 +75,17 @@ fn insert_jumps<'a>(
|
|||
match stmt {
|
||||
Let(
|
||||
symbol,
|
||||
Expr::FunctionCall {
|
||||
call_type: CallType::ByName(fsym),
|
||||
args,
|
||||
Expr::Call(crate::ir::Call {
|
||||
call_type: CallType::ByName { name: fsym, .. },
|
||||
arguments,
|
||||
..
|
||||
},
|
||||
}),
|
||||
_,
|
||||
Stmt::Ret(rsym),
|
||||
) if needle == *fsym && symbol == rsym => {
|
||||
// replace the call and return with a jump
|
||||
|
||||
let jump = Stmt::Jump(goal_id, args);
|
||||
let jump = Stmt::Jump(goal_id, arguments);
|
||||
|
||||
Some(arena.alloc(jump))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue