mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 08:17:40 +03:00
Merge pull request #1675 from rtfeldman/list-literals
List literals in globals
This commit is contained in:
commit
fd7c267ddb
@ -8,7 +8,9 @@ use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_module::ident::{ModuleName, TagName};
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{Interns, Symbol};
|
||||
use roc_mono::ir::{BranchInfo, CallType, Expr, JoinPointId, Literal, Proc, Stmt};
|
||||
use roc_mono::ir::{
|
||||
BranchInfo, CallType, Expr, JoinPointId, ListLiteralElement, Literal, Proc, Stmt,
|
||||
};
|
||||
use roc_mono::layout::{Builtin, Layout, LayoutIds};
|
||||
use target_lexicon::Triple;
|
||||
|
||||
@ -150,7 +152,7 @@ where
|
||||
match expr {
|
||||
Expr::Literal(lit) => {
|
||||
if self.env().lazy_literals {
|
||||
self.literal_map().insert(*sym, lit.clone());
|
||||
self.literal_map().insert(*sym, *lit);
|
||||
} else {
|
||||
self.load_literal(sym, lit)?;
|
||||
}
|
||||
@ -601,10 +603,12 @@ where
|
||||
self.set_last_seen(*structure, stmt);
|
||||
}
|
||||
Expr::Array { elems, .. } => {
|
||||
for sym in *elems {
|
||||
for elem in *elems {
|
||||
if let ListLiteralElement::Symbol(sym) = elem {
|
||||
self.set_last_seen(*sym, stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
Expr::Reuse {
|
||||
symbol,
|
||||
arguments,
|
||||
|
@ -51,7 +51,10 @@ use roc_builtins::bitcode;
|
||||
use roc_collections::all::{ImMap, MutMap, MutSet};
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||
use roc_mono::ir::{BranchInfo, CallType, EntryPoint, JoinPointId, ModifyRc, OptLevel, ProcLayout};
|
||||
use roc_mono::ir::{
|
||||
BranchInfo, CallType, EntryPoint, JoinPointId, ListLiteralElement, ModifyRc, OptLevel,
|
||||
ProcLayout,
|
||||
};
|
||||
use roc_mono::layout::{Builtin, LambdaSet, Layout, LayoutIds, UnionLayout};
|
||||
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
||||
|
||||
@ -2157,57 +2160,141 @@ fn list_literal<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
scope: &Scope<'a, 'ctx>,
|
||||
elem_layout: &Layout<'a>,
|
||||
elems: &&[Symbol],
|
||||
elems: &[ListLiteralElement],
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let ctx = env.context;
|
||||
let builder = env.builder;
|
||||
|
||||
let len_u64 = elems.len() as u64;
|
||||
let element_type = basic_type_from_layout(env, elem_layout);
|
||||
|
||||
let ptr = {
|
||||
let len_type = env.ptr_int();
|
||||
let len = len_type.const_int(len_u64, false);
|
||||
let list_length = elems.len();
|
||||
let list_length_intval = env.ptr_int().const_int(list_length as _, false);
|
||||
|
||||
allocate_list(env, elem_layout, len)
|
||||
};
|
||||
if element_type.is_int_type() {
|
||||
let element_type = element_type.into_int_type();
|
||||
let element_width = elem_layout.stack_size(env.ptr_bytes);
|
||||
let size = list_length * element_width as usize;
|
||||
let alignment = elem_layout
|
||||
.alignment_bytes(env.ptr_bytes)
|
||||
.max(env.ptr_bytes);
|
||||
|
||||
let mut is_all_constant = true;
|
||||
let zero_elements = (env.ptr_bytes as f64 / element_width as f64).ceil() as usize;
|
||||
|
||||
// runtime-evaluated elements
|
||||
let mut runtime_evaluated_elements = Vec::with_capacity_in(list_length, env.arena);
|
||||
|
||||
// set up a global that contains all the literal elements of the array
|
||||
// any variables or expressions are represented as `undef`
|
||||
let global = {
|
||||
let mut global_elements = Vec::with_capacity_in(list_length, env.arena);
|
||||
|
||||
// insert NULL bytes for the refcount
|
||||
// these elements are (dropped again if the list contains non-constants)
|
||||
for _ in 0..zero_elements {
|
||||
global_elements.push(element_type.const_zero());
|
||||
}
|
||||
|
||||
// Copy the elements from the list literal into the array
|
||||
for (index, symbol) in elems.iter().enumerate() {
|
||||
for (index, element) in elems.iter().enumerate() {
|
||||
match element {
|
||||
ListLiteralElement::Literal(literal) => {
|
||||
let val = build_exp_literal(env, elem_layout, literal);
|
||||
global_elements.push(val.into_int_value());
|
||||
}
|
||||
ListLiteralElement::Symbol(symbol) => {
|
||||
let val = load_symbol(scope, symbol);
|
||||
let intval = val.into_int_value();
|
||||
|
||||
if intval.is_const() {
|
||||
global_elements.push(intval);
|
||||
} else {
|
||||
is_all_constant = false;
|
||||
|
||||
runtime_evaluated_elements.push((index, val));
|
||||
|
||||
global_elements.push(element_type.get_undef());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let const_elements = if is_all_constant {
|
||||
global_elements.into_bump_slice()
|
||||
} else {
|
||||
&global_elements[zero_elements..]
|
||||
};
|
||||
|
||||
// use None for the address space (e.g. Const does not work)
|
||||
let typ = element_type.array_type(const_elements.len() as u32);
|
||||
let global = env.module.add_global(typ, None, "roc__list_literal");
|
||||
|
||||
global.set_constant(true);
|
||||
global.set_alignment(alignment);
|
||||
global.set_unnamed_addr(true);
|
||||
global.set_linkage(inkwell::module::Linkage::Private);
|
||||
|
||||
global.set_initializer(&element_type.const_array(const_elements));
|
||||
global.as_pointer_value()
|
||||
};
|
||||
|
||||
if is_all_constant {
|
||||
// all elements are constants, so we can use the memory in the constants section directly
|
||||
// here we make a pointer to the first actual element (skipping the 0 bytes that
|
||||
// represent the refcount)
|
||||
let zero = env.ptr_int().const_zero();
|
||||
let offset = env.ptr_int().const_int(zero_elements as _, false);
|
||||
|
||||
let ptr = unsafe {
|
||||
env.builder
|
||||
.build_in_bounds_gep(global, &[zero, offset], "first_element_pointer")
|
||||
};
|
||||
|
||||
super::build_list::store_list(env, ptr, list_length_intval)
|
||||
} else {
|
||||
// some of our elements are non-constant, so we must allocate space on the heap
|
||||
let ptr = allocate_list(env, elem_layout, list_length_intval);
|
||||
|
||||
// then, copy the relevant segment from the constant section into the heap
|
||||
env.builder
|
||||
.build_memcpy(
|
||||
ptr,
|
||||
alignment,
|
||||
global,
|
||||
alignment,
|
||||
env.ptr_int().const_int(size as _, false),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// then replace the `undef`s with the values that we evaluate at runtime
|
||||
for (index, val) in runtime_evaluated_elements {
|
||||
let index_val = ctx.i64_type().const_int(index as u64, false);
|
||||
let elem_ptr = unsafe { builder.build_in_bounds_gep(ptr, &[index_val], "index") };
|
||||
|
||||
builder.build_store(elem_ptr, val);
|
||||
}
|
||||
|
||||
let u8_ptr_type = ctx.i8_type().ptr_type(AddressSpace::Generic);
|
||||
let generic_ptr = builder.build_bitcast(ptr, u8_ptr_type, "to_generic_ptr");
|
||||
super::build_list::store_list(env, ptr, list_length_intval)
|
||||
}
|
||||
} else {
|
||||
let ptr = allocate_list(env, elem_layout, list_length_intval);
|
||||
|
||||
let struct_type = super::convert::zig_list_type(env);
|
||||
let len = BasicValueEnum::IntValue(env.ptr_int().const_int(len_u64, false));
|
||||
let mut struct_val;
|
||||
// Copy the elements from the list literal into the array
|
||||
for (index, element) in elems.iter().enumerate() {
|
||||
let val = match element {
|
||||
ListLiteralElement::Literal(literal) => {
|
||||
build_exp_literal(env, elem_layout, literal)
|
||||
}
|
||||
ListLiteralElement::Symbol(symbol) => load_symbol(scope, symbol),
|
||||
};
|
||||
let index_val = ctx.i64_type().const_int(index as u64, false);
|
||||
let elem_ptr = unsafe { builder.build_in_bounds_gep(ptr, &[index_val], "index") };
|
||||
|
||||
// Store the pointer
|
||||
struct_val = builder
|
||||
.build_insert_value(
|
||||
struct_type.get_undef(),
|
||||
generic_ptr,
|
||||
Builtin::WRAPPER_PTR,
|
||||
"insert_ptr_list_literal",
|
||||
)
|
||||
.unwrap();
|
||||
builder.build_store(elem_ptr, val);
|
||||
}
|
||||
|
||||
// Store the length
|
||||
struct_val = builder
|
||||
.build_insert_value(struct_val, len, Builtin::WRAPPER_LEN, "insert_len")
|
||||
.unwrap();
|
||||
|
||||
// Bitcast to an array of raw bytes
|
||||
builder.build_bitcast(
|
||||
struct_val.into_struct_value(),
|
||||
super::convert::zig_list_type(env),
|
||||
"cast_collection",
|
||||
)
|
||||
super::build_list::store_list(env, ptr, list_length_intval)
|
||||
}
|
||||
}
|
||||
|
||||
fn decrement_with_size_check<'a, 'ctx, 'env>(
|
||||
|
@ -9,7 +9,7 @@ use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::Symbol;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use crate::ir::{Call, CallType, Expr, Literal, ModifyRc, Proc, Stmt};
|
||||
use crate::ir::{Call, CallType, Expr, ListLiteralElement, Literal, ModifyRc, Proc, Stmt};
|
||||
use crate::layout::{Builtin, Layout, ListLayout, UnionLayout};
|
||||
|
||||
// just using one module for now
|
||||
@ -1118,8 +1118,12 @@ fn expr_spec<'a>(
|
||||
|
||||
let mut bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?;
|
||||
|
||||
for symbol in elems.iter() {
|
||||
let value_id = env.symbols[symbol];
|
||||
for element in elems.iter() {
|
||||
let value_id = if let ListLiteralElement::Symbol(symbol) = element {
|
||||
env.symbols[symbol]
|
||||
} else {
|
||||
builder.add_make_tuple(block, &[]).unwrap()
|
||||
};
|
||||
|
||||
bag = builder.add_bag_insert(block, bag, value_id)?;
|
||||
}
|
||||
|
@ -740,7 +740,15 @@ impl<'a> BorrowInfState<'a> {
|
||||
use Expr::*;
|
||||
|
||||
match e {
|
||||
Tag { arguments: xs, .. } | Struct(xs) | Array { elems: xs, .. } => {
|
||||
Array { elems: xs, .. } => {
|
||||
let xs = Vec::from_iter_in(xs.iter().filter_map(|e| e.to_symbol()), self.arena);
|
||||
self.own_var(z);
|
||||
|
||||
// if the used symbol is an argument to the current function,
|
||||
// the function must take it as an owned parameter
|
||||
self.own_args_if_param(&xs);
|
||||
}
|
||||
Tag { arguments: xs, .. } | Struct(xs) => {
|
||||
self.own_var(z);
|
||||
|
||||
// if the used symbol is an argument to the current function,
|
||||
|
@ -95,11 +95,11 @@ pub fn occurring_variables_expr(expr: &Expr<'_>, result: &mut MutSet<Symbol>) {
|
||||
|
||||
Call(call) => occurring_variables_call(call, result),
|
||||
|
||||
Tag { arguments, .. }
|
||||
| Struct(arguments)
|
||||
| Array {
|
||||
Array {
|
||||
elems: arguments, ..
|
||||
} => {
|
||||
} => result.extend(arguments.iter().filter_map(|e| e.to_symbol())),
|
||||
|
||||
Tag { arguments, .. } | Struct(arguments) => {
|
||||
result.extend(arguments.iter().copied());
|
||||
}
|
||||
Reuse {
|
||||
@ -733,15 +733,22 @@ impl<'a> Context<'a> {
|
||||
live_vars.remove(&z);
|
||||
|
||||
let new_b = match v {
|
||||
Reuse { arguments: ys, .. }
|
||||
| Tag { arguments: ys, .. }
|
||||
| Struct(ys)
|
||||
| Array { elems: ys, .. } => self.add_inc_before_consume_all(
|
||||
Reuse { arguments: ys, .. } | Tag { arguments: ys, .. } | Struct(ys) => self
|
||||
.add_inc_before_consume_all(
|
||||
ys,
|
||||
self.arena.alloc(Stmt::Let(z, v, l, b)),
|
||||
b_live_vars,
|
||||
),
|
||||
|
||||
Array { elems, .. } => {
|
||||
let ys = Vec::from_iter_in(elems.iter().filter_map(|e| e.to_symbol()), self.arena);
|
||||
self.add_inc_before_consume_all(
|
||||
&ys,
|
||||
self.arena.alloc(Stmt::Let(z, v, l, b)),
|
||||
b_live_vars,
|
||||
)
|
||||
}
|
||||
|
||||
Call(crate::ir::Call {
|
||||
call_type,
|
||||
arguments,
|
||||
|
@ -1020,7 +1020,7 @@ impl ModifyRc {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum Literal<'a> {
|
||||
// Literals
|
||||
Int(i128),
|
||||
@ -1038,6 +1038,21 @@ pub enum Literal<'a> {
|
||||
Byte(u8),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum ListLiteralElement<'a> {
|
||||
Literal(Literal<'a>),
|
||||
Symbol(Symbol),
|
||||
}
|
||||
|
||||
impl<'a> ListLiteralElement<'a> {
|
||||
pub fn to_symbol(&self) -> Option<Symbol> {
|
||||
match self {
|
||||
Self::Symbol(s) => Some(*s),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Call<'a> {
|
||||
pub call_type: CallType<'a>,
|
||||
@ -1177,7 +1192,7 @@ pub enum Expr<'a> {
|
||||
|
||||
Array {
|
||||
elem_layout: Layout<'a>,
|
||||
elems: &'a [Symbol],
|
||||
elems: &'a [ListLiteralElement<'a>],
|
||||
},
|
||||
EmptyArray,
|
||||
|
||||
@ -1317,7 +1332,10 @@ impl<'a> Expr<'a> {
|
||||
.append(alloc.text("}"))
|
||||
}
|
||||
Array { elems, .. } => {
|
||||
let it = elems.iter().map(|s| symbol_to_doc(alloc, *s));
|
||||
let it = elems.iter().map(|e| match e {
|
||||
ListLiteralElement::Literal(l) => l.to_doc(alloc),
|
||||
ListLiteralElement::Symbol(s) => symbol_to_doc(alloc, *s),
|
||||
});
|
||||
|
||||
alloc
|
||||
.text("Array [")
|
||||
@ -2728,6 +2746,63 @@ macro_rules! match_on_closure_argument {
|
||||
}};
|
||||
}
|
||||
|
||||
fn try_make_literal<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
can_expr: &roc_can::expr::Expr,
|
||||
) -> Option<Literal<'a>> {
|
||||
use roc_can::expr::Expr::*;
|
||||
|
||||
match can_expr {
|
||||
Int(_, precision, _, int) => {
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *precision, false) {
|
||||
IntOrFloat::SignedIntType(_) | IntOrFloat::UnsignedIntType(_) => {
|
||||
Some(Literal::Int(*int))
|
||||
}
|
||||
_ => unreachable!("unexpected float precision for integer"),
|
||||
}
|
||||
}
|
||||
|
||||
Float(_, precision, float_str, float) => {
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *precision, true) {
|
||||
IntOrFloat::BinaryFloatType(_) => Some(Literal::Float(*float)),
|
||||
IntOrFloat::DecimalFloatType => {
|
||||
let dec = match RocDec::from_str(float_str) {
|
||||
Some(d) => d,
|
||||
None => panic!("Invalid decimal for float literal = {}. TODO: Make this a nice, user-friendly error message", float_str),
|
||||
};
|
||||
|
||||
Some(Literal::Decimal(dec))
|
||||
}
|
||||
_ => unreachable!("unexpected float precision for integer"),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO investigate lifetime trouble
|
||||
// Str(string) => Some(Literal::Str(env.arena.alloc(string))),
|
||||
Num(var, num_str, num) => {
|
||||
// first figure out what kind of number this is
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *var, false) {
|
||||
IntOrFloat::SignedIntType(_) | IntOrFloat::UnsignedIntType(_) => {
|
||||
Some(Literal::Int((*num).into()))
|
||||
}
|
||||
IntOrFloat::BinaryFloatType(_) => Some(Literal::Float(*num as f64)),
|
||||
IntOrFloat::DecimalFloatType => {
|
||||
let dec = match RocDec::from_str(num_str) {
|
||||
Some(d) => d,
|
||||
None => panic!(
|
||||
r"Invalid decimal for float literal = {}. TODO: Make this a nice, user-friendly error message",
|
||||
num_str
|
||||
),
|
||||
};
|
||||
|
||||
Some(Literal::Decimal(dec))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_hole<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
can_expr: roc_can::expr::Expr,
|
||||
@ -3423,8 +3498,20 @@ pub fn with_hole<'a>(
|
||||
loc_elems,
|
||||
} => {
|
||||
let mut arg_symbols = Vec::with_capacity_in(loc_elems.len(), env.arena);
|
||||
for arg_expr in loc_elems.iter() {
|
||||
arg_symbols.push(possible_reuse_symbol(env, procs, &arg_expr.value));
|
||||
let mut elements = Vec::with_capacity_in(loc_elems.len(), env.arena);
|
||||
|
||||
let mut symbol_exprs = Vec::with_capacity_in(loc_elems.len(), env.arena);
|
||||
|
||||
for arg_expr in loc_elems.into_iter() {
|
||||
if let Some(literal) = try_make_literal(env, &arg_expr.value) {
|
||||
elements.push(ListLiteralElement::Literal(literal));
|
||||
} else {
|
||||
let symbol = possible_reuse_symbol(env, procs, &arg_expr.value);
|
||||
|
||||
elements.push(ListLiteralElement::Symbol(symbol));
|
||||
arg_symbols.push(symbol);
|
||||
symbol_exprs.push(arg_expr);
|
||||
}
|
||||
}
|
||||
let arg_symbols = arg_symbols.into_bump_slice();
|
||||
|
||||
@ -3434,7 +3521,7 @@ pub fn with_hole<'a>(
|
||||
|
||||
let expr = Expr::Array {
|
||||
elem_layout,
|
||||
elems: arg_symbols,
|
||||
elems: elements.into_bump_slice(),
|
||||
};
|
||||
|
||||
let stmt = Stmt::Let(
|
||||
@ -3444,7 +3531,7 @@ pub fn with_hole<'a>(
|
||||
hole,
|
||||
);
|
||||
|
||||
let iter = loc_elems
|
||||
let iter = symbol_exprs
|
||||
.into_iter()
|
||||
.rev()
|
||||
.map(|e| (elem_var, e))
|
||||
@ -5485,11 +5572,17 @@ fn substitute_in_expr<'a>(
|
||||
} => {
|
||||
let mut did_change = false;
|
||||
let new_args = Vec::from_iter_in(
|
||||
args.iter().map(|s| match substitute(subs, *s) {
|
||||
None => *s,
|
||||
args.iter().map(|e| {
|
||||
if let ListLiteralElement::Symbol(s) = e {
|
||||
match substitute(subs, *s) {
|
||||
None => ListLiteralElement::Symbol(*s),
|
||||
Some(s) => {
|
||||
did_change = true;
|
||||
s
|
||||
ListLiteralElement::Symbol(s)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*e
|
||||
}
|
||||
}),
|
||||
arena,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::inc_dec::{collect_stmt, occurring_variables_expr, JPLiveVarMap, LiveVarSet};
|
||||
use crate::ir::{BranchInfo, Call, Expr, Proc, Stmt};
|
||||
use crate::ir::{BranchInfo, Call, Expr, ListLiteralElement, Proc, Stmt};
|
||||
use crate::layout::{Layout, UnionLayout};
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
@ -564,8 +564,18 @@ fn has_live_var_expr<'a>(expr: &'a Expr<'a>, needle: Symbol) -> bool {
|
||||
match expr {
|
||||
Expr::Literal(_) => false,
|
||||
Expr::Call(call) => has_live_var_call(call, needle),
|
||||
Expr::Array { elems: fields, .. }
|
||||
| Expr::Tag {
|
||||
Expr::Array { elems: fields, .. } => {
|
||||
for element in fields.iter() {
|
||||
if let ListLiteralElement::Symbol(s) = element {
|
||||
if *s == needle {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
Expr::Tag {
|
||||
arguments: fields, ..
|
||||
}
|
||||
| Expr::Struct(fields) => fields.iter().any(|s| *s == needle),
|
||||
|
@ -3,14 +3,8 @@ procedure Test.1 (Test.2, Test.3):
|
||||
ret Test.2;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.11 = 1i64;
|
||||
let Test.12 = 2i64;
|
||||
let Test.13 = 3i64;
|
||||
let Test.5 = Array [Test.11, Test.12, Test.13];
|
||||
let Test.8 = 3i64;
|
||||
let Test.9 = 2i64;
|
||||
let Test.10 = 1i64;
|
||||
let Test.6 = Array [Test.8, Test.9, Test.10];
|
||||
let Test.5 = Array [1i64, 2i64, 3i64];
|
||||
let Test.6 = Array [3i64, 2i64, 1i64];
|
||||
let Test.4 = CallByName Test.1 Test.5 Test.6;
|
||||
dec Test.6;
|
||||
dec Test.5;
|
||||
|
@ -7,9 +7,7 @@ procedure Num.24 (#Attr.2, #Attr.3):
|
||||
ret Test.5;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.11 = 1i64;
|
||||
let Test.12 = 2i64;
|
||||
let Test.1 = Array [Test.11, Test.12];
|
||||
let Test.1 = Array [1i64, 2i64];
|
||||
let Test.9 = 5i64;
|
||||
let Test.10 = 4i64;
|
||||
let Test.7 = CallByName Num.24 Test.9 Test.10;
|
||||
|
@ -1,8 +1,5 @@
|
||||
procedure Test.0 ():
|
||||
let Test.6 = 1i64;
|
||||
let Test.7 = 3i64;
|
||||
let Test.8 = 4i64;
|
||||
let Test.4 = Array [Test.6, Test.7, Test.8];
|
||||
let Test.4 = Array [1i64, 3i64, 4i64];
|
||||
let Test.5 = 3.14f64;
|
||||
let Test.3 = Struct {Test.4, Test.5};
|
||||
let Test.1 = StructAtIndex 0 Test.3;
|
||||
|
@ -3,8 +3,7 @@ procedure List.5 (#Attr.2, #Attr.3):
|
||||
ret Test.4;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 = 1i64;
|
||||
let Test.2 = Array [Test.5];
|
||||
let Test.2 = Array [1i64];
|
||||
let Test.3 = 2i64;
|
||||
let Test.1 = CallByName List.5 Test.2 Test.3;
|
||||
ret Test.1;
|
||||
|
@ -8,8 +8,6 @@ procedure Test.1 (Test.2):
|
||||
ret Test.5;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.8 = 1i64;
|
||||
let Test.9 = 2i64;
|
||||
let Test.4 = Array [Test.8, Test.9];
|
||||
let Test.4 = Array [1i64, 2i64];
|
||||
let Test.3 = CallByName Test.1 Test.4;
|
||||
ret Test.3;
|
||||
|
@ -1,9 +1,9 @@
|
||||
procedure List.4 (#Attr.2, #Attr.3, #Attr.4):
|
||||
let Test.22 = lowlevel ListLen #Attr.2;
|
||||
let Test.20 = lowlevel NumLt #Attr.3 Test.22;
|
||||
if Test.20 then
|
||||
let Test.21 = lowlevel ListSet #Attr.2 #Attr.3 #Attr.4;
|
||||
ret Test.21;
|
||||
let Test.19 = lowlevel ListLen #Attr.2;
|
||||
let Test.17 = lowlevel NumLt #Attr.3 Test.19;
|
||||
if Test.17 then
|
||||
let Test.18 = lowlevel ListSet #Attr.2 #Attr.3 #Attr.4;
|
||||
ret Test.18;
|
||||
else
|
||||
ret #Attr.2;
|
||||
|
||||
@ -16,23 +16,20 @@ procedure Num.24 (#Attr.2, #Attr.3):
|
||||
ret Test.7;
|
||||
|
||||
procedure Test.1 ():
|
||||
let Test.11 = 1i64;
|
||||
let Test.12 = 2i64;
|
||||
let Test.13 = 3i64;
|
||||
let Test.10 = Array [Test.11, Test.12, Test.13];
|
||||
let Test.10 = Array [1i64, 2i64, 3i64];
|
||||
ret Test.10;
|
||||
|
||||
procedure Test.2 (Test.3):
|
||||
let Test.17 = 0i64;
|
||||
let Test.18 = 0i64;
|
||||
let Test.16 = CallByName List.4 Test.3 Test.17 Test.18;
|
||||
ret Test.16;
|
||||
let Test.14 = 0i64;
|
||||
let Test.15 = 0i64;
|
||||
let Test.13 = CallByName List.4 Test.3 Test.14 Test.15;
|
||||
ret Test.13;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.15 = CallByName Test.1;
|
||||
let Test.14 = CallByName Test.2 Test.15;
|
||||
let Test.5 = CallByName List.7 Test.14;
|
||||
dec Test.14;
|
||||
let Test.12 = CallByName Test.1;
|
||||
let Test.11 = CallByName Test.2 Test.12;
|
||||
let Test.5 = CallByName List.7 Test.11;
|
||||
dec Test.11;
|
||||
let Test.8 = CallByName Test.1;
|
||||
let Test.6 = CallByName List.7 Test.8;
|
||||
dec Test.8;
|
||||
|
@ -11,10 +11,7 @@ procedure List.3 (#Attr.2, #Attr.3):
|
||||
ret Test.8;
|
||||
|
||||
procedure Test.1 (Test.2):
|
||||
let Test.14 = 1i64;
|
||||
let Test.15 = 2i64;
|
||||
let Test.16 = 3i64;
|
||||
let Test.6 = Array [Test.14, Test.15, Test.16];
|
||||
let Test.6 = Array [1i64, 2i64, 3i64];
|
||||
let Test.7 = 0i64;
|
||||
let Test.5 = CallByName List.3 Test.6 Test.7;
|
||||
dec Test.6;
|
||||
|
@ -11,12 +11,8 @@ procedure Num.24 (#Attr.2, #Attr.3):
|
||||
ret Test.6;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.10 = 1i64;
|
||||
let Test.11 = 2i64;
|
||||
let Test.12 = 3i64;
|
||||
let Test.1 = Array [Test.10, Test.11, Test.12];
|
||||
let Test.9 = 1f64;
|
||||
let Test.2 = Array [Test.9];
|
||||
let Test.1 = Array [1i64, 2i64, 3i64];
|
||||
let Test.2 = Array [1f64];
|
||||
let Test.4 = CallByName List.7 Test.1;
|
||||
dec Test.1;
|
||||
let Test.5 = CallByName List.7 Test.2;
|
||||
|
@ -14,9 +14,6 @@ procedure Test.2 (Test.3):
|
||||
ret Test.5;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.12 = 1i64;
|
||||
let Test.13 = 2i64;
|
||||
let Test.14 = 3i64;
|
||||
let Test.1 = Array [Test.12, Test.13, Test.14];
|
||||
let Test.1 = Array [1i64, 2i64, 3i64];
|
||||
let Test.4 = CallByName Test.2 Test.1;
|
||||
ret Test.4;
|
||||
|
@ -4,9 +4,6 @@ procedure Test.1 (Test.2):
|
||||
ret Test.6;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.7 = 1i64;
|
||||
let Test.8 = 2i64;
|
||||
let Test.9 = 3i64;
|
||||
let Test.5 = Array [Test.7, Test.8, Test.9];
|
||||
let Test.5 = Array [1i64, 2i64, 3i64];
|
||||
let Test.4 = CallByName Test.1 Test.5;
|
||||
ret Test.4;
|
||||
|
@ -56,8 +56,6 @@ procedure Test.1 (Test.2):
|
||||
jump Test.26;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.39 = 1i64;
|
||||
let Test.40 = 2i64;
|
||||
let Test.7 = Array [Test.39, Test.40];
|
||||
let Test.7 = Array [1i64, 2i64];
|
||||
let Test.6 = CallByName Test.1 Test.7;
|
||||
ret Test.6;
|
||||
|
@ -54,7 +54,6 @@ procedure Test.1 (Test.2, Test.3, Test.4):
|
||||
procedure Test.0 ():
|
||||
let Test.10 = 0i64;
|
||||
let Test.11 = 0i64;
|
||||
let Test.40 = 1i64;
|
||||
let Test.12 = Array [Test.40];
|
||||
let Test.12 = Array [1i64];
|
||||
let Test.9 = CallByName Test.1 Test.10 Test.11 Test.12;
|
||||
ret Test.9;
|
||||
|
Loading…
Reference in New Issue
Block a user