mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
Merge branch 'main' into fromutf-roc
This commit is contained in:
commit
6c29d7aa1f
237 changed files with 7237 additions and 5353 deletions
|
@ -39,7 +39,6 @@ ROC_TRACE_COMPACTION = "0"
|
|||
ROC_PRINT_UNIFICATIONS_DERIVED = "0"
|
||||
ROC_PRINT_MISMATCHES = "0"
|
||||
ROC_PRINT_FIXPOINT_FIXING = "0"
|
||||
ROC_VERIFY_RIGID_LET_GENERALIZED = "0"
|
||||
ROC_VERIFY_OCCURS_ONE_RECURSION = "0"
|
||||
ROC_CHECK_MONO_IR = "0"
|
||||
ROC_PRINT_IR_AFTER_SPECIALIZATION = "0"
|
||||
|
|
27
Cargo.lock
generated
27
Cargo.lock
generated
|
@ -2393,6 +2393,7 @@ dependencies = [
|
|||
"bumpalo",
|
||||
"indoc",
|
||||
"pretty_assertions",
|
||||
"roc_can_solo",
|
||||
"roc_collections",
|
||||
"roc_error_macros",
|
||||
"roc_exhaustive",
|
||||
|
@ -2408,6 +2409,25 @@ dependencies = [
|
|||
"ven_pretty",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roc_can_solo"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"bumpalo",
|
||||
"roc_collections",
|
||||
"roc_error_macros",
|
||||
"roc_module",
|
||||
"roc_parse",
|
||||
"roc_problem",
|
||||
"roc_region",
|
||||
"roc_serialize",
|
||||
"roc_types",
|
||||
"soa",
|
||||
"static_assertions",
|
||||
"ven_pretty",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roc_checkmate"
|
||||
version = "0.0.1"
|
||||
|
@ -2805,6 +2825,7 @@ dependencies = [
|
|||
"pretty_assertions",
|
||||
"roc_builtins",
|
||||
"roc_can",
|
||||
"roc_can_solo",
|
||||
"roc_collections",
|
||||
"roc_constrain",
|
||||
"roc_derive",
|
||||
|
@ -2828,6 +2849,8 @@ dependencies = [
|
|||
name = "roc_load_internal"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"base64-url",
|
||||
"blake3",
|
||||
"bumpalo",
|
||||
"crossbeam",
|
||||
"indoc",
|
||||
|
@ -2836,6 +2859,7 @@ dependencies = [
|
|||
"pretty_assertions",
|
||||
"roc_builtins",
|
||||
"roc_can",
|
||||
"roc_can_solo",
|
||||
"roc_checkmate",
|
||||
"roc_collections",
|
||||
"roc_constrain",
|
||||
|
@ -3281,6 +3305,7 @@ dependencies = [
|
|||
name = "roc_types"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bumpalo",
|
||||
"roc_collections",
|
||||
"roc_debug_flags",
|
||||
|
@ -3871,6 +3896,7 @@ dependencies = [
|
|||
"pretty_assertions",
|
||||
"roc_builtins",
|
||||
"roc_can",
|
||||
"roc_can_solo",
|
||||
"roc_collections",
|
||||
"roc_constrain",
|
||||
"roc_derive",
|
||||
|
@ -4015,6 +4041,7 @@ dependencies = [
|
|||
"indoc",
|
||||
"pretty_assertions",
|
||||
"roc_can",
|
||||
"roc_can_solo",
|
||||
"roc_collections",
|
||||
"roc_error_macros",
|
||||
"roc_fmt",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"crates/build/specialize_types",
|
||||
"crates/build/*",
|
||||
"crates/check/*",
|
||||
"crates/compiler/*",
|
||||
"crates/vendor/*",
|
||||
"crates/fs",
|
||||
|
@ -174,6 +175,7 @@ roc_bitcode_bc = { path = "crates/compiler/builtins/bitcode/bc" }
|
|||
roc_build = { path = "crates/compiler/build" }
|
||||
roc_builtins = { path = "crates/compiler/builtins" }
|
||||
roc_can = { path = "crates/compiler/can" }
|
||||
roc_can_solo = { path = "crates/check/can_solo" }
|
||||
roc_checkmate = { path = "crates/compiler/checkmate" }
|
||||
roc_checkmate_schema = { path = "crates/compiler/checkmate_schema" }
|
||||
roc_cli = { path = "crates/cli" }
|
||||
|
|
23
crates/check/can_solo/Cargo.toml
Normal file
23
crates/check/can_solo/Cargo.toml
Normal file
|
@ -0,0 +1,23 @@
|
|||
[package]
|
||||
name = "roc_can_solo"
|
||||
description = "Canonicalize a Roc module in preparation for typechecking without any knowledge of other modules."
|
||||
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
roc_collections.workspace = true
|
||||
roc_error_macros.workspace = true
|
||||
roc_module.workspace = true
|
||||
roc_parse.workspace = true
|
||||
roc_problem.workspace = true
|
||||
roc_region.workspace = true
|
||||
roc_serialize.workspace = true
|
||||
roc_types.workspace = true
|
||||
ven_pretty.workspace = true
|
||||
bitvec.workspace = true
|
||||
bumpalo.workspace = true
|
||||
static_assertions.workspace = true
|
||||
soa.workspace = true
|
1858
crates/check/can_solo/src/desugar.rs
Normal file
1858
crates/check/can_solo/src/desugar.rs
Normal file
File diff suppressed because it is too large
Load diff
48
crates/check/can_solo/src/env.rs
Normal file
48
crates/check/can_solo/src/env.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use std::path::Path;
|
||||
|
||||
use bumpalo::Bump;
|
||||
use roc_module::symbol::ModuleId;
|
||||
use roc_problem::can::Problem;
|
||||
use roc_region::all::LineInfo;
|
||||
|
||||
/// The canonicalization environment for a particular module.
|
||||
#[derive(Debug)]
|
||||
pub struct SoloEnv<'a> {
|
||||
pub arena: &'a Bump,
|
||||
|
||||
pub module_path: &'a Path,
|
||||
|
||||
pub solo_home: ModuleId,
|
||||
|
||||
/// Problems we've encountered along the way, which will be reported to the user at the end.
|
||||
pub problems: Vec<Problem>,
|
||||
|
||||
pub src: &'a str,
|
||||
|
||||
/// Lazily calculated line info. This data is only needed if the code contains calls to `dbg`,
|
||||
/// otherwise we can leave it as `None` and never pay the cost of scanning the source an extra
|
||||
/// time.
|
||||
pub lazy_line_info: &'a mut Option<LineInfo>,
|
||||
}
|
||||
|
||||
impl<'a> SoloEnv<'a> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(arena: &'a Bump, src: &'a str, module_path: &'a Path) -> SoloEnv<'a> {
|
||||
SoloEnv {
|
||||
arena,
|
||||
module_path,
|
||||
solo_home: ModuleId::first_after_builtins(),
|
||||
src,
|
||||
problems: Vec::new(),
|
||||
lazy_line_info: arena.alloc(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn line_info(&mut self) -> &LineInfo {
|
||||
if self.lazy_line_info.is_none() {
|
||||
*self.lazy_line_info = Some(LineInfo::new(self.src));
|
||||
}
|
||||
|
||||
self.lazy_line_info.as_ref().unwrap()
|
||||
}
|
||||
}
|
5
crates/check/can_solo/src/lib.rs
Normal file
5
crates/check/can_solo/src/lib.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
#![warn(clippy::dbg_macro)]
|
||||
pub mod desugar;
|
||||
pub mod env;
|
||||
pub mod module;
|
||||
pub mod scope;
|
81
crates/check/can_solo/src/module.rs
Normal file
81
crates/check/can_solo/src/module.rs
Normal file
|
@ -0,0 +1,81 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use bumpalo::Bump;
|
||||
use roc_module::symbol::ModuleId;
|
||||
use roc_parse::{
|
||||
ast::{Collection, Defs, Pattern},
|
||||
header::HeaderType,
|
||||
};
|
||||
use roc_problem::can::Problem;
|
||||
use roc_region::all::{LineInfo, Loc, Region};
|
||||
|
||||
use crate::{
|
||||
desugar::{desugar_defs_node_values, desugar_record_destructures},
|
||||
env::SoloEnv,
|
||||
scope::SoloScope,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SoloCanOutput<'a> {
|
||||
pub scope: SoloScope,
|
||||
pub loc_defs: Defs<'a>,
|
||||
pub solo_home: ModuleId,
|
||||
|
||||
/// Problems we've encountered along the way, which will be reported to the user at the end.
|
||||
pub problems: Vec<Problem>,
|
||||
|
||||
pub src: &'a str,
|
||||
|
||||
/// Lazily calculated line info. This data is only needed if the code contains calls to `dbg`,
|
||||
/// otherwise we can leave it as `None` and never pay the cost of scanning the source an extra
|
||||
/// time.
|
||||
pub lazy_line_info: &'a mut Option<LineInfo>,
|
||||
|
||||
pub module_params: Option<(Region, Collection<'a, Loc<Pattern<'a>>>)>,
|
||||
}
|
||||
|
||||
// TODO trim these down
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn solo_canonicalize_module_defs<'a>(
|
||||
arena: &'a Bump,
|
||||
header_type: HeaderType<'a>,
|
||||
loc_defs: &'a mut Defs<'a>,
|
||||
module_path: PathBuf,
|
||||
src: &'a str,
|
||||
) -> SoloCanOutput<'a> {
|
||||
let mut scope = SoloScope::new();
|
||||
let mut env = SoloEnv::new(arena, src, arena.alloc(module_path));
|
||||
|
||||
// Desugar operators (convert them to Apply calls, taking into account
|
||||
// operator precedence and associativity rules), before doing other canonicalization.
|
||||
//
|
||||
// If we did this *during* canonicalization, then each time we
|
||||
// visited a BinOp node we'd recursively try to apply this to each of its nested
|
||||
// operators, and then again on *their* nested operators, ultimately applying the
|
||||
// rules multiple times unnecessarily.
|
||||
|
||||
desugar_defs_node_values(&mut env, &mut scope, loc_defs);
|
||||
|
||||
let module_params = header_type.get_params().as_ref().map(
|
||||
|roc_parse::header::ModuleParams {
|
||||
pattern,
|
||||
before_arrow: _,
|
||||
after_arrow: _,
|
||||
}| {
|
||||
let desugared_patterns =
|
||||
desugar_record_destructures(&mut env, &mut scope, pattern.value);
|
||||
|
||||
(pattern.region, desugared_patterns)
|
||||
},
|
||||
);
|
||||
|
||||
SoloCanOutput {
|
||||
scope,
|
||||
solo_home: env.solo_home,
|
||||
loc_defs: loc_defs.clone(),
|
||||
problems: env.problems,
|
||||
src: env.src,
|
||||
lazy_line_info: env.lazy_line_info,
|
||||
module_params,
|
||||
}
|
||||
}
|
229
crates/check/can_solo/src/scope.rs
Normal file
229
crates/check/can_solo/src/scope.rs
Normal file
|
@ -0,0 +1,229 @@
|
|||
use roc_collections::VecMap;
|
||||
use roc_module::ident::ModuleName;
|
||||
use roc_module::symbol::{IdentId, IdentIds, ModuleId, ModuleIds, Symbol};
|
||||
use roc_problem::can::ScopeModuleSource;
|
||||
use roc_region::all::Region;
|
||||
use roc_types::subs::Variable;
|
||||
use roc_types::types::{Alias, EarlyReturnKind};
|
||||
|
||||
use bitvec::vec::BitVec;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SoloScope {
|
||||
/// The type aliases currently in scope
|
||||
pub aliases: VecMap<Symbol, Alias>,
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// The current module being processed. This will be used to turn
|
||||
/// unqualified idents into Symbols.
|
||||
solo_home: ModuleId,
|
||||
|
||||
/// Modules that are imported
|
||||
pub modules: ScopeModules,
|
||||
|
||||
/// Identifiers that are in scope, and defined in the current module
|
||||
pub locals: ScopedIdentIds,
|
||||
|
||||
pub early_returns: Vec<(Variable, Region, EarlyReturnKind)>,
|
||||
}
|
||||
|
||||
impl Default for SoloScope {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl SoloScope {
|
||||
pub fn new() -> Self {
|
||||
let solo_home = ModuleId::first_after_builtins();
|
||||
|
||||
Self {
|
||||
solo_home,
|
||||
locals: ScopedIdentIds::from_ident_ids(solo_home),
|
||||
aliases: VecMap::default(),
|
||||
modules: ScopeModules::new(solo_home),
|
||||
early_returns: Vec::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates a unique new symbol and return the symbol's unqualified identifier name.
|
||||
pub fn gen_unique_symbol_name(&mut self) -> &str {
|
||||
let ident_id = self.locals.gen_unique();
|
||||
self.locals.ident_ids.get_name(ident_id).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ScopedIdentIds {
|
||||
pub ident_ids: IdentIds,
|
||||
in_scope: BitVec,
|
||||
regions: Vec<Region>,
|
||||
#[allow(dead_code)]
|
||||
solo_home: ModuleId,
|
||||
}
|
||||
|
||||
impl ScopedIdentIds {
|
||||
fn from_ident_ids(solo_home: ModuleId) -> Self {
|
||||
Self {
|
||||
in_scope: BitVec::repeat(false, 0),
|
||||
ident_ids: IdentIds::default(),
|
||||
regions: vec![Region::zero(); 0],
|
||||
solo_home,
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_unique(&mut self) -> IdentId {
|
||||
let id = self.ident_ids.gen_unique();
|
||||
|
||||
debug_assert_eq!(id.index(), self.in_scope.len());
|
||||
debug_assert_eq!(id.index(), self.regions.len());
|
||||
|
||||
self.in_scope.push(false);
|
||||
self.regions.push(Region::zero());
|
||||
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ScopeModules {
|
||||
/// The ids of all modules in scope
|
||||
ids: Vec<ModuleId>,
|
||||
/// The alias or original name of each module in scope
|
||||
names: Vec<ModuleName>,
|
||||
/// Why is this module in scope?
|
||||
sources: Vec<ScopeModuleSource>,
|
||||
/// The params of a module if any
|
||||
params: Vec<Option<(Variable, Symbol)>>,
|
||||
}
|
||||
|
||||
impl ScopeModules {
|
||||
pub fn new(home_id: ModuleId) -> Self {
|
||||
let builtins = ModuleIds::default();
|
||||
let builtins_iter = builtins.iter();
|
||||
let count = builtins_iter.len();
|
||||
|
||||
let mut ids = Vec::with_capacity(count + 1);
|
||||
let mut names = Vec::with_capacity(count + 1);
|
||||
let mut sources = vec![ScopeModuleSource::Builtin; count];
|
||||
let mut params = vec![None; count];
|
||||
|
||||
for (module_id, module_name) in builtins_iter {
|
||||
ids.push(module_id);
|
||||
names.push(module_name.clone());
|
||||
}
|
||||
|
||||
if !home_id.is_builtin() {
|
||||
ids.push(home_id);
|
||||
names.push("".into());
|
||||
sources.push(ScopeModuleSource::Current);
|
||||
params.push(None);
|
||||
}
|
||||
|
||||
Self {
|
||||
ids,
|
||||
names,
|
||||
sources,
|
||||
params,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup(&self, module_name: &ModuleName) -> Option<ModuleLookup> {
|
||||
self.names
|
||||
.iter()
|
||||
.position(|name| name == module_name)
|
||||
.map(|index| ModuleLookup {
|
||||
id: self.ids[index],
|
||||
params: self.params[index],
|
||||
})
|
||||
}
|
||||
|
||||
pub fn lookup_by_id(&self, module_id: &ModuleId) -> Option<ModuleLookup> {
|
||||
self.ids
|
||||
.iter()
|
||||
.position(|id| id == module_id)
|
||||
.map(|index| ModuleLookup {
|
||||
id: self.ids[index],
|
||||
params: self.params[index],
|
||||
})
|
||||
}
|
||||
|
||||
pub fn available_names(&self) -> impl Iterator<Item = &ModuleName> {
|
||||
self.names.iter()
|
||||
}
|
||||
|
||||
pub fn insert(
|
||||
&mut self,
|
||||
module_name: ModuleName,
|
||||
module_id: ModuleId,
|
||||
params: Option<(Variable, Symbol)>,
|
||||
region: Region,
|
||||
) -> Result<(), ScopeModuleSource> {
|
||||
if let Some(index) = self.names.iter().position(|name| name == &module_name) {
|
||||
if self.ids[index] == module_id {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
return Err(self.sources[index]);
|
||||
}
|
||||
|
||||
self.ids.push(module_id);
|
||||
self.names.push(module_name);
|
||||
self.sources.push(ScopeModuleSource::Import(region));
|
||||
self.params.push(params);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
debug_assert_eq!(self.ids.len(), self.names.len());
|
||||
debug_assert_eq!(self.ids.len(), self.sources.len());
|
||||
debug_assert_eq!(self.ids.len(), self.params.len());
|
||||
self.ids.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.ids.is_empty()
|
||||
}
|
||||
|
||||
pub fn truncate(&mut self, len: usize) {
|
||||
self.ids.truncate(len);
|
||||
self.names.truncate(len);
|
||||
self.sources.truncate(len);
|
||||
self.params.truncate(len);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct SymbolLookup {
|
||||
pub symbol: Symbol,
|
||||
pub module_params: Option<(Variable, Symbol)>,
|
||||
}
|
||||
|
||||
impl SymbolLookup {
|
||||
pub fn new(symbol: Symbol, params: Option<(Variable, Symbol)>) -> Self {
|
||||
Self {
|
||||
symbol,
|
||||
module_params: params,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn no_params(symbol: Symbol) -> Self {
|
||||
Self::new(symbol, None)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ModuleLookup {
|
||||
pub id: ModuleId,
|
||||
pub params: Option<(Variable, Symbol)>,
|
||||
}
|
||||
|
||||
impl ModuleLookup {
|
||||
pub fn into_symbol(&self, symbol: Symbol) -> SymbolLookup {
|
||||
debug_assert_eq!(symbol.module_id(), self.id);
|
||||
|
||||
SymbolLookup {
|
||||
symbol,
|
||||
module_params: self.params,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -90,12 +90,12 @@ astar = \cost_fn, move_fn, goal, model ->
|
|||
new_neighbors =
|
||||
Set.difference(neighbors, model_popped.evaluated)
|
||||
|
||||
model_with_neighbors : Model position
|
||||
model_with_neighbors : Model _
|
||||
model_with_neighbors =
|
||||
model_popped
|
||||
|> &open_set(Set.union(model_popped.open_set, new_neighbors))
|
||||
|
||||
walker : Model position, position -> Model position
|
||||
walker : Model _, _ -> Model _
|
||||
walker = \amodel, n -> update_cost(current, n, amodel)
|
||||
|
||||
model_with_costs =
|
||||
|
|
|
@ -148,19 +148,19 @@ is_valid_char = \c ->
|
|||
|
||||
is_alpha_num : U8 -> Bool
|
||||
is_alpha_num = \key ->
|
||||
(key >= 48 && key <= 57) || (key >= 64 && key <= 90) || (key >= 97 && key <= 122)
|
||||
(key >= 48 and key <= 57) or (key >= 64 and key <= 90) or (key >= 97 and key <= 122)
|
||||
|
||||
# Convert a base64 character/digit to its index
|
||||
# See also [Wikipedia](https://en.wikipedia.org/wiki/Base64#Base64_table)
|
||||
unsafe_convert_char : U8 -> U8
|
||||
unsafe_convert_char = \key ->
|
||||
if key >= 65 && key <= 90 then
|
||||
if key >= 65 and key <= 90 then
|
||||
# A-Z
|
||||
key - 65
|
||||
else if key >= 97 && key <= 122 then
|
||||
else if key >= 97 and key <= 122 then
|
||||
# a-z
|
||||
(key - 97) + 26
|
||||
else if key >= 48 && key <= 57 then
|
||||
else if key >= 48 and key <= 57 then
|
||||
# 0-9
|
||||
(key - 48) + 26 + 26
|
||||
else
|
||||
|
|
|
@ -50,7 +50,7 @@ safe = \queen, diagonal, xs ->
|
|||
when xs is
|
||||
Nil -> Bool.true
|
||||
Cons(q, t) ->
|
||||
if queen != q && queen != q + diagonal && queen != q - diagonal then
|
||||
if queen != q and queen != q + diagonal and queen != q - diagonal then
|
||||
safe(queen, (diagonal + 1), t)
|
||||
else
|
||||
Bool.false
|
||||
|
|
|
@ -19,10 +19,8 @@ to_str = \@Variable(char) ->
|
|||
from_utf8 : U8 -> Result Variable [InvalidVariableUtf8]
|
||||
from_utf8 = \char ->
|
||||
if
|
||||
char
|
||||
>= 0x61 # "a"
|
||||
&& char
|
||||
<= 0x7A # "z"
|
||||
char >= 0x61 # "a"
|
||||
and char <= 0x7A # "z"
|
||||
then
|
||||
Ok(@Variable(char))
|
||||
else
|
||||
|
|
|
@ -457,21 +457,15 @@ pop_variable = \ctx ->
|
|||
|
||||
is_digit : U8 -> Bool
|
||||
is_digit = \char ->
|
||||
char
|
||||
>= 0x30 # `0`
|
||||
&& char
|
||||
<= 0x39 # `0`
|
||||
char >= 0x30 # `0`
|
||||
and char <= 0x39 # `0`
|
||||
|
||||
is_whitespace : U8 -> Bool
|
||||
is_whitespace = \char ->
|
||||
char
|
||||
== 0xA # new line
|
||||
|| char
|
||||
== 0xD # carriage return
|
||||
|| char
|
||||
== 0x20 # space
|
||||
|| char
|
||||
== 0x9 # tab
|
||||
char == 0xA # new line
|
||||
or char == 0xD # carriage return
|
||||
or char == 0x20 # space
|
||||
or char == 0x9 # tab
|
||||
|
||||
end_unexpected = \err ->
|
||||
when err is
|
||||
|
|
|
@ -212,6 +212,7 @@ comptime {
|
|||
exportStrFn(str.withCapacityC, "with_capacity");
|
||||
exportStrFn(str.strAllocationPtr, "allocation_ptr");
|
||||
exportStrFn(str.strReleaseExcessCapacity, "release_excess_capacity");
|
||||
exportStrFn(str.strWithAsciiLowercased, "with_ascii_lowercased");
|
||||
|
||||
for (INTEGERS) |T| {
|
||||
str.exportFromInt(T, ROC_BUILTINS ++ "." ++ STR ++ ".from_int.");
|
||||
|
|
|
@ -2,6 +2,7 @@ const utils = @import("utils.zig");
|
|||
const RocList = @import("list.zig").RocList;
|
||||
const UpdateMode = utils.UpdateMode;
|
||||
const std = @import("std");
|
||||
const ascii = std.ascii;
|
||||
const mem = std.mem;
|
||||
const unicode = std.unicode;
|
||||
const testing = std.testing;
|
||||
|
@ -370,11 +371,17 @@ pub const RocStr = extern struct {
|
|||
}
|
||||
|
||||
fn refcount(self: RocStr) usize {
|
||||
if ((self.getCapacity() == 0 and !self.isSeamlessSlice()) or self.isSmallStr()) {
|
||||
const is_seamless_slice = self.isSeamlessSlice();
|
||||
if ((self.getCapacity() == 0 and !is_seamless_slice) or self.isSmallStr()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const ptr: [*]usize = @as([*]usize, @ptrCast(@alignCast(self.bytes)));
|
||||
const data_ptr = if (is_seamless_slice)
|
||||
self.getAllocationPtr()
|
||||
else
|
||||
self.bytes;
|
||||
|
||||
const ptr: [*]usize = @as([*]usize, @ptrCast(@alignCast(data_ptr)));
|
||||
return (ptr - 1)[0];
|
||||
}
|
||||
|
||||
|
@ -611,16 +618,6 @@ fn initFromSmallStr(slice_bytes: [*]u8, len: usize, _: usize) RocStr {
|
|||
return RocStr.init(slice_bytes, len);
|
||||
}
|
||||
|
||||
// The alloc_ptr must already be shifted to be ready for storing in a seamless slice.
|
||||
fn initFromBigStr(slice_bytes: [*]u8, len: usize, alloc_ptr: usize) RocStr {
|
||||
// Here we can make seamless slices instead of copying to a new small str.
|
||||
return RocStr{
|
||||
.bytes = slice_bytes,
|
||||
.length = len | SEAMLESS_SLICE_BIT,
|
||||
.capacity_or_alloc_ptr = alloc_ptr,
|
||||
};
|
||||
}
|
||||
|
||||
fn strSplitOnHelp(array: [*]RocStr, string: RocStr, delimiter: RocStr) void {
|
||||
if (delimiter.len() == 0) {
|
||||
string.incref(1);
|
||||
|
@ -2138,6 +2135,66 @@ fn countTrailingWhitespaceBytes(string: RocStr) usize {
|
|||
return byte_count;
|
||||
}
|
||||
|
||||
// Str.with_ascii_lowercased
|
||||
pub fn strWithAsciiLowercased(string: RocStr) callconv(.C) RocStr {
|
||||
var new_str = if (string.isUnique())
|
||||
string
|
||||
else blk: {
|
||||
string.decref();
|
||||
break :blk RocStr.fromSlice(string.asSlice());
|
||||
};
|
||||
|
||||
const new_str_bytes = new_str.asU8ptrMut()[0..string.len()];
|
||||
for (new_str_bytes) |*c| {
|
||||
c.* = ascii.toLower(c.*);
|
||||
}
|
||||
return new_str;
|
||||
}
|
||||
|
||||
test "withAsciiLowercased: small str" {
|
||||
const original = RocStr.fromSlice("cOFFÉ");
|
||||
try expect(original.isSmallStr());
|
||||
|
||||
const expected = RocStr.fromSlice("coffÉ");
|
||||
defer expected.decref();
|
||||
|
||||
const str_result = strWithAsciiLowercased(original);
|
||||
defer str_result.decref();
|
||||
|
||||
try expect(str_result.isSmallStr());
|
||||
try expect(str_result.eq(expected));
|
||||
}
|
||||
|
||||
test "withAsciiLowercased: non small str" {
|
||||
const original = RocStr.fromSlice("cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ");
|
||||
defer original.decref();
|
||||
try expect(!original.isSmallStr());
|
||||
|
||||
const expected = RocStr.fromSlice("coffÉ coffÉ coffÉ coffÉ coffÉ coffÉ");
|
||||
defer expected.decref();
|
||||
|
||||
const str_result = strWithAsciiLowercased(original);
|
||||
|
||||
try expect(!str_result.isSmallStr());
|
||||
try expect(str_result.eq(expected));
|
||||
}
|
||||
|
||||
test "withAsciiLowercased: seamless slice" {
|
||||
const l = RocStr.fromSlice("cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ");
|
||||
const original = substringUnsafeC(l, 1, l.len() - 1);
|
||||
defer original.decref();
|
||||
|
||||
try expect(original.isSeamlessSlice());
|
||||
|
||||
const expected = RocStr.fromSlice("offÉ coffÉ coffÉ coffÉ coffÉ coffÉ");
|
||||
defer expected.decref();
|
||||
|
||||
const str_result = strWithAsciiLowercased(original);
|
||||
|
||||
try expect(!str_result.isSmallStr());
|
||||
try expect(str_result.eq(expected));
|
||||
}
|
||||
|
||||
fn rcNone(_: ?[*]u8) callconv(.C) void {}
|
||||
|
||||
fn decStr(ptr: ?[*]u8) callconv(.C) void {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module [Bool, Eq, true, false, and, or, not, is_eq, is_not_eq]
|
||||
module [Bool, Eq, true, false, not, is_eq, is_not_eq]
|
||||
|
||||
## Defines a type that can be compared for total equality.
|
||||
##
|
||||
|
@ -44,55 +44,6 @@ true = @Bool(True)
|
|||
false : Bool
|
||||
false = @Bool(False)
|
||||
|
||||
## Returns `Bool.true` when both inputs are `Bool.true`. This is equivalent to
|
||||
## the logic [AND](https://en.wikipedia.org/wiki/Logical_conjunction)
|
||||
## gate. The infix operator `&&` can also be used as shorthand for
|
||||
## `Bool.and`.
|
||||
##
|
||||
## ```roc
|
||||
## expect Bool.and(Bool.true, Bool.true) == Bool.true
|
||||
## expect (Bool.true && Bool.true) == Bool.true
|
||||
## expect (Bool.false && Bool.true) == Bool.false
|
||||
## expect (Bool.true && Bool.false) == Bool.false
|
||||
## expect (Bool.false && Bool.false) == Bool.false
|
||||
## ```
|
||||
##
|
||||
## ## Performance Details
|
||||
##
|
||||
## In Roc the `&&` and `||` work the same way as any
|
||||
## other function. However, in some languages `&&` and `||` are special-cased.
|
||||
## In these languages the compiler will skip evaluating the expression after the
|
||||
## first operator under certain circumstances. For example an expression like
|
||||
## `enable_pets && likes_dogs(user)` would compile to.
|
||||
## ```roc
|
||||
## if enable_pets then
|
||||
## likes_dogs(user)
|
||||
## else
|
||||
## Bool.false
|
||||
## ```
|
||||
## Roc does not do this because conditionals like `if` and `when` have a
|
||||
## performance cost. Calling a function can sometimes be faster across the board
|
||||
## than doing an `if` to decide whether to skip calling it.
|
||||
and : Bool, Bool -> Bool
|
||||
|
||||
## Returns `Bool.true` when either input is a `Bool.true`. This is equivalent to
|
||||
## the logic [OR](https://en.wikipedia.org/wiki/Logical_disjunction) gate.
|
||||
## The infix operator `||` can also be used as shorthand for `Bool.or`.
|
||||
## ```roc
|
||||
## expect Bool.or(Bool.false, Bool.true) == Bool.true
|
||||
## expect (Bool.true || Bool.true) == Bool.true
|
||||
## expect (Bool.false || Bool.true) == Bool.true
|
||||
## expect (Bool.true || Bool.false) == Bool.true
|
||||
## expect (Bool.false || Bool.false) == Bool.false
|
||||
## ```
|
||||
##
|
||||
## ## Performance Details
|
||||
##
|
||||
## In Roc the `&&` and `||` work the same way as any
|
||||
## other functions. However, in some languages `&&` and `||` are special-cased.
|
||||
## Refer to the note in `Bool.and` for more detail.
|
||||
or : Bool, Bool -> Bool
|
||||
|
||||
## Returns `Bool.false` when given `Bool.true`, and vice versa. This is
|
||||
## equivalent to the logic [NOT](https://en.wikipedia.org/wiki/Negation)
|
||||
## gate. The operator `!` can also be used as shorthand for `Bool.not`.
|
||||
|
|
|
@ -170,7 +170,7 @@ reserve = |@Dict({ buckets, data, max_bucket_capacity: original_max_bucket_capac
|
|||
size = Num.min(requested_size, max_size)
|
||||
|
||||
requested_shifts = calc_shifts_for_size(size, max_load_factor)
|
||||
if List.is_empty(buckets) || requested_shifts > shifts then
|
||||
if List.is_empty(buckets) or requested_shifts > shifts then
|
||||
(buckets0, max_bucket_capacity) = alloc_buckets_from_shift(requested_shifts, max_load_factor)
|
||||
buckets1 = fill_buckets_from_data(buckets0, data, requested_shifts)
|
||||
@Dict(
|
||||
|
@ -915,7 +915,7 @@ calc_shifts_for_size_helper = |shifts, size, max_load_factor|
|
|||
|> Num.to_f32
|
||||
|> Num.mul(max_load_factor)
|
||||
|> Num.floor
|
||||
if shifts > 0 && max_bucket_capacity < size then
|
||||
if shifts > 0 and max_bucket_capacity < size then
|
||||
calc_shifts_for_size_helper(Num.sub_wrap(shifts, 1), size, max_load_factor)
|
||||
else
|
||||
shifts
|
||||
|
@ -1087,7 +1087,7 @@ expect
|
|||
|> insert("bar", {})
|
||||
|> insert("baz", {})
|
||||
|
||||
contains(dict, "baz") && !(contains(dict, "other"))
|
||||
contains(dict, "baz") and !(contains(dict, "other"))
|
||||
|
||||
expect
|
||||
dict =
|
||||
|
@ -1145,17 +1145,17 @@ expect
|
|||
|> insert("l", 11)
|
||||
|
||||
(get(dict, "a") == Ok(0))
|
||||
&& (get(dict, "b") == Ok(1))
|
||||
&& (get(dict, "c") == Ok(2))
|
||||
&& (get(dict, "d") == Ok(3))
|
||||
&& (get(dict, "e") == Ok(4))
|
||||
&& (get(dict, "f") == Ok(5))
|
||||
&& (get(dict, "g") == Ok(6))
|
||||
&& (get(dict, "h") == Ok(7))
|
||||
&& (get(dict, "i") == Ok(8))
|
||||
&& (get(dict, "j") == Ok(9))
|
||||
&& (get(dict, "k") == Ok(10))
|
||||
&& (get(dict, "l") == Ok(11))
|
||||
and (get(dict, "b") == Ok(1))
|
||||
and (get(dict, "c") == Ok(2))
|
||||
and (get(dict, "d") == Ok(3))
|
||||
and (get(dict, "e") == Ok(4))
|
||||
and (get(dict, "f") == Ok(5))
|
||||
and (get(dict, "g") == Ok(6))
|
||||
and (get(dict, "h") == Ok(7))
|
||||
and (get(dict, "i") == Ok(8))
|
||||
and (get(dict, "j") == Ok(9))
|
||||
and (get(dict, "k") == Ok(10))
|
||||
and (get(dict, "l") == Ok(11))
|
||||
|
||||
# Force rehash.
|
||||
expect
|
||||
|
@ -1197,18 +1197,18 @@ expect
|
|||
|> insert("m", 12)
|
||||
|
||||
(get(dict, "a") == Ok(0))
|
||||
&& (get(dict, "b") == Ok(1))
|
||||
&& (get(dict, "c") == Ok(2))
|
||||
&& (get(dict, "d") == Ok(3))
|
||||
&& (get(dict, "e") == Ok(4))
|
||||
&& (get(dict, "f") == Ok(5))
|
||||
&& (get(dict, "g") == Ok(6))
|
||||
&& (get(dict, "h") == Ok(7))
|
||||
&& (get(dict, "i") == Ok(8))
|
||||
&& (get(dict, "j") == Ok(9))
|
||||
&& (get(dict, "k") == Ok(10))
|
||||
&& (get(dict, "l") == Ok(11))
|
||||
&& (get(dict, "m") == Ok(12))
|
||||
and (get(dict, "b") == Ok(1))
|
||||
and (get(dict, "c") == Ok(2))
|
||||
and (get(dict, "d") == Ok(3))
|
||||
and (get(dict, "e") == Ok(4))
|
||||
and (get(dict, "f") == Ok(5))
|
||||
and (get(dict, "g") == Ok(6))
|
||||
and (get(dict, "h") == Ok(7))
|
||||
and (get(dict, "i") == Ok(8))
|
||||
and (get(dict, "j") == Ok(9))
|
||||
and (get(dict, "k") == Ok(10))
|
||||
and (get(dict, "l") == Ok(11))
|
||||
and (get(dict, "m") == Ok(12))
|
||||
|
||||
expect
|
||||
empty({})
|
||||
|
@ -1266,7 +1266,7 @@ expect
|
|||
bad_keys,
|
||||
Bool.true,
|
||||
|acc, k|
|
||||
acc && Dict.contains(dict, k),
|
||||
acc and Dict.contains(dict, k),
|
||||
)
|
||||
|
||||
all_inserted_correctly
|
||||
|
|
|
@ -1361,7 +1361,7 @@ split_last = |list, delimiter|
|
|||
## result is an empty list.
|
||||
chunks_of : List a, U64 -> List (List a)
|
||||
chunks_of = |list, chunk_size|
|
||||
if chunk_size == 0 || List.is_empty(list) then
|
||||
if chunk_size == 0 or List.is_empty(list) then
|
||||
[]
|
||||
else
|
||||
chunk_capacity = Num.div_ceil(List.len(list), chunk_size)
|
||||
|
|
|
@ -532,7 +532,7 @@ pi = 3.14159265358979323846264338327950288419716939937510
|
|||
|
||||
## Circle constant (τ)
|
||||
tau : Frac *
|
||||
tau = 2 * pi
|
||||
tau = 6.2831853071795864769252867665590057683943387987502
|
||||
|
||||
# ------- Functions
|
||||
## Convert a number to a [Str].
|
||||
|
@ -619,9 +619,9 @@ is_gte : Num a, Num a -> Bool
|
|||
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
||||
is_approx_eq : Frac a, Frac a, { rtol ?? Frac a, atol ?? Frac a } -> Bool
|
||||
is_approx_eq = |x, y, { rtol ?? 0.00001, atol ?? 0.00000001 }|
|
||||
eq = x <= y && x >= y
|
||||
eq = x <= y and x >= y
|
||||
meets_tolerance = Num.abs_diff(x, y) <= Num.max(atol, (rtol * Num.max(Num.abs(x), Num.abs(y))))
|
||||
eq || meets_tolerance
|
||||
eq or meets_tolerance
|
||||
|
||||
## Returns `Bool.true` if the number is `0`, and `Bool.false` otherwise.
|
||||
is_zero : Num a -> Bool
|
||||
|
|
|
@ -373,6 +373,7 @@ module [
|
|||
contains,
|
||||
drop_prefix,
|
||||
drop_suffix,
|
||||
with_ascii_lowercased,
|
||||
]
|
||||
|
||||
import Bool exposing [Bool]
|
||||
|
@ -1205,7 +1206,7 @@ matches_at_help = |state|
|
|||
},
|
||||
)
|
||||
|
||||
does_this_match && does_rest_match
|
||||
does_this_match and does_rest_match
|
||||
|
||||
## Walks over the `UTF-8` bytes of the given [Str] and calls a function to update
|
||||
## state for each byte. The index for that byte in the string is provided
|
||||
|
@ -1325,3 +1326,29 @@ drop_suffix = |haystack, suffix|
|
|||
substring_unsafe(haystack, start, len)
|
||||
else
|
||||
haystack
|
||||
|
||||
## Returns a version of the string with all [ASCII characters](https://en.wikipedia.org/wiki/ASCII) lowercased.
|
||||
## Non-ASCII characters are left unmodified. For example:
|
||||
##
|
||||
## ```roc
|
||||
## expect "CAFÉ".with_ascii_lowercased() == "cafÉ"
|
||||
## ```
|
||||
##
|
||||
## This function is useful for things like [command-line options](https://en.wikipedia.org/wiki/Command-line_interface#Command-line_option)
|
||||
## and [environment variables](https://en.wikipedia.org/wiki/Environment_variable)
|
||||
## know in advance that you're dealing with a hardcoded string containing only ASCII characters.
|
||||
## It has better performance than lowercasing operations which take Unicode into account.
|
||||
##
|
||||
## That said, strings received from user input can always contain
|
||||
## non-ASCII Unicode characters, and lowercasing [Unicode](https://unicode.org) works
|
||||
## differently in different languages. For example, the string `"I"` lowercases to `"i"`
|
||||
## in English and to `"ı"` (a [dotless i](https://en.wikipedia.org/wiki/Dotless_I))
|
||||
## in Turkish. These rules can also change in each [Unicode release](https://www.unicode.org/releases/),
|
||||
## so we have separate [`unicode` package](https://github.com/roc-lang/unicode)
|
||||
## for Unicode capitalization that can be upgraded independently from the language's builtins.
|
||||
##
|
||||
## To do a case-insensitive comparison of the ASCII characters in a string,
|
||||
## use [`caseless_ascii_equals`](#caseless_ascii_equals).
|
||||
with_ascii_lowercased : Str -> Str
|
||||
|
||||
expect Str.with_ascii_lowercased("cOFFÉ") == "coffÉ"
|
||||
|
|
|
@ -359,6 +359,7 @@ pub const STR_CLONE_TO: &str = "roc_builtins.str.clone_to";
|
|||
pub const STR_WITH_CAPACITY: &str = "roc_builtins.str.with_capacity";
|
||||
pub const STR_ALLOCATION_PTR: &str = "roc_builtins.str.allocation_ptr";
|
||||
pub const STR_RELEASE_EXCESS_CAPACITY: &str = "roc_builtins.str.release_excess_capacity";
|
||||
pub const STR_WITH_ASCII_LOWERCASED: &str = "roc_builtins.str.with_ascii_lowercased";
|
||||
|
||||
pub const LIST_MAP: &str = "roc_builtins.list.map";
|
||||
pub const LIST_MAP2: &str = "roc_builtins.list.map2";
|
||||
|
|
|
@ -8,6 +8,7 @@ license.workspace = true
|
|||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
roc_can_solo.workspace = true
|
||||
roc_collections.workspace = true
|
||||
roc_error_macros.workspace = true
|
||||
roc_exhaustive.workspace = true
|
||||
|
|
|
@ -131,6 +131,7 @@ map_symbol_to_lowlevel_and_arity! {
|
|||
StrToNum; STR_TO_NUM; 1,
|
||||
StrWithCapacity; STR_WITH_CAPACITY; 1,
|
||||
StrReleaseExcessCapacity; STR_RELEASE_EXCESS_CAPACITY; 1,
|
||||
StrWithAsciiLowercased; STR_WITH_ASCII_LOWERCASED; 1,
|
||||
|
||||
ListLenUsize; LIST_LEN_USIZE; 1,
|
||||
ListLenU64; LIST_LEN_U64; 1,
|
||||
|
@ -213,8 +214,6 @@ map_symbol_to_lowlevel_and_arity! {
|
|||
|
||||
Eq; BOOL_STRUCTURAL_EQ; 2,
|
||||
NotEq; BOOL_STRUCTURAL_NOT_EQ; 2,
|
||||
And; BOOL_AND; 2,
|
||||
Or; BOOL_OR; 2,
|
||||
Not; BOOL_NOT; 1,
|
||||
BoxExpr; BOX_BOX_FUNCTION; 1,
|
||||
UnboxExpr; BOX_UNBOX; 1,
|
||||
|
|
|
@ -915,7 +915,7 @@ pub struct DefTypes {
|
|||
pub loc_symbols: Slice<(Symbol, Region)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Generalizable(pub bool);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,6 +11,7 @@ use roc_region::all::{LineInfo, Loc, Region};
|
|||
use roc_types::subs::Variable;
|
||||
|
||||
/// The canonicalization environment for a particular module.
|
||||
#[derive(Debug)]
|
||||
pub struct Env<'a> {
|
||||
/// The module's path. Opaques and unqualified references to identifiers
|
||||
/// are assumed to be relative to this path.
|
||||
|
@ -51,6 +52,36 @@ pub struct Env<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Env<'a> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn from_solo_can(
|
||||
arena: &'a Bump,
|
||||
module_path: &'a Path,
|
||||
home: ModuleId,
|
||||
dep_idents: &'a IdentIdsByModule,
|
||||
qualified_module_ids: &'a PackageModuleIds<'a>,
|
||||
problems: Vec<Problem>,
|
||||
opt_shorthand: Option<&'a str>,
|
||||
src: &'a str,
|
||||
line_info: &'a mut Option<LineInfo>,
|
||||
) -> Self {
|
||||
Env {
|
||||
arena,
|
||||
src,
|
||||
home,
|
||||
module_path,
|
||||
dep_idents,
|
||||
qualified_module_ids,
|
||||
problems,
|
||||
closures: MutMap::default(),
|
||||
qualified_value_lookups: Default::default(),
|
||||
tailcallable_symbol: None,
|
||||
top_level_symbols: Default::default(),
|
||||
home_params_record: None,
|
||||
opt_shorthand,
|
||||
line_info,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
arena: &'a Bump,
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use std::path::Path;
|
||||
|
||||
use crate::abilities::{AbilitiesStore, ImplKey, PendingAbilitiesStore, ResolvedImpl};
|
||||
use crate::annotation::{canonicalize_annotation, AnnotationFor};
|
||||
use crate::def::{canonicalize_defs, report_unused_imports, Def, DefKind};
|
||||
use crate::desugar::desugar_record_destructures;
|
||||
use crate::env::Env;
|
||||
use crate::expr::{ClosureData, Declarations, ExpectLookup, Expr, Output, PendingDerives};
|
||||
use crate::pattern::{
|
||||
|
@ -16,8 +13,8 @@ use roc_collections::{MutMap, SendMap, VecMap, VecSet};
|
|||
use roc_error_macros::internal_error;
|
||||
use roc_module::ident::Ident;
|
||||
use roc_module::ident::Lowercase;
|
||||
use roc_module::symbol::{IdentId, IdentIds, IdentIdsByModule, ModuleId, PackageModuleIds, Symbol};
|
||||
use roc_parse::ast::{Defs, TypeAnnotation};
|
||||
use roc_module::symbol::{IdentId, ModuleId, Symbol};
|
||||
use roc_parse::ast::{Collection, Defs, Pattern as ParsePattern, TypeAnnotation};
|
||||
use roc_parse::header::HeaderType;
|
||||
use roc_parse::pattern::PatternType;
|
||||
use roc_problem::can::{Problem, RuntimeError};
|
||||
|
@ -209,55 +206,19 @@ fn has_no_implementation(expr: &Expr) -> bool {
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn canonicalize_module_defs<'a>(
|
||||
arena: &'a Bump,
|
||||
loc_defs: &'a mut Defs<'a>,
|
||||
header_type: &'a roc_parse::header::HeaderType,
|
||||
home: ModuleId,
|
||||
module_path: &'a str,
|
||||
src: &'a str,
|
||||
qualified_module_ids: &'a PackageModuleIds<'a>,
|
||||
exposed_ident_ids: IdentIds,
|
||||
dep_idents: &'a IdentIdsByModule,
|
||||
aliases: MutMap<Symbol, Alias>,
|
||||
imported_abilities_state: PendingAbilitiesStore,
|
||||
initial_scope: MutMap<Ident, (Symbol, Region)>,
|
||||
exposed_symbols: VecSet<Symbol>,
|
||||
symbols_from_requires: &[(Loc<Symbol>, Loc<TypeAnnotation<'a>>)],
|
||||
var_store: &mut VarStore,
|
||||
opt_shorthand: Option<&'a str>,
|
||||
mut scope: Scope,
|
||||
mut env: Env<'a>,
|
||||
loc_defs: Defs<'a>,
|
||||
module_params: Option<(Region, Collection<'a, Loc<ParsePattern<'a>>>)>,
|
||||
) -> ModuleOutput {
|
||||
let mut can_exposed_imports = MutMap::default();
|
||||
|
||||
let mut scope = Scope::new(
|
||||
home,
|
||||
qualified_module_ids
|
||||
.get_name(home)
|
||||
.expect("home module not found")
|
||||
.as_inner()
|
||||
.to_owned(),
|
||||
exposed_ident_ids,
|
||||
imported_abilities_state,
|
||||
);
|
||||
let mut env = Env::new(
|
||||
arena,
|
||||
src,
|
||||
home,
|
||||
arena.alloc(Path::new(module_path)),
|
||||
dep_idents,
|
||||
qualified_module_ids,
|
||||
opt_shorthand,
|
||||
);
|
||||
|
||||
for (name, alias) in aliases.into_iter() {
|
||||
scope.add_alias(
|
||||
name,
|
||||
alias.region,
|
||||
alias.type_variables,
|
||||
alias.infer_ext_in_output_variables,
|
||||
alias.typ,
|
||||
alias.kind,
|
||||
);
|
||||
}
|
||||
|
||||
// Desugar operators (convert them to Apply calls, taking into account
|
||||
// operator precedence and associativity rules), before doing other canonicalization.
|
||||
//
|
||||
|
@ -266,8 +227,6 @@ pub fn canonicalize_module_defs<'a>(
|
|||
// operators, and then again on *their* nested operators, ultimately applying the
|
||||
// rules multiple times unnecessarily.
|
||||
|
||||
crate::desugar::desugar_defs_node_values(&mut env, &mut scope, loc_defs);
|
||||
|
||||
let mut rigid_variables = RigidVariables::default();
|
||||
|
||||
// Initial scope values are treated like defs that appear before any others.
|
||||
|
@ -319,51 +278,42 @@ pub fn canonicalize_module_defs<'a>(
|
|||
|
||||
let mut output = Output::default();
|
||||
|
||||
let module_params = header_type.get_params().as_ref().map(
|
||||
|roc_parse::header::ModuleParams {
|
||||
pattern,
|
||||
before_arrow: _,
|
||||
after_arrow: _,
|
||||
}| {
|
||||
let desugared_patterns =
|
||||
desugar_record_destructures(&mut env, &mut scope, pattern.value);
|
||||
let module_params = module_params.map(|(params_region, desugared_patterns)| {
|
||||
let (destructs, _) = canonicalize_record_destructs(
|
||||
&mut env,
|
||||
var_store,
|
||||
&mut scope,
|
||||
&mut output,
|
||||
PatternType::ModuleParams,
|
||||
&desugared_patterns,
|
||||
params_region,
|
||||
PermitShadows(false),
|
||||
);
|
||||
|
||||
let (destructs, _) = canonicalize_record_destructs(
|
||||
&mut env,
|
||||
var_store,
|
||||
&mut scope,
|
||||
&mut output,
|
||||
PatternType::ModuleParams,
|
||||
&desugared_patterns,
|
||||
pattern.region,
|
||||
PermitShadows(false),
|
||||
);
|
||||
let whole_symbol = scope.gen_unique_symbol();
|
||||
env.top_level_symbols.insert(whole_symbol);
|
||||
|
||||
let whole_symbol = scope.gen_unique_symbol();
|
||||
env.top_level_symbols.insert(whole_symbol);
|
||||
let whole_var = var_store.fresh();
|
||||
|
||||
let whole_var = var_store.fresh();
|
||||
env.home_params_record = Some((whole_symbol, whole_var));
|
||||
|
||||
env.home_params_record = Some((whole_symbol, whole_var));
|
||||
|
||||
ModuleParams {
|
||||
region: pattern.region,
|
||||
whole_var,
|
||||
whole_symbol,
|
||||
record_var: var_store.fresh(),
|
||||
record_ext_var: var_store.fresh(),
|
||||
destructs,
|
||||
arity_by_name: Default::default(),
|
||||
}
|
||||
},
|
||||
);
|
||||
ModuleParams {
|
||||
region: params_region,
|
||||
whole_var,
|
||||
whole_symbol,
|
||||
record_var: var_store.fresh(),
|
||||
record_ext_var: var_store.fresh(),
|
||||
destructs,
|
||||
arity_by_name: Default::default(),
|
||||
}
|
||||
});
|
||||
|
||||
let (defs, output, symbols_introduced, imports_introduced) = canonicalize_defs(
|
||||
&mut env,
|
||||
output,
|
||||
var_store,
|
||||
&mut scope,
|
||||
loc_defs,
|
||||
arena.alloc(loc_defs),
|
||||
PatternType::TopLevelDef,
|
||||
);
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
extern crate bumpalo;
|
||||
|
||||
use self::bumpalo::Bump;
|
||||
use roc_can::desugar;
|
||||
use roc_can::env::Env;
|
||||
use roc_can::expr::{canonicalize_expr, Expr};
|
||||
use roc_can::scope::Scope;
|
||||
use roc_can_solo::env::SoloEnv;
|
||||
use roc_can_solo::scope::SoloScope;
|
||||
use roc_collections::all::MutMap;
|
||||
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, PackageModuleIds, Symbol};
|
||||
use roc_problem::can::Problem;
|
||||
|
@ -65,7 +66,9 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
|
|||
// visited a BinOp node we'd recursively try to apply this to each of its nested
|
||||
// operators, and then again on *their* nested operators, ultimately applying the
|
||||
// rules multiple times unnecessarily.
|
||||
let loc_expr = desugar::desugar_expr(&mut env, &mut scope, &loc_expr);
|
||||
let mut solo_env = SoloEnv::new(arena, expr_str, Path::new("Test.roc"));
|
||||
let mut solo_scope = SoloScope::new();
|
||||
let loc_expr = roc_can_solo::desugar::desugar_expr(&mut solo_env, &mut solo_scope, &loc_expr);
|
||||
|
||||
scope.add_alias(
|
||||
Symbol::NUM_INT,
|
||||
|
|
|
@ -972,7 +972,59 @@ mod test_can {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn try_desugar_double_question_binop() {
|
||||
fn try_desugar_works_elsewhere() {
|
||||
let src = indoc!(
|
||||
r#"
|
||||
when Foo 123 is
|
||||
Foo try -> try
|
||||
"#
|
||||
);
|
||||
let arena = Bump::new();
|
||||
let out = can_expr_with(&arena, test_home(), src);
|
||||
|
||||
assert_eq!(out.problems, Vec::new());
|
||||
|
||||
// Assert that we don't treat `try` as a keyword here
|
||||
// by desugaring to:
|
||||
//
|
||||
// when Foo 123 is
|
||||
// Foo try -> try
|
||||
|
||||
let (cond_expr, branches) = assert_when_expr(&out.loc_expr.value);
|
||||
match cond_expr {
|
||||
Expr::Tag {
|
||||
name, arguments, ..
|
||||
} => {
|
||||
assert_eq!(name.0.to_string(), "Foo");
|
||||
assert_eq!(arguments.len(), 1);
|
||||
assert_num_value(&arguments[0].1.value, 123);
|
||||
}
|
||||
_ => panic!("cond_expr was not a Tag: {:?}", cond_expr),
|
||||
}
|
||||
|
||||
assert_eq!(branches.len(), 1);
|
||||
assert_eq!(branches[0].patterns.len(), 1);
|
||||
assert!(!branches[0].patterns[0].degenerate);
|
||||
|
||||
match &branches[0].patterns[0].pattern.value {
|
||||
Pattern::AppliedTag {
|
||||
tag_name,
|
||||
arguments,
|
||||
..
|
||||
} => {
|
||||
assert_eq!(tag_name.0.to_string(), "Foo");
|
||||
assert_eq!(arguments.len(), 1);
|
||||
assert_pattern_name(&arguments[0].1.value, "try", &out.interns);
|
||||
}
|
||||
other => panic!("First argument was not an applied tag: {:?}", other),
|
||||
}
|
||||
|
||||
assert_var_usage(&branches[0].value.value, "try", &out.interns);
|
||||
assert!(&branches[0].guard.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn desugar_double_question_binop() {
|
||||
let src = indoc!(
|
||||
r#"
|
||||
Str.to_u64("123") ?? Num.max_u64
|
||||
|
@ -989,7 +1041,7 @@ mod test_can {
|
|||
// Ok(#double_question_ok_0_17) -> Ok(#double_question_ok_0_17)
|
||||
// Err(_) -> Num.max_u64
|
||||
|
||||
let (cond_expr, branches) = assert_when(&out.loc_expr.value);
|
||||
let (cond_expr, branches) = assert_when_expr(&out.loc_expr.value);
|
||||
let cond_args = assert_func_call(cond_expr, "to_u64", CalledVia::Space, &out.interns);
|
||||
|
||||
assert_eq!(cond_args.len(), 1);
|
||||
|
@ -1016,7 +1068,7 @@ mod test_can {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn try_desugar_single_question_binop() {
|
||||
fn desugar_single_question_binop() {
|
||||
let src = indoc!(
|
||||
r#"
|
||||
Str.to_u64("123") ? FailedToConvert
|
||||
|
@ -1033,7 +1085,7 @@ mod test_can {
|
|||
// Ok(#single_question_ok_0_17) -> #single_question_ok_0_17
|
||||
// Err(#single_question_err_0_17) -> return Err(FailedToConvert(#single_question_err_0_17))
|
||||
|
||||
let (cond_expr, branches) = assert_when(&out.loc_expr.value);
|
||||
let (cond_expr, branches) = assert_when_expr(&out.loc_expr.value);
|
||||
let cond_args = assert_func_call(cond_expr, "to_u64", CalledVia::Space, &out.interns);
|
||||
|
||||
assert_eq!(cond_args.len(), 1);
|
||||
|
@ -1075,11 +1127,13 @@ mod test_can {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn try_desugar_works_elsewhere() {
|
||||
fn desugar_and_operator() {
|
||||
let src = indoc!(
|
||||
r#"
|
||||
when Foo 123 is
|
||||
Foo try -> try
|
||||
left = Bool.true
|
||||
right = Bool.false
|
||||
|
||||
left and right
|
||||
"#
|
||||
);
|
||||
let arena = Bump::new();
|
||||
|
@ -1087,43 +1141,49 @@ mod test_can {
|
|||
|
||||
assert_eq!(out.problems, Vec::new());
|
||||
|
||||
// Assert that we don't treat `try` as a keyword here
|
||||
// by desugaring to:
|
||||
// Assert that we desugar to:
|
||||
//
|
||||
// when Foo 123 is
|
||||
// Foo try -> try
|
||||
// if left then right else Bool.false
|
||||
|
||||
let (cond_expr, branches) = assert_when(&out.loc_expr.value);
|
||||
match cond_expr {
|
||||
Expr::Tag {
|
||||
name, arguments, ..
|
||||
} => {
|
||||
assert_eq!(name.0.to_string(), "Foo");
|
||||
assert_eq!(arguments.len(), 1);
|
||||
assert_num_value(&arguments[0].1.value, 123);
|
||||
}
|
||||
_ => panic!("cond_expr was not a Tag: {:?}", cond_expr),
|
||||
}
|
||||
let continuation1 = assert_let_expr(&out.loc_expr.value);
|
||||
let continuation2 = assert_let_expr(&continuation1.value);
|
||||
let (branches, final_else) = assert_if_expr(&continuation2.value);
|
||||
|
||||
assert_eq!(branches.len(), 1);
|
||||
assert_eq!(branches[0].patterns.len(), 1);
|
||||
assert!(!branches[0].patterns[0].degenerate);
|
||||
|
||||
match &branches[0].patterns[0].pattern.value {
|
||||
Pattern::AppliedTag {
|
||||
tag_name,
|
||||
arguments,
|
||||
..
|
||||
} => {
|
||||
assert_eq!(tag_name.0.to_string(), "Foo");
|
||||
assert_eq!(arguments.len(), 1);
|
||||
assert_pattern_name(&arguments[0].1.value, "try", &out.interns);
|
||||
}
|
||||
other => panic!("First argument was not an applied tag: {:?}", other),
|
||||
}
|
||||
assert_var_usage(&branches[0].0.value, "left", &out.interns);
|
||||
assert_var_usage(&branches[0].1.value, "right", &out.interns);
|
||||
assert_var_usage(&final_else.value, "false", &out.interns);
|
||||
}
|
||||
|
||||
assert_var_usage(&branches[0].value.value, "try", &out.interns);
|
||||
assert!(&branches[0].guard.is_none());
|
||||
#[test]
|
||||
fn desugar_or_operator() {
|
||||
let src = indoc!(
|
||||
r#"
|
||||
left = Bool.true
|
||||
right = Bool.false
|
||||
|
||||
left or right
|
||||
"#
|
||||
);
|
||||
let arena = Bump::new();
|
||||
let out = can_expr_with(&arena, test_home(), src);
|
||||
|
||||
assert_eq!(out.problems, Vec::new());
|
||||
|
||||
// Assert that we desugar to:
|
||||
//
|
||||
// if left then Bool.true else right
|
||||
|
||||
let continuation1 = assert_let_expr(&out.loc_expr.value);
|
||||
let continuation2 = assert_let_expr(&continuation1.value);
|
||||
let (branches, final_else) = assert_if_expr(&continuation2.value);
|
||||
|
||||
assert_eq!(branches.len(), 1);
|
||||
|
||||
assert_var_usage(&branches[0].0.value, "left", &out.interns);
|
||||
assert_var_usage(&branches[0].1.value, "true", &out.interns);
|
||||
assert_var_usage(&final_else.value, "right", &out.interns);
|
||||
}
|
||||
|
||||
fn assert_num_value(expr: &Expr, num: usize) {
|
||||
|
@ -1238,7 +1298,14 @@ mod test_can {
|
|||
}
|
||||
}
|
||||
|
||||
fn assert_when(expr: &Expr) -> (&Expr, &Vec<WhenBranch>) {
|
||||
fn assert_let_expr(expr: &Expr) -> &Loc<Expr> {
|
||||
match expr {
|
||||
Expr::LetNonRec(_, continuation) | Expr::LetRec(_, continuation, _) => continuation,
|
||||
_ => panic!("Expr was not a Let(Non)?Rec: {expr:?}",),
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_when_expr(expr: &Expr) -> (&Expr, &Vec<WhenBranch>) {
|
||||
match expr {
|
||||
Expr::When {
|
||||
loc_cond, branches, ..
|
||||
|
@ -1247,6 +1314,18 @@ mod test_can {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn assert_if_expr(expr: &Expr) -> (&[(Loc<Expr>, Loc<Expr>)], &Loc<Expr>) {
|
||||
match expr {
|
||||
Expr::If {
|
||||
branches,
|
||||
final_else,
|
||||
..
|
||||
} => (&branches, &**final_else),
|
||||
_ => panic!("Expr was not a When: {:?}", expr),
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_try_expr(expr: &Expr) -> &Expr {
|
||||
match expr {
|
||||
Expr::Try { result_expr, .. } => &result_expr.value,
|
||||
|
|
|
@ -95,22 +95,6 @@ flags! {
|
|||
/// Prints all type variables entered for fixpoint-fixing.
|
||||
ROC_PRINT_FIXPOINT_FIXING
|
||||
|
||||
/// Verifies that after let-generalization of a def, any rigid variables in the type annotation
|
||||
/// of the def are indeed generalized.
|
||||
///
|
||||
/// Note that rigids need not always be generalized in a def. For example, they may be
|
||||
/// constrained by a type from a lower rank, as `b` is in the following def:
|
||||
///
|
||||
/// F a : { foo : a }
|
||||
/// foo = \arg ->
|
||||
/// x : F b
|
||||
/// x = arg
|
||||
/// x.foo
|
||||
///
|
||||
/// Instead, this flag is useful for checking that in general, introduction is correct, when
|
||||
/// chainging how defs are constrained.
|
||||
ROC_VERIFY_RIGID_LET_GENERALIZED
|
||||
|
||||
/// Verifies that an `occurs` check indeed only contains non-recursive types that need to be
|
||||
/// fixed-up with one new recursion variable.
|
||||
///
|
||||
|
|
|
@ -1206,7 +1206,6 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
before: first_node.before,
|
||||
node: Node::CommaSequence {
|
||||
allow_blank_lines: false,
|
||||
allow_newlines: true,
|
||||
indent_rest: false,
|
||||
first: arena.alloc(first_node.node),
|
||||
rest: rest_nodes.into_bump_slice(),
|
||||
|
@ -1313,11 +1312,12 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
.to_node(arena, flags)
|
||||
.add_parens(arena, Parens::NotNeeded);
|
||||
|
||||
let mut needs_indent = annot.needs_indent || !annot.after.is_empty();
|
||||
let before = filter_newlines(arena, annot.after);
|
||||
let mut needs_indent = annot.needs_indent || !before.is_empty();
|
||||
|
||||
items.push(Item {
|
||||
comma_before: false,
|
||||
before: annot.after,
|
||||
before,
|
||||
newline: false,
|
||||
space: true,
|
||||
node: Node::Literal(roc_parse::keyword::WHERE),
|
||||
|
@ -1327,7 +1327,8 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
|
||||
for (i, clause) in implements_clauses.iter().enumerate() {
|
||||
let node = clause.value.to_node(arena, flags);
|
||||
let before = merge_spaces_conservative(arena, last_after, node.before);
|
||||
let before =
|
||||
filter_newlines(arena, merge_spaces(arena, last_after, node.before));
|
||||
last_after = node.after;
|
||||
items.push(Item {
|
||||
before,
|
||||
|
@ -1346,8 +1347,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
first: arena.alloc(annot.node),
|
||||
rest: arena.alloc_slice_copy(&items),
|
||||
allow_blank_lines: false,
|
||||
allow_newlines: false,
|
||||
indent_rest: false,
|
||||
indent_rest: true,
|
||||
},
|
||||
after: last_after,
|
||||
needs_indent,
|
||||
|
@ -1358,6 +1358,24 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn filter_newlines<'a, 'b: 'a>(
|
||||
arena: &'a Bump,
|
||||
items: &'b [CommentOrNewline<'b>],
|
||||
) -> &'a [CommentOrNewline<'a>] {
|
||||
let count = items.iter().filter(|i| i.is_newline()).count();
|
||||
if count > 0 {
|
||||
let mut new_items = Vec::with_capacity_in(items.len() - count, arena);
|
||||
for item in items {
|
||||
if !item.is_newline() {
|
||||
new_items.push(*item);
|
||||
}
|
||||
}
|
||||
arena.alloc_slice_copy(&new_items)
|
||||
} else {
|
||||
items
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Nodify<'a> for &'a str {
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, flags: MigrationFlags) -> NodeInfo<'b>
|
||||
where
|
||||
|
@ -1451,7 +1469,6 @@ impl<'a> Nodify<'a> for ImplementsClause<'a> {
|
|||
first: arena.alloc(var.node),
|
||||
rest: arena.alloc_slice_copy(&items),
|
||||
allow_blank_lines: false,
|
||||
allow_newlines: true,
|
||||
indent_rest: false,
|
||||
},
|
||||
after: last_after,
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
use crate::annotation::{
|
||||
ann_lift_spaces, ann_lift_spaces_after, is_collection_multiline, ty_is_outdentable,
|
||||
Formattable, Newlines, Parens,
|
||||
ann_lift_spaces_after, is_collection_multiline, Formattable, Newlines, Parens,
|
||||
};
|
||||
use crate::collection::{fmt_collection, Braces};
|
||||
use crate::expr::{
|
||||
expr_lift_and_lower, expr_lift_spaces, expr_lift_spaces_after, expr_lift_spaces_before,
|
||||
fmt_str_literal, is_str_multiline, merge_spaces_conservative, sub_expr_requests_parens,
|
||||
expr_lift_spaces, expr_lift_spaces_after, expr_lift_spaces_before, fmt_str_literal,
|
||||
is_str_multiline, merge_spaces_conservative, sub_expr_requests_parens,
|
||||
};
|
||||
use crate::node::Nodify;
|
||||
use crate::pattern::pattern_lift_spaces_before;
|
||||
use crate::pattern::{pattern_lift_spaces, pattern_lift_spaces_before};
|
||||
use crate::spaces::{
|
||||
fmt_comments_only, fmt_default_newline, fmt_default_spaces, fmt_spaces, NewlineAt, INDENT,
|
||||
};
|
||||
use crate::Buf;
|
||||
use bumpalo::Bump;
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_parse::ast::Spaceable;
|
||||
use roc_parse::ast::{
|
||||
AbilityMember, Defs, Expr, ExtractSpaces, ImportAlias, ImportAsKeyword, ImportExposingKeyword,
|
||||
ImportedModuleName, IngestedFileAnnotation, IngestedFileImport, ModuleImport,
|
||||
|
@ -182,16 +182,29 @@ pub fn valdef_lift_spaces<'a, 'b: 'a>(
|
|||
}
|
||||
}
|
||||
ValueDef::Body(pat, expr) => {
|
||||
let pat_lifted = pattern_lift_spaces_before(arena, &pat.value);
|
||||
let expr_lifted = expr_lift_spaces_after(Parens::NotNeeded, arena, &expr.value);
|
||||
let pat_lifted = pattern_lift_spaces(arena, &pat.value);
|
||||
|
||||
Spaces {
|
||||
before: pat_lifted.before,
|
||||
item: ValueDef::Body(
|
||||
arena.alloc(Loc::at(pat.region, pat_lifted.item)),
|
||||
arena.alloc(Loc::at(expr.region, expr_lifted.item)),
|
||||
),
|
||||
after: expr_lifted.after,
|
||||
// Don't format the `{} =` for defs with this pattern
|
||||
if is_body_unit_assignment(&pat_lifted, &expr.extract_spaces()) {
|
||||
let lifted = expr_lift_spaces(Parens::NotNeeded, arena, &expr.value);
|
||||
Spaces {
|
||||
before: lifted.before,
|
||||
item: ValueDef::Stmt(arena.alloc(Loc::at_zero(lifted.item))),
|
||||
after: lifted.after,
|
||||
}
|
||||
} else {
|
||||
let lifted = expr_lift_spaces(Parens::NotNeeded, arena, &expr.value);
|
||||
Spaces {
|
||||
before: pat_lifted.before,
|
||||
item: ValueDef::Body(
|
||||
arena.alloc(Loc::at(
|
||||
pat.region,
|
||||
pat_lifted.item.maybe_after(arena, pat_lifted.after),
|
||||
)),
|
||||
expr,
|
||||
),
|
||||
after: lifted.after,
|
||||
}
|
||||
}
|
||||
}
|
||||
ValueDef::AnnotatedBody {
|
||||
|
@ -312,11 +325,26 @@ pub fn valdef_lift_spaces_before<'a, 'b: 'a>(
|
|||
}
|
||||
}
|
||||
ValueDef::Body(pat, expr) => {
|
||||
let pat_lifted = pattern_lift_spaces_before(arena, &pat.value);
|
||||
let pat_lifted = pattern_lift_spaces(arena, &pat.value);
|
||||
|
||||
SpacesBefore {
|
||||
before: pat_lifted.before,
|
||||
item: ValueDef::Body(arena.alloc(Loc::at(pat.region, pat_lifted.item)), expr),
|
||||
// Don't format the `{} =` for defs with this pattern
|
||||
if is_body_unit_assignment(&pat_lifted, &expr.extract_spaces()) {
|
||||
let lifted = expr_lift_spaces_before(Parens::NotNeeded, arena, &expr.value);
|
||||
SpacesBefore {
|
||||
before: lifted.before,
|
||||
item: ValueDef::Stmt(arena.alloc(Loc::at_zero(lifted.item))),
|
||||
}
|
||||
} else {
|
||||
SpacesBefore {
|
||||
before: pat_lifted.before,
|
||||
item: ValueDef::Body(
|
||||
arena.alloc(Loc::at(
|
||||
pat.region,
|
||||
pat_lifted.item.maybe_after(arena, pat_lifted.after),
|
||||
)),
|
||||
expr,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
ValueDef::AnnotatedBody {
|
||||
|
@ -396,6 +424,20 @@ pub fn valdef_lift_spaces_before<'a, 'b: 'a>(
|
|||
}
|
||||
}
|
||||
|
||||
fn is_body_unit_assignment(pat: &Spaces<'_, Pattern<'_>>, body: &Spaces<'_, Expr<'_>>) -> bool {
|
||||
if let Pattern::RecordDestructure(collection) = pat.item {
|
||||
collection.is_empty()
|
||||
&& pat.before.iter().all(|s| s.is_newline())
|
||||
&& pat.after.iter().all(|s| s.is_newline())
|
||||
&& !matches!(body.item, Expr::Defs(..))
|
||||
&& !matches!(body.item, Expr::Return(..))
|
||||
&& !matches!(body.item, Expr::DbgStmt { .. })
|
||||
&& !starts_with_expect_ident(&body.item)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Formattable for TypeDef<'a> {
|
||||
fn is_multiline(&self) -> bool {
|
||||
use roc_parse::ast::TypeDef::*;
|
||||
|
@ -412,22 +454,15 @@ impl<'a> Formattable for TypeDef<'a> {
|
|||
|
||||
match self {
|
||||
Alias { header, ann } => {
|
||||
header.format(buf, indent);
|
||||
|
||||
buf.indent(indent);
|
||||
buf.push_str(" :");
|
||||
buf.spaces(1);
|
||||
|
||||
let ann = ann_lift_spaces(buf.text.bump(), &ann.value);
|
||||
|
||||
let inner_indent = if ty_is_outdentable(&ann.item) {
|
||||
indent
|
||||
} else {
|
||||
indent + INDENT
|
||||
};
|
||||
fmt_comments_only(buf, ann.before.iter(), NewlineAt::Bottom, inner_indent);
|
||||
ann.item.format(buf, inner_indent);
|
||||
fmt_spaces(buf, ann.after.iter(), indent);
|
||||
fmt_general_def(
|
||||
header,
|
||||
Parens::NotNeeded,
|
||||
buf,
|
||||
indent,
|
||||
":",
|
||||
&ann.value,
|
||||
newlines,
|
||||
);
|
||||
}
|
||||
Opaque {
|
||||
header,
|
||||
|
@ -797,7 +832,7 @@ impl<'a> Formattable for ValueDef<'a> {
|
|||
);
|
||||
}
|
||||
Body(loc_pattern, loc_expr) => {
|
||||
fmt_body(buf, true, &loc_pattern.value, &loc_expr.value, indent);
|
||||
fmt_body(buf, &loc_pattern.value, &loc_expr.value, indent);
|
||||
}
|
||||
Dbg { condition, .. } => fmt_dbg_in_def(buf, condition, self.is_multiline(), indent),
|
||||
Expect { condition, .. } => fmt_expect(buf, condition, self.is_multiline(), indent),
|
||||
|
@ -826,7 +861,7 @@ impl<'a> Formattable for ValueDef<'a> {
|
|||
fmt_annotated_body_comment(buf, indent, lines_between);
|
||||
|
||||
buf.newline();
|
||||
fmt_body(buf, false, &body_pattern.value, &body_expr.value, indent);
|
||||
fmt_body(buf, &body_pattern.value, &body_expr.value, indent);
|
||||
}
|
||||
ModuleImport(module_import) => module_import.format(buf, indent),
|
||||
IngestedFileImport(ingested_file_import) => ingested_file_import.format(buf, indent),
|
||||
|
@ -957,34 +992,7 @@ pub fn fmt_annotated_body_comment<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fmt_body<'a>(
|
||||
buf: &mut Buf,
|
||||
allow_simplify_empty_record_destructure: bool,
|
||||
pattern: &'a Pattern<'a>,
|
||||
body: &'a Expr<'a>,
|
||||
indent: u16,
|
||||
) {
|
||||
let pattern_extracted = pattern.extract_spaces();
|
||||
// Check if this is an assignment into the unit value
|
||||
let is_unit_assignment = if let Pattern::RecordDestructure(collection) = pattern_extracted.item
|
||||
{
|
||||
allow_simplify_empty_record_destructure
|
||||
&& collection.is_empty()
|
||||
&& pattern_extracted.before.iter().all(|s| s.is_newline())
|
||||
&& pattern_extracted.after.iter().all(|s| s.is_newline())
|
||||
&& !matches!(body.extract_spaces().item, Expr::Defs(..))
|
||||
&& !matches!(body.extract_spaces().item, Expr::Return(..))
|
||||
&& !matches!(body.extract_spaces().item, Expr::DbgStmt { .. })
|
||||
&& !starts_with_expect_ident(body)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
// Don't format the `{} =` for defs with this pattern
|
||||
if is_unit_assignment {
|
||||
return body.format_with_options(buf, Parens::NotNeeded, Newlines::No, indent);
|
||||
}
|
||||
|
||||
pub fn fmt_body<'a>(buf: &mut Buf, pattern: &'a Pattern<'a>, body: &'a Expr<'a>, indent: u16) {
|
||||
pattern.format_with_options(buf, Parens::InApply, Newlines::No, indent);
|
||||
|
||||
if pattern.is_multiline() {
|
||||
|
@ -996,7 +1004,12 @@ pub fn fmt_body<'a>(
|
|||
let indent = buf.cur_line_indent();
|
||||
buf.push_str("=");
|
||||
|
||||
let body = expr_lift_and_lower(Parens::NotNeeded, buf.text.bump(), body);
|
||||
let body_lifted = expr_lift_spaces(Parens::NotNeeded, buf.text.bump(), body);
|
||||
|
||||
let after = body_lifted.after;
|
||||
let body = body_lifted
|
||||
.item
|
||||
.maybe_before(buf.text.bump(), body_lifted.before);
|
||||
|
||||
if body.is_multiline() {
|
||||
match body {
|
||||
|
@ -1009,10 +1022,7 @@ pub fn fmt_body<'a>(
|
|||
_ => false,
|
||||
};
|
||||
|
||||
if is_unit_assignment {
|
||||
fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent);
|
||||
sub_def.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||
} else if should_outdent {
|
||||
if should_outdent {
|
||||
buf.spaces(1);
|
||||
sub_def.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||
} else {
|
||||
|
@ -1057,7 +1067,7 @@ pub fn fmt_body<'a>(
|
|||
buf.ensure_ends_with_newline();
|
||||
body.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent + INDENT);
|
||||
}
|
||||
Expr::Defs(..) | Expr::BinOps(_, _) => {
|
||||
Expr::Defs(..) | Expr::BinOps(..) => {
|
||||
// Binop chains always get a newline. Otherwise you can have things like:
|
||||
//
|
||||
// something = foo
|
||||
|
@ -1092,6 +1102,8 @@ pub fn fmt_body<'a>(
|
|||
buf.spaces(1);
|
||||
body.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||
}
|
||||
|
||||
fmt_spaces(buf, after.iter(), indent);
|
||||
}
|
||||
|
||||
fn starts_with_expect_ident(expr: &Expr<'_>) -> bool {
|
||||
|
@ -1116,6 +1128,7 @@ pub fn starts_with_block_string_literal(expr: &Expr<'_>) -> bool {
|
|||
}
|
||||
Expr::Apply(inner, _, _) => starts_with_block_string_literal(&inner.value),
|
||||
Expr::RecordAccess(inner, _) => starts_with_block_string_literal(inner),
|
||||
Expr::TupleAccess(inner, _) => starts_with_block_string_literal(inner),
|
||||
Expr::PncApply(inner, _) => starts_with_block_string_literal(&inner.value),
|
||||
Expr::TrySuffix(inner) => starts_with_block_string_literal(inner),
|
||||
_ => false,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::annotation::{except_last, is_collection_multiline, Formattable, Newlines, Parens};
|
||||
use crate::collection::{fmt_collection, Braces};
|
||||
use crate::def::{fmt_defs, valdef_lift_spaces_before};
|
||||
use crate::def::{fmt_defs, starts_with_block_string_literal, valdef_lift_spaces_before};
|
||||
use crate::node::Prec;
|
||||
use crate::pattern::{
|
||||
fmt_pattern, pattern_lift_spaces, snakify_camel_ident, starts_with_inline_comment,
|
||||
|
@ -264,7 +264,7 @@ fn format_expr_only(
|
|||
let before_all_newlines = lifted.before.iter().all(|s| s.is_newline());
|
||||
|
||||
let needs_newline =
|
||||
!before_all_newlines || term_starts_with_multiline_str(&lifted.item);
|
||||
!before_all_newlines || starts_with_block_string_literal(&lifted.item);
|
||||
|
||||
let needs_parens = (needs_newline
|
||||
&& matches!(unary_op.value, called_via::UnaryOp::Negate))
|
||||
|
@ -367,14 +367,6 @@ fn format_expr_only(
|
|||
}
|
||||
}
|
||||
|
||||
fn term_starts_with_multiline_str(expr: &Expr<'_>) -> bool {
|
||||
match expr {
|
||||
Expr::Str(text) => is_str_multiline(text),
|
||||
Expr::PncApply(inner, _) => term_starts_with_multiline_str(&inner.value),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_expr_field_collection<'a>(
|
||||
arena: &'a Bump,
|
||||
items: Collection<'a, Loc<AssignedField<'a, Expr<'a>>>>,
|
||||
|
@ -959,8 +951,8 @@ fn push_op(buf: &mut Buf, op: BinOp) {
|
|||
called_via::BinOp::GreaterThan => buf.push('>'),
|
||||
called_via::BinOp::LessThanOrEq => buf.push_str("<="),
|
||||
called_via::BinOp::GreaterThanOrEq => buf.push_str(">="),
|
||||
called_via::BinOp::And => buf.push_str("&&"),
|
||||
called_via::BinOp::Or => buf.push_str("||"),
|
||||
called_via::BinOp::Or => buf.push_str("or"),
|
||||
called_via::BinOp::And => buf.push_str("and"),
|
||||
called_via::BinOp::Pizza => buf.push_str("|>"),
|
||||
called_via::BinOp::DoubleQuestion => buf.push_str("??"),
|
||||
called_via::BinOp::SingleQuestion => buf.push_str("?"),
|
||||
|
@ -1026,14 +1018,6 @@ pub fn fmt_str_literal(buf: &mut Buf, literal: StrLiteral, indent: u16) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expr_lift_and_lower<'a, 'b: 'a>(
|
||||
_parens: Parens,
|
||||
arena: &'a Bump,
|
||||
expr: &Expr<'b>,
|
||||
) -> Expr<'a> {
|
||||
lower(arena, expr_lift_spaces(Parens::NotNeeded, arena, expr))
|
||||
}
|
||||
|
||||
pub fn expr_lift_spaces<'a, 'b: 'a>(
|
||||
parens: Parens,
|
||||
arena: &'a Bump,
|
||||
|
@ -1496,7 +1480,6 @@ fn fmt_binops<'a>(
|
|||
buf: &mut Buf,
|
||||
lefts: &'a [(Loc<Expr<'a>>, Loc<BinOp>)],
|
||||
loc_right_side: &'a Loc<Expr<'a>>,
|
||||
|
||||
indent: u16,
|
||||
) {
|
||||
let is_multiline = loc_right_side.value.is_multiline()
|
||||
|
@ -1825,6 +1808,8 @@ fn guard_needs_parens(value: &Expr<'_>) -> bool {
|
|||
Expr::ParensAround(expr) | Expr::SpaceBefore(expr, _) | Expr::SpaceAfter(expr, _) => {
|
||||
guard_needs_parens(expr)
|
||||
}
|
||||
Expr::BinOps(_lefts, right) => guard_needs_parens(&right.value),
|
||||
Expr::UnaryOp(inner, _) => guard_needs_parens(&inner.value),
|
||||
Expr::Closure(_, body) => guard_needs_parens(&body.value),
|
||||
Expr::Defs(_, final_expr) => guard_needs_parens(&final_expr.value),
|
||||
_ => false,
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
annotation::{Formattable, Newlines, Parens},
|
||||
collection::Braces,
|
||||
expr::merge_spaces_conservative,
|
||||
spaces::{fmt_comments_only, fmt_spaces, fmt_spaces_no_blank_lines, NewlineAt, INDENT},
|
||||
spaces::{fmt_spaces, fmt_spaces_no_blank_lines, INDENT},
|
||||
Buf, MigrationFlags,
|
||||
};
|
||||
|
||||
|
@ -87,7 +87,6 @@ pub enum Node<'a> {
|
|||
},
|
||||
CommaSequence {
|
||||
allow_blank_lines: bool,
|
||||
allow_newlines: bool,
|
||||
indent_rest: bool,
|
||||
first: &'a Node<'a>,
|
||||
rest: &'a [Item<'a>],
|
||||
|
@ -124,12 +123,8 @@ pub struct Item<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Item<'a> {
|
||||
fn is_multiline(&self, allow_newlines: bool) -> bool {
|
||||
let has_newlines = if allow_newlines {
|
||||
!self.before.is_empty()
|
||||
} else {
|
||||
self.before.iter().any(|c| c.is_comment())
|
||||
};
|
||||
fn is_multiline(&self) -> bool {
|
||||
let has_newlines = !self.before.is_empty();
|
||||
self.newline || has_newlines || self.node.is_multiline()
|
||||
}
|
||||
}
|
||||
|
@ -273,7 +268,6 @@ impl<'b> NodeInfo<'b> {
|
|||
},
|
||||
node: Node::CommaSequence {
|
||||
allow_blank_lines: false,
|
||||
allow_newlines: true,
|
||||
indent_rest,
|
||||
first: arena.alloc(first.node),
|
||||
rest: rest.into_bump_slice(),
|
||||
|
@ -361,11 +355,10 @@ impl<'a> Formattable for Node<'a> {
|
|||
} => after.is_multiline() || items.iter().any(|item| item.is_multiline()),
|
||||
Node::CommaSequence {
|
||||
allow_blank_lines: _,
|
||||
allow_newlines,
|
||||
indent_rest: _,
|
||||
first,
|
||||
rest,
|
||||
} => first.is_multiline() || rest.iter().any(|item| item.is_multiline(*allow_newlines)),
|
||||
} => first.is_multiline() || rest.iter().any(|item| item.is_multiline()),
|
||||
Node::Literal(_) => false,
|
||||
Node::TypeAnnotation(type_annotation) => type_annotation.is_multiline(),
|
||||
Node::Pattern(pat) => pat.is_multiline(),
|
||||
|
@ -429,7 +422,6 @@ impl<'a> Formattable for Node<'a> {
|
|||
}
|
||||
Node::CommaSequence {
|
||||
allow_blank_lines,
|
||||
allow_newlines,
|
||||
indent_rest,
|
||||
first,
|
||||
rest,
|
||||
|
@ -448,10 +440,8 @@ impl<'a> Formattable for Node<'a> {
|
|||
}
|
||||
if *allow_blank_lines {
|
||||
fmt_spaces(buf, item.before.iter(), indent);
|
||||
} else if *allow_newlines {
|
||||
fmt_spaces_no_blank_lines(buf, item.before.iter(), inner_indent);
|
||||
} else {
|
||||
fmt_comments_only(buf, item.before.iter(), NewlineAt::Bottom, inner_indent);
|
||||
fmt_spaces_no_blank_lines(buf, item.before.iter(), inner_indent);
|
||||
}
|
||||
if item.newline {
|
||||
buf.ensure_ends_with_newline();
|
||||
|
|
|
@ -294,7 +294,8 @@ fn fmt_pattern_only(
|
|||
is_negative,
|
||||
} => {
|
||||
buf.indent(indent);
|
||||
let needs_parens = parens == Parens::InClosurePattern;
|
||||
let needs_parens = parens == Parens::InClosurePattern
|
||||
|| (parens == Parens::InPncApplyFunc && *is_negative);
|
||||
if needs_parens {
|
||||
buf.push('(');
|
||||
}
|
||||
|
@ -317,7 +318,8 @@ fn fmt_pattern_only(
|
|||
}
|
||||
Pattern::FloatLiteral(string) => {
|
||||
buf.indent(indent);
|
||||
let needs_parens = parens == Parens::InClosurePattern;
|
||||
let needs_parens = parens == Parens::InClosurePattern
|
||||
|| (parens == Parens::InPncApplyFunc && string.starts_with('-'));
|
||||
if needs_parens {
|
||||
buf.push('(');
|
||||
}
|
||||
|
|
|
@ -1268,20 +1268,6 @@ trait Backend<'a> {
|
|||
internal_error!("bitwise xor on a non-integer")
|
||||
}
|
||||
}
|
||||
LowLevel::And => {
|
||||
if let LayoutRepr::Builtin(Builtin::Bool) = self.interner().get_repr(*ret_layout) {
|
||||
self.build_int_bitwise_and(sym, &args[0], &args[1], IntWidth::U8)
|
||||
} else {
|
||||
internal_error!("bitwise and on a non-integer")
|
||||
}
|
||||
}
|
||||
LowLevel::Or => {
|
||||
if let LayoutRepr::Builtin(Builtin::Bool) = self.interner().get_repr(*ret_layout) {
|
||||
self.build_int_bitwise_or(sym, &args[0], &args[1], IntWidth::U8)
|
||||
} else {
|
||||
internal_error!("bitwise or on a non-integer")
|
||||
}
|
||||
}
|
||||
LowLevel::NumShiftLeftBy => {
|
||||
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
||||
self.interner().get_repr(*ret_layout)
|
||||
|
@ -1733,6 +1719,13 @@ trait Backend<'a> {
|
|||
arg_layouts,
|
||||
ret_layout,
|
||||
),
|
||||
LowLevel::StrWithAsciiLowercased => self.build_fn_call(
|
||||
sym,
|
||||
bitcode::STR_WITH_ASCII_LOWERCASED.to_string(),
|
||||
args,
|
||||
arg_layouts,
|
||||
ret_layout,
|
||||
),
|
||||
LowLevel::StrToNum => {
|
||||
let number_layout = match self.interner().get_repr(*ret_layout) {
|
||||
LayoutRepr::Struct(field_layouts) => field_layouts[0], // TODO: why is it sometimes a struct?
|
||||
|
|
|
@ -572,6 +572,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
bitcode::STR_WITH_CAPACITY,
|
||||
)
|
||||
}
|
||||
|
||||
ListLenU64 => {
|
||||
// List.len : List * -> U64
|
||||
arguments!(list);
|
||||
|
@ -614,6 +615,17 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
list_element_layout!(layout_interner, result_layout),
|
||||
)
|
||||
}
|
||||
StrWithAsciiLowercased => {
|
||||
arguments!(string);
|
||||
|
||||
call_str_bitcode_fn(
|
||||
env,
|
||||
&[string],
|
||||
&[],
|
||||
BitcodeReturns::Str,
|
||||
bitcode::STR_WITH_ASCII_LOWERCASED,
|
||||
)
|
||||
}
|
||||
ListConcat => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
|
@ -1263,30 +1275,6 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
rhs_layout,
|
||||
)
|
||||
}
|
||||
And => {
|
||||
// The (&&) operator
|
||||
arguments!(lhs_arg, rhs_arg);
|
||||
|
||||
let bool_val = env.builder.new_build_and(
|
||||
lhs_arg.into_int_value(),
|
||||
rhs_arg.into_int_value(),
|
||||
"bool_and",
|
||||
);
|
||||
|
||||
BasicValueEnum::IntValue(bool_val)
|
||||
}
|
||||
Or => {
|
||||
// The (||) operator
|
||||
arguments!(lhs_arg, rhs_arg);
|
||||
|
||||
let bool_val = env.builder.new_build_or(
|
||||
lhs_arg.into_int_value(),
|
||||
rhs_arg.into_int_value(),
|
||||
"bool_or",
|
||||
);
|
||||
|
||||
BasicValueEnum::IntValue(bool_val)
|
||||
}
|
||||
Not => {
|
||||
// The (!) operator
|
||||
arguments!(arg);
|
||||
|
|
|
@ -259,6 +259,9 @@ impl<'a> LowLevelCall<'a> {
|
|||
self.load_args_and_call_zig(backend, bitcode::STR_SUBSTRING_UNSAFE)
|
||||
}
|
||||
StrWithCapacity => self.load_args_and_call_zig(backend, bitcode::STR_WITH_CAPACITY),
|
||||
StrWithAsciiLowercased => {
|
||||
self.load_args_and_call_zig(backend, bitcode::STR_WITH_ASCII_LOWERCASED)
|
||||
}
|
||||
|
||||
// List
|
||||
ListLenU64 => {
|
||||
|
@ -2164,14 +2167,6 @@ impl<'a> LowLevelCall<'a> {
|
|||
NumF64ToParts => self.load_args_and_call_zig(backend, bitcode::NUM_F64_TO_PARTS),
|
||||
NumF32FromParts => self.load_args_and_call_zig(backend, bitcode::NUM_F32_FROM_PARTS),
|
||||
NumF64FromParts => self.load_args_and_call_zig(backend, bitcode::NUM_F64_FROM_PARTS),
|
||||
And => {
|
||||
self.load_args(backend);
|
||||
backend.code_builder.i32_and();
|
||||
}
|
||||
Or => {
|
||||
self.load_args(backend);
|
||||
backend.code_builder.i32_or();
|
||||
}
|
||||
Not => {
|
||||
self.load_args(backend);
|
||||
backend.code_builder.i32_eqz();
|
||||
|
|
|
@ -9,6 +9,7 @@ version.workspace = true
|
|||
|
||||
[dependencies]
|
||||
roc_can.workspace = true
|
||||
roc_can_solo.workspace = true
|
||||
roc_collections.workspace = true
|
||||
roc_load_internal.workspace = true
|
||||
roc_module.workspace = true
|
||||
|
|
|
@ -3,11 +3,12 @@ extern crate bumpalo;
|
|||
use self::bumpalo::Bump;
|
||||
use roc_can::abilities::AbilitiesStore;
|
||||
use roc_can::constraint::{Constraint, Constraints};
|
||||
use roc_can::desugar;
|
||||
use roc_can::env::Env;
|
||||
use roc_can::expected::Expected;
|
||||
use roc_can::expr::{canonicalize_expr, Expr, Output, PendingDerives};
|
||||
use roc_can::scope::Scope;
|
||||
use roc_can_solo::env::SoloEnv;
|
||||
use roc_can_solo::scope::SoloScope;
|
||||
use roc_collections::all::{ImMap, MutMap, SendSet};
|
||||
use roc_constrain::expr::constrain_expr;
|
||||
use roc_derive::SharedDerivedModule;
|
||||
|
@ -162,24 +163,6 @@ pub fn can_expr_with<'a>(
|
|||
// ensure the Test module is accessible in our tests
|
||||
module_ids.get_or_insert(&PQModuleName::Unqualified("Test".into()));
|
||||
|
||||
let mut scope = Scope::new(
|
||||
home,
|
||||
"TestPath".into(),
|
||||
IdentIds::default(),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
let dep_idents = IdentIds::exposed_builtins(0);
|
||||
let mut env = Env::new(
|
||||
arena,
|
||||
expr_str,
|
||||
home,
|
||||
Path::new("Test.roc"),
|
||||
&dep_idents,
|
||||
&module_ids,
|
||||
None,
|
||||
);
|
||||
|
||||
// Desugar operators (convert them to Apply calls, taking into account
|
||||
// operator precedence and associativity rules), before doing other canonicalization.
|
||||
//
|
||||
|
@ -187,7 +170,9 @@ pub fn can_expr_with<'a>(
|
|||
// visited a BinOp node we'd recursively try to apply this to each of its nested
|
||||
// operators, and then again on *their* nested operators, ultimately applying the
|
||||
// rules multiple times unnecessarily.
|
||||
let loc_expr = desugar::desugar_expr(&mut env, &mut scope, &loc_expr);
|
||||
let mut solo_env = SoloEnv::new(arena, expr_str, Path::new("Test.roc"));
|
||||
let mut solo_scope = SoloScope::new();
|
||||
let loc_expr = roc_can_solo::desugar::desugar_expr(&mut solo_env, &mut solo_scope, &loc_expr);
|
||||
|
||||
let mut scope = Scope::new(
|
||||
home,
|
||||
|
|
|
@ -1522,18 +1522,18 @@ mod test_reporting {
|
|||
from_annotation_if,
|
||||
indoc!(
|
||||
r"
|
||||
x : Num.Int *
|
||||
x : Num.Int _
|
||||
x = if Bool.true then 3.14 else 4
|
||||
|
||||
x
|
||||
"
|
||||
),
|
||||
@r"
|
||||
@r###"
|
||||
── TYPE MISMATCH in /code/proj/Main.roc ────────────────────────────────────────
|
||||
|
||||
Something is off with the `then` branch of this `if` expression:
|
||||
|
||||
4│ x : Num.Int *
|
||||
4│ x : Num.Int _
|
||||
5│ x = if Bool.true then 3.14 else 4
|
||||
^^^^
|
||||
|
||||
|
@ -1547,14 +1547,14 @@ mod test_reporting {
|
|||
|
||||
Tip: You can convert between integers and fractions using functions
|
||||
like `Num.to_frac` and `Num.round`.
|
||||
"
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
from_annotation_when,
|
||||
indoc!(
|
||||
r"
|
||||
x : Num.Int *
|
||||
x : Num.Int _
|
||||
x =
|
||||
when True is
|
||||
_ -> 3.14
|
||||
|
@ -1562,12 +1562,12 @@ mod test_reporting {
|
|||
x
|
||||
"
|
||||
),
|
||||
@r"
|
||||
@r###"
|
||||
── TYPE MISMATCH in /code/proj/Main.roc ────────────────────────────────────────
|
||||
|
||||
Something is off with the body of the `x` definition:
|
||||
|
||||
4│ x : Num.Int *
|
||||
4│ x : Num.Int _
|
||||
5│ x =
|
||||
6│> when True is
|
||||
7│> _ -> 3.14
|
||||
|
@ -1582,7 +1582,7 @@ mod test_reporting {
|
|||
|
||||
Tip: You can convert between integers and fractions using functions
|
||||
like `Num.to_frac` and `Num.round`.
|
||||
"
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
|
@ -1910,7 +1910,7 @@ mod test_reporting {
|
|||
from_annotation_complex_pattern,
|
||||
indoc!(
|
||||
r"
|
||||
{ x } : { x : Num.Int * }
|
||||
{ x } : { x : Num.Int _ }
|
||||
{ x } = { x: 4.0 }
|
||||
|
||||
x
|
||||
|
@ -1921,7 +1921,7 @@ mod test_reporting {
|
|||
|
||||
Something is off with the body of this definition:
|
||||
|
||||
4│ { x } : { x : Num.Int * }
|
||||
4│ { x } : { x : Num.Int _ }
|
||||
5│ { x } = { x: 4.0 }
|
||||
^^^^^^^^^^
|
||||
|
||||
|
@ -2047,18 +2047,18 @@ mod test_reporting {
|
|||
missing_fields,
|
||||
indoc!(
|
||||
r"
|
||||
x : { a : Num.Int *, b : Num.Frac *, c : Str }
|
||||
x : { a : Num.Int _, b : Num.Frac _, c : Str }
|
||||
x = { b: 4.0 }
|
||||
|
||||
x
|
||||
"
|
||||
),
|
||||
@r"
|
||||
@r###"
|
||||
── TYPE MISMATCH in /code/proj/Main.roc ────────────────────────────────────────
|
||||
|
||||
Something is off with the body of the `x` definition:
|
||||
|
||||
4│ x : { a : Num.Int *, b : Num.Frac *, c : Str }
|
||||
4│ x : { a : Num.Int _, b : Num.Frac _, c : Str }
|
||||
5│ x = { b: 4.0 }
|
||||
^^^^^^^^^^
|
||||
|
||||
|
@ -2075,7 +2075,7 @@ mod test_reporting {
|
|||
}
|
||||
|
||||
Tip: Looks like the c and a fields are missing.
|
||||
"
|
||||
"###
|
||||
);
|
||||
|
||||
// this previously reported the message below, not sure which is better
|
||||
|
@ -3448,7 +3448,7 @@ mod test_reporting {
|
|||
x : AList Num.I64 Num.I64
|
||||
x = ACons 0 (BCons 1 (ACons "foo" BNil ))
|
||||
|
||||
y : BList a a
|
||||
y : BList _ _
|
||||
y = BNil
|
||||
|
||||
{ x, y }
|
||||
|
@ -4189,9 +4189,8 @@ mod test_reporting {
|
|||
RBTree k v : [Node NodeColor k v (RBTree k v) (RBTree k v), Empty]
|
||||
|
||||
# Create an empty dictionary.
|
||||
empty : RBTree k v
|
||||
empty =
|
||||
Empty
|
||||
empty : {} -> RBTree k v
|
||||
empty = \{} -> Empty
|
||||
|
||||
empty
|
||||
"
|
||||
|
@ -6036,7 +6035,7 @@ All branches in an `if` must have the same type!
|
|||
double_binop,
|
||||
indoc!(
|
||||
r"
|
||||
key >= 97 && <= 122
|
||||
key >= 97 and <= 122
|
||||
"
|
||||
),
|
||||
@r"
|
||||
|
@ -6692,17 +6691,20 @@ All branches in an `if` must have the same type!
|
|||
)
|
||||
"
|
||||
),
|
||||
@r"
|
||||
── UNFINISHED FUNCTION in tmp/unfinished_closure_pattern_in_parens/Test.roc ────
|
||||
@r###"
|
||||
── MISSING ARROW in tmp/unfinished_closure_pattern_in_parens/Test.roc ──────────
|
||||
|
||||
I was partway through parsing a function, but I got stuck here:
|
||||
I am partway through parsing a function argument list, but I got stuck
|
||||
here:
|
||||
|
||||
4│ x = \( a
|
||||
5│ )
|
||||
^
|
||||
6│
|
||||
7│
|
||||
^
|
||||
|
||||
I just saw a pattern, so I was expecting to see a -> next.
|
||||
"
|
||||
I was expecting a -> next.
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
|
@ -11215,10 +11217,10 @@ All branches in an `if` must have the same type!
|
|||
|
||||
import Decode exposing [decoder]
|
||||
|
||||
main =
|
||||
my_decoder : Decoder (a -> a) fmt where fmt implements DecoderFormatting
|
||||
my_decoder = decoder
|
||||
my_decoder : Decoder (_ -> _) _
|
||||
my_decoder = decoder
|
||||
|
||||
main =
|
||||
my_decoder
|
||||
"#
|
||||
),
|
||||
|
@ -11227,12 +11229,12 @@ All branches in an `if` must have the same type!
|
|||
|
||||
This expression has a type that does not implement the abilities it's expected to:
|
||||
|
||||
7│ my_decoder = decoder
|
||||
^^^^^^^
|
||||
6│ my_decoder = decoder
|
||||
^^^^^^^
|
||||
|
||||
I can't generate an implementation of the `Decoding` ability for
|
||||
|
||||
a -> a
|
||||
* -> *
|
||||
|
||||
Note: `Decoding` cannot be generated for functions.
|
||||
"
|
||||
|
@ -11248,10 +11250,10 @@ All branches in an `if` must have the same type!
|
|||
|
||||
A := {}
|
||||
|
||||
main =
|
||||
my_decoder : Decoder {x : A} fmt where fmt implements DecoderFormatting
|
||||
my_decoder = decoder
|
||||
my_decoder : Decoder {x : A} _
|
||||
my_decoder = decoder
|
||||
|
||||
main =
|
||||
my_decoder
|
||||
"#
|
||||
),
|
||||
|
@ -11260,8 +11262,8 @@ All branches in an `if` must have the same type!
|
|||
|
||||
This expression has a type that does not implement the abilities it's expected to:
|
||||
|
||||
9│ my_decoder = decoder
|
||||
^^^^^^^
|
||||
8│ my_decoder = decoder
|
||||
^^^^^^^
|
||||
|
||||
I can't generate an implementation of the `Decoding` ability for
|
||||
|
||||
|
@ -11511,11 +11513,10 @@ All branches in an `if` must have the same type!
|
|||
|
||||
import Decode exposing [decoder]
|
||||
|
||||
main =
|
||||
my_decoder : Decoder {x : Str, y ? Str} fmt where fmt implements DecoderFormatting
|
||||
my_decoder = decoder
|
||||
my_decoder : Decoder {x : Str, y ? Str} _
|
||||
my_decoder = decoder
|
||||
|
||||
my_decoder
|
||||
main = my_decoder
|
||||
"#
|
||||
),
|
||||
@r"
|
||||
|
@ -11523,8 +11524,8 @@ All branches in an `if` must have the same type!
|
|||
|
||||
This expression has a type that does not implement the abilities it's expected to:
|
||||
|
||||
7│ my_decoder = decoder
|
||||
^^^^^^^
|
||||
6│ my_decoder = decoder
|
||||
^^^^^^^
|
||||
|
||||
I can't generate an implementation of the `Decoding` ability for
|
||||
|
||||
|
@ -14108,11 +14109,10 @@ All branches in an `if` must have the same type!
|
|||
|
||||
import Decode exposing [decoder]
|
||||
|
||||
main =
|
||||
my_decoder : Decoder (U32, Str) fmt where fmt implements DecoderFormatting
|
||||
my_decoder = decoder
|
||||
my_decoder : Decoder (U32, Str) _
|
||||
my_decoder = decoder
|
||||
|
||||
my_decoder
|
||||
main = my_decoder
|
||||
"#
|
||||
)
|
||||
);
|
||||
|
@ -14125,11 +14125,10 @@ All branches in an `if` must have the same type!
|
|||
|
||||
import Decode exposing [decoder]
|
||||
|
||||
main =
|
||||
my_decoder : Decoder (U32, {} -> {}) fmt where fmt implements DecoderFormatting
|
||||
my_decoder = decoder
|
||||
my_decoder : Decoder (U32, {} -> {}) _
|
||||
my_decoder = decoder
|
||||
|
||||
my_decoder
|
||||
main = my_decoder
|
||||
"#
|
||||
),
|
||||
@r"
|
||||
|
@ -14137,8 +14136,8 @@ All branches in an `if` must have the same type!
|
|||
|
||||
This expression has a type that does not implement the abilities it's expected to:
|
||||
|
||||
7│ my_decoder = decoder
|
||||
^^^^^^^
|
||||
6│ my_decoder = decoder
|
||||
^^^^^^^
|
||||
|
||||
I can't generate an implementation of the `Decoding` ability for
|
||||
|
||||
|
@ -15994,4 +15993,66 @@ All branches in an `if` must have the same type!
|
|||
Str -> {}
|
||||
"#
|
||||
);
|
||||
|
||||
test_report!(
|
||||
invalid_generic_literal,
|
||||
indoc!(
|
||||
r#"
|
||||
module [v]
|
||||
|
||||
v : *
|
||||
v = 1
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
── TYPE MISMATCH in /code/proj/Main.roc ────────────────────────────────────────
|
||||
|
||||
Something is off with the body of the `v` definition:
|
||||
|
||||
3│ v : *
|
||||
4│ v = 1
|
||||
^
|
||||
|
||||
The body is a number of type:
|
||||
|
||||
Num *
|
||||
|
||||
But the type annotation on `v` says it should be:
|
||||
|
||||
*
|
||||
|
||||
Tip: The type annotation uses the type variable `*` to say that this
|
||||
definition can produce any type of value. But in the body I see that
|
||||
it will only produce a `Num` value of a single specific type. Maybe
|
||||
change the type annotation to be more specific? Maybe change the code
|
||||
to be more general?
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
invalid_generic_literal_list,
|
||||
indoc!(
|
||||
r#"
|
||||
module [v]
|
||||
|
||||
v : List *
|
||||
v = []
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
── TYPE VARIABLE IS NOT GENERIC in /code/proj/Main.roc ─────────────────────────
|
||||
|
||||
This type variable has a single type:
|
||||
|
||||
3│ v : List *
|
||||
^
|
||||
|
||||
Type variables tell me that they can be used with any type, but they
|
||||
can only be used with functions. All other values have exactly one
|
||||
type.
|
||||
|
||||
Hint: If you would like the type to be inferred for you, use an
|
||||
underscore _ instead.
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ version.workspace = true
|
|||
[dependencies]
|
||||
roc_builtins.workspace = true
|
||||
roc_can.workspace = true
|
||||
roc_can_solo.workspace = true
|
||||
roc_work.workspace = true
|
||||
roc_checkmate.workspace = true
|
||||
roc_collections.workspace = true
|
||||
|
@ -39,6 +40,8 @@ bumpalo.workspace = true
|
|||
crossbeam.workspace = true
|
||||
parking_lot.workspace = true
|
||||
tempfile.workspace = true
|
||||
base64-url.workspace = true
|
||||
blake3.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
roc_test_utils_dir.workspace = true
|
||||
|
|
|
@ -15,11 +15,14 @@ use parking_lot::Mutex;
|
|||
use roc_builtins::roc::module_source;
|
||||
use roc_can::abilities::{AbilitiesStore, PendingAbilitiesStore, ResolvedImpl};
|
||||
use roc_can::constraint::{Constraint as ConstraintSoa, Constraints, TypeOrVar};
|
||||
use roc_can::env::Env;
|
||||
use roc_can::expr::{Declarations, ExpectLookup, PendingDerives};
|
||||
use roc_can::module::{
|
||||
canonicalize_module_defs, ExposedByModule, ExposedForModule, ExposedModuleTypes, Module,
|
||||
ModuleParams, ResolvedImplementations, TypeState,
|
||||
};
|
||||
use roc_can::scope::Scope;
|
||||
use roc_can_solo::module::{solo_canonicalize_module_defs, SoloCanOutput};
|
||||
use roc_collections::soa::slice_extend_new;
|
||||
use roc_collections::{default_hasher, BumpMap, MutMap, MutSet, VecMap, VecSet};
|
||||
use roc_constrain::module::constrain_module;
|
||||
|
@ -204,9 +207,20 @@ fn start_phase<'a>(
|
|||
root_type: state.root_type.clone(),
|
||||
}
|
||||
}
|
||||
Phase::SoloCanonicalize => {
|
||||
// canonicalize the file
|
||||
let parsed = state.module_cache.parsed.get(&module_id).unwrap().clone();
|
||||
|
||||
BuildTask::SoloCanonicalize { parsed }
|
||||
}
|
||||
Phase::CanonicalizeAndConstrain => {
|
||||
// canonicalize the file
|
||||
let parsed = state.module_cache.parsed.remove(&module_id).unwrap();
|
||||
let solo_can_output = state
|
||||
.module_cache
|
||||
.solo_canonicalized
|
||||
.remove(&module_id)
|
||||
.unwrap();
|
||||
|
||||
let deps_by_name = &parsed.deps_by_name;
|
||||
let num_deps = deps_by_name.len();
|
||||
|
@ -318,6 +332,7 @@ fn start_phase<'a>(
|
|||
exposed_module_ids: state.exposed_modules,
|
||||
exec_mode: state.exec_mode,
|
||||
imported_module_params,
|
||||
solo_can_output,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -577,6 +592,7 @@ enum Msg<'a> {
|
|||
Many(Vec<Msg<'a>>),
|
||||
Header(ModuleHeader<'a>),
|
||||
Parsed(ParsedModule<'a>),
|
||||
SoloCanonicalized(ModuleId, CanSolo<'a>),
|
||||
CanonicalizedAndConstrained(CanAndCon),
|
||||
SolvedTypes {
|
||||
module_id: ModuleId,
|
||||
|
@ -651,6 +667,9 @@ enum Msg<'a> {
|
|||
IncorrectModuleName(FileError<'a, IncorrectModuleName<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct CanSolo<'a>(SoloCanOutput<'a>);
|
||||
|
||||
#[derive(Debug)]
|
||||
struct CanAndCon {
|
||||
constrained_module: ConstrainedModule,
|
||||
|
@ -890,6 +909,9 @@ enum BuildTask<'a> {
|
|||
ident_ids_by_module: SharedIdentIdsByModule,
|
||||
root_type: RootType,
|
||||
},
|
||||
SoloCanonicalize {
|
||||
parsed: ParsedModule<'a>,
|
||||
},
|
||||
CanonicalizeAndConstrain {
|
||||
parsed: ParsedModule<'a>,
|
||||
qualified_module_ids: PackageModuleIds<'a>,
|
||||
|
@ -901,6 +923,7 @@ enum BuildTask<'a> {
|
|||
skip_constraint_gen: bool,
|
||||
exec_mode: ExecutionMode,
|
||||
imported_module_params: VecMap<ModuleId, ModuleParams>,
|
||||
solo_can_output: SoloCanOutput<'a>,
|
||||
},
|
||||
Solve {
|
||||
module: Module,
|
||||
|
@ -2411,6 +2434,23 @@ fn update<'a>(
|
|||
Ok(state)
|
||||
}
|
||||
|
||||
SoloCanonicalized(module_id, CanSolo(solo_can_output)) => {
|
||||
log!("solo canonicalized module {:?}", module_id);
|
||||
|
||||
state
|
||||
.module_cache
|
||||
.solo_canonicalized
|
||||
.insert(module_id, solo_can_output);
|
||||
|
||||
let work = state
|
||||
.dependencies
|
||||
.notify(module_id, Phase::SoloCanonicalize);
|
||||
|
||||
start_tasks(arena, &mut state, work, injector, worker_wakers)?;
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
|
||||
CanonicalizedAndConstrained(CanAndCon {
|
||||
constrained_module,
|
||||
canonicalization_problems,
|
||||
|
@ -2462,6 +2502,7 @@ fn update<'a>(
|
|||
|
||||
Ok(state)
|
||||
}
|
||||
|
||||
SolvedTypes {
|
||||
module_id,
|
||||
ident_ids,
|
||||
|
@ -5082,6 +5123,31 @@ fn build_platform_header<'a>(
|
|||
build_header(info, parse_state, module_ids, module_timing)
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn canonicalize_solo<'a>(arena: &'a Bump, parsed: ParsedModule<'a>) -> CanSolo<'a> {
|
||||
let canonicalize_solo_start = Instant::now();
|
||||
|
||||
let ParsedModule {
|
||||
module_path,
|
||||
header_type,
|
||||
src,
|
||||
parsed_defs,
|
||||
mut module_timing,
|
||||
..
|
||||
} = parsed;
|
||||
|
||||
let parsed_defs = arena.alloc(parsed_defs);
|
||||
|
||||
let solo_can_output =
|
||||
solo_canonicalize_module_defs(arena, header_type, parsed_defs, module_path, src);
|
||||
|
||||
let canonicalize_solo_end = Instant::now();
|
||||
|
||||
module_timing.canonicalize_solo = canonicalize_solo_end.duration_since(canonicalize_solo_start);
|
||||
|
||||
CanSolo(solo_can_output)
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn canonicalize_and_constrain<'a>(
|
||||
arena: &'a Bump,
|
||||
|
@ -5095,21 +5161,21 @@ fn canonicalize_and_constrain<'a>(
|
|||
exposed_module_ids: &[ModuleId],
|
||||
exec_mode: ExecutionMode,
|
||||
imported_module_params: VecMap<ModuleId, ModuleParams>,
|
||||
solo_can_output: SoloCanOutput<'a>,
|
||||
) -> CanAndCon {
|
||||
let canonicalize_start = Instant::now();
|
||||
|
||||
let ParsedModule {
|
||||
module_id,
|
||||
module_path,
|
||||
src,
|
||||
header_type,
|
||||
exposed_ident_ids,
|
||||
parsed_defs,
|
||||
initial_scope,
|
||||
available_modules,
|
||||
mut module_timing,
|
||||
symbols_from_requires,
|
||||
opt_shorthand,
|
||||
exposed_ident_ids,
|
||||
..
|
||||
} = parsed;
|
||||
|
||||
|
@ -5117,27 +5183,55 @@ fn canonicalize_and_constrain<'a>(
|
|||
let _before = roc_types::types::get_type_clone_count();
|
||||
|
||||
let parsed_defs_for_docs = parsed_defs.clone();
|
||||
let parsed_defs = arena.alloc(parsed_defs);
|
||||
|
||||
let mut var_store = VarStore::default();
|
||||
|
||||
let env = Env::from_solo_can(
|
||||
arena,
|
||||
&module_path,
|
||||
module_id,
|
||||
&dep_idents,
|
||||
qualified_module_ids,
|
||||
solo_can_output.problems,
|
||||
opt_shorthand,
|
||||
solo_can_output.src,
|
||||
solo_can_output.lazy_line_info,
|
||||
);
|
||||
|
||||
let mut scope = Scope::new(
|
||||
module_id,
|
||||
qualified_module_ids
|
||||
.get_name(module_id)
|
||||
.expect("home module not found")
|
||||
.as_inner()
|
||||
.to_owned(),
|
||||
exposed_ident_ids,
|
||||
imported_abilities_state,
|
||||
);
|
||||
|
||||
for (name, alias) in aliases.into_iter() {
|
||||
scope.add_alias(
|
||||
name,
|
||||
alias.region,
|
||||
alias.type_variables,
|
||||
alias.infer_ext_in_output_variables,
|
||||
alias.typ,
|
||||
alias.kind,
|
||||
);
|
||||
}
|
||||
|
||||
let mut module_output = canonicalize_module_defs(
|
||||
arena,
|
||||
parsed_defs,
|
||||
&header_type,
|
||||
module_id,
|
||||
&*arena.alloc(module_path.to_string_lossy()),
|
||||
src,
|
||||
qualified_module_ids,
|
||||
exposed_ident_ids,
|
||||
&dep_idents,
|
||||
aliases,
|
||||
imported_abilities_state,
|
||||
initial_scope,
|
||||
exposed_symbols,
|
||||
&symbols_from_requires,
|
||||
&mut var_store,
|
||||
opt_shorthand,
|
||||
scope,
|
||||
env,
|
||||
solo_can_output.loc_defs,
|
||||
solo_can_output.module_params,
|
||||
);
|
||||
|
||||
let mut types = Types::new();
|
||||
|
@ -6237,6 +6331,12 @@ fn run_task<'a>(
|
|||
ident_ids_by_module,
|
||||
root_type,
|
||||
),
|
||||
SoloCanonicalize { parsed } => {
|
||||
let module_id = parsed.module_id;
|
||||
let solo_can = canonicalize_solo(arena, parsed);
|
||||
|
||||
Ok(Msg::SoloCanonicalized(module_id, solo_can))
|
||||
}
|
||||
CanonicalizeAndConstrain {
|
||||
parsed,
|
||||
qualified_module_ids,
|
||||
|
@ -6248,6 +6348,7 @@ fn run_task<'a>(
|
|||
exposed_module_ids,
|
||||
exec_mode,
|
||||
imported_module_params,
|
||||
solo_can_output,
|
||||
} => {
|
||||
let can_and_con = canonicalize_and_constrain(
|
||||
arena,
|
||||
|
@ -6261,6 +6362,7 @@ fn run_task<'a>(
|
|||
exposed_module_ids,
|
||||
exec_mode,
|
||||
imported_module_params,
|
||||
solo_can_output,
|
||||
);
|
||||
|
||||
Ok(Msg::CanonicalizedAndConstrained(can_and_con))
|
||||
|
|
|
@ -189,7 +189,7 @@ pub struct MonomorphizedModule<'a> {
|
|||
pub glue_layouts: GlueLayouts<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ParsedModule<'a> {
|
||||
pub module_id: ModuleId,
|
||||
pub module_path: PathBuf,
|
||||
|
@ -237,11 +237,12 @@ pub struct ExposedToHost {
|
|||
pub getters: Vec<Symbol>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ModuleTiming {
|
||||
pub read_roc_file: Duration,
|
||||
pub parse_header: Duration,
|
||||
pub parse_body: Duration,
|
||||
pub canonicalize_solo: Duration,
|
||||
pub canonicalize: Duration,
|
||||
pub constrain: Duration,
|
||||
pub solve: Duration,
|
||||
|
@ -261,6 +262,7 @@ impl ModuleTiming {
|
|||
read_roc_file: Duration::default(),
|
||||
parse_header: Duration::default(),
|
||||
parse_body: Duration::default(),
|
||||
canonicalize_solo: Duration::default(),
|
||||
canonicalize: Duration::default(),
|
||||
constrain: Duration::default(),
|
||||
solve: Duration::default(),
|
||||
|
@ -281,6 +283,7 @@ impl ModuleTiming {
|
|||
read_roc_file,
|
||||
parse_header,
|
||||
parse_body,
|
||||
canonicalize_solo,
|
||||
canonicalize,
|
||||
constrain,
|
||||
solve,
|
||||
|
@ -297,6 +300,7 @@ impl ModuleTiming {
|
|||
.checked_sub(*find_specializations)?
|
||||
.checked_sub(*solve)?
|
||||
.checked_sub(*constrain)?
|
||||
.checked_sub(*canonicalize_solo)?
|
||||
.checked_sub(*canonicalize)?
|
||||
.checked_sub(*parse_body)?
|
||||
.checked_sub(*parse_header)?
|
||||
|
|
|
@ -5,6 +5,7 @@ use crate::module::{
|
|||
};
|
||||
use roc_can::abilities::PendingAbilitiesStore;
|
||||
use roc_can::module::ModuleParams;
|
||||
use roc_can_solo::module::SoloCanOutput;
|
||||
use roc_collections::{MutMap, MutSet, VecMap};
|
||||
use roc_module::ident::ModuleName;
|
||||
use roc_module::symbol::{ModuleId, PQModuleName, Symbol};
|
||||
|
@ -26,6 +27,7 @@ pub(crate) struct ModuleCache<'a> {
|
|||
pub(crate) parsed: MutMap<ModuleId, ParsedModule<'a>>,
|
||||
pub(crate) aliases: MutMap<ModuleId, MutMap<Symbol, (bool, Alias)>>,
|
||||
pub(crate) pending_abilities: MutMap<ModuleId, PendingAbilitiesStore>,
|
||||
pub(crate) solo_canonicalized: MutMap<ModuleId, SoloCanOutput<'a>>,
|
||||
pub(crate) constrained: MutMap<ModuleId, ConstrainedModule>,
|
||||
pub(crate) module_params: MutMap<ModuleId, ModuleParams>,
|
||||
pub(crate) typechecked: MutMap<ModuleId, TypeCheckedModule<'a>>,
|
||||
|
@ -45,6 +47,8 @@ pub(crate) struct ModuleCache<'a> {
|
|||
pub(crate) type_problems: MutMap<ModuleId, Vec<TypeError>>,
|
||||
|
||||
pub(crate) sources: MutMap<ModuleId, (PathBuf, &'a str)>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) content_hashes: MutMap<ModuleId, String>,
|
||||
}
|
||||
|
||||
impl<'a> ModuleCache<'a> {
|
||||
|
@ -65,6 +69,19 @@ impl<'a> ModuleCache<'a> {
|
|||
pub fn has_errors(&self) -> bool {
|
||||
self.has_can_errors() || self.has_type_errors()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn add_module_content_hash(&mut self, module_id: ModuleId, contents: &str) -> String {
|
||||
let hash = Self::hash_contents(contents);
|
||||
self.content_hashes.insert(module_id, hash.clone());
|
||||
|
||||
hash
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn hash_contents(contents: &str) -> String {
|
||||
base64_url::encode(blake3::hash(contents.as_bytes()).as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ModuleCache<'_> {
|
||||
|
@ -101,6 +118,7 @@ impl Default for ModuleCache<'_> {
|
|||
parsed: Default::default(),
|
||||
aliases: Default::default(),
|
||||
pending_abilities: Default::default(),
|
||||
solo_canonicalized: Default::default(),
|
||||
constrained: Default::default(),
|
||||
module_params: Default::default(),
|
||||
typechecked: Default::default(),
|
||||
|
@ -116,6 +134,7 @@ impl Default for ModuleCache<'_> {
|
|||
can_problems: Default::default(),
|
||||
type_problems: Default::default(),
|
||||
sources: Default::default(),
|
||||
content_hashes: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ succeed = \x -> Identity(x)
|
|||
|
||||
with_default = Res.with_default
|
||||
|
||||
yay : Res.Res {} err
|
||||
yay : Res.Res {} _
|
||||
yay =
|
||||
ok = Ok("foo")
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ succeed = \x -> Identity(x)
|
|||
|
||||
with_default = Res.with_default
|
||||
|
||||
yay : Res.Res {} err
|
||||
yay : Res.Res {} _
|
||||
yay =
|
||||
ok = Ok("foo")
|
||||
|
||||
|
|
|
@ -271,11 +271,13 @@ fn load_fixture(
|
|||
);
|
||||
}
|
||||
|
||||
assert!(loaded_module
|
||||
.type_problems
|
||||
.remove(&home)
|
||||
.unwrap_or_default()
|
||||
.is_empty());
|
||||
assert_eq!(
|
||||
loaded_module
|
||||
.type_problems
|
||||
.remove(&home)
|
||||
.unwrap_or_default(),
|
||||
Vec::new()
|
||||
);
|
||||
|
||||
let expected_name = loaded_module
|
||||
.interns
|
||||
|
@ -433,11 +435,13 @@ fn module_with_deps() {
|
|||
loaded_module.can_problems.remove(&home).unwrap_or_default(),
|
||||
Vec::new()
|
||||
);
|
||||
assert!(loaded_module
|
||||
.type_problems
|
||||
.remove(&home)
|
||||
.unwrap_or_default()
|
||||
.is_empty(),);
|
||||
assert_eq!(
|
||||
loaded_module
|
||||
.type_problems
|
||||
.remove(&home)
|
||||
.unwrap_or_default(),
|
||||
Vec::new()
|
||||
);
|
||||
|
||||
let mut def_count = 0;
|
||||
let declarations = loaded_module.declarations_by_id.remove(&home).unwrap();
|
||||
|
|
|
@ -105,7 +105,8 @@ pub fn remove_module_param_arguments(
|
|||
| TypeError::ExpectedEffectful(_, _)
|
||||
| TypeError::UnsuffixedEffectfulFunction(_, _)
|
||||
| TypeError::SuffixedPureFunction(_, _)
|
||||
| TypeError::InvalidTryTarget(_, _, _) => {}
|
||||
| TypeError::InvalidTryTarget(_, _, _)
|
||||
| TypeError::TypeIsNotGeneralized(..) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -213,6 +214,7 @@ fn drop_last_argument(err_type: &mut ErrorType) {
|
|||
| ErrorType::Alias(_, _, _, _)
|
||||
| ErrorType::Range(_)
|
||||
| ErrorType::Error
|
||||
| ErrorType::EffectfulFunc => {}
|
||||
| ErrorType::EffectfulFunc
|
||||
| ErrorType::InferenceVar => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,8 +62,8 @@ const DISPLAY_STRINGS: [(BinOp, &str); 18] = [
|
|||
(GreaterThan, ">"),
|
||||
(LessThanOrEq, "<="),
|
||||
(GreaterThanOrEq, ">="),
|
||||
(And, "&&"),
|
||||
(Or, "||"),
|
||||
(And, "and"),
|
||||
(Or, "or"),
|
||||
];
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
|
@ -199,7 +199,7 @@ pub enum Associativity {
|
|||
/// right-associative operators:
|
||||
///
|
||||
/// exponentiation: ^
|
||||
/// boolean: && ||
|
||||
/// boolean: and or
|
||||
/// application: <|
|
||||
RightAssociative,
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ pub enum LowLevel {
|
|||
StrReserve,
|
||||
StrWithCapacity,
|
||||
StrReleaseExcessCapacity,
|
||||
StrWithAsciiLowercased,
|
||||
ListLenUsize,
|
||||
ListLenU64,
|
||||
ListWithCapacity,
|
||||
|
@ -110,8 +111,6 @@ pub enum LowLevel {
|
|||
NumF64FromParts,
|
||||
Eq,
|
||||
NotEq,
|
||||
And,
|
||||
Or,
|
||||
Not,
|
||||
Hash,
|
||||
PtrCast,
|
||||
|
@ -269,6 +268,7 @@ map_symbol_to_lowlevel! {
|
|||
StrToNum <= STR_TO_NUM;
|
||||
StrWithCapacity <= STR_WITH_CAPACITY;
|
||||
StrReleaseExcessCapacity <= STR_RELEASE_EXCESS_CAPACITY;
|
||||
StrWithAsciiLowercased <= STR_WITH_ASCII_LOWERCASED;
|
||||
ListLenU64 <= LIST_LEN_U64;
|
||||
ListLenUsize <= LIST_LEN_USIZE;
|
||||
ListGetCapacity <= LIST_CAPACITY;
|
||||
|
@ -345,8 +345,6 @@ map_symbol_to_lowlevel! {
|
|||
NumF64FromParts <= NUM_F64_FROM_PARTS;
|
||||
Eq <= BOOL_STRUCTURAL_EQ;
|
||||
NotEq <= BOOL_STRUCTURAL_NOT_EQ;
|
||||
And <= BOOL_AND;
|
||||
Or <= BOOL_OR;
|
||||
Not <= BOOL_NOT;
|
||||
Unreachable <= LIST_UNREACHABLE;
|
||||
DictPseudoSeed <= DICT_PSEUDO_SEED;
|
||||
|
|
|
@ -986,6 +986,10 @@ macro_rules! define_builtins {
|
|||
self.to_zero_indexed() < $total
|
||||
}
|
||||
|
||||
pub const fn first_after_builtins() -> Self {
|
||||
ModuleId::from_zero_indexed($total)
|
||||
}
|
||||
|
||||
$(
|
||||
pub const $module_const: ModuleId = ModuleId::from_zero_indexed($module_id);
|
||||
)+
|
||||
|
@ -1355,16 +1359,14 @@ define_builtins! {
|
|||
0 BOOL_BOOL: "Bool" exposed_type=true // the Bool.Bool type alias
|
||||
1 BOOL_FALSE: "false"
|
||||
2 BOOL_TRUE: "true"
|
||||
3 BOOL_AND: "and"
|
||||
4 BOOL_OR: "or"
|
||||
5 BOOL_NOT: "not"
|
||||
6 BOOL_XOR: "xor"
|
||||
7 BOOL_NEQ: "is_not_eq"
|
||||
8 BOOL_EQ: "Eq" exposed_type=true
|
||||
9 BOOL_IS_EQ: "is_eq"
|
||||
10 BOOL_IS_EQ_IMPL: "bool_is_eq"
|
||||
unexposed 11 BOOL_STRUCTURAL_EQ: "structural_eq"
|
||||
unexposed 12 BOOL_STRUCTURAL_NOT_EQ: "structural_not_eq"
|
||||
3 BOOL_NOT: "not"
|
||||
4 BOOL_XOR: "xor"
|
||||
5 BOOL_NEQ: "is_not_eq"
|
||||
6 BOOL_EQ: "Eq" exposed_type=true
|
||||
7 BOOL_IS_EQ: "is_eq"
|
||||
8 BOOL_IS_EQ_IMPL: "bool_is_eq"
|
||||
unexposed 9 BOOL_STRUCTURAL_EQ: "structural_eq"
|
||||
unexposed 10 BOOL_STRUCTURAL_NOT_EQ: "structural_not_eq"
|
||||
}
|
||||
5 STR: "Str" => {
|
||||
0 STR_STR: "Str" exposed_apply_type=true // the Str.Str type alias
|
||||
|
@ -1418,10 +1420,11 @@ define_builtins! {
|
|||
48 STR_RELEASE_EXCESS_CAPACITY: "release_excess_capacity"
|
||||
49 STR_DROP_PREFIX: "drop_prefix"
|
||||
50 STR_DROP_SUFFIX: "drop_suffix"
|
||||
51 STR_FROM_UTF16: "from_utf16"
|
||||
52 STR_FROM_UTF16_LOSSY: "from_utf16_lossy"
|
||||
53 STR_FROM_UTF32: "from_utf32"
|
||||
54 STR_FROM_UTF32_LOSSY: "from_utf32_lossy"
|
||||
51 STR_WITH_ASCII_LOWERCASED: "with_ascii_lowercased"
|
||||
52 STR_FROM_UTF16: "from_utf16"
|
||||
53 STR_FROM_UTF16_LOSSY: "from_utf16_lossy"
|
||||
54 STR_FROM_UTF32: "from_utf32"
|
||||
55 STR_FROM_UTF32_LOSSY: "from_utf32_lossy"
|
||||
}
|
||||
6 LIST: "List" => {
|
||||
0 LIST_LIST: "List" exposed_apply_type=true // the List.List type alias
|
||||
|
|
|
@ -1549,6 +1549,7 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC {
|
|||
ListPrepend => RC::Rc,
|
||||
StrJoinWith => RC::NoRc,
|
||||
ListSortWith => RC::Rc,
|
||||
StrWithAsciiLowercased => RC::Rc,
|
||||
|
||||
ListAppendUnsafe
|
||||
| ListReserve
|
||||
|
@ -1562,7 +1563,7 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC {
|
|||
|
||||
Eq | NotEq => RC::NoRc,
|
||||
|
||||
And | Or | NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap
|
||||
NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap
|
||||
| NumSubChecked | NumSubSaturated | NumMul | NumMulWrap | NumMulSaturated
|
||||
| NumMulChecked | NumGt | NumGte | NumLt | NumLte | NumCompare | NumDivFrac
|
||||
| NumDivTruncUnchecked | NumDivCeilUnchecked | NumRemUnchecked | NumIsMultipleOf
|
||||
|
|
|
@ -1258,10 +1258,11 @@ pub(crate) fn lowlevel_borrow_signature(op: LowLevel) -> &'static [Ownership] {
|
|||
StrReleaseExcessCapacity => &[OWNED],
|
||||
ListIncref => &[OWNED],
|
||||
ListDecref => &[OWNED],
|
||||
StrWithAsciiLowercased => &[OWNED],
|
||||
|
||||
Eq | NotEq => &[BORROWED, BORROWED],
|
||||
|
||||
And | Or | NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap
|
||||
NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap
|
||||
| NumSubChecked | NumSubSaturated | NumMul | NumMulWrap | NumMulSaturated
|
||||
| NumMulChecked | NumGt | NumGte | NumLt | NumLte | NumCompare | NumDivFrac
|
||||
| NumDivTruncUnchecked | NumDivCeilUnchecked | NumRemUnchecked | NumIsMultipleOf
|
||||
|
|
|
@ -49,7 +49,15 @@ pub fn apply_trmc<'a, 'i>(
|
|||
|
||||
let env = &mut env;
|
||||
|
||||
for proc in procs.values_mut() {
|
||||
// TODO temporary workaround for #7531, remove this cloning and sorting once that is fixed
|
||||
let clone_procs = procs.clone();
|
||||
let mut procs_key_value_list = clone_procs.iter().collect::<std::vec::Vec<_>>();
|
||||
|
||||
procs_key_value_list.sort_by(|a, b| a.0 .0.cmp(&b.0 .0));
|
||||
|
||||
for (key, _) in procs_key_value_list {
|
||||
let proc = procs.get_mut(key).unwrap();
|
||||
|
||||
use self::SelfRecursive::*;
|
||||
if let SelfRecursive(id) = proc.is_self_recursive {
|
||||
let trmc_candidate_symbols = trmc_candidates(env.interner, proc);
|
||||
|
|
|
@ -738,7 +738,7 @@ fn parse_stmt_operator_chain<'a>(
|
|||
| Expr::Apply(
|
||||
Loc {
|
||||
region: _,
|
||||
value: Expr::Tag(..)
|
||||
value: Expr::Tag(_)
|
||||
},
|
||||
&[],
|
||||
_
|
||||
|
@ -752,7 +752,7 @@ fn parse_stmt_operator_chain<'a>(
|
|||
// try an operator
|
||||
return parse_stmt_after_apply(
|
||||
arena,
|
||||
state.clone(),
|
||||
state,
|
||||
min_indent,
|
||||
call_min_indent,
|
||||
expr_state,
|
||||
|
@ -1934,43 +1934,6 @@ fn parse_stmt_after_apply<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
// #[allow(clippy::too_many_arguments)]
|
||||
// fn parse_expr_after_apply<'a>(
|
||||
// arena: &'a Bump,
|
||||
// state: State<'a>,
|
||||
// min_indent: u32,
|
||||
// call_min_indent: u32,
|
||||
// check_for_arrow: CheckForArrow,
|
||||
// check_for_defs: bool,
|
||||
// mut expr_state: ExprState<'a>,
|
||||
// before_op: State<'a>,
|
||||
// initial_state: State<'a>,
|
||||
// ) -> Result<(Progress, Expr<'a>, State<'a>), (Progress, EExpr<'a>)> {
|
||||
// match loc(bin_op(check_for_defs)).parse(arena, state.clone(), call_min_indent) {
|
||||
// Err((MadeProgress, f)) => Err((MadeProgress, f)),
|
||||
// Ok((_, loc_op, state)) => {
|
||||
// expr_state.consume_spaces(arena);
|
||||
// let initial_state = before_op;
|
||||
// parse_expr_operator(
|
||||
// arena,
|
||||
// state,
|
||||
// min_indent,
|
||||
// call_min_indent,
|
||||
// options,
|
||||
// check_for_defs,
|
||||
// expr_state,
|
||||
// loc_op,
|
||||
// initial_state,
|
||||
// )
|
||||
// }
|
||||
// Err((NoProgress, _)) => {
|
||||
// let expr = parse_expr_final(expr_state, arena);
|
||||
// // roll back space parsing
|
||||
// Ok((MadeProgress, expr, initial_state))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn parse_apply_arg<'a>(
|
||||
arena: &'a Bump,
|
||||
|
@ -2340,16 +2303,18 @@ pub fn parse_top_level_defs<'a>(
|
|||
|
||||
fn closure_help<'a>(check_for_arrow: CheckForArrow) -> impl Parser<'a, Expr<'a>, EClosure<'a>> {
|
||||
one_of!(
|
||||
closure_new_syntax_help(),
|
||||
closure_new_syntax_help(check_for_arrow),
|
||||
closure_old_syntax_help(check_for_arrow),
|
||||
)
|
||||
}
|
||||
|
||||
fn closure_new_syntax_help<'a>() -> impl Parser<'a, Expr<'a>, EClosure<'a>> {
|
||||
fn closure_new_syntax_help<'a>(
|
||||
check_for_arrow: CheckForArrow,
|
||||
) -> impl Parser<'a, Expr<'a>, EClosure<'a>> {
|
||||
map_with_arena(
|
||||
indented_seq_skip_first(
|
||||
skip_first(
|
||||
error_on_pizza(byte_indent(b'|', EClosure::Bar), EClosure::Start),
|
||||
and(
|
||||
reset_min_indent(and(
|
||||
sep_by1_e(
|
||||
byte_indent(b',', EClosure::Comma),
|
||||
space0_around_ee(
|
||||
|
@ -2363,14 +2328,9 @@ fn closure_new_syntax_help<'a>() -> impl Parser<'a, Expr<'a>, EClosure<'a>> {
|
|||
// Parse the -> which separates params from body
|
||||
byte(b'|', EClosure::Bar),
|
||||
// Parse the body
|
||||
block(
|
||||
CheckForArrow(false),
|
||||
true,
|
||||
EClosure::IndentBody,
|
||||
EClosure::Body,
|
||||
),
|
||||
block(check_for_arrow, true, EClosure::IndentBody, EClosure::Body),
|
||||
),
|
||||
),
|
||||
)),
|
||||
),
|
||||
|arena: &'a Bump, (params, body)| {
|
||||
let params: Vec<'a, Loc<Pattern<'a>>> = params;
|
||||
|
@ -2386,12 +2346,12 @@ fn closure_old_syntax_help<'a>(
|
|||
// closure_help_help(options)
|
||||
map_with_arena(
|
||||
// After the first token, all other tokens must be indented past the start of the line
|
||||
indented_seq_skip_first(
|
||||
skip_first(
|
||||
// All closures start with a '\' - e.g. (\x -> x + 1)
|
||||
byte_indent(b'\\', EClosure::Start),
|
||||
// Once we see the '\', we're committed to parsing this as a closure.
|
||||
// It may turn out to be malformed, but it is definitely a closure.
|
||||
and(
|
||||
reset_min_indent(and(
|
||||
// Parse the params
|
||||
// Params are comma-separated
|
||||
sep_by1_e(
|
||||
|
@ -2409,7 +2369,7 @@ fn closure_old_syntax_help<'a>(
|
|||
// Parse the body
|
||||
block(check_for_arrow, true, EClosure::IndentBody, EClosure::Body),
|
||||
),
|
||||
),
|
||||
)),
|
||||
),
|
||||
|arena: &'a Bump, (params, body)| {
|
||||
let params: Vec<'a, Loc<Pattern<'a>>> = params;
|
||||
|
@ -4031,7 +3991,7 @@ enum OperatorOrDef {
|
|||
}
|
||||
|
||||
fn bin_op<'a>(check_for_defs: bool) -> impl Parser<'a, BinOp, EExpr<'a>> {
|
||||
move |_, state: State<'a>, min_indent| {
|
||||
(move |_, state: State<'a>, min_indent| {
|
||||
let start = state.pos();
|
||||
let (_, op, state) = operator_help(EExpr::Start, EExpr::BadOperator, state, min_indent)?;
|
||||
let err_progress = if check_for_defs {
|
||||
|
@ -4049,7 +4009,8 @@ fn bin_op<'a>(check_for_defs: bool) -> impl Parser<'a, BinOp, EExpr<'a>> {
|
|||
Err((err_progress, EExpr::BadOperator(":=", start)))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.trace("bin_op")
|
||||
}
|
||||
|
||||
fn operator<'a>() -> impl Parser<'a, OperatorOrDef, EExpr<'a>> {
|
||||
|
@ -4069,6 +4030,24 @@ where
|
|||
G: Fn(&'a str, Position) -> E,
|
||||
E: 'a,
|
||||
{
|
||||
match *state.bytes() {
|
||||
[b'o', b'r', ..] => {
|
||||
return Ok((
|
||||
MadeProgress,
|
||||
OperatorOrDef::BinOp(BinOp::Or),
|
||||
state.advance(2),
|
||||
))
|
||||
}
|
||||
[b'a', b'n', b'd', ..] => {
|
||||
return Ok((
|
||||
MadeProgress,
|
||||
OperatorOrDef::BinOp(BinOp::And),
|
||||
state.advance(3),
|
||||
))
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let chomped = chomp_ops(state.bytes());
|
||||
|
||||
macro_rules! good {
|
||||
|
@ -4125,6 +4104,7 @@ where
|
|||
"<=" => good!(OperatorOrDef::BinOp(BinOp::LessThanOrEq), 2),
|
||||
"&&" => good!(OperatorOrDef::BinOp(BinOp::And), 2),
|
||||
"||" => good!(OperatorOrDef::BinOp(BinOp::Or), 2),
|
||||
"|" => Err((NoProgress, to_error("|", state.pos()))),
|
||||
"//" => good!(OperatorOrDef::BinOp(BinOp::DoubleSlash), 2),
|
||||
"->" => {
|
||||
// makes no progress, so it does not interfere with `_ if isGood -> ...`
|
||||
|
|
|
@ -927,7 +927,7 @@ impl<'a> HeaderType<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum HeaderType<'a> {
|
||||
App {
|
||||
provides: &'a [Loc<ExposedName<'a>>],
|
||||
|
|
|
@ -10,6 +10,8 @@ pub const IMPORT: &str = "import";
|
|||
pub const EXPECT: &str = "expect";
|
||||
pub const RETURN: &str = "return";
|
||||
pub const CRASH: &str = "crash";
|
||||
pub const AND: &str = "and";
|
||||
pub const OR: &str = "or";
|
||||
|
||||
// These keywords are valid in imports
|
||||
pub const EXPOSING: &str = "exposing";
|
||||
|
@ -21,8 +23,8 @@ pub const WHERE: &str = "where";
|
|||
// These keywords are valid in headers
|
||||
pub const PLATFORM: &str = "platform";
|
||||
|
||||
pub const KEYWORDS: [&str; 11] = [
|
||||
IF, THEN, ELSE, WHEN, AS, IS, DBG, IMPORT, EXPECT, RETURN, CRASH,
|
||||
pub const KEYWORDS: [&str; 13] = [
|
||||
IF, THEN, ELSE, WHEN, AS, IS, DBG, IMPORT, EXPECT, RETURN, CRASH, AND, OR,
|
||||
];
|
||||
|
||||
pub fn is_allowed_identifier(mut ident: &str) -> bool {
|
||||
|
|
|
@ -15,15 +15,12 @@ use bumpalo::Bump;
|
|||
use roc_can::abilities::{AbilitiesStore, MemberSpecializationInfo};
|
||||
use roc_can::constraint::Constraint::{self, *};
|
||||
use roc_can::constraint::{
|
||||
Cycle, FxCallConstraint, FxSuffixConstraint, FxSuffixKind, LetConstraint, OpportunisticResolve,
|
||||
TryTargetConstraint,
|
||||
Cycle, FxCallConstraint, FxSuffixConstraint, FxSuffixKind, Generalizable, LetConstraint,
|
||||
OpportunisticResolve, TryTargetConstraint,
|
||||
};
|
||||
use roc_can::expected::{Expected, PExpected};
|
||||
use roc_can::module::ModuleParams;
|
||||
use roc_collections::{VecMap, VecSet};
|
||||
use roc_debug_flags::dbg_do;
|
||||
#[cfg(debug_assertions)]
|
||||
use roc_debug_flags::ROC_VERIFY_RIGID_LET_GENERALIZED;
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_module::ident::IdentSuffix;
|
||||
use roc_module::symbol::{ModuleId, Symbol};
|
||||
|
@ -32,8 +29,8 @@ use roc_region::all::{Loc, Region};
|
|||
use roc_solve_problem::TypeError;
|
||||
use roc_solve_schema::UnificationMode;
|
||||
use roc_types::subs::{
|
||||
self, Content, FlatType, GetSubsSlice, Mark, OptVariable, Rank, Subs, TagExt, UlsOfVar,
|
||||
Variable,
|
||||
self, Content, ErrorTypeContext, FlatType, GetSubsSlice, Mark, OptVariable, Rank, Subs, TagExt,
|
||||
UlsOfVar, Variable,
|
||||
};
|
||||
use roc_types::types::{Category, Polarity, Reason, RecordField, Type, TypeExtension, Types, Uls};
|
||||
use roc_unify::unify::{
|
||||
|
@ -356,29 +353,13 @@ fn solve(
|
|||
generalize(env, young_mark, visit_mark, rank.next());
|
||||
debug_assert!(env.pools.get(rank.next()).is_empty(), "variables left over in let-binding scope, but they should all be in a lower scope or generalized now");
|
||||
|
||||
// check that things went well
|
||||
dbg_do!(ROC_VERIFY_RIGID_LET_GENERALIZED, {
|
||||
let rigid_vars = &env.constraints[let_con.rigid_vars];
|
||||
|
||||
// NOTE the `subs.redundant` check does not come from elm.
|
||||
// It's unclear whether this is a bug with our implementation
|
||||
// (something is redundant that shouldn't be)
|
||||
// or that it just never came up in elm.
|
||||
let mut it = rigid_vars
|
||||
.iter()
|
||||
.filter(|loc_var| {
|
||||
let var = loc_var.value;
|
||||
!env.subs.redundant(var) && env.subs.get_rank(var) != Rank::GENERALIZED
|
||||
})
|
||||
.peekable();
|
||||
|
||||
if it.peek().is_some() {
|
||||
let failing: Vec<_> = it.collect();
|
||||
println!("Rigids {:?}", &rigid_vars);
|
||||
println!("Failing {failing:?}");
|
||||
debug_assert!(false);
|
||||
}
|
||||
});
|
||||
let named_variables = &env.constraints[let_con.rigid_vars];
|
||||
check_named_variables_are_generalized(
|
||||
env,
|
||||
problems,
|
||||
named_variables,
|
||||
let_con.generalizable,
|
||||
);
|
||||
|
||||
let mut new_scope = scope.clone();
|
||||
for (symbol, loc_var) in local_def_vars.iter() {
|
||||
|
@ -1636,6 +1617,30 @@ fn solve(
|
|||
state
|
||||
}
|
||||
|
||||
fn check_named_variables_are_generalized(
|
||||
env: &mut InferenceEnv<'_>,
|
||||
problems: &mut Vec<TypeError>,
|
||||
named_variables: &[Loc<Variable>],
|
||||
generalizable: Generalizable,
|
||||
) {
|
||||
for loc_var in named_variables {
|
||||
let is_generalized = env.subs.get_rank(loc_var.value) == Rank::GENERALIZED;
|
||||
if !is_generalized {
|
||||
// TODO: should be OF_PATTERN if on the LHS of a function, otherwise OF_VALUE.
|
||||
let polarity = Polarity::OF_VALUE;
|
||||
let ctx = ErrorTypeContext::NON_GENERALIZED_AS_INFERRED;
|
||||
let error_type = env
|
||||
.subs
|
||||
.var_to_error_type_contextual(loc_var.value, ctx, polarity);
|
||||
problems.push(TypeError::TypeIsNotGeneralized(
|
||||
loc_var.region,
|
||||
error_type,
|
||||
generalizable,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn solve_suffix_fx(
|
||||
env: &mut InferenceEnv<'_>,
|
||||
problems: &mut Vec<TypeError>,
|
||||
|
|
|
@ -2510,13 +2510,15 @@ mod solve_expr {
|
|||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r"
|
||||
empty : [Cons a (ConsList a), Nil] as ConsList a
|
||||
empty = Nil
|
||||
ConsList a : [Cons a (ConsList a), Nil]
|
||||
|
||||
empty
|
||||
"
|
||||
empty : ConsList _
|
||||
empty = Nil
|
||||
|
||||
empty
|
||||
"
|
||||
),
|
||||
"ConsList a",
|
||||
"ConsList *",
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3742,7 +3744,7 @@ mod solve_expr {
|
|||
indoc!(
|
||||
r"
|
||||
\rec ->
|
||||
{ x, y } : { x : I64, y ? Bool }*
|
||||
{ x, y } : { x : I64, y ? Bool }_
|
||||
{ x, y ? Bool.false } = rec
|
||||
|
||||
{ x, y }
|
||||
|
@ -3824,6 +3826,18 @@ mod solve_expr {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_with_ascii_lowercased() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r"
|
||||
Str.with_ascii_lowercased
|
||||
"
|
||||
),
|
||||
"Str -> Str",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_take_first() {
|
||||
infer_eq_without_problem(
|
||||
|
@ -3909,26 +3923,6 @@ mod solve_expr {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_named_rigids() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
|
||||
main : List x
|
||||
main =
|
||||
empty : List x
|
||||
empty = []
|
||||
|
||||
empty
|
||||
"#
|
||||
),
|
||||
"List x",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_tag_application() {
|
||||
infer_eq_without_problem(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Provides types to describe problems that can occur during solving.
|
||||
use std::{path::PathBuf, str::Utf8Error};
|
||||
|
||||
use roc_can::constraint::{ExpectEffectfulReason, FxSuffixKind};
|
||||
use roc_can::constraint::{ExpectEffectfulReason, FxSuffixKind, Generalizable};
|
||||
use roc_can::expr::TryKind;
|
||||
use roc_can::{
|
||||
constraint::FxCallKind,
|
||||
|
@ -50,6 +50,7 @@ pub enum TypeError {
|
|||
UnsuffixedEffectfulFunction(Region, FxSuffixKind),
|
||||
SuffixedPureFunction(Region, FxSuffixKind),
|
||||
InvalidTryTarget(Region, ErrorType, TryKind),
|
||||
TypeIsNotGeneralized(Region, ErrorType, Generalizable),
|
||||
}
|
||||
|
||||
impl TypeError {
|
||||
|
@ -80,6 +81,7 @@ impl TypeError {
|
|||
TypeError::UnsuffixedEffectfulFunction(_, _) => Warning,
|
||||
TypeError::SuffixedPureFunction(_, _) => Warning,
|
||||
TypeError::InvalidTryTarget(_, _, _) => RuntimeError,
|
||||
TypeError::TypeIsNotGeneralized(..) => RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +103,8 @@ impl TypeError {
|
|||
| TypeError::ExpectedEffectful(region, _)
|
||||
| TypeError::UnsuffixedEffectfulFunction(region, _)
|
||||
| TypeError::SuffixedPureFunction(region, _)
|
||||
| TypeError::InvalidTryTarget(region, _, _) => Some(*region),
|
||||
| TypeError::InvalidTryTarget(region, _, _)
|
||||
| TypeError::TypeIsNotGeneralized(region, _, _) => Some(*region),
|
||||
TypeError::UnfulfilledAbility(ab, ..) => ab.region(),
|
||||
TypeError::Exhaustive(e) => Some(e.region()),
|
||||
TypeError::CircularDef(c) => c.first().map(|ce| ce.symbol_region),
|
||||
|
|
|
@ -2095,13 +2095,13 @@ mod eq {
|
|||
|
||||
LyingEq := U8 implements [Eq {is_eq}]
|
||||
|
||||
is_eq = \@LyingEq m, @LyingEq n -> m != n
|
||||
is_eq = \@LyingEq(m), @LyingEq(n) -> m != n
|
||||
|
||||
main =
|
||||
a = @LyingEq 10
|
||||
b = @LyingEq 5
|
||||
c = @LyingEq 5
|
||||
if Bool.is_eq a b && !(Bool.is_eq b c) then
|
||||
a = @LyingEq(10)
|
||||
b = @LyingEq(5)
|
||||
c = @LyingEq(5)
|
||||
if Bool.is_eq(a, b) and !(Bool.is_eq(b, c)) then
|
||||
"okay"
|
||||
else
|
||||
"fail"
|
||||
|
|
|
@ -121,7 +121,7 @@ fn bool_logic() {
|
|||
bool2 = Bool.false
|
||||
bool3 = !bool1
|
||||
|
||||
(bool1 && bool2) || bool2 && bool3
|
||||
(bool1 and bool2) or bool2 and bool3
|
||||
"#
|
||||
),
|
||||
false,
|
||||
|
@ -132,19 +132,19 @@ fn bool_logic() {
|
|||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||
fn and_bool() {
|
||||
assert_evals_to!("Bool.true && Bool.true", true, bool);
|
||||
assert_evals_to!("Bool.true && Bool.false", false, bool);
|
||||
assert_evals_to!("Bool.false && Bool.true", false, bool);
|
||||
assert_evals_to!("Bool.false && Bool.false", false, bool);
|
||||
assert_evals_to!("Bool.true and Bool.true", true, bool);
|
||||
assert_evals_to!("Bool.true and Bool.false", false, bool);
|
||||
assert_evals_to!("Bool.false and Bool.true", false, bool);
|
||||
assert_evals_to!("Bool.false and Bool.false", false, bool);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||
fn or_bool() {
|
||||
assert_evals_to!("Bool.true || Bool.true", true, bool);
|
||||
assert_evals_to!("Bool.true || Bool.false", true, bool);
|
||||
assert_evals_to!("Bool.false || Bool.true", true, bool);
|
||||
assert_evals_to!("Bool.false || Bool.false", false, bool);
|
||||
assert_evals_to!("Bool.true or Bool.true", true, bool);
|
||||
assert_evals_to!("Bool.true or Bool.false", true, bool);
|
||||
assert_evals_to!("Bool.false or Bool.true", true, bool);
|
||||
assert_evals_to!("Bool.false or Bool.false", false, bool);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -544,7 +544,7 @@ fn eq_different_rosetrees() {
|
|||
|
||||
cd = c2 == d2
|
||||
|
||||
ab && cd
|
||||
ab and cd
|
||||
"#
|
||||
),
|
||||
true,
|
||||
|
|
|
@ -662,7 +662,7 @@ fn linked_list_len_1() {
|
|||
|
||||
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||
|
||||
one : LinkedList (Int *)
|
||||
one : LinkedList (Int _)
|
||||
one = Cons 1 Nil
|
||||
|
||||
length : LinkedList a -> Int *
|
||||
|
@ -690,7 +690,7 @@ fn linked_list_len_twice_1() {
|
|||
|
||||
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||
|
||||
one : LinkedList (Int *)
|
||||
one : LinkedList (Int _)
|
||||
one = Cons 1 Nil
|
||||
|
||||
length : LinkedList a -> Int *
|
||||
|
@ -718,7 +718,7 @@ fn linked_list_len_3() {
|
|||
|
||||
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||
|
||||
three : LinkedList (Int *)
|
||||
three : LinkedList (Int _)
|
||||
three = Cons 3 (Cons 2 (Cons 1 Nil))
|
||||
|
||||
length : LinkedList a -> Int *
|
||||
|
@ -747,7 +747,7 @@ fn linked_list_sum_num_a() {
|
|||
|
||||
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||
|
||||
three : LinkedList (Int *)
|
||||
three : LinkedList (Int _)
|
||||
three = Cons 3 (Cons 2 (Cons 1 Nil))
|
||||
|
||||
|
||||
|
@ -776,7 +776,7 @@ fn linked_list_sum_int() {
|
|||
|
||||
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||
|
||||
zero : LinkedList (Int *)
|
||||
zero : LinkedList (Int _)
|
||||
zero = Nil
|
||||
|
||||
sum : LinkedList (Int a) -> Int a
|
||||
|
@ -804,7 +804,7 @@ fn linked_list_map() {
|
|||
|
||||
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||
|
||||
three : LinkedList (Int *)
|
||||
three : LinkedList (Int _)
|
||||
three = Cons 3 (Cons 2 (Cons 1 Nil))
|
||||
|
||||
sum : LinkedList (Num a) -> Num a
|
||||
|
@ -836,7 +836,7 @@ fn when_nested_maybe() {
|
|||
r"
|
||||
Maybe a : [Nothing, Just a]
|
||||
|
||||
x : Maybe (Maybe (Int a))
|
||||
x : Maybe (Maybe (Int _))
|
||||
x = Just (Just 41)
|
||||
|
||||
when x is
|
||||
|
@ -853,7 +853,7 @@ fn when_nested_maybe() {
|
|||
r"
|
||||
Maybe a : [Nothing, Just a]
|
||||
|
||||
x : Maybe (Maybe (Int *))
|
||||
x : Maybe (Maybe (Int _))
|
||||
x = Just Nothing
|
||||
|
||||
when x is
|
||||
|
@ -871,7 +871,7 @@ fn when_nested_maybe() {
|
|||
r"
|
||||
Maybe a : [Nothing, Just a]
|
||||
|
||||
x : Maybe (Maybe (Int *))
|
||||
x : Maybe (Maybe (Int _))
|
||||
x = Nothing
|
||||
|
||||
when x is
|
||||
|
@ -1402,7 +1402,7 @@ fn recursive_function_with_rigid() {
|
|||
else
|
||||
1 + foo { count: state.count - 1, x: state.x }
|
||||
|
||||
main : Int *
|
||||
main : Int _
|
||||
main =
|
||||
foo { count: 3, x: {} }
|
||||
"#
|
||||
|
@ -1517,7 +1517,7 @@ fn rbtree_balance_3() {
|
|||
balance = \key, left ->
|
||||
Node key left Empty
|
||||
|
||||
main : RedBlackTree (Int *)
|
||||
main : RedBlackTree (Int _)
|
||||
main =
|
||||
balance 0 Empty
|
||||
"#
|
||||
|
@ -1696,7 +1696,7 @@ fn nested_pattern_match_two_ways() {
|
|||
_ -> 3
|
||||
_ -> 3
|
||||
|
||||
main : Int *
|
||||
main : Int _
|
||||
main =
|
||||
when balance Nil is
|
||||
_ -> 3
|
||||
|
@ -1719,7 +1719,7 @@ fn nested_pattern_match_two_ways() {
|
|||
Cons 1 (Cons 1 _) -> 3
|
||||
_ -> 3
|
||||
|
||||
main : Int *
|
||||
main : Int _
|
||||
main =
|
||||
when balance Nil is
|
||||
_ -> 3
|
||||
|
@ -1751,7 +1751,7 @@ fn linked_list_guarded_double_pattern_match() {
|
|||
_ -> 3
|
||||
_ -> 3
|
||||
|
||||
main : Int *
|
||||
main : Int _
|
||||
main =
|
||||
when balance Nil is
|
||||
_ -> 3
|
||||
|
@ -1778,7 +1778,7 @@ fn linked_list_double_pattern_match() {
|
|||
Cons _ (Cons x _) -> x
|
||||
_ -> 0
|
||||
|
||||
main : Int *
|
||||
main : Int _
|
||||
main =
|
||||
foo (Cons 1 (Cons 32 Nil))
|
||||
"#
|
||||
|
@ -1886,7 +1886,7 @@ fn wildcard_rigid() {
|
|||
@Effect inner
|
||||
|
||||
|
||||
main : MyTask {} (Frac *)
|
||||
main : MyTask {} (Frac _)
|
||||
main = always {}
|
||||
"#
|
||||
),
|
||||
|
|
|
@ -135,7 +135,7 @@ fn err_type_var_annotation() {
|
|||
assert_evals_to!(
|
||||
indoc!(
|
||||
r"
|
||||
ok : Result I64 *
|
||||
ok : Result I64 _
|
||||
ok = Ok 3
|
||||
|
||||
Result.map_ok ok (\x -> x + 1)
|
||||
|
|
|
@ -2218,3 +2218,29 @@ fn str_drop_suffix() {
|
|||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn with_ascii_lowercased() {
|
||||
assert_evals_to!(
|
||||
r#"
|
||||
Str.with_ascii_lowercased("cOFFÉ")
|
||||
"#,
|
||||
RocStr::from("coffÉ"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn with_ascii_lowercased_non_zero_refcount() {
|
||||
assert_evals_to!(
|
||||
r#"
|
||||
original = "cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ cOFFÉ"
|
||||
res = Str.with_ascii_lowercased(original)
|
||||
Str.drop_prefix(res, original)
|
||||
"#,
|
||||
RocStr::from("coffÉ coffÉ coffÉ coffÉ coffÉ coffÉ coffÉ coffÉ coffÉ coffÉ coffÉ coffÉ"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
|
|
@ -158,19 +158,19 @@ fn even_odd() {
|
|||
assert_evals_to!(
|
||||
indoc!(
|
||||
r"
|
||||
even = \n ->
|
||||
even = |n|
|
||||
when n is
|
||||
0 -> Bool.true
|
||||
1 -> Bool.false
|
||||
_ -> odd (n - 1)
|
||||
_ -> odd(n - 1)
|
||||
|
||||
odd = \n ->
|
||||
odd = |n|
|
||||
when n is
|
||||
0 -> Bool.false
|
||||
1 -> Bool.true
|
||||
_ -> even (n - 1)
|
||||
_ -> even(n - 1)
|
||||
|
||||
odd 5 && even 42
|
||||
odd(5) and even(42)
|
||||
"
|
||||
),
|
||||
true,
|
||||
|
@ -1075,7 +1075,7 @@ fn applied_tag_function_result() {
|
|||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
x : List (Result Str *)
|
||||
x : List (Result Str _)
|
||||
x = List.map ["a", "b"] Ok
|
||||
|
||||
List.keep_oks x (\y -> y)
|
||||
|
@ -2315,12 +2315,12 @@ fn recursive_tag_id_in_allocation_eq() {
|
|||
]
|
||||
|
||||
x : Value
|
||||
x = G 42
|
||||
x = G(42)
|
||||
|
||||
y : Value
|
||||
y = H 42
|
||||
y = H(42)
|
||||
|
||||
main = (x == x) && (x != y) && (y == y)
|
||||
main = x == x and x != y and y == y
|
||||
"#
|
||||
),
|
||||
true,
|
||||
|
|
|
@ -66,7 +66,7 @@ fn build_app_mono<'a>(
|
|||
|
||||
let or1_expr = Expr::Call(Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::Or,
|
||||
op: LowLevel::NumBitwiseOr,
|
||||
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||
},
|
||||
arguments: arena.alloc([js_call_result, host_call_result]),
|
||||
|
@ -74,7 +74,7 @@ fn build_app_mono<'a>(
|
|||
|
||||
let or2_expr = Expr::Call(Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::Or,
|
||||
op: LowLevel::NumBitwiseOr,
|
||||
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||
},
|
||||
arguments: arena.alloc([or1, bitflag]),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.23 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.23;
|
||||
procedure Bool.9 (#Attr.2, #Attr.3):
|
||||
let Bool.21 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.21;
|
||||
|
||||
procedure List.116 (List.563, List.564, List.565):
|
||||
let List.693 : U64 = 0i64;
|
||||
|
@ -51,7 +51,7 @@ procedure List.72 (#Attr.2, #Attr.3, #Attr.4):
|
|||
let List.681 : List U8 = lowlevel ListSublist #Attr.2 #Attr.3 #Attr.4;
|
||||
ret List.681;
|
||||
|
||||
procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4):
|
||||
procedure List.80 (Bool.22, Bool.23, Bool.24, Bool.25, Bool.26):
|
||||
joinpoint List.695 List.566 List.567 List.568 List.569 List.570:
|
||||
let List.697 : Int1 = CallByName Num.22 List.569 List.570;
|
||||
if List.697 then
|
||||
|
@ -75,8 +75,8 @@ procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
|
|||
let List.696 : [C U64, C U64] = TagId(1) List.567;
|
||||
ret List.696;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
jump List.695 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
|
||||
inc Bool.22;
|
||||
jump List.695 Bool.22 Bool.23 Bool.24 Bool.25 Bool.26;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
|
@ -95,7 +95,7 @@ procedure Test.1 (Test.2):
|
|||
let Test.14 : {} = Struct {};
|
||||
let Test.3 : U64 = CallByName List.26 Test.2 Test.13 Test.14;
|
||||
let Test.12 : U64 = 0i64;
|
||||
let Test.10 : Int1 = CallByName Bool.11 Test.3 Test.12;
|
||||
let Test.10 : Int1 = CallByName Bool.9 Test.3 Test.12;
|
||||
if Test.10 then
|
||||
ret Test.2;
|
||||
else
|
||||
|
|
|
@ -8,7 +8,7 @@ procedure Test.4 (Test.27):
|
|||
let Test.38 : I64 = CallByName Test.5 Test.27 Test.39 Test.40;
|
||||
ret Test.38;
|
||||
|
||||
procedure Test.5 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||
procedure Test.5 (Bool.21, Bool.22, Bool.23):
|
||||
joinpoint Test.41 Test.29 Test.30 Test.31:
|
||||
let Test.51 : U8 = 0i64;
|
||||
let Test.52 : U8 = GetTagId Test.29;
|
||||
|
@ -16,22 +16,22 @@ procedure Test.5 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
|||
if Test.53 then
|
||||
let Test.32 : [<rnu><null>, C *self *self] = UnionAtIndex (Id 0) (Index 0) Test.29;
|
||||
let Test.33 : [<rnu><null>, C *self *self] = UnionAtIndex (Id 0) (Index 1) Test.29;
|
||||
joinpoint #Derived_gen.3 #Derived_gen.6:
|
||||
let #Derived_gen.7 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = lowlevel PtrCast #Derived_gen.6;
|
||||
let Test.43 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = Reuse #Derived_gen.7 UpdateModeId { id: 1 } TagId(1) Test.33 Test.30;
|
||||
joinpoint Bool.24 Bool.27:
|
||||
let Bool.28 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = lowlevel PtrCast Bool.27;
|
||||
let Test.43 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = Reuse Bool.28 UpdateModeId { id: 1 } TagId(1) Test.33 Test.30;
|
||||
let Test.45 : I64 = 1i64;
|
||||
let Test.44 : I64 = CallByName Num.19 Test.31 Test.45;
|
||||
jump Test.41 Test.32 Test.43 Test.44;
|
||||
in
|
||||
let #Derived_gen.4 : Int1 = lowlevel RefCountIsUnique Test.29;
|
||||
if #Derived_gen.4 then
|
||||
jump #Derived_gen.3 Test.29;
|
||||
let Bool.25 : Int1 = lowlevel RefCountIsUnique Test.29;
|
||||
if Bool.25 then
|
||||
jump Bool.24 Test.29;
|
||||
else
|
||||
inc Test.32;
|
||||
inc Test.33;
|
||||
decref Test.29;
|
||||
let #Derived_gen.8 : [<rnu><null>, C *self *self] = NullPointer;
|
||||
jump #Derived_gen.3 #Derived_gen.8;
|
||||
let Bool.29 : [<rnu><null>, C *self *self] = NullPointer;
|
||||
jump Bool.24 Bool.29;
|
||||
else
|
||||
let Test.48 : U8 = 1i64;
|
||||
let Test.49 : U8 = GetTagId Test.30;
|
||||
|
@ -39,8 +39,8 @@ procedure Test.5 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
|||
if Test.50 then
|
||||
let Test.35 : [<rnu><null>, C *self *self] = UnionAtIndex (Id 1) (Index 0) Test.30;
|
||||
let Test.36 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = UnionAtIndex (Id 1) (Index 1) Test.30;
|
||||
let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique Test.30;
|
||||
if #Derived_gen.5 then
|
||||
let Bool.26 : Int1 = lowlevel RefCountIsUnique Test.30;
|
||||
if Bool.26 then
|
||||
free Test.30;
|
||||
jump Test.41 Test.35 Test.36 Test.31;
|
||||
else
|
||||
|
@ -51,7 +51,7 @@ procedure Test.5 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
|||
else
|
||||
ret Test.31;
|
||||
in
|
||||
jump Test.41 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2;
|
||||
jump Test.41 Bool.21 Bool.22 Bool.23;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.64 : [<rnu><null>, C *self *self] = TagId(1) ;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4):
|
||||
procedure List.101 (Bool.21, Bool.22, Bool.23, Bool.24, Bool.25):
|
||||
joinpoint List.681 List.175 List.176 List.177 List.178 List.179:
|
||||
let List.683 : Int1 = CallByName Num.22 List.178 List.179;
|
||||
if List.683 then
|
||||
|
@ -11,8 +11,8 @@ procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen
|
|||
dec List.175;
|
||||
ret List.176;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
jump List.681 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
|
||||
inc Bool.21;
|
||||
jump List.681 Bool.21 Bool.22 Bool.23 Bool.24 Bool.25;
|
||||
|
||||
procedure List.18 (List.172, List.173, List.174):
|
||||
let List.679 : U64 = 0i64;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4):
|
||||
procedure List.101 (Bool.21, Bool.22, Bool.23, Bool.24, Bool.25):
|
||||
joinpoint List.681 List.175 List.176 List.177 List.178 List.179:
|
||||
let List.683 : Int1 = CallByName Num.22 List.178 List.179;
|
||||
if List.683 then
|
||||
|
@ -11,8 +11,8 @@ procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen
|
|||
dec List.175;
|
||||
ret List.176;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
jump List.681 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
|
||||
inc Bool.21;
|
||||
jump List.681 Bool.21 Bool.22 Bool.23 Bool.24 Bool.25;
|
||||
|
||||
procedure List.18 (List.172, List.173, List.174):
|
||||
let List.679 : U64 = 0i64;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
procedure List.101 (#Derived_gen.8, #Derived_gen.9, #Derived_gen.10, #Derived_gen.11, #Derived_gen.12):
|
||||
procedure List.101 (Bool.34, Bool.35, Bool.36, Bool.37, Bool.38):
|
||||
joinpoint List.678 List.175 List.176 List.177 List.178 List.179:
|
||||
let List.680 : Int1 = CallByName Num.22 List.178 List.179;
|
||||
if List.680 then
|
||||
|
@ -11,8 +11,8 @@ procedure List.101 (#Derived_gen.8, #Derived_gen.9, #Derived_gen.10, #Derived_ge
|
|||
dec List.175;
|
||||
ret List.176;
|
||||
in
|
||||
inc #Derived_gen.8;
|
||||
jump List.678 #Derived_gen.8 #Derived_gen.9 #Derived_gen.10 #Derived_gen.11 #Derived_gen.12;
|
||||
inc Bool.34;
|
||||
jump List.678 Bool.34 Bool.35 Bool.36 Bool.37 Bool.38;
|
||||
|
||||
procedure List.18 (List.172, List.173, List.174):
|
||||
let List.676 : U64 = 0i64;
|
||||
|
@ -38,8 +38,8 @@ procedure Num.51 (#Attr.2, #Attr.3):
|
|||
|
||||
procedure Test.10 (Test.69, #Attr.12):
|
||||
let Test.72 : {} = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
||||
let #Derived_gen.18 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||
if #Derived_gen.18 then
|
||||
let Bool.39 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||
if Bool.39 then
|
||||
free #Attr.12;
|
||||
ret Test.72;
|
||||
else
|
||||
|
@ -53,7 +53,7 @@ procedure Test.10 (Test.69, #Attr.12):
|
|||
procedure Test.14 (Test.45, #Attr.12):
|
||||
let Test.55 : {{}, []} = UnionAtIndex (Id 1) (Index 1) #Attr.12;
|
||||
let Test.54 : [<r>C {}, C *self {{}, []}] = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
||||
joinpoint #Derived_gen.19:
|
||||
joinpoint Bool.40:
|
||||
let Test.50 : {} = Struct {};
|
||||
let Test.51 : U8 = GetTagId Test.54;
|
||||
joinpoint Test.52 Test.15:
|
||||
|
@ -80,14 +80,14 @@ procedure Test.14 (Test.45, #Attr.12):
|
|||
jump Test.52 Test.53;
|
||||
|
||||
in
|
||||
let #Derived_gen.20 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||
if #Derived_gen.20 then
|
||||
let Bool.41 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||
if Bool.41 then
|
||||
free #Attr.12;
|
||||
jump #Derived_gen.19;
|
||||
jump Bool.40;
|
||||
else
|
||||
inc Test.54;
|
||||
decref #Attr.12;
|
||||
jump #Derived_gen.19;
|
||||
jump Bool.40;
|
||||
|
||||
procedure Test.20 (Test.21, Test.18):
|
||||
let Test.23 : [C {}, C []] = CallByName Test.32 Test.21 Test.18;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
procedure Bool.1 ():
|
||||
let Bool.23 : Int1 = false;
|
||||
ret Bool.23;
|
||||
let Bool.21 : Int1 = false;
|
||||
ret Bool.21;
|
||||
|
||||
procedure Test.2 (Test.6):
|
||||
let Test.22 : U8 = 1i64;
|
||||
|
@ -8,7 +8,7 @@ procedure Test.2 (Test.6):
|
|||
let Test.24 : Int1 = lowlevel Eq Test.22 Test.23;
|
||||
if Test.24 then
|
||||
let Test.7 : [<r>C List *self, C *self] = UnionAtIndex (Id 1) (Index 0) Test.6;
|
||||
joinpoint #Derived_gen.1:
|
||||
joinpoint Bool.23:
|
||||
let Test.8 : Str = CallByName Test.2 Test.7;
|
||||
let Test.18 : Int1 = CallByName Bool.1;
|
||||
if Test.18 then
|
||||
|
@ -18,29 +18,29 @@ procedure Test.2 (Test.6):
|
|||
let Test.17 : Str = "foo";
|
||||
ret Test.17;
|
||||
in
|
||||
let #Derived_gen.2 : Int1 = lowlevel RefCountIsUnique Test.6;
|
||||
if #Derived_gen.2 then
|
||||
let Bool.24 : Int1 = lowlevel RefCountIsUnique Test.6;
|
||||
if Bool.24 then
|
||||
free Test.6;
|
||||
jump #Derived_gen.1;
|
||||
jump Bool.23;
|
||||
else
|
||||
inc Test.7;
|
||||
decref Test.6;
|
||||
jump #Derived_gen.1;
|
||||
jump Bool.23;
|
||||
else
|
||||
let Test.9 : List [<r>C List [<r>C List *self, C *self], C [<r>C List *self, C *self]] = UnionAtIndex (Id 0) (Index 0) Test.6;
|
||||
joinpoint #Derived_gen.3:
|
||||
joinpoint Bool.25:
|
||||
dec Test.9;
|
||||
let Test.21 : Str = "ValueNotExposed { module_name: ModuleName(IdentStr { string: \"Result\" }), ident: Ident(IdentStr { string: \"withDefault\" }), region: @662-680, exposed_values: ['is_err', 'on_err', 'map_ok', 'map_err', 'with_default', 'try', 'is_ok', 'map_both', 'map2', 'on_err!'] }";
|
||||
Crash Test.21
|
||||
in
|
||||
let #Derived_gen.4 : Int1 = lowlevel RefCountIsUnique Test.6;
|
||||
if #Derived_gen.4 then
|
||||
let Bool.26 : Int1 = lowlevel RefCountIsUnique Test.6;
|
||||
if Bool.26 then
|
||||
free Test.6;
|
||||
jump #Derived_gen.3;
|
||||
jump Bool.25;
|
||||
else
|
||||
inc Test.9;
|
||||
decref Test.6;
|
||||
jump #Derived_gen.3;
|
||||
jump Bool.25;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.25 : List [<r>C List [<r>C List *self, C *self], C [<r>C List *self, C *self]] = Array [];
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
procedure Bool.2 ():
|
||||
let Bool.23 : Int1 = true;
|
||||
ret Bool.23;
|
||||
let Bool.21 : Int1 = true;
|
||||
ret Bool.21;
|
||||
|
||||
procedure List.101 (#Derived_gen.5, #Derived_gen.6, #Derived_gen.7, #Derived_gen.8, #Derived_gen.9):
|
||||
procedure List.101 (Bool.29, Bool.30, Bool.31, Bool.32, Bool.33):
|
||||
joinpoint List.678 List.175 List.176 List.177 List.178 List.179:
|
||||
let List.680 : Int1 = CallByName Num.22 List.178 List.179;
|
||||
if List.680 then
|
||||
|
@ -15,8 +15,8 @@ procedure List.101 (#Derived_gen.5, #Derived_gen.6, #Derived_gen.7, #Derived_gen
|
|||
dec List.175;
|
||||
ret List.176;
|
||||
in
|
||||
inc #Derived_gen.5;
|
||||
jump List.678 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7 #Derived_gen.8 #Derived_gen.9;
|
||||
inc Bool.29;
|
||||
jump List.678 Bool.29 Bool.30 Bool.31 Bool.32 Bool.33;
|
||||
|
||||
procedure List.18 (List.172, List.173, List.174):
|
||||
let List.676 : U64 = 0i64;
|
||||
|
@ -41,17 +41,17 @@ procedure Num.51 (#Attr.2, #Attr.3):
|
|||
ret Num.283;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.380 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.380;
|
||||
let Str.250 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.250;
|
||||
|
||||
procedure Test.1 (Test.5):
|
||||
ret Test.5;
|
||||
|
||||
procedure Test.11 (#Derived_gen.10, #Derived_gen.11):
|
||||
procedure Test.11 (Bool.27, Bool.28):
|
||||
joinpoint Test.27 Test.12 #Attr.12:
|
||||
let Test.34 : Int1 = UnionAtIndex (Id 2) (Index 1) #Attr.12;
|
||||
let Test.33 : [<rnw><null>, C *self Int1, C *self Int1] = UnionAtIndex (Id 2) (Index 0) #Attr.12;
|
||||
joinpoint #Derived_gen.14:
|
||||
joinpoint Bool.36:
|
||||
joinpoint Test.31 Test.29:
|
||||
let Test.30 : U8 = GetTagId Test.33;
|
||||
switch Test.30:
|
||||
|
@ -78,16 +78,16 @@ procedure Test.11 (#Derived_gen.10, #Derived_gen.11):
|
|||
jump Test.31 Test.32;
|
||||
|
||||
in
|
||||
let #Derived_gen.15 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||
if #Derived_gen.15 then
|
||||
let Bool.37 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||
if Bool.37 then
|
||||
free #Attr.12;
|
||||
jump #Derived_gen.14;
|
||||
jump Bool.36;
|
||||
else
|
||||
inc Test.33;
|
||||
decref #Attr.12;
|
||||
jump #Derived_gen.14;
|
||||
jump Bool.36;
|
||||
in
|
||||
jump Test.27 #Derived_gen.10 #Derived_gen.11;
|
||||
jump Test.27 Bool.27 Bool.28;
|
||||
|
||||
procedure Test.2 (Test.13):
|
||||
ret Test.13;
|
||||
|
@ -118,7 +118,7 @@ procedure Test.6 (Test.7, Test.8, Test.5):
|
|||
procedure Test.9 (Test.10, #Attr.12):
|
||||
let Test.43 : Int1 = UnionAtIndex (Id 1) (Index 1) #Attr.12;
|
||||
let Test.42 : [<rnw><null>, C *self Int1, C *self Int1] = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
||||
joinpoint #Derived_gen.12:
|
||||
joinpoint Bool.34:
|
||||
let Test.39 : U8 = GetTagId Test.42;
|
||||
joinpoint Test.40 Test.38:
|
||||
switch Test.43:
|
||||
|
@ -146,14 +146,14 @@ procedure Test.9 (Test.10, #Attr.12):
|
|||
jump Test.40 Test.41;
|
||||
|
||||
in
|
||||
let #Derived_gen.13 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||
if #Derived_gen.13 then
|
||||
let Bool.35 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||
if Bool.35 then
|
||||
free #Attr.12;
|
||||
jump #Derived_gen.12;
|
||||
jump Bool.34;
|
||||
else
|
||||
inc Test.42;
|
||||
decref #Attr.12;
|
||||
jump #Derived_gen.12;
|
||||
jump Bool.34;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.45 : Int1 = false;
|
||||
|
|
18
crates/compiler/test_mono/generated/dbg_expr.txt
generated
18
crates/compiler/test_mono/generated/dbg_expr.txt
generated
|
@ -43,14 +43,14 @@ procedure Num.96 (#Attr.2):
|
|||
ret Num.284;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.378 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.378;
|
||||
let Str.248 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.248;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 : I64 = 1i64;
|
||||
let Test.2 : I64 = 2i64;
|
||||
let Test.3 : Str = CallByName Inspect.33 Test.2;
|
||||
dbg Test.3;
|
||||
dec Test.3;
|
||||
let Test.4 : I64 = CallByName Num.19 Test.5 Test.2;
|
||||
ret Test.4;
|
||||
let Test.4 : I64 = 1i64;
|
||||
let Test.1 : I64 = 2i64;
|
||||
let Test.2 : Str = CallByName Inspect.33 Test.1;
|
||||
dbg Test.2;
|
||||
dec Test.2;
|
||||
let Test.3 : I64 = CallByName Num.19 Test.4 Test.1;
|
||||
ret Test.3;
|
||||
|
|
323
crates/compiler/test_mono/generated/dbg_in_expect.txt
generated
323
crates/compiler/test_mono/generated/dbg_in_expect.txt
generated
|
@ -1,17 +1,17 @@
|
|||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.25 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.25;
|
||||
|
||||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.26 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.26;
|
||||
procedure Bool.1 ():
|
||||
let Bool.22 : Int1 = false;
|
||||
ret Bool.22;
|
||||
|
||||
procedure Bool.2 ():
|
||||
let Bool.23 : Int1 = true;
|
||||
let Bool.21 : Int1 = true;
|
||||
ret Bool.21;
|
||||
|
||||
procedure Bool.9 (#Attr.2, #Attr.3):
|
||||
let Bool.23 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Bool.3 (#Attr.2, #Attr.3):
|
||||
let Bool.24 : Int1 = lowlevel And #Attr.2 #Attr.3;
|
||||
procedure Bool.9 (#Attr.2, #Attr.3):
|
||||
let Bool.24 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.24;
|
||||
|
||||
procedure Inspect.245 (Inspect.246, Inspect.244):
|
||||
|
@ -104,181 +104,184 @@ procedure Num.77 (#Attr.2, #Attr.3):
|
|||
ret Num.293;
|
||||
|
||||
procedure Str.20 (#Attr.2):
|
||||
let Str.445 : Str = lowlevel StrWithCapacity #Attr.2;
|
||||
ret Str.445;
|
||||
let Str.316 : Str = lowlevel StrWithCapacity #Attr.2;
|
||||
ret Str.316;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.378 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.378;
|
||||
let Str.248 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.248;
|
||||
|
||||
procedure Str.35 (#Attr.2, #Attr.3):
|
||||
let Str.435 : U8 = lowlevel StrGetUnsafe #Attr.2 #Attr.3;
|
||||
ret Str.435;
|
||||
let Str.306 : U8 = lowlevel StrGetUnsafe #Attr.2 #Attr.3;
|
||||
ret Str.306;
|
||||
|
||||
procedure Str.36 (#Attr.2):
|
||||
let Str.398 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.398;
|
||||
let Str.268 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.268;
|
||||
|
||||
procedure Str.37 (#Attr.2, #Attr.3, #Attr.4):
|
||||
let Str.396 : Str = lowlevel StrSubstringUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret Str.396;
|
||||
let Str.266 : Str = lowlevel StrSubstringUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret Str.266;
|
||||
|
||||
procedure Str.38 (Str.210, Str.211):
|
||||
let Str.392 : [C , C U64] = CallByName Str.62 Str.210 Str.211;
|
||||
let Str.405 : U8 = 1i64;
|
||||
let Str.406 : U8 = GetTagId Str.392;
|
||||
let Str.407 : Int1 = lowlevel Eq Str.405 Str.406;
|
||||
if Str.407 then
|
||||
let Str.212 : U64 = UnionAtIndex (Id 1) (Index 0) Str.392;
|
||||
let Str.401 : U64 = CallByName Str.36 Str.210;
|
||||
let Str.402 : U64 = CallByName Str.36 Str.211;
|
||||
let Str.400 : U64 = CallByName Num.20 Str.401 Str.402;
|
||||
let Str.213 : U64 = CallByName Num.20 Str.400 Str.212;
|
||||
let Str.399 : U64 = 0i64;
|
||||
inc Str.210;
|
||||
let Str.214 : Str = CallByName Str.37 Str.210 Str.399 Str.212;
|
||||
let Str.397 : U64 = CallByName Str.36 Str.211;
|
||||
let Str.395 : U64 = CallByName Num.51 Str.212 Str.397;
|
||||
let Str.215 : Str = CallByName Str.37 Str.210 Str.395 Str.213;
|
||||
let Str.394 : {Str, Str} = Struct {Str.215, Str.214};
|
||||
let Str.393 : [C {}, C {Str, Str}] = TagId(1) Str.394;
|
||||
ret Str.393;
|
||||
procedure Str.38 (Str.113, Str.114):
|
||||
let Str.262 : [C , C U64] = CallByName Str.58 Str.113 Str.114;
|
||||
let Str.275 : U8 = 1i64;
|
||||
let Str.276 : U8 = GetTagId Str.262;
|
||||
let Str.277 : Int1 = lowlevel Eq Str.275 Str.276;
|
||||
if Str.277 then
|
||||
let Str.115 : U64 = UnionAtIndex (Id 1) (Index 0) Str.262;
|
||||
let Str.271 : U64 = CallByName Str.36 Str.113;
|
||||
let Str.272 : U64 = CallByName Str.36 Str.114;
|
||||
let Str.270 : U64 = CallByName Num.20 Str.271 Str.272;
|
||||
let Str.116 : U64 = CallByName Num.20 Str.270 Str.115;
|
||||
let Str.269 : U64 = 0i64;
|
||||
inc Str.113;
|
||||
let Str.117 : Str = CallByName Str.37 Str.113 Str.269 Str.115;
|
||||
let Str.267 : U64 = CallByName Str.36 Str.114;
|
||||
let Str.265 : U64 = CallByName Num.51 Str.115 Str.267;
|
||||
let Str.118 : Str = CallByName Str.37 Str.113 Str.265 Str.116;
|
||||
let Str.264 : {Str, Str} = Struct {Str.118, Str.117};
|
||||
let Str.263 : [C {}, C {Str, Str}] = TagId(1) Str.264;
|
||||
ret Str.263;
|
||||
else
|
||||
dec Str.210;
|
||||
let Str.404 : {} = Struct {};
|
||||
let Str.403 : [C {}, C {Str, Str}] = TagId(0) Str.404;
|
||||
ret Str.403;
|
||||
dec Str.113;
|
||||
let Str.274 : {} = Struct {};
|
||||
let Str.273 : [C {}, C {Str, Str}] = TagId(0) Str.274;
|
||||
ret Str.273;
|
||||
|
||||
procedure Str.45 (Str.189, Str.190, Str.191):
|
||||
inc Str.189;
|
||||
let Str.473 : [C {}, C {Str, Str}] = CallByName Str.38 Str.189 Str.190;
|
||||
let Str.481 : U8 = 1i64;
|
||||
let Str.482 : U8 = GetTagId Str.473;
|
||||
let Str.483 : Int1 = lowlevel Eq Str.481 Str.482;
|
||||
if Str.483 then
|
||||
let Str.480 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.473;
|
||||
let Str.193 : Str = StructAtIndex 0 Str.480;
|
||||
let Str.192 : Str = StructAtIndex 1 Str.480;
|
||||
let Str.478 : U64 = CallByName Str.36 Str.189;
|
||||
dec Str.189;
|
||||
let Str.477 : Str = CallByName Str.20 Str.478;
|
||||
let Str.476 : Str = CallByName Str.3 Str.477 Str.192;
|
||||
dec Str.192;
|
||||
let Str.475 : Str = CallByName Str.3 Str.476 Str.191;
|
||||
let Str.474 : Str = CallByName Str.61 Str.475 Str.193 Str.190 Str.191;
|
||||
ret Str.474;
|
||||
procedure Str.45 (Str.92, Str.93, Str.94):
|
||||
inc Str.92;
|
||||
let Str.344 : [C {}, C {Str, Str}] = CallByName Str.38 Str.92 Str.93;
|
||||
let Str.352 : U8 = 1i64;
|
||||
let Str.353 : U8 = GetTagId Str.344;
|
||||
let Str.354 : Int1 = lowlevel Eq Str.352 Str.353;
|
||||
if Str.354 then
|
||||
let Str.351 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.344;
|
||||
let Str.96 : Str = StructAtIndex 0 Str.351;
|
||||
let Str.95 : Str = StructAtIndex 1 Str.351;
|
||||
let Str.349 : U64 = CallByName Str.36 Str.92;
|
||||
dec Str.92;
|
||||
let Str.348 : Str = CallByName Str.20 Str.349;
|
||||
let Str.347 : Str = CallByName Str.3 Str.348 Str.95;
|
||||
dec Str.95;
|
||||
let Str.346 : Str = CallByName Str.3 Str.347 Str.94;
|
||||
let Str.345 : Str = CallByName Str.57 Str.346 Str.96 Str.93 Str.94;
|
||||
ret Str.345;
|
||||
else
|
||||
dec Str.473;
|
||||
ret Str.189;
|
||||
dec Str.344;
|
||||
ret Str.92;
|
||||
|
||||
procedure Str.61 (#Derived_gen.5, #Derived_gen.6, #Derived_gen.7, #Derived_gen.8):
|
||||
joinpoint Str.382 Str.194 Str.195 Str.196 Str.197:
|
||||
inc Str.195;
|
||||
let Str.383 : [C {}, C {Str, Str}] = CallByName Str.38 Str.195 Str.196;
|
||||
let Str.389 : U8 = 1i64;
|
||||
let Str.390 : U8 = GetTagId Str.383;
|
||||
let Str.391 : Int1 = lowlevel Eq Str.389 Str.390;
|
||||
if Str.391 then
|
||||
dec Str.195;
|
||||
let Str.388 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.383;
|
||||
let Str.199 : Str = StructAtIndex 0 Str.388;
|
||||
let Str.198 : Str = StructAtIndex 1 Str.388;
|
||||
let Str.386 : Str = CallByName Str.3 Str.194 Str.198;
|
||||
dec Str.198;
|
||||
let Str.385 : Str = CallByName Str.3 Str.386 Str.197;
|
||||
jump Str.382 Str.385 Str.199 Str.196 Str.197;
|
||||
procedure Str.57 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3):
|
||||
joinpoint Str.252 Str.97 Str.98 Str.99 Str.100:
|
||||
inc Str.98;
|
||||
let Str.253 : [C {}, C {Str, Str}] = CallByName Str.38 Str.98 Str.99;
|
||||
let Str.259 : U8 = 1i64;
|
||||
let Str.260 : U8 = GetTagId Str.253;
|
||||
let Str.261 : Int1 = lowlevel Eq Str.259 Str.260;
|
||||
if Str.261 then
|
||||
dec Str.98;
|
||||
let Str.258 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.253;
|
||||
let Str.102 : Str = StructAtIndex 0 Str.258;
|
||||
let Str.101 : Str = StructAtIndex 1 Str.258;
|
||||
let Str.256 : Str = CallByName Str.3 Str.97 Str.101;
|
||||
dec Str.101;
|
||||
let Str.255 : Str = CallByName Str.3 Str.256 Str.100;
|
||||
jump Str.252 Str.255 Str.102 Str.99 Str.100;
|
||||
else
|
||||
dec Str.196;
|
||||
dec Str.383;
|
||||
dec Str.197;
|
||||
let Str.387 : Str = CallByName Str.3 Str.194 Str.195;
|
||||
dec Str.195;
|
||||
ret Str.387;
|
||||
dec Str.100;
|
||||
dec Str.99;
|
||||
dec Str.253;
|
||||
let Str.257 : Str = CallByName Str.3 Str.97 Str.98;
|
||||
dec Str.98;
|
||||
ret Str.257;
|
||||
in
|
||||
inc #Derived_gen.7;
|
||||
inc #Derived_gen.8;
|
||||
jump Str.382 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7 #Derived_gen.8;
|
||||
inc #Derived_gen.3;
|
||||
inc #Derived_gen.2;
|
||||
jump Str.252 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3;
|
||||
|
||||
procedure Str.62 (Str.219, Str.220):
|
||||
let Str.221 : U64 = CallByName Str.36 Str.219;
|
||||
let Str.222 : U64 = CallByName Str.36 Str.220;
|
||||
let Str.223 : U64 = CallByName Num.77 Str.221 Str.222;
|
||||
let Str.409 : U64 = 0i64;
|
||||
let Str.408 : [C , C U64] = CallByName Str.63 Str.219 Str.220 Str.409 Str.223;
|
||||
ret Str.408;
|
||||
procedure Str.58 (Str.122, Str.123):
|
||||
let Str.124 : U64 = CallByName Str.36 Str.122;
|
||||
let Str.125 : U64 = CallByName Str.36 Str.123;
|
||||
let Str.126 : U64 = CallByName Num.77 Str.124 Str.125;
|
||||
let Str.279 : U64 = 0i64;
|
||||
let Str.278 : [C , C U64] = CallByName Str.59 Str.122 Str.123 Str.279 Str.126;
|
||||
ret Str.278;
|
||||
|
||||
procedure Str.63 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3):
|
||||
joinpoint Str.410 Str.224 Str.225 Str.226 Str.227:
|
||||
let Str.412 : Int1 = CallByName Num.23 Str.226 Str.227;
|
||||
if Str.412 then
|
||||
let Str.416 : Int1 = CallByName Str.67 Str.224 Str.226 Str.225;
|
||||
if Str.416 then
|
||||
dec Str.224;
|
||||
dec Str.225;
|
||||
let Str.417 : [C , C U64] = TagId(1) Str.226;
|
||||
ret Str.417;
|
||||
procedure Str.59 (#Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7):
|
||||
joinpoint Str.280 Str.127 Str.128 Str.129 Str.130:
|
||||
let Str.282 : Int1 = CallByName Num.23 Str.129 Str.130;
|
||||
if Str.282 then
|
||||
let Str.286 : Int1 = CallByName Str.63 Str.127 Str.129 Str.128;
|
||||
if Str.286 then
|
||||
dec Str.127;
|
||||
dec Str.128;
|
||||
let Str.287 : [C , C U64] = TagId(1) Str.129;
|
||||
ret Str.287;
|
||||
else
|
||||
let Str.415 : U64 = 1i64;
|
||||
let Str.414 : U64 = CallByName Num.51 Str.226 Str.415;
|
||||
jump Str.410 Str.224 Str.225 Str.414 Str.227;
|
||||
let Str.285 : U64 = 1i64;
|
||||
let Str.284 : U64 = CallByName Num.51 Str.129 Str.285;
|
||||
jump Str.280 Str.127 Str.128 Str.284 Str.130;
|
||||
else
|
||||
dec Str.224;
|
||||
dec Str.225;
|
||||
let Str.411 : [C , C U64] = TagId(0) ;
|
||||
ret Str.411;
|
||||
dec Str.127;
|
||||
dec Str.128;
|
||||
let Str.281 : [C , C U64] = TagId(0) ;
|
||||
ret Str.281;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
inc #Derived_gen.1;
|
||||
jump Str.410 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3;
|
||||
inc #Derived_gen.5;
|
||||
inc #Derived_gen.4;
|
||||
jump Str.280 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7;
|
||||
|
||||
procedure Str.66 (Str.250, Str.251):
|
||||
let Str.440 : Int1 = CallByName Num.22 Str.250 Str.251;
|
||||
if Str.440 then
|
||||
ret Str.250;
|
||||
procedure Str.62 (Str.153, Str.154):
|
||||
let Str.311 : Int1 = CallByName Num.22 Str.153 Str.154;
|
||||
if Str.311 then
|
||||
ret Str.153;
|
||||
else
|
||||
ret Str.251;
|
||||
ret Str.154;
|
||||
|
||||
procedure Str.67 (Str.252, Str.253, Str.254):
|
||||
let Str.255 : U64 = CallByName Str.36 Str.252;
|
||||
let Str.256 : U64 = CallByName Str.36 Str.254;
|
||||
let Str.438 : U64 = CallByName Num.53 Str.253 Str.256;
|
||||
let Str.257 : U64 = CallByName Str.66 Str.438 Str.255;
|
||||
let Str.437 : U64 = 0i64;
|
||||
inc Str.252;
|
||||
inc Str.254;
|
||||
let Str.419 : {U64, Str, U64, Str, U64, U64} = Struct {Str.257, Str.252, Str.253, Str.254, Str.437, Str.256};
|
||||
let Str.418 : Int1 = CallByName Str.68 Str.419;
|
||||
ret Str.418;
|
||||
procedure Str.63 (Str.155, Str.156, Str.157):
|
||||
let Str.158 : U64 = CallByName Str.36 Str.155;
|
||||
let Str.159 : U64 = CallByName Str.36 Str.157;
|
||||
let Str.309 : U64 = CallByName Num.53 Str.156 Str.159;
|
||||
let Str.160 : U64 = CallByName Str.62 Str.309 Str.158;
|
||||
let Str.308 : U64 = 0i64;
|
||||
inc Str.157;
|
||||
inc Str.155;
|
||||
let Str.289 : {U64, Str, U64, Str, U64, U64} = Struct {Str.160, Str.155, Str.156, Str.157, Str.308, Str.159};
|
||||
let Str.288 : Int1 = CallByName Str.64 Str.289;
|
||||
ret Str.288;
|
||||
|
||||
procedure Str.68 (Str.258):
|
||||
let Str.264 : U64 = StructAtIndex 0 Str.258;
|
||||
let Str.259 : Str = StructAtIndex 1 Str.258;
|
||||
let Str.260 : U64 = StructAtIndex 2 Str.258;
|
||||
let Str.261 : Str = StructAtIndex 3 Str.258;
|
||||
let Str.262 : U64 = StructAtIndex 4 Str.258;
|
||||
let Str.263 : U64 = StructAtIndex 5 Str.258;
|
||||
let Str.265 : Int1 = CallByName Num.25 Str.260 Str.264;
|
||||
if Str.265 then
|
||||
dec Str.259;
|
||||
dec Str.261;
|
||||
let Str.266 : Int1 = CallByName Bool.11 Str.262 Str.263;
|
||||
ret Str.266;
|
||||
procedure Str.64 (Str.161):
|
||||
let Str.167 : U64 = StructAtIndex 0 Str.161;
|
||||
let Str.162 : Str = StructAtIndex 1 Str.161;
|
||||
let Str.163 : U64 = StructAtIndex 2 Str.161;
|
||||
let Str.164 : Str = StructAtIndex 3 Str.161;
|
||||
let Str.165 : U64 = StructAtIndex 4 Str.161;
|
||||
let Str.166 : U64 = StructAtIndex 5 Str.161;
|
||||
let Str.168 : Int1 = CallByName Num.25 Str.163 Str.167;
|
||||
if Str.168 then
|
||||
dec Str.162;
|
||||
dec Str.164;
|
||||
let Str.169 : Int1 = CallByName Bool.9 Str.165 Str.166;
|
||||
ret Str.169;
|
||||
else
|
||||
let Str.433 : U8 = CallByName Str.35 Str.259 Str.260;
|
||||
let Str.434 : U8 = CallByName Str.35 Str.261 Str.262;
|
||||
let Str.267 : Int1 = CallByName Bool.11 Str.433 Str.434;
|
||||
let Str.423 : U64 = StructAtIndex 0 Str.258;
|
||||
let Str.424 : Str = StructAtIndex 1 Str.258;
|
||||
let Str.426 : Str = StructAtIndex 3 Str.258;
|
||||
let Str.428 : U64 = StructAtIndex 5 Str.258;
|
||||
let Str.432 : U64 = 1i64;
|
||||
let Str.430 : U64 = CallByName Num.51 Str.262 Str.432;
|
||||
let Str.431 : U64 = 1i64;
|
||||
let Str.429 : U64 = CallByName Num.51 Str.260 Str.431;
|
||||
let Str.422 : {U64, Str, U64, Str, U64, U64} = Struct {Str.423, Str.424, Str.429, Str.426, Str.430, Str.428};
|
||||
let Str.268 : Int1 = CallByName Str.68 Str.422;
|
||||
let Str.421 : Int1 = CallByName Bool.3 Str.267 Str.268;
|
||||
ret Str.421;
|
||||
let Str.304 : U8 = CallByName Str.35 Str.162 Str.163;
|
||||
let Str.305 : U8 = CallByName Str.35 Str.164 Str.165;
|
||||
let Str.170 : Int1 = CallByName Bool.9 Str.304 Str.305;
|
||||
let Str.294 : U64 = StructAtIndex 0 Str.161;
|
||||
let Str.295 : Str = StructAtIndex 1 Str.161;
|
||||
let Str.297 : Str = StructAtIndex 3 Str.161;
|
||||
let Str.299 : U64 = StructAtIndex 5 Str.161;
|
||||
let Str.303 : U64 = 1i64;
|
||||
let Str.301 : U64 = CallByName Num.51 Str.165 Str.303;
|
||||
let Str.302 : U64 = 1i64;
|
||||
let Str.300 : U64 = CallByName Num.51 Str.163 Str.302;
|
||||
let Str.293 : {U64, Str, U64, Str, U64, U64} = Struct {Str.294, Str.295, Str.300, Str.297, Str.301, Str.299};
|
||||
let Str.171 : Int1 = CallByName Str.64 Str.293;
|
||||
if Str.170 then
|
||||
ret Str.171;
|
||||
else
|
||||
let Str.291 : Int1 = CallByName Bool.1;
|
||||
ret Str.291;
|
||||
|
||||
procedure Test.1 ():
|
||||
let Test.4 : Str = "";
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.24 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.24;
|
||||
procedure Bool.1 ():
|
||||
let Bool.21 : Int1 = false;
|
||||
ret Bool.21;
|
||||
|
||||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.25 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.25;
|
||||
procedure Bool.9 (#Attr.2, #Attr.3):
|
||||
let Bool.22 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.22;
|
||||
|
||||
procedure Bool.3 (#Attr.2, #Attr.3):
|
||||
let Bool.23 : Int1 = lowlevel And #Attr.2 #Attr.3;
|
||||
procedure Bool.9 (#Attr.2, #Attr.3):
|
||||
let Bool.23 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Inspect.245 (Inspect.246, Inspect.244):
|
||||
|
@ -100,192 +100,195 @@ procedure Num.77 (#Attr.2, #Attr.3):
|
|||
ret Num.293;
|
||||
|
||||
procedure Str.20 (#Attr.2):
|
||||
let Str.447 : Str = lowlevel StrWithCapacity #Attr.2;
|
||||
ret Str.447;
|
||||
let Str.318 : Str = lowlevel StrWithCapacity #Attr.2;
|
||||
ret Str.318;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.380 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.380;
|
||||
let Str.250 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.250;
|
||||
|
||||
procedure Str.35 (#Attr.2, #Attr.3):
|
||||
let Str.437 : U8 = lowlevel StrGetUnsafe #Attr.2 #Attr.3;
|
||||
ret Str.437;
|
||||
let Str.308 : U8 = lowlevel StrGetUnsafe #Attr.2 #Attr.3;
|
||||
ret Str.308;
|
||||
|
||||
procedure Str.36 (#Attr.2):
|
||||
let Str.400 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.400;
|
||||
let Str.270 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.270;
|
||||
|
||||
procedure Str.37 (#Attr.2, #Attr.3, #Attr.4):
|
||||
let Str.398 : Str = lowlevel StrSubstringUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret Str.398;
|
||||
let Str.268 : Str = lowlevel StrSubstringUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret Str.268;
|
||||
|
||||
procedure Str.38 (Str.210, Str.211):
|
||||
let Str.394 : [C , C U64] = CallByName Str.62 Str.210 Str.211;
|
||||
let Str.407 : U8 = 1i64;
|
||||
let Str.408 : U8 = GetTagId Str.394;
|
||||
let Str.409 : Int1 = lowlevel Eq Str.407 Str.408;
|
||||
if Str.409 then
|
||||
let Str.212 : U64 = UnionAtIndex (Id 1) (Index 0) Str.394;
|
||||
let Str.403 : U64 = CallByName Str.36 Str.210;
|
||||
let Str.404 : U64 = CallByName Str.36 Str.211;
|
||||
let Str.402 : U64 = CallByName Num.20 Str.403 Str.404;
|
||||
let Str.213 : U64 = CallByName Num.20 Str.402 Str.212;
|
||||
let Str.401 : U64 = 0i64;
|
||||
inc Str.210;
|
||||
let Str.214 : Str = CallByName Str.37 Str.210 Str.401 Str.212;
|
||||
let Str.399 : U64 = CallByName Str.36 Str.211;
|
||||
let Str.397 : U64 = CallByName Num.51 Str.212 Str.399;
|
||||
let Str.215 : Str = CallByName Str.37 Str.210 Str.397 Str.213;
|
||||
let Str.396 : {Str, Str} = Struct {Str.215, Str.214};
|
||||
let Str.395 : [C {}, C {Str, Str}] = TagId(1) Str.396;
|
||||
ret Str.395;
|
||||
procedure Str.38 (Str.113, Str.114):
|
||||
let Str.264 : [C , C U64] = CallByName Str.58 Str.113 Str.114;
|
||||
let Str.277 : U8 = 1i64;
|
||||
let Str.278 : U8 = GetTagId Str.264;
|
||||
let Str.279 : Int1 = lowlevel Eq Str.277 Str.278;
|
||||
if Str.279 then
|
||||
let Str.115 : U64 = UnionAtIndex (Id 1) (Index 0) Str.264;
|
||||
let Str.273 : U64 = CallByName Str.36 Str.113;
|
||||
let Str.274 : U64 = CallByName Str.36 Str.114;
|
||||
let Str.272 : U64 = CallByName Num.20 Str.273 Str.274;
|
||||
let Str.116 : U64 = CallByName Num.20 Str.272 Str.115;
|
||||
let Str.271 : U64 = 0i64;
|
||||
inc Str.113;
|
||||
let Str.117 : Str = CallByName Str.37 Str.113 Str.271 Str.115;
|
||||
let Str.269 : U64 = CallByName Str.36 Str.114;
|
||||
let Str.267 : U64 = CallByName Num.51 Str.115 Str.269;
|
||||
let Str.118 : Str = CallByName Str.37 Str.113 Str.267 Str.116;
|
||||
let Str.266 : {Str, Str} = Struct {Str.118, Str.117};
|
||||
let Str.265 : [C {}, C {Str, Str}] = TagId(1) Str.266;
|
||||
ret Str.265;
|
||||
else
|
||||
dec Str.210;
|
||||
let Str.406 : {} = Struct {};
|
||||
let Str.405 : [C {}, C {Str, Str}] = TagId(0) Str.406;
|
||||
ret Str.405;
|
||||
dec Str.113;
|
||||
let Str.276 : {} = Struct {};
|
||||
let Str.275 : [C {}, C {Str, Str}] = TagId(0) Str.276;
|
||||
ret Str.275;
|
||||
|
||||
procedure Str.45 (Str.189, Str.190, Str.191):
|
||||
inc Str.189;
|
||||
let Str.475 : [C {}, C {Str, Str}] = CallByName Str.38 Str.189 Str.190;
|
||||
let Str.483 : U8 = 1i64;
|
||||
let Str.484 : U8 = GetTagId Str.475;
|
||||
let Str.485 : Int1 = lowlevel Eq Str.483 Str.484;
|
||||
if Str.485 then
|
||||
let Str.482 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.475;
|
||||
let Str.193 : Str = StructAtIndex 0 Str.482;
|
||||
let Str.192 : Str = StructAtIndex 1 Str.482;
|
||||
let Str.480 : U64 = CallByName Str.36 Str.189;
|
||||
dec Str.189;
|
||||
let Str.479 : Str = CallByName Str.20 Str.480;
|
||||
let Str.478 : Str = CallByName Str.3 Str.479 Str.192;
|
||||
dec Str.192;
|
||||
let Str.477 : Str = CallByName Str.3 Str.478 Str.191;
|
||||
let Str.476 : Str = CallByName Str.61 Str.477 Str.193 Str.190 Str.191;
|
||||
ret Str.476;
|
||||
procedure Str.45 (Str.92, Str.93, Str.94):
|
||||
inc Str.92;
|
||||
let Str.346 : [C {}, C {Str, Str}] = CallByName Str.38 Str.92 Str.93;
|
||||
let Str.354 : U8 = 1i64;
|
||||
let Str.355 : U8 = GetTagId Str.346;
|
||||
let Str.356 : Int1 = lowlevel Eq Str.354 Str.355;
|
||||
if Str.356 then
|
||||
let Str.353 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.346;
|
||||
let Str.96 : Str = StructAtIndex 0 Str.353;
|
||||
let Str.95 : Str = StructAtIndex 1 Str.353;
|
||||
let Str.351 : U64 = CallByName Str.36 Str.92;
|
||||
dec Str.92;
|
||||
let Str.350 : Str = CallByName Str.20 Str.351;
|
||||
let Str.349 : Str = CallByName Str.3 Str.350 Str.95;
|
||||
dec Str.95;
|
||||
let Str.348 : Str = CallByName Str.3 Str.349 Str.94;
|
||||
let Str.347 : Str = CallByName Str.57 Str.348 Str.96 Str.93 Str.94;
|
||||
ret Str.347;
|
||||
else
|
||||
dec Str.475;
|
||||
ret Str.189;
|
||||
dec Str.346;
|
||||
ret Str.92;
|
||||
|
||||
procedure Str.61 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3):
|
||||
joinpoint Str.384 Str.194 Str.195 Str.196 Str.197:
|
||||
inc Str.195;
|
||||
let Str.385 : [C {}, C {Str, Str}] = CallByName Str.38 Str.195 Str.196;
|
||||
let Str.391 : U8 = 1i64;
|
||||
let Str.392 : U8 = GetTagId Str.385;
|
||||
let Str.393 : Int1 = lowlevel Eq Str.391 Str.392;
|
||||
if Str.393 then
|
||||
dec Str.195;
|
||||
let Str.390 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.385;
|
||||
let Str.199 : Str = StructAtIndex 0 Str.390;
|
||||
let Str.198 : Str = StructAtIndex 1 Str.390;
|
||||
let Str.388 : Str = CallByName Str.3 Str.194 Str.198;
|
||||
dec Str.198;
|
||||
let Str.387 : Str = CallByName Str.3 Str.388 Str.197;
|
||||
jump Str.384 Str.387 Str.199 Str.196 Str.197;
|
||||
procedure Str.57 (Bool.24, Bool.25, Bool.26, Bool.27):
|
||||
joinpoint Str.254 Str.97 Str.98 Str.99 Str.100:
|
||||
inc Str.98;
|
||||
let Str.255 : [C {}, C {Str, Str}] = CallByName Str.38 Str.98 Str.99;
|
||||
let Str.261 : U8 = 1i64;
|
||||
let Str.262 : U8 = GetTagId Str.255;
|
||||
let Str.263 : Int1 = lowlevel Eq Str.261 Str.262;
|
||||
if Str.263 then
|
||||
dec Str.98;
|
||||
let Str.260 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.255;
|
||||
let Str.102 : Str = StructAtIndex 0 Str.260;
|
||||
let Str.101 : Str = StructAtIndex 1 Str.260;
|
||||
let Str.258 : Str = CallByName Str.3 Str.97 Str.101;
|
||||
dec Str.101;
|
||||
let Str.257 : Str = CallByName Str.3 Str.258 Str.100;
|
||||
jump Str.254 Str.257 Str.102 Str.99 Str.100;
|
||||
else
|
||||
dec Str.385;
|
||||
dec Str.196;
|
||||
dec Str.197;
|
||||
let Str.389 : Str = CallByName Str.3 Str.194 Str.195;
|
||||
dec Str.195;
|
||||
ret Str.389;
|
||||
dec Str.100;
|
||||
dec Str.99;
|
||||
dec Str.255;
|
||||
let Str.259 : Str = CallByName Str.3 Str.97 Str.98;
|
||||
dec Str.98;
|
||||
ret Str.259;
|
||||
in
|
||||
inc #Derived_gen.3;
|
||||
inc #Derived_gen.2;
|
||||
jump Str.384 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3;
|
||||
inc Bool.26;
|
||||
inc Bool.27;
|
||||
jump Str.254 Bool.24 Bool.25 Bool.26 Bool.27;
|
||||
|
||||
procedure Str.62 (Str.219, Str.220):
|
||||
let Str.221 : U64 = CallByName Str.36 Str.219;
|
||||
let Str.222 : U64 = CallByName Str.36 Str.220;
|
||||
let Str.223 : U64 = CallByName Num.77 Str.221 Str.222;
|
||||
let Str.411 : U64 = 0i64;
|
||||
let Str.410 : [C , C U64] = CallByName Str.63 Str.219 Str.220 Str.411 Str.223;
|
||||
ret Str.410;
|
||||
procedure Str.58 (Str.122, Str.123):
|
||||
let Str.124 : U64 = CallByName Str.36 Str.122;
|
||||
let Str.125 : U64 = CallByName Str.36 Str.123;
|
||||
let Str.126 : U64 = CallByName Num.77 Str.124 Str.125;
|
||||
let Str.281 : U64 = 0i64;
|
||||
let Str.280 : [C , C U64] = CallByName Str.59 Str.122 Str.123 Str.281 Str.126;
|
||||
ret Str.280;
|
||||
|
||||
procedure Str.63 (#Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7):
|
||||
joinpoint Str.412 Str.224 Str.225 Str.226 Str.227:
|
||||
let Str.414 : Int1 = CallByName Num.23 Str.226 Str.227;
|
||||
if Str.414 then
|
||||
let Str.418 : Int1 = CallByName Str.67 Str.224 Str.226 Str.225;
|
||||
if Str.418 then
|
||||
dec Str.224;
|
||||
dec Str.225;
|
||||
let Str.419 : [C , C U64] = TagId(1) Str.226;
|
||||
ret Str.419;
|
||||
procedure Str.59 (Bool.28, Bool.29, Bool.30, Bool.31):
|
||||
joinpoint Str.282 Str.127 Str.128 Str.129 Str.130:
|
||||
let Str.284 : Int1 = CallByName Num.23 Str.129 Str.130;
|
||||
if Str.284 then
|
||||
let Str.288 : Int1 = CallByName Str.63 Str.127 Str.129 Str.128;
|
||||
if Str.288 then
|
||||
dec Str.127;
|
||||
dec Str.128;
|
||||
let Str.289 : [C , C U64] = TagId(1) Str.129;
|
||||
ret Str.289;
|
||||
else
|
||||
let Str.417 : U64 = 1i64;
|
||||
let Str.416 : U64 = CallByName Num.51 Str.226 Str.417;
|
||||
jump Str.412 Str.224 Str.225 Str.416 Str.227;
|
||||
let Str.287 : U64 = 1i64;
|
||||
let Str.286 : U64 = CallByName Num.51 Str.129 Str.287;
|
||||
jump Str.282 Str.127 Str.128 Str.286 Str.130;
|
||||
else
|
||||
dec Str.224;
|
||||
dec Str.225;
|
||||
let Str.413 : [C , C U64] = TagId(0) ;
|
||||
ret Str.413;
|
||||
dec Str.127;
|
||||
dec Str.128;
|
||||
let Str.283 : [C , C U64] = TagId(0) ;
|
||||
ret Str.283;
|
||||
in
|
||||
inc #Derived_gen.5;
|
||||
inc #Derived_gen.4;
|
||||
jump Str.412 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7;
|
||||
inc Bool.29;
|
||||
inc Bool.28;
|
||||
jump Str.282 Bool.28 Bool.29 Bool.30 Bool.31;
|
||||
|
||||
procedure Str.66 (Str.250, Str.251):
|
||||
let Str.442 : Int1 = CallByName Num.22 Str.250 Str.251;
|
||||
if Str.442 then
|
||||
ret Str.250;
|
||||
procedure Str.62 (Str.153, Str.154):
|
||||
let Str.313 : Int1 = CallByName Num.22 Str.153 Str.154;
|
||||
if Str.313 then
|
||||
ret Str.153;
|
||||
else
|
||||
ret Str.251;
|
||||
ret Str.154;
|
||||
|
||||
procedure Str.67 (Str.252, Str.253, Str.254):
|
||||
let Str.255 : U64 = CallByName Str.36 Str.252;
|
||||
let Str.256 : U64 = CallByName Str.36 Str.254;
|
||||
let Str.440 : U64 = CallByName Num.53 Str.253 Str.256;
|
||||
let Str.257 : U64 = CallByName Str.66 Str.440 Str.255;
|
||||
let Str.439 : U64 = 0i64;
|
||||
inc Str.252;
|
||||
inc Str.254;
|
||||
let Str.421 : {U64, Str, U64, Str, U64, U64} = Struct {Str.257, Str.252, Str.253, Str.254, Str.439, Str.256};
|
||||
let Str.420 : Int1 = CallByName Str.68 Str.421;
|
||||
ret Str.420;
|
||||
procedure Str.63 (Str.155, Str.156, Str.157):
|
||||
let Str.158 : U64 = CallByName Str.36 Str.155;
|
||||
let Str.159 : U64 = CallByName Str.36 Str.157;
|
||||
let Str.311 : U64 = CallByName Num.53 Str.156 Str.159;
|
||||
let Str.160 : U64 = CallByName Str.62 Str.311 Str.158;
|
||||
let Str.310 : U64 = 0i64;
|
||||
inc Str.157;
|
||||
inc Str.155;
|
||||
let Str.291 : {U64, Str, U64, Str, U64, U64} = Struct {Str.160, Str.155, Str.156, Str.157, Str.310, Str.159};
|
||||
let Str.290 : Int1 = CallByName Str.64 Str.291;
|
||||
ret Str.290;
|
||||
|
||||
procedure Str.68 (Str.258):
|
||||
let Str.264 : U64 = StructAtIndex 0 Str.258;
|
||||
let Str.259 : Str = StructAtIndex 1 Str.258;
|
||||
let Str.260 : U64 = StructAtIndex 2 Str.258;
|
||||
let Str.261 : Str = StructAtIndex 3 Str.258;
|
||||
let Str.262 : U64 = StructAtIndex 4 Str.258;
|
||||
let Str.263 : U64 = StructAtIndex 5 Str.258;
|
||||
let Str.265 : Int1 = CallByName Num.25 Str.260 Str.264;
|
||||
if Str.265 then
|
||||
dec Str.259;
|
||||
dec Str.261;
|
||||
let Str.266 : Int1 = CallByName Bool.11 Str.262 Str.263;
|
||||
ret Str.266;
|
||||
procedure Str.64 (Str.161):
|
||||
let Str.167 : U64 = StructAtIndex 0 Str.161;
|
||||
let Str.162 : Str = StructAtIndex 1 Str.161;
|
||||
let Str.163 : U64 = StructAtIndex 2 Str.161;
|
||||
let Str.164 : Str = StructAtIndex 3 Str.161;
|
||||
let Str.165 : U64 = StructAtIndex 4 Str.161;
|
||||
let Str.166 : U64 = StructAtIndex 5 Str.161;
|
||||
let Str.168 : Int1 = CallByName Num.25 Str.163 Str.167;
|
||||
if Str.168 then
|
||||
dec Str.162;
|
||||
dec Str.164;
|
||||
let Str.169 : Int1 = CallByName Bool.9 Str.165 Str.166;
|
||||
ret Str.169;
|
||||
else
|
||||
let Str.435 : U8 = CallByName Str.35 Str.259 Str.260;
|
||||
let Str.436 : U8 = CallByName Str.35 Str.261 Str.262;
|
||||
let Str.267 : Int1 = CallByName Bool.11 Str.435 Str.436;
|
||||
let Str.425 : U64 = StructAtIndex 0 Str.258;
|
||||
let Str.426 : Str = StructAtIndex 1 Str.258;
|
||||
let Str.428 : Str = StructAtIndex 3 Str.258;
|
||||
let Str.430 : U64 = StructAtIndex 5 Str.258;
|
||||
let Str.434 : U64 = 1i64;
|
||||
let Str.432 : U64 = CallByName Num.51 Str.262 Str.434;
|
||||
let Str.433 : U64 = 1i64;
|
||||
let Str.431 : U64 = CallByName Num.51 Str.260 Str.433;
|
||||
let Str.424 : {U64, Str, U64, Str, U64, U64} = Struct {Str.425, Str.426, Str.431, Str.428, Str.432, Str.430};
|
||||
let Str.268 : Int1 = CallByName Str.68 Str.424;
|
||||
let Str.423 : Int1 = CallByName Bool.3 Str.267 Str.268;
|
||||
ret Str.423;
|
||||
let Str.306 : U8 = CallByName Str.35 Str.162 Str.163;
|
||||
let Str.307 : U8 = CallByName Str.35 Str.164 Str.165;
|
||||
let Str.170 : Int1 = CallByName Bool.9 Str.306 Str.307;
|
||||
let Str.296 : U64 = StructAtIndex 0 Str.161;
|
||||
let Str.297 : Str = StructAtIndex 1 Str.161;
|
||||
let Str.299 : Str = StructAtIndex 3 Str.161;
|
||||
let Str.301 : U64 = StructAtIndex 5 Str.161;
|
||||
let Str.305 : U64 = 1i64;
|
||||
let Str.303 : U64 = CallByName Num.51 Str.165 Str.305;
|
||||
let Str.304 : U64 = 1i64;
|
||||
let Str.302 : U64 = CallByName Num.51 Str.163 Str.304;
|
||||
let Str.295 : {U64, Str, U64, Str, U64, U64} = Struct {Str.296, Str.297, Str.302, Str.299, Str.303, Str.301};
|
||||
let Str.171 : Int1 = CallByName Str.64 Str.295;
|
||||
if Str.170 then
|
||||
ret Str.171;
|
||||
else
|
||||
let Str.293 : Int1 = CallByName Bool.1;
|
||||
ret Str.293;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 : Str = "Hello ";
|
||||
let Test.2 : Str = "world";
|
||||
inc Test.2;
|
||||
let Test.3 : Str = CallByName Inspect.33 Test.2;
|
||||
dbg Test.3;
|
||||
dec Test.3;
|
||||
let Test.8 : Str = "!";
|
||||
let Test.6 : Str = CallByName Str.3 Test.2 Test.8;
|
||||
dec Test.8;
|
||||
let Test.4 : Str = CallByName Str.3 Test.5 Test.6;
|
||||
dec Test.6;
|
||||
ret Test.4;
|
||||
let Test.4 : Str = "Hello ";
|
||||
let Test.1 : Str = "world";
|
||||
inc Test.1;
|
||||
let Test.2 : Str = CallByName Inspect.33 Test.1;
|
||||
dbg Test.2;
|
||||
dec Test.2;
|
||||
let Test.7 : Str = "!";
|
||||
let Test.5 : Str = CallByName Str.3 Test.1 Test.7;
|
||||
dec Test.7;
|
||||
let Test.3 : Str = CallByName Str.3 Test.4 Test.5;
|
||||
dec Test.5;
|
||||
ret Test.3;
|
||||
|
|
|
@ -39,18 +39,18 @@ procedure Num.96 (#Attr.2):
|
|||
ret Num.283;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.378 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.378;
|
||||
let Str.248 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.248;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.6 : I64 = 1i64;
|
||||
let Test.7 : Str = CallByName Inspect.33 Test.6;
|
||||
dbg Test.7;
|
||||
dec Test.7;
|
||||
let Test.8 : Str = CallByName Inspect.33 Test.6;
|
||||
dbg Test.8;
|
||||
dec Test.8;
|
||||
let Test.9 : Str = CallByName Inspect.33 Test.6;
|
||||
dbg Test.9;
|
||||
dec Test.9;
|
||||
ret Test.6;
|
||||
let Test.3 : I64 = 1i64;
|
||||
let Test.4 : Str = CallByName Inspect.33 Test.3;
|
||||
dbg Test.4;
|
||||
dec Test.4;
|
||||
let Test.5 : Str = CallByName Inspect.33 Test.3;
|
||||
dbg Test.5;
|
||||
dec Test.5;
|
||||
let Test.6 : Str = CallByName Inspect.33 Test.3;
|
||||
dbg Test.6;
|
||||
dec Test.6;
|
||||
ret Test.3;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.24 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.24;
|
||||
procedure Bool.1 ():
|
||||
let Bool.21 : Int1 = false;
|
||||
ret Bool.21;
|
||||
|
||||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.25 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.25;
|
||||
procedure Bool.9 (#Attr.2, #Attr.3):
|
||||
let Bool.22 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.22;
|
||||
|
||||
procedure Bool.3 (#Attr.2, #Attr.3):
|
||||
let Bool.23 : Int1 = lowlevel And #Attr.2 #Attr.3;
|
||||
procedure Bool.9 (#Attr.2, #Attr.3):
|
||||
let Bool.23 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Inspect.245 (Inspect.246, Inspect.244):
|
||||
|
@ -100,181 +100,184 @@ procedure Num.77 (#Attr.2, #Attr.3):
|
|||
ret Num.293;
|
||||
|
||||
procedure Str.20 (#Attr.2):
|
||||
let Str.445 : Str = lowlevel StrWithCapacity #Attr.2;
|
||||
ret Str.445;
|
||||
let Str.316 : Str = lowlevel StrWithCapacity #Attr.2;
|
||||
ret Str.316;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.378 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.378;
|
||||
let Str.248 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.248;
|
||||
|
||||
procedure Str.35 (#Attr.2, #Attr.3):
|
||||
let Str.435 : U8 = lowlevel StrGetUnsafe #Attr.2 #Attr.3;
|
||||
ret Str.435;
|
||||
let Str.306 : U8 = lowlevel StrGetUnsafe #Attr.2 #Attr.3;
|
||||
ret Str.306;
|
||||
|
||||
procedure Str.36 (#Attr.2):
|
||||
let Str.398 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.398;
|
||||
let Str.268 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.268;
|
||||
|
||||
procedure Str.37 (#Attr.2, #Attr.3, #Attr.4):
|
||||
let Str.396 : Str = lowlevel StrSubstringUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret Str.396;
|
||||
let Str.266 : Str = lowlevel StrSubstringUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret Str.266;
|
||||
|
||||
procedure Str.38 (Str.210, Str.211):
|
||||
let Str.392 : [C , C U64] = CallByName Str.62 Str.210 Str.211;
|
||||
let Str.405 : U8 = 1i64;
|
||||
let Str.406 : U8 = GetTagId Str.392;
|
||||
let Str.407 : Int1 = lowlevel Eq Str.405 Str.406;
|
||||
if Str.407 then
|
||||
let Str.212 : U64 = UnionAtIndex (Id 1) (Index 0) Str.392;
|
||||
let Str.401 : U64 = CallByName Str.36 Str.210;
|
||||
let Str.402 : U64 = CallByName Str.36 Str.211;
|
||||
let Str.400 : U64 = CallByName Num.20 Str.401 Str.402;
|
||||
let Str.213 : U64 = CallByName Num.20 Str.400 Str.212;
|
||||
let Str.399 : U64 = 0i64;
|
||||
inc Str.210;
|
||||
let Str.214 : Str = CallByName Str.37 Str.210 Str.399 Str.212;
|
||||
let Str.397 : U64 = CallByName Str.36 Str.211;
|
||||
let Str.395 : U64 = CallByName Num.51 Str.212 Str.397;
|
||||
let Str.215 : Str = CallByName Str.37 Str.210 Str.395 Str.213;
|
||||
let Str.394 : {Str, Str} = Struct {Str.215, Str.214};
|
||||
let Str.393 : [C {}, C {Str, Str}] = TagId(1) Str.394;
|
||||
ret Str.393;
|
||||
procedure Str.38 (Str.113, Str.114):
|
||||
let Str.262 : [C , C U64] = CallByName Str.58 Str.113 Str.114;
|
||||
let Str.275 : U8 = 1i64;
|
||||
let Str.276 : U8 = GetTagId Str.262;
|
||||
let Str.277 : Int1 = lowlevel Eq Str.275 Str.276;
|
||||
if Str.277 then
|
||||
let Str.115 : U64 = UnionAtIndex (Id 1) (Index 0) Str.262;
|
||||
let Str.271 : U64 = CallByName Str.36 Str.113;
|
||||
let Str.272 : U64 = CallByName Str.36 Str.114;
|
||||
let Str.270 : U64 = CallByName Num.20 Str.271 Str.272;
|
||||
let Str.116 : U64 = CallByName Num.20 Str.270 Str.115;
|
||||
let Str.269 : U64 = 0i64;
|
||||
inc Str.113;
|
||||
let Str.117 : Str = CallByName Str.37 Str.113 Str.269 Str.115;
|
||||
let Str.267 : U64 = CallByName Str.36 Str.114;
|
||||
let Str.265 : U64 = CallByName Num.51 Str.115 Str.267;
|
||||
let Str.118 : Str = CallByName Str.37 Str.113 Str.265 Str.116;
|
||||
let Str.264 : {Str, Str} = Struct {Str.118, Str.117};
|
||||
let Str.263 : [C {}, C {Str, Str}] = TagId(1) Str.264;
|
||||
ret Str.263;
|
||||
else
|
||||
dec Str.210;
|
||||
let Str.404 : {} = Struct {};
|
||||
let Str.403 : [C {}, C {Str, Str}] = TagId(0) Str.404;
|
||||
ret Str.403;
|
||||
dec Str.113;
|
||||
let Str.274 : {} = Struct {};
|
||||
let Str.273 : [C {}, C {Str, Str}] = TagId(0) Str.274;
|
||||
ret Str.273;
|
||||
|
||||
procedure Str.45 (Str.189, Str.190, Str.191):
|
||||
inc Str.189;
|
||||
let Str.473 : [C {}, C {Str, Str}] = CallByName Str.38 Str.189 Str.190;
|
||||
let Str.481 : U8 = 1i64;
|
||||
let Str.482 : U8 = GetTagId Str.473;
|
||||
let Str.483 : Int1 = lowlevel Eq Str.481 Str.482;
|
||||
if Str.483 then
|
||||
let Str.480 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.473;
|
||||
let Str.193 : Str = StructAtIndex 0 Str.480;
|
||||
let Str.192 : Str = StructAtIndex 1 Str.480;
|
||||
let Str.478 : U64 = CallByName Str.36 Str.189;
|
||||
dec Str.189;
|
||||
let Str.477 : Str = CallByName Str.20 Str.478;
|
||||
let Str.476 : Str = CallByName Str.3 Str.477 Str.192;
|
||||
dec Str.192;
|
||||
let Str.475 : Str = CallByName Str.3 Str.476 Str.191;
|
||||
let Str.474 : Str = CallByName Str.61 Str.475 Str.193 Str.190 Str.191;
|
||||
ret Str.474;
|
||||
procedure Str.45 (Str.92, Str.93, Str.94):
|
||||
inc Str.92;
|
||||
let Str.344 : [C {}, C {Str, Str}] = CallByName Str.38 Str.92 Str.93;
|
||||
let Str.352 : U8 = 1i64;
|
||||
let Str.353 : U8 = GetTagId Str.344;
|
||||
let Str.354 : Int1 = lowlevel Eq Str.352 Str.353;
|
||||
if Str.354 then
|
||||
let Str.351 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.344;
|
||||
let Str.96 : Str = StructAtIndex 0 Str.351;
|
||||
let Str.95 : Str = StructAtIndex 1 Str.351;
|
||||
let Str.349 : U64 = CallByName Str.36 Str.92;
|
||||
dec Str.92;
|
||||
let Str.348 : Str = CallByName Str.20 Str.349;
|
||||
let Str.347 : Str = CallByName Str.3 Str.348 Str.95;
|
||||
dec Str.95;
|
||||
let Str.346 : Str = CallByName Str.3 Str.347 Str.94;
|
||||
let Str.345 : Str = CallByName Str.57 Str.346 Str.96 Str.93 Str.94;
|
||||
ret Str.345;
|
||||
else
|
||||
dec Str.473;
|
||||
ret Str.189;
|
||||
dec Str.344;
|
||||
ret Str.92;
|
||||
|
||||
procedure Str.61 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3):
|
||||
joinpoint Str.382 Str.194 Str.195 Str.196 Str.197:
|
||||
inc Str.195;
|
||||
let Str.383 : [C {}, C {Str, Str}] = CallByName Str.38 Str.195 Str.196;
|
||||
let Str.389 : U8 = 1i64;
|
||||
let Str.390 : U8 = GetTagId Str.383;
|
||||
let Str.391 : Int1 = lowlevel Eq Str.389 Str.390;
|
||||
if Str.391 then
|
||||
dec Str.195;
|
||||
let Str.388 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.383;
|
||||
let Str.199 : Str = StructAtIndex 0 Str.388;
|
||||
let Str.198 : Str = StructAtIndex 1 Str.388;
|
||||
let Str.386 : Str = CallByName Str.3 Str.194 Str.198;
|
||||
dec Str.198;
|
||||
let Str.385 : Str = CallByName Str.3 Str.386 Str.197;
|
||||
jump Str.382 Str.385 Str.199 Str.196 Str.197;
|
||||
procedure Str.57 (Bool.24, Bool.25, Bool.26, Bool.27):
|
||||
joinpoint Str.252 Str.97 Str.98 Str.99 Str.100:
|
||||
inc Str.98;
|
||||
let Str.253 : [C {}, C {Str, Str}] = CallByName Str.38 Str.98 Str.99;
|
||||
let Str.259 : U8 = 1i64;
|
||||
let Str.260 : U8 = GetTagId Str.253;
|
||||
let Str.261 : Int1 = lowlevel Eq Str.259 Str.260;
|
||||
if Str.261 then
|
||||
dec Str.98;
|
||||
let Str.258 : {Str, Str} = UnionAtIndex (Id 1) (Index 0) Str.253;
|
||||
let Str.102 : Str = StructAtIndex 0 Str.258;
|
||||
let Str.101 : Str = StructAtIndex 1 Str.258;
|
||||
let Str.256 : Str = CallByName Str.3 Str.97 Str.101;
|
||||
dec Str.101;
|
||||
let Str.255 : Str = CallByName Str.3 Str.256 Str.100;
|
||||
jump Str.252 Str.255 Str.102 Str.99 Str.100;
|
||||
else
|
||||
dec Str.196;
|
||||
dec Str.383;
|
||||
dec Str.197;
|
||||
let Str.387 : Str = CallByName Str.3 Str.194 Str.195;
|
||||
dec Str.195;
|
||||
ret Str.387;
|
||||
dec Str.100;
|
||||
dec Str.99;
|
||||
dec Str.253;
|
||||
let Str.257 : Str = CallByName Str.3 Str.97 Str.98;
|
||||
dec Str.98;
|
||||
ret Str.257;
|
||||
in
|
||||
inc #Derived_gen.3;
|
||||
inc #Derived_gen.2;
|
||||
jump Str.382 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3;
|
||||
inc Bool.26;
|
||||
inc Bool.27;
|
||||
jump Str.252 Bool.24 Bool.25 Bool.26 Bool.27;
|
||||
|
||||
procedure Str.62 (Str.219, Str.220):
|
||||
let Str.221 : U64 = CallByName Str.36 Str.219;
|
||||
let Str.222 : U64 = CallByName Str.36 Str.220;
|
||||
let Str.223 : U64 = CallByName Num.77 Str.221 Str.222;
|
||||
let Str.409 : U64 = 0i64;
|
||||
let Str.408 : [C , C U64] = CallByName Str.63 Str.219 Str.220 Str.409 Str.223;
|
||||
ret Str.408;
|
||||
procedure Str.58 (Str.122, Str.123):
|
||||
let Str.124 : U64 = CallByName Str.36 Str.122;
|
||||
let Str.125 : U64 = CallByName Str.36 Str.123;
|
||||
let Str.126 : U64 = CallByName Num.77 Str.124 Str.125;
|
||||
let Str.279 : U64 = 0i64;
|
||||
let Str.278 : [C , C U64] = CallByName Str.59 Str.122 Str.123 Str.279 Str.126;
|
||||
ret Str.278;
|
||||
|
||||
procedure Str.63 (#Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7):
|
||||
joinpoint Str.410 Str.224 Str.225 Str.226 Str.227:
|
||||
let Str.412 : Int1 = CallByName Num.23 Str.226 Str.227;
|
||||
if Str.412 then
|
||||
let Str.416 : Int1 = CallByName Str.67 Str.224 Str.226 Str.225;
|
||||
if Str.416 then
|
||||
dec Str.224;
|
||||
dec Str.225;
|
||||
let Str.417 : [C , C U64] = TagId(1) Str.226;
|
||||
ret Str.417;
|
||||
procedure Str.59 (Bool.28, Bool.29, Bool.30, Bool.31):
|
||||
joinpoint Str.280 Str.127 Str.128 Str.129 Str.130:
|
||||
let Str.282 : Int1 = CallByName Num.23 Str.129 Str.130;
|
||||
if Str.282 then
|
||||
let Str.286 : Int1 = CallByName Str.63 Str.127 Str.129 Str.128;
|
||||
if Str.286 then
|
||||
dec Str.127;
|
||||
dec Str.128;
|
||||
let Str.287 : [C , C U64] = TagId(1) Str.129;
|
||||
ret Str.287;
|
||||
else
|
||||
let Str.415 : U64 = 1i64;
|
||||
let Str.414 : U64 = CallByName Num.51 Str.226 Str.415;
|
||||
jump Str.410 Str.224 Str.225 Str.414 Str.227;
|
||||
let Str.285 : U64 = 1i64;
|
||||
let Str.284 : U64 = CallByName Num.51 Str.129 Str.285;
|
||||
jump Str.280 Str.127 Str.128 Str.284 Str.130;
|
||||
else
|
||||
dec Str.224;
|
||||
dec Str.225;
|
||||
let Str.411 : [C , C U64] = TagId(0) ;
|
||||
ret Str.411;
|
||||
dec Str.127;
|
||||
dec Str.128;
|
||||
let Str.281 : [C , C U64] = TagId(0) ;
|
||||
ret Str.281;
|
||||
in
|
||||
inc #Derived_gen.5;
|
||||
inc #Derived_gen.4;
|
||||
jump Str.410 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7;
|
||||
inc Bool.29;
|
||||
inc Bool.28;
|
||||
jump Str.280 Bool.28 Bool.29 Bool.30 Bool.31;
|
||||
|
||||
procedure Str.66 (Str.250, Str.251):
|
||||
let Str.440 : Int1 = CallByName Num.22 Str.250 Str.251;
|
||||
if Str.440 then
|
||||
ret Str.250;
|
||||
procedure Str.62 (Str.153, Str.154):
|
||||
let Str.311 : Int1 = CallByName Num.22 Str.153 Str.154;
|
||||
if Str.311 then
|
||||
ret Str.153;
|
||||
else
|
||||
ret Str.251;
|
||||
ret Str.154;
|
||||
|
||||
procedure Str.67 (Str.252, Str.253, Str.254):
|
||||
let Str.255 : U64 = CallByName Str.36 Str.252;
|
||||
let Str.256 : U64 = CallByName Str.36 Str.254;
|
||||
let Str.438 : U64 = CallByName Num.53 Str.253 Str.256;
|
||||
let Str.257 : U64 = CallByName Str.66 Str.438 Str.255;
|
||||
let Str.437 : U64 = 0i64;
|
||||
inc Str.252;
|
||||
inc Str.254;
|
||||
let Str.419 : {U64, Str, U64, Str, U64, U64} = Struct {Str.257, Str.252, Str.253, Str.254, Str.437, Str.256};
|
||||
let Str.418 : Int1 = CallByName Str.68 Str.419;
|
||||
ret Str.418;
|
||||
procedure Str.63 (Str.155, Str.156, Str.157):
|
||||
let Str.158 : U64 = CallByName Str.36 Str.155;
|
||||
let Str.159 : U64 = CallByName Str.36 Str.157;
|
||||
let Str.309 : U64 = CallByName Num.53 Str.156 Str.159;
|
||||
let Str.160 : U64 = CallByName Str.62 Str.309 Str.158;
|
||||
let Str.308 : U64 = 0i64;
|
||||
inc Str.157;
|
||||
inc Str.155;
|
||||
let Str.289 : {U64, Str, U64, Str, U64, U64} = Struct {Str.160, Str.155, Str.156, Str.157, Str.308, Str.159};
|
||||
let Str.288 : Int1 = CallByName Str.64 Str.289;
|
||||
ret Str.288;
|
||||
|
||||
procedure Str.68 (Str.258):
|
||||
let Str.264 : U64 = StructAtIndex 0 Str.258;
|
||||
let Str.259 : Str = StructAtIndex 1 Str.258;
|
||||
let Str.260 : U64 = StructAtIndex 2 Str.258;
|
||||
let Str.261 : Str = StructAtIndex 3 Str.258;
|
||||
let Str.262 : U64 = StructAtIndex 4 Str.258;
|
||||
let Str.263 : U64 = StructAtIndex 5 Str.258;
|
||||
let Str.265 : Int1 = CallByName Num.25 Str.260 Str.264;
|
||||
if Str.265 then
|
||||
dec Str.259;
|
||||
dec Str.261;
|
||||
let Str.266 : Int1 = CallByName Bool.11 Str.262 Str.263;
|
||||
ret Str.266;
|
||||
procedure Str.64 (Str.161):
|
||||
let Str.167 : U64 = StructAtIndex 0 Str.161;
|
||||
let Str.162 : Str = StructAtIndex 1 Str.161;
|
||||
let Str.163 : U64 = StructAtIndex 2 Str.161;
|
||||
let Str.164 : Str = StructAtIndex 3 Str.161;
|
||||
let Str.165 : U64 = StructAtIndex 4 Str.161;
|
||||
let Str.166 : U64 = StructAtIndex 5 Str.161;
|
||||
let Str.168 : Int1 = CallByName Num.25 Str.163 Str.167;
|
||||
if Str.168 then
|
||||
dec Str.162;
|
||||
dec Str.164;
|
||||
let Str.169 : Int1 = CallByName Bool.9 Str.165 Str.166;
|
||||
ret Str.169;
|
||||
else
|
||||
let Str.433 : U8 = CallByName Str.35 Str.259 Str.260;
|
||||
let Str.434 : U8 = CallByName Str.35 Str.261 Str.262;
|
||||
let Str.267 : Int1 = CallByName Bool.11 Str.433 Str.434;
|
||||
let Str.423 : U64 = StructAtIndex 0 Str.258;
|
||||
let Str.424 : Str = StructAtIndex 1 Str.258;
|
||||
let Str.426 : Str = StructAtIndex 3 Str.258;
|
||||
let Str.428 : U64 = StructAtIndex 5 Str.258;
|
||||
let Str.432 : U64 = 1i64;
|
||||
let Str.430 : U64 = CallByName Num.51 Str.262 Str.432;
|
||||
let Str.431 : U64 = 1i64;
|
||||
let Str.429 : U64 = CallByName Num.51 Str.260 Str.431;
|
||||
let Str.422 : {U64, Str, U64, Str, U64, U64} = Struct {Str.423, Str.424, Str.429, Str.426, Str.430, Str.428};
|
||||
let Str.268 : Int1 = CallByName Str.68 Str.422;
|
||||
let Str.421 : Int1 = CallByName Bool.3 Str.267 Str.268;
|
||||
ret Str.421;
|
||||
let Str.304 : U8 = CallByName Str.35 Str.162 Str.163;
|
||||
let Str.305 : U8 = CallByName Str.35 Str.164 Str.165;
|
||||
let Str.170 : Int1 = CallByName Bool.9 Str.304 Str.305;
|
||||
let Str.294 : U64 = StructAtIndex 0 Str.161;
|
||||
let Str.295 : Str = StructAtIndex 1 Str.161;
|
||||
let Str.297 : Str = StructAtIndex 3 Str.161;
|
||||
let Str.299 : U64 = StructAtIndex 5 Str.161;
|
||||
let Str.303 : U64 = 1i64;
|
||||
let Str.301 : U64 = CallByName Num.51 Str.165 Str.303;
|
||||
let Str.302 : U64 = 1i64;
|
||||
let Str.300 : U64 = CallByName Num.51 Str.163 Str.302;
|
||||
let Str.293 : {U64, Str, U64, Str, U64, U64} = Struct {Str.294, Str.295, Str.300, Str.297, Str.301, Str.299};
|
||||
let Str.171 : Int1 = CallByName Str.64 Str.293;
|
||||
if Str.170 then
|
||||
ret Str.171;
|
||||
else
|
||||
let Str.291 : Int1 = CallByName Bool.1;
|
||||
ret Str.291;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.3 : Str = "";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.24 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.24;
|
||||
procedure Bool.9 (#Attr.2, #Attr.3):
|
||||
let Bool.22 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.22;
|
||||
|
||||
procedure Num.19 (#Attr.2, #Attr.3):
|
||||
let Num.285 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
|
@ -11,8 +11,8 @@ procedure Num.96 (#Attr.2):
|
|||
ret Num.284;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.379 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.379;
|
||||
let Str.249 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.249;
|
||||
|
||||
procedure Test.1 (Test.2):
|
||||
let Test.3 : Str = CallByName Num.96 Test.2;
|
||||
|
@ -25,7 +25,7 @@ procedure Test.1 (Test.2):
|
|||
ret Test.8;
|
||||
in
|
||||
let Test.22 : I64 = 1i64;
|
||||
let Test.20 : Int1 = CallByName Bool.11 Test.2 Test.22;
|
||||
let Test.20 : Int1 = CallByName Bool.9 Test.2 Test.22;
|
||||
if Test.20 then
|
||||
dec Test.3;
|
||||
let Test.21 : Str = "early 1";
|
||||
|
@ -38,7 +38,7 @@ procedure Test.1 (Test.2):
|
|||
jump Test.12 Test.11;
|
||||
in
|
||||
let Test.17 : I64 = 2i64;
|
||||
let Test.15 : Int1 = CallByName Bool.11 Test.2 Test.17;
|
||||
let Test.15 : Int1 = CallByName Bool.9 Test.2 Test.17;
|
||||
if Test.15 then
|
||||
dec Test.3;
|
||||
dec Test.5;
|
||||
|
|
4
crates/compiler/test_mono/generated/dict.txt
generated
4
crates/compiler/test_mono/generated/dict.txt
generated
|
@ -9,8 +9,8 @@ procedure Dict.1 (Dict.732):
|
|||
|
||||
procedure Dict.4 (Dict.738):
|
||||
let Dict.163 : List {[], []} = StructAtIndex 1 Dict.738;
|
||||
let #Derived_gen.0 : List {U32, U32} = StructAtIndex 0 Dict.738;
|
||||
dec #Derived_gen.0;
|
||||
let Bool.21 : List {U32, U32} = StructAtIndex 0 Dict.738;
|
||||
dec Bool.21;
|
||||
let Dict.739 : U64 = CallByName List.6 Dict.163;
|
||||
dec Dict.163;
|
||||
ret Dict.739;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
procedure Bool.2 ():
|
||||
let Bool.23 : Int1 = true;
|
||||
ret Bool.23;
|
||||
let Bool.21 : Int1 = true;
|
||||
ret Bool.21;
|
||||
|
||||
procedure Test.2 (Test.5):
|
||||
let Test.6 : Int1 = CallByName Bool.2;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
procedure Bool.2 ():
|
||||
let Bool.23 : Int1 = true;
|
||||
ret Bool.23;
|
||||
let Bool.21 : Int1 = true;
|
||||
ret Bool.21;
|
||||
|
||||
procedure Test.2 (Test.5):
|
||||
let Test.6 : Int1 = CallByName Bool.2;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
procedure Bool.1 ():
|
||||
let Bool.23 : Int1 = false;
|
||||
ret Bool.23;
|
||||
let Bool.21 : Int1 = false;
|
||||
ret Bool.21;
|
||||
|
||||
procedure List.2 (List.120, List.121):
|
||||
let List.681 : U64 = CallByName List.6 List.120;
|
||||
|
|
|
@ -67,7 +67,7 @@ procedure Encode.26 (Encode.107, Encode.108):
|
|||
let Encode.110 : List U8 = CallByName Encode.24 Encode.111 Encode.112 Encode.108;
|
||||
ret Encode.110;
|
||||
|
||||
procedure List.101 (#Derived_gen.26, #Derived_gen.27, #Derived_gen.28, #Derived_gen.29, #Derived_gen.30):
|
||||
procedure List.101 (#Derived_gen.35, #Derived_gen.36, #Derived_gen.37, #Derived_gen.38, #Derived_gen.39):
|
||||
joinpoint List.678 List.175 List.176 List.177 List.178 List.179:
|
||||
let List.680 : Int1 = CallByName Num.22 List.178 List.179;
|
||||
if List.680 then
|
||||
|
@ -81,10 +81,10 @@ procedure List.101 (#Derived_gen.26, #Derived_gen.27, #Derived_gen.28, #Derived_
|
|||
dec List.175;
|
||||
ret List.176;
|
||||
in
|
||||
inc #Derived_gen.26;
|
||||
jump List.678 #Derived_gen.26 #Derived_gen.27 #Derived_gen.28 #Derived_gen.29 #Derived_gen.30;
|
||||
inc #Derived_gen.35;
|
||||
jump List.678 #Derived_gen.35 #Derived_gen.36 #Derived_gen.37 #Derived_gen.38 #Derived_gen.39;
|
||||
|
||||
procedure List.101 (#Derived_gen.31, #Derived_gen.32, #Derived_gen.33, #Derived_gen.34, #Derived_gen.35):
|
||||
procedure List.101 (#Derived_gen.40, #Derived_gen.41, #Derived_gen.42, #Derived_gen.43, #Derived_gen.44):
|
||||
joinpoint List.704 List.175 List.176 List.177 List.178 List.179:
|
||||
let List.706 : Int1 = CallByName Num.22 List.178 List.179;
|
||||
if List.706 then
|
||||
|
@ -98,8 +98,8 @@ procedure List.101 (#Derived_gen.31, #Derived_gen.32, #Derived_gen.33, #Derived_
|
|||
dec List.175;
|
||||
ret List.176;
|
||||
in
|
||||
inc #Derived_gen.31;
|
||||
jump List.704 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33 #Derived_gen.34 #Derived_gen.35;
|
||||
inc #Derived_gen.40;
|
||||
jump List.704 #Derived_gen.40 #Derived_gen.41 #Derived_gen.42 #Derived_gen.43 #Derived_gen.44;
|
||||
|
||||
procedure List.18 (List.172, List.173, List.174):
|
||||
let List.676 : U64 = 0i64;
|
||||
|
@ -164,32 +164,32 @@ procedure Num.96 (#Attr.2):
|
|||
ret Num.287;
|
||||
|
||||
procedure Str.12 (#Attr.2):
|
||||
let Str.391 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.391;
|
||||
let Str.261 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.261;
|
||||
|
||||
procedure Str.36 (#Attr.2):
|
||||
let Str.392 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.392;
|
||||
let Str.262 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.262;
|
||||
|
||||
procedure Str.43 (#Attr.2):
|
||||
let Str.386 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.386;
|
||||
let Str.256 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.256;
|
||||
|
||||
procedure Str.9 (Str.76):
|
||||
let Str.77 : {U64, Str, Int1, U8} = CallByName Str.43 Str.76;
|
||||
let Str.383 : Int1 = StructAtIndex 2 Str.77;
|
||||
if Str.383 then
|
||||
let Str.385 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.384 : [C {U64, U8}, C Str] = TagId(1) Str.385;
|
||||
ret Str.384;
|
||||
procedure Str.9 (Str.74):
|
||||
let Str.75 : {U64, Str, Int1, U8} = CallByName Str.43 Str.74;
|
||||
let Str.253 : Int1 = StructAtIndex 2 Str.75;
|
||||
if Str.253 then
|
||||
let Str.255 : Str = StructAtIndex 1 Str.75;
|
||||
let Str.254 : [C {U64, U8}, C Str] = TagId(1) Str.255;
|
||||
ret Str.254;
|
||||
else
|
||||
let Str.381 : U64 = StructAtIndex 0 Str.77;
|
||||
let Str.382 : U8 = StructAtIndex 3 Str.77;
|
||||
let #Derived_gen.45 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.251 : U64 = StructAtIndex 0 Str.75;
|
||||
let Str.252 : U8 = StructAtIndex 3 Str.75;
|
||||
let #Derived_gen.45 : Str = StructAtIndex 1 Str.75;
|
||||
dec #Derived_gen.45;
|
||||
let Str.380 : {U64, U8} = Struct {Str.381, Str.382};
|
||||
let Str.378 : [C {U64, U8}, C Str] = TagId(0) Str.380;
|
||||
ret Str.378;
|
||||
let Str.250 : {U64, U8} = Struct {Str.251, Str.252};
|
||||
let Str.248 : [C {U64, U8}, C Str] = TagId(0) Str.250;
|
||||
ret Str.248;
|
||||
|
||||
procedure Test.20 (Test.56):
|
||||
let Test.325 : Str = CallByName Encode.23 Test.56;
|
||||
|
|
|
@ -39,7 +39,7 @@ procedure Encode.26 (Encode.107, Encode.108):
|
|||
let Encode.110 : List U8 = CallByName Encode.24 Encode.111 Encode.112 Encode.108;
|
||||
ret Encode.110;
|
||||
|
||||
procedure List.101 (#Derived_gen.16, #Derived_gen.17, #Derived_gen.18, #Derived_gen.19, #Derived_gen.20):
|
||||
procedure List.101 (#Derived_gen.19, #Derived_gen.20, #Derived_gen.21, #Derived_gen.22, #Derived_gen.23):
|
||||
joinpoint List.678 List.175 List.176 List.177 List.178 List.179:
|
||||
let List.680 : Int1 = CallByName Num.22 List.178 List.179;
|
||||
if List.680 then
|
||||
|
@ -53,8 +53,8 @@ procedure List.101 (#Derived_gen.16, #Derived_gen.17, #Derived_gen.18, #Derived_
|
|||
dec List.175;
|
||||
ret List.176;
|
||||
in
|
||||
inc #Derived_gen.16;
|
||||
jump List.678 #Derived_gen.16 #Derived_gen.17 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20;
|
||||
inc #Derived_gen.19;
|
||||
jump List.678 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21 #Derived_gen.22 #Derived_gen.23;
|
||||
|
||||
procedure List.18 (List.172, List.173, List.174):
|
||||
let List.676 : U64 = 0i64;
|
||||
|
@ -105,32 +105,32 @@ procedure Num.96 (#Attr.2):
|
|||
ret Num.283;
|
||||
|
||||
procedure Str.12 (#Attr.2):
|
||||
let Str.388 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.388;
|
||||
let Str.258 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.258;
|
||||
|
||||
procedure Str.36 (#Attr.2):
|
||||
let Str.389 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.389;
|
||||
let Str.259 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.259;
|
||||
|
||||
procedure Str.43 (#Attr.2):
|
||||
let Str.386 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.386;
|
||||
let Str.256 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.256;
|
||||
|
||||
procedure Str.9 (Str.76):
|
||||
let Str.77 : {U64, Str, Int1, U8} = CallByName Str.43 Str.76;
|
||||
let Str.383 : Int1 = StructAtIndex 2 Str.77;
|
||||
if Str.383 then
|
||||
let Str.385 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.384 : [C {U64, U8}, C Str] = TagId(1) Str.385;
|
||||
ret Str.384;
|
||||
procedure Str.9 (Str.74):
|
||||
let Str.75 : {U64, Str, Int1, U8} = CallByName Str.43 Str.74;
|
||||
let Str.253 : Int1 = StructAtIndex 2 Str.75;
|
||||
if Str.253 then
|
||||
let Str.255 : Str = StructAtIndex 1 Str.75;
|
||||
let Str.254 : [C {U64, U8}, C Str] = TagId(1) Str.255;
|
||||
ret Str.254;
|
||||
else
|
||||
let Str.381 : U64 = StructAtIndex 0 Str.77;
|
||||
let Str.382 : U8 = StructAtIndex 3 Str.77;
|
||||
let #Derived_gen.24 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.251 : U64 = StructAtIndex 0 Str.75;
|
||||
let Str.252 : U8 = StructAtIndex 3 Str.75;
|
||||
let #Derived_gen.24 : Str = StructAtIndex 1 Str.75;
|
||||
dec #Derived_gen.24;
|
||||
let Str.380 : {U64, U8} = Struct {Str.381, Str.382};
|
||||
let Str.378 : [C {U64, U8}, C Str] = TagId(0) Str.380;
|
||||
ret Str.378;
|
||||
let Str.250 : {U64, U8} = Struct {Str.251, Str.252};
|
||||
let Str.248 : [C {U64, U8}, C Str] = TagId(0) Str.250;
|
||||
ret Str.248;
|
||||
|
||||
procedure Test.20 (Test.56):
|
||||
let Test.292 : Str = CallByName Encode.23 Test.56;
|
||||
|
|
|
@ -46,7 +46,7 @@ procedure Encode.26 (Encode.107, Encode.108):
|
|||
let Encode.110 : List U8 = CallByName Encode.24 Encode.111 Encode.112 Encode.108;
|
||||
ret Encode.110;
|
||||
|
||||
procedure List.101 (#Derived_gen.20, #Derived_gen.21, #Derived_gen.22, #Derived_gen.23, #Derived_gen.24):
|
||||
procedure List.101 (#Derived_gen.23, #Derived_gen.24, #Derived_gen.25, #Derived_gen.26, #Derived_gen.27):
|
||||
joinpoint List.678 List.175 List.176 List.177 List.178 List.179:
|
||||
let List.680 : Int1 = CallByName Num.22 List.178 List.179;
|
||||
if List.680 then
|
||||
|
@ -60,8 +60,8 @@ procedure List.101 (#Derived_gen.20, #Derived_gen.21, #Derived_gen.22, #Derived_
|
|||
dec List.175;
|
||||
ret List.176;
|
||||
in
|
||||
inc #Derived_gen.20;
|
||||
jump List.678 #Derived_gen.20 #Derived_gen.21 #Derived_gen.22 #Derived_gen.23 #Derived_gen.24;
|
||||
inc #Derived_gen.23;
|
||||
jump List.678 #Derived_gen.23 #Derived_gen.24 #Derived_gen.25 #Derived_gen.26 #Derived_gen.27;
|
||||
|
||||
procedure List.18 (List.172, List.173, List.174):
|
||||
let List.676 : U64 = 0i64;
|
||||
|
@ -112,32 +112,32 @@ procedure Num.96 (#Attr.2):
|
|||
ret Num.283;
|
||||
|
||||
procedure Str.12 (#Attr.2):
|
||||
let Str.388 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.388;
|
||||
let Str.258 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.258;
|
||||
|
||||
procedure Str.36 (#Attr.2):
|
||||
let Str.389 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.389;
|
||||
let Str.259 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.259;
|
||||
|
||||
procedure Str.43 (#Attr.2):
|
||||
let Str.386 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.386;
|
||||
let Str.256 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.256;
|
||||
|
||||
procedure Str.9 (Str.76):
|
||||
let Str.77 : {U64, Str, Int1, U8} = CallByName Str.43 Str.76;
|
||||
let Str.383 : Int1 = StructAtIndex 2 Str.77;
|
||||
if Str.383 then
|
||||
let Str.385 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.384 : [C {U64, U8}, C Str] = TagId(1) Str.385;
|
||||
ret Str.384;
|
||||
procedure Str.9 (Str.74):
|
||||
let Str.75 : {U64, Str, Int1, U8} = CallByName Str.43 Str.74;
|
||||
let Str.253 : Int1 = StructAtIndex 2 Str.75;
|
||||
if Str.253 then
|
||||
let Str.255 : Str = StructAtIndex 1 Str.75;
|
||||
let Str.254 : [C {U64, U8}, C Str] = TagId(1) Str.255;
|
||||
ret Str.254;
|
||||
else
|
||||
let Str.381 : U64 = StructAtIndex 0 Str.77;
|
||||
let Str.382 : U8 = StructAtIndex 3 Str.77;
|
||||
let #Derived_gen.28 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.251 : U64 = StructAtIndex 0 Str.75;
|
||||
let Str.252 : U8 = StructAtIndex 3 Str.75;
|
||||
let #Derived_gen.28 : Str = StructAtIndex 1 Str.75;
|
||||
dec #Derived_gen.28;
|
||||
let Str.380 : {U64, U8} = Struct {Str.381, Str.382};
|
||||
let Str.378 : [C {U64, U8}, C Str] = TagId(0) Str.380;
|
||||
ret Str.378;
|
||||
let Str.250 : {U64, U8} = Struct {Str.251, Str.252};
|
||||
let Str.248 : [C {U64, U8}, C Str] = TagId(0) Str.250;
|
||||
ret Str.248;
|
||||
|
||||
procedure Test.20 (Test.56):
|
||||
let Test.296 : Str = CallByName Encode.23 Test.56;
|
||||
|
|
|
@ -38,32 +38,32 @@ procedure Num.96 (#Attr.2):
|
|||
ret Num.283;
|
||||
|
||||
procedure Str.12 (#Attr.2):
|
||||
let Str.388 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.388;
|
||||
let Str.258 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.258;
|
||||
|
||||
procedure Str.36 (#Attr.2):
|
||||
let Str.389 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.389;
|
||||
let Str.259 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.259;
|
||||
|
||||
procedure Str.43 (#Attr.2):
|
||||
let Str.386 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.386;
|
||||
let Str.256 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.256;
|
||||
|
||||
procedure Str.9 (Str.76):
|
||||
let Str.77 : {U64, Str, Int1, U8} = CallByName Str.43 Str.76;
|
||||
let Str.383 : Int1 = StructAtIndex 2 Str.77;
|
||||
if Str.383 then
|
||||
let Str.385 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.384 : [C {U64, U8}, C Str] = TagId(1) Str.385;
|
||||
ret Str.384;
|
||||
procedure Str.9 (Str.74):
|
||||
let Str.75 : {U64, Str, Int1, U8} = CallByName Str.43 Str.74;
|
||||
let Str.253 : Int1 = StructAtIndex 2 Str.75;
|
||||
if Str.253 then
|
||||
let Str.255 : Str = StructAtIndex 1 Str.75;
|
||||
let Str.254 : [C {U64, U8}, C Str] = TagId(1) Str.255;
|
||||
ret Str.254;
|
||||
else
|
||||
let Str.381 : U64 = StructAtIndex 0 Str.77;
|
||||
let Str.382 : U8 = StructAtIndex 3 Str.77;
|
||||
let #Derived_gen.3 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.251 : U64 = StructAtIndex 0 Str.75;
|
||||
let Str.252 : U8 = StructAtIndex 3 Str.75;
|
||||
let #Derived_gen.3 : Str = StructAtIndex 1 Str.75;
|
||||
dec #Derived_gen.3;
|
||||
let Str.380 : {U64, U8} = Struct {Str.381, Str.382};
|
||||
let Str.378 : [C {U64, U8}, C Str] = TagId(0) Str.380;
|
||||
ret Str.378;
|
||||
let Str.250 : {U64, U8} = Struct {Str.251, Str.252};
|
||||
let Str.248 : [C {U64, U8}, C Str] = TagId(0) Str.250;
|
||||
ret Str.248;
|
||||
|
||||
procedure Test.20 (Test.56):
|
||||
let Test.259 : Str = CallByName Encode.23 Test.56;
|
||||
|
|
|
@ -40,7 +40,7 @@ procedure Encode.26 (Encode.107, Encode.108):
|
|||
let Encode.110 : List U8 = CallByName Encode.24 Encode.111 Encode.112 Encode.108;
|
||||
ret Encode.110;
|
||||
|
||||
procedure List.101 (#Derived_gen.10, #Derived_gen.11, #Derived_gen.12, #Derived_gen.13, #Derived_gen.14):
|
||||
procedure List.101 (#Derived_gen.22, #Derived_gen.23, #Derived_gen.24, #Derived_gen.25, #Derived_gen.26):
|
||||
joinpoint List.678 List.175 List.176 List.177 List.178 List.179:
|
||||
let List.680 : Int1 = CallByName Num.22 List.178 List.179;
|
||||
if List.680 then
|
||||
|
@ -54,8 +54,8 @@ procedure List.101 (#Derived_gen.10, #Derived_gen.11, #Derived_gen.12, #Derived_
|
|||
dec List.175;
|
||||
ret List.176;
|
||||
in
|
||||
inc #Derived_gen.10;
|
||||
jump List.678 #Derived_gen.10 #Derived_gen.11 #Derived_gen.12 #Derived_gen.13 #Derived_gen.14;
|
||||
inc #Derived_gen.22;
|
||||
jump List.678 #Derived_gen.22 #Derived_gen.23 #Derived_gen.24 #Derived_gen.25 #Derived_gen.26;
|
||||
|
||||
procedure List.13 (#Attr.2, #Attr.3):
|
||||
let List.701 : List Str = lowlevel ListPrepend #Attr.2 #Attr.3;
|
||||
|
@ -110,32 +110,32 @@ procedure Num.96 (#Attr.2):
|
|||
ret Num.283;
|
||||
|
||||
procedure Str.12 (#Attr.2):
|
||||
let Str.388 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.388;
|
||||
let Str.258 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.258;
|
||||
|
||||
procedure Str.36 (#Attr.2):
|
||||
let Str.389 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.389;
|
||||
let Str.259 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.259;
|
||||
|
||||
procedure Str.43 (#Attr.2):
|
||||
let Str.386 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.386;
|
||||
let Str.256 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.256;
|
||||
|
||||
procedure Str.9 (Str.76):
|
||||
let Str.77 : {U64, Str, Int1, U8} = CallByName Str.43 Str.76;
|
||||
let Str.383 : Int1 = StructAtIndex 2 Str.77;
|
||||
if Str.383 then
|
||||
let Str.385 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.384 : [C {U64, U8}, C Str] = TagId(1) Str.385;
|
||||
ret Str.384;
|
||||
procedure Str.9 (Str.74):
|
||||
let Str.75 : {U64, Str, Int1, U8} = CallByName Str.43 Str.74;
|
||||
let Str.253 : Int1 = StructAtIndex 2 Str.75;
|
||||
if Str.253 then
|
||||
let Str.255 : Str = StructAtIndex 1 Str.75;
|
||||
let Str.254 : [C {U64, U8}, C Str] = TagId(1) Str.255;
|
||||
ret Str.254;
|
||||
else
|
||||
let Str.381 : U64 = StructAtIndex 0 Str.77;
|
||||
let Str.382 : U8 = StructAtIndex 3 Str.77;
|
||||
let #Derived_gen.27 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.251 : U64 = StructAtIndex 0 Str.75;
|
||||
let Str.252 : U8 = StructAtIndex 3 Str.75;
|
||||
let #Derived_gen.27 : Str = StructAtIndex 1 Str.75;
|
||||
dec #Derived_gen.27;
|
||||
let Str.380 : {U64, U8} = Struct {Str.381, Str.382};
|
||||
let Str.378 : [C {U64, U8}, C Str] = TagId(0) Str.380;
|
||||
ret Str.378;
|
||||
let Str.250 : {U64, U8} = Struct {Str.251, Str.252};
|
||||
let Str.248 : [C {U64, U8}, C Str] = TagId(0) Str.250;
|
||||
ret Str.248;
|
||||
|
||||
procedure Test.20 (Test.56):
|
||||
let Test.297 : Str = CallByName Encode.23 Test.56;
|
||||
|
|
|
@ -43,7 +43,7 @@ procedure Encode.26 (Encode.107, Encode.108):
|
|||
let Encode.110 : List U8 = CallByName Encode.24 Encode.111 Encode.112 Encode.108;
|
||||
ret Encode.110;
|
||||
|
||||
procedure List.101 (#Derived_gen.20, #Derived_gen.21, #Derived_gen.22, #Derived_gen.23, #Derived_gen.24):
|
||||
procedure List.101 (#Derived_gen.23, #Derived_gen.24, #Derived_gen.25, #Derived_gen.26, #Derived_gen.27):
|
||||
joinpoint List.678 List.175 List.176 List.177 List.178 List.179:
|
||||
let List.680 : Int1 = CallByName Num.22 List.178 List.179;
|
||||
if List.680 then
|
||||
|
@ -57,8 +57,8 @@ procedure List.101 (#Derived_gen.20, #Derived_gen.21, #Derived_gen.22, #Derived_
|
|||
dec List.175;
|
||||
ret List.176;
|
||||
in
|
||||
inc #Derived_gen.20;
|
||||
jump List.678 #Derived_gen.20 #Derived_gen.21 #Derived_gen.22 #Derived_gen.23 #Derived_gen.24;
|
||||
inc #Derived_gen.23;
|
||||
jump List.678 #Derived_gen.23 #Derived_gen.24 #Derived_gen.25 #Derived_gen.26 #Derived_gen.27;
|
||||
|
||||
procedure List.13 (#Attr.2, #Attr.3):
|
||||
let List.701 : List Str = lowlevel ListPrepend #Attr.2 #Attr.3;
|
||||
|
@ -113,32 +113,32 @@ procedure Num.96 (#Attr.2):
|
|||
ret Num.283;
|
||||
|
||||
procedure Str.12 (#Attr.2):
|
||||
let Str.388 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.388;
|
||||
let Str.258 : List U8 = lowlevel StrToUtf8 #Attr.2;
|
||||
ret Str.258;
|
||||
|
||||
procedure Str.36 (#Attr.2):
|
||||
let Str.389 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.389;
|
||||
let Str.259 : U64 = lowlevel StrCountUtf8Bytes #Attr.2;
|
||||
ret Str.259;
|
||||
|
||||
procedure Str.43 (#Attr.2):
|
||||
let Str.386 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.386;
|
||||
let Str.256 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8 #Attr.2;
|
||||
ret Str.256;
|
||||
|
||||
procedure Str.9 (Str.76):
|
||||
let Str.77 : {U64, Str, Int1, U8} = CallByName Str.43 Str.76;
|
||||
let Str.383 : Int1 = StructAtIndex 2 Str.77;
|
||||
if Str.383 then
|
||||
let Str.385 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.384 : [C {U64, U8}, C Str] = TagId(1) Str.385;
|
||||
ret Str.384;
|
||||
procedure Str.9 (Str.74):
|
||||
let Str.75 : {U64, Str, Int1, U8} = CallByName Str.43 Str.74;
|
||||
let Str.253 : Int1 = StructAtIndex 2 Str.75;
|
||||
if Str.253 then
|
||||
let Str.255 : Str = StructAtIndex 1 Str.75;
|
||||
let Str.254 : [C {U64, U8}, C Str] = TagId(1) Str.255;
|
||||
ret Str.254;
|
||||
else
|
||||
let Str.381 : U64 = StructAtIndex 0 Str.77;
|
||||
let Str.382 : U8 = StructAtIndex 3 Str.77;
|
||||
let #Derived_gen.28 : Str = StructAtIndex 1 Str.77;
|
||||
let Str.251 : U64 = StructAtIndex 0 Str.75;
|
||||
let Str.252 : U8 = StructAtIndex 3 Str.75;
|
||||
let #Derived_gen.28 : Str = StructAtIndex 1 Str.75;
|
||||
dec #Derived_gen.28;
|
||||
let Str.380 : {U64, U8} = Struct {Str.381, Str.382};
|
||||
let Str.378 : [C {U64, U8}, C Str] = TagId(0) Str.380;
|
||||
ret Str.378;
|
||||
let Str.250 : {U64, U8} = Struct {Str.251, Str.252};
|
||||
let Str.248 : [C {U64, U8}, C Str] = TagId(0) Str.250;
|
||||
ret Str.248;
|
||||
|
||||
procedure Test.20 (Test.56):
|
||||
let Test.301 : Str = CallByName Encode.23 Test.56;
|
||||
|
|
|
@ -6,7 +6,7 @@ procedure Num.21 (#Attr.2, #Attr.3):
|
|||
let Num.283 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
|
||||
ret Num.283;
|
||||
|
||||
procedure Test.1 (#Derived_gen.0, #Derived_gen.1):
|
||||
procedure Test.1 (Bool.21, Bool.22):
|
||||
joinpoint Test.7 Test.2 Test.3:
|
||||
let Test.13 : I64 = 0i64;
|
||||
let Test.14 : Int1 = lowlevel Eq Test.13 Test.2;
|
||||
|
@ -18,7 +18,7 @@ procedure Test.1 (#Derived_gen.0, #Derived_gen.1):
|
|||
let Test.11 : I64 = CallByName Num.21 Test.2 Test.3;
|
||||
jump Test.7 Test.10 Test.11;
|
||||
in
|
||||
jump Test.7 #Derived_gen.0 #Derived_gen.1;
|
||||
jump Test.7 Bool.21 Bool.22;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 : I64 = 10i64;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
procedure Bool.1 ():
|
||||
let Bool.23 : Int1 = false;
|
||||
ret Bool.23;
|
||||
let Bool.21 : Int1 = false;
|
||||
ret Bool.21;
|
||||
|
||||
procedure Test.1 (Test.2):
|
||||
let Test.5 : I64 = 2i64;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.23 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.23;
|
||||
procedure Bool.9 (#Attr.2, #Attr.3):
|
||||
let Bool.21 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.21;
|
||||
|
||||
procedure Test.1 (Test.3):
|
||||
let Test.6 : I64 = 10i64;
|
||||
|
@ -13,7 +13,7 @@ procedure Test.1 (Test.3):
|
|||
ret Test.8;
|
||||
in
|
||||
let Test.12 : I64 = 5i64;
|
||||
let Test.11 : Int1 = CallByName Bool.11 Test.6 Test.12;
|
||||
let Test.11 : Int1 = CallByName Bool.9 Test.6 Test.12;
|
||||
jump Test.10 Test.11;
|
||||
|
||||
procedure Test.0 ():
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
procedure Bool.1 ():
|
||||
let Bool.23 : Int1 = false;
|
||||
ret Bool.23;
|
||||
let Bool.21 : Int1 = false;
|
||||
ret Bool.21;
|
||||
|
||||
procedure Bool.2 ():
|
||||
let Bool.24 : Int1 = true;
|
||||
ret Bool.24;
|
||||
let Bool.22 : Int1 = true;
|
||||
ret Bool.22;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.4 : Int1 = CallByName Bool.2;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
procedure Bool.1 ():
|
||||
let Bool.23 : Int1 = false;
|
||||
ret Bool.23;
|
||||
let Bool.21 : Int1 = false;
|
||||
ret Bool.21;
|
||||
|
||||
procedure Num.19 (#Attr.2, #Attr.3):
|
||||
let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
|
@ -9,7 +9,7 @@ procedure Num.19 (#Attr.2, #Attr.3):
|
|||
procedure Test.3 (Test.4):
|
||||
ret Test.4;
|
||||
|
||||
procedure Test.0 (#Derived_gen.0):
|
||||
procedure Test.0 (Bool.22):
|
||||
joinpoint Test.5 Test.1:
|
||||
joinpoint Test.10 Test.2:
|
||||
let Test.8 : I64 = 1i64;
|
||||
|
@ -31,4 +31,4 @@ procedure Test.0 (#Derived_gen.0):
|
|||
let Test.9 : Int1 = true;
|
||||
jump Test.10 Test.9;
|
||||
in
|
||||
jump Test.5 #Derived_gen.0;
|
||||
jump Test.5 Bool.22;
|
||||
|
|
|
@ -34,7 +34,7 @@ procedure Test.8 (Test.9):
|
|||
let Test.23 : I64 = CallByName Num.19 Test.9 Test.24;
|
||||
ret Test.23;
|
||||
|
||||
procedure Test.0 (#Derived_gen.0):
|
||||
procedure Test.0 (Bool.21):
|
||||
joinpoint Test.11 Test.1:
|
||||
let Test.25 : I64 = 1i64;
|
||||
let Test.13 : I64 = CallByName Num.19 Test.1 Test.25;
|
||||
|
@ -57,4 +57,4 @@ procedure Test.0 (#Derived_gen.0):
|
|||
ret Test.12;
|
||||
|
||||
in
|
||||
jump Test.11 #Derived_gen.0;
|
||||
jump Test.11 Bool.21;
|
||||
|
|
|
@ -17,7 +17,7 @@ procedure Test.4 (Test.5, #Attr.12):
|
|||
let Test.16 : I64 = CallByName Num.19 Test.5 Test.17;
|
||||
ret Test.16;
|
||||
|
||||
procedure Test.0 (#Derived_gen.0):
|
||||
procedure Test.0 (Bool.21):
|
||||
joinpoint Test.7 Test.1:
|
||||
let Test.21 : I64 = 1i64;
|
||||
let Test.9 : I64 = CallByName Num.19 Test.1 Test.21;
|
||||
|
@ -33,4 +33,4 @@ procedure Test.0 (#Derived_gen.0):
|
|||
ret Test.8;
|
||||
|
||||
in
|
||||
jump Test.7 #Derived_gen.0;
|
||||
jump Test.7 Bool.21;
|
||||
|
|
1073
crates/compiler/test_mono/generated/inspect_derived_dict.txt
generated
1073
crates/compiler/test_mono/generated/inspect_derived_dict.txt
generated
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue