deal with closure argument everywhere

This commit is contained in:
Folkert 2021-06-16 23:09:40 +02:00
parent cc98237a0a
commit 5ba378551c

View file

@ -138,12 +138,15 @@ where
for proc in procs { for proc in procs {
let bytes = func_name_bytes(proc); let bytes = func_name_bytes(proc);
let func_name = FuncName(&bytes); let func_name = FuncName(&bytes);
eprintln!(
"{:?}: {:?} with {:?} args", if DEBUG {
proc.name, eprintln!(
bytes_as_ascii(&bytes), "{:?}: {:?} with {:?} args",
proc.args.len() proc.name,
); bytes_as_ascii(&bytes),
proc.args.len()
);
}
let spec = proc_spec(proc)?; let spec = proc_spec(proc)?;
@ -163,7 +166,9 @@ where
p.build()? p.build()?
}; };
eprintln!("{}", program.to_source_string()); if DEBUG {
eprintln!("{}", program.to_source_string());
}
morphic_lib::solve(program) morphic_lib::solve(program)
} }
@ -235,11 +240,25 @@ fn stmt_spec(
use Stmt::*; use Stmt::*;
match stmt { match stmt {
Let(symbol, expr, expr_layout, continuation) => { Let(symbol, expr, expr_layout, mut continuation) => {
let value_id = expr_spec(builder, env, block, expr_layout, expr)?; let value_id = expr_spec(builder, env, block, expr_layout, expr)?;
env.symbols.insert(*symbol, value_id); env.symbols.insert(*symbol, value_id);
let mut queue = vec![symbol];
while let Let(symbol, expr, expr_layout, c) = continuation {
let value_id = expr_spec(builder, env, block, expr_layout, expr)?;
env.symbols.insert(*symbol, value_id);
queue.push(symbol);
continuation = c;
}
let result = stmt_spec(builder, env, block, layout, continuation)?; let result = stmt_spec(builder, env, block, layout, continuation)?;
env.symbols.remove(symbol);
for symbol in queue {
env.symbols.remove(symbol);
}
Ok(result) Ok(result)
} }
@ -511,8 +530,11 @@ fn call_spec(
let key = builder.add_get_tuple_field(block, first, 0)?; let key = builder.add_get_tuple_field(block, first, 0)?;
let val = builder.add_get_tuple_field(block, first, 1)?; let val = builder.add_get_tuple_field(block, first, 1)?;
let argument = let argument = if closure_env_layout.is_none() {
builder.add_make_tuple(block, &[key, val, default, closure_env])?; builder.add_make_tuple(block, &[key, val, default])?
} else {
builder.add_make_tuple(block, &[key, val, default, closure_env])?
};
builder.add_call(block, spec_var, module, name, argument)?; builder.add_call(block, spec_var, module, name, argument)?;
} }
@ -536,6 +558,7 @@ fn call_spec(
ListMapWithIndex => { ListMapWithIndex => {
let list = env.symbols[&call.arguments[0]]; let list = env.symbols[&call.arguments[0]];
let closure_env = env.symbols[&call.arguments[2]];
let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?; let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?;
let _cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?; let _cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?;
@ -543,25 +566,52 @@ fn call_spec(
let first = builder.add_bag_get(block, bag)?; let first = builder.add_bag_get(block, bag)?;
let index = builder.add_make_tuple(block, &[])?; let index = builder.add_make_tuple(block, &[])?;
let argument = builder.add_make_tuple(block, &[first, index])?; let argument = if closure_env_layout.is_none() {
builder.add_make_tuple(block, &[first, index])?
} else {
builder.add_make_tuple(block, &[first, index, closure_env])?
};
builder.add_call(block, spec_var, module, name, argument)?; builder.add_call(block, spec_var, module, name, argument)?;
} }
ListMap => { ListMap => {
let list1 = env.symbols[&call.arguments[0]]; let list1 = env.symbols[&call.arguments[0]];
let closure_env = env.symbols[&call.arguments[2]];
let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?; let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?;
let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?; let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?;
let elem1 = builder.add_bag_get(block, bag1)?; let elem1 = builder.add_bag_get(block, bag1)?;
let argument = builder.add_make_tuple(block, &[elem1])?; let argument = if closure_env_layout.is_none() {
builder.add_make_tuple(block, &[elem1])?
} else {
builder.add_make_tuple(block, &[elem1, closure_env])?
};
builder.add_call(block, spec_var, module, name, argument)?;
}
ListSortWith => {
let list1 = env.symbols[&call.arguments[0]];
let closure_env = env.symbols[&call.arguments[2]];
let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?;
let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?;
let elem1 = builder.add_bag_get(block, bag1)?;
let argument = if closure_env_layout.is_none() {
builder.add_make_tuple(block, &[elem1, elem1])?
} else {
builder.add_make_tuple(block, &[elem1, elem1, closure_env])?
};
builder.add_call(block, spec_var, module, name, argument)?; builder.add_call(block, spec_var, module, name, argument)?;
} }
ListMap2 => { ListMap2 => {
let list1 = env.symbols[&call.arguments[0]]; let list1 = env.symbols[&call.arguments[0]];
let list2 = env.symbols[&call.arguments[1]]; let list2 = env.symbols[&call.arguments[1]];
let closure_env = env.symbols[&call.arguments[3]];
let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?; let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?;
let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?; let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?;
@ -571,7 +621,37 @@ fn call_spec(
let _cell2 = builder.add_get_tuple_field(block, list2, LIST_CELL_INDEX)?; let _cell2 = builder.add_get_tuple_field(block, list2, LIST_CELL_INDEX)?;
let elem2 = builder.add_bag_get(block, bag2)?; let elem2 = builder.add_bag_get(block, bag2)?;
let argument = builder.add_make_tuple(block, &[elem1, elem2])?; let argument = if closure_env_layout.is_none() {
builder.add_make_tuple(block, &[elem1, elem2])?
} else {
builder.add_make_tuple(block, &[elem1, elem2, closure_env])?
};
builder.add_call(block, spec_var, module, name, argument)?;
}
ListMap3 => {
let list1 = env.symbols[&call.arguments[0]];
let list2 = env.symbols[&call.arguments[1]];
let list3 = env.symbols[&call.arguments[2]];
let closure_env = env.symbols[&call.arguments[4]];
let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?;
let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?;
let elem1 = builder.add_bag_get(block, bag1)?;
let bag2 = builder.add_get_tuple_field(block, list2, LIST_BAG_INDEX)?;
let _cell2 = builder.add_get_tuple_field(block, list2, LIST_CELL_INDEX)?;
let elem2 = builder.add_bag_get(block, bag2)?;
let bag3 = builder.add_get_tuple_field(block, list3, LIST_BAG_INDEX)?;
let _cell3 = builder.add_get_tuple_field(block, list3, LIST_CELL_INDEX)?;
let elem3 = builder.add_bag_get(block, bag3)?;
let argument = if closure_env_layout.is_none() {
builder.add_make_tuple(block, &[elem1, elem2, elem3])?
} else {
builder.add_make_tuple(block, &[elem1, elem2, elem3, closure_env])?
};
builder.add_call(block, spec_var, module, name, argument)?; builder.add_call(block, spec_var, module, name, argument)?;
} }
@ -584,7 +664,11 @@ fn call_spec(
let first = builder.add_bag_get(block, bag)?; let first = builder.add_bag_get(block, bag)?;
let argument = builder.add_make_tuple(block, &[first, closure_env])?; let argument = if closure_env_layout.is_none() {
builder.add_make_tuple(block, &[first])?
} else {
builder.add_make_tuple(block, &[first, closure_env])?
};
let result = builder.add_call(block, spec_var, module, name, argument)?; let result = builder.add_call(block, spec_var, module, name, argument)?;
let unit = builder.add_tuple_type(&[])?; let unit = builder.add_tuple_type(&[])?;
builder.add_unknown_with(block, &[result], unit)?; builder.add_unknown_with(block, &[result], unit)?;