mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-09-11 03:45:29 +03:00
[sc-653] Reorder compiled redexes recursive last
This commit is contained in:
parent
bd6b4c129a
commit
1313a73aa1
@ -15,6 +15,7 @@
|
|||||||
"combinators",
|
"combinators",
|
||||||
"concat",
|
"concat",
|
||||||
"ctrs",
|
"ctrs",
|
||||||
|
"cuda",
|
||||||
"Dall",
|
"Dall",
|
||||||
"datatypes",
|
"datatypes",
|
||||||
"Deque",
|
"Deque",
|
||||||
|
@ -235,15 +235,6 @@ impl DiagnosticsConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_strict() -> Self {
|
|
||||||
// TODO: Pre-reduce recursion check disabled while execution not implemented for hvm32
|
|
||||||
Self { recursion_cycle: Severity::Error, ..Self::default() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_lazy() -> Self {
|
|
||||||
Self { recursion_cycle: Severity::Allow, ..Self::default() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn warning_severity(&self, warn: WarningType) -> Severity {
|
pub fn warning_severity(&self, warn: WarningType) -> Severity {
|
||||||
match warn {
|
match warn {
|
||||||
WarningType::UnusedDefinition => self.unused_definition,
|
WarningType::UnusedDefinition => self.unused_definition,
|
||||||
@ -258,7 +249,9 @@ impl DiagnosticsConfig {
|
|||||||
|
|
||||||
impl Default for DiagnosticsConfig {
|
impl Default for DiagnosticsConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new(Severity::Warning, false)
|
let mut cfg = Self::new(Severity::Warning, false);
|
||||||
|
cfg.recursion_cycle = Severity::Error;
|
||||||
|
cfg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
pub mod check_net_size;
|
pub mod check_net_size;
|
||||||
pub mod mutual_recursion;
|
pub mod mutual_recursion;
|
||||||
|
pub mod reorder_redexes;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
diagnostics::{Diagnostics, WarningType, ERR_INDENT_SIZE},
|
diagnostics::{Diagnostics, WarningType, ERR_INDENT_SIZE},
|
||||||
|
maybe_grow,
|
||||||
term::transform::definition_merge::MERGE_SEPARATOR,
|
term::transform::definition_merge::MERGE_SEPARATOR,
|
||||||
};
|
};
|
||||||
use hvmc::ast::{Book, Tree};
|
use hvmc::ast::{Book, Tree};
|
||||||
@ -101,8 +102,9 @@ impl Graph {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Collect active refs from the tree.
|
||||||
fn collect_refs(current: Ref, tree: &Tree, graph: &mut Graph) {
|
fn collect_refs(current: Ref, tree: &Tree, graph: &mut Graph) {
|
||||||
match tree {
|
maybe_grow(|| match tree {
|
||||||
Tree::Ref { nam } => graph.add(current, nam.clone()),
|
Tree::Ref { nam } => graph.add(current, nam.clone()),
|
||||||
Tree::Ctr { ports, .. } => {
|
Tree::Ctr { ports, .. } => {
|
||||||
if let Some(last) = ports.last() {
|
if let Some(last) = ports.last() {
|
||||||
@ -114,7 +116,7 @@ fn collect_refs(current: Ref, tree: &Tree, graph: &mut Graph) {
|
|||||||
collect_refs(current.clone(), subtree, graph);
|
collect_refs(current.clone(), subtree, graph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Book> for Graph {
|
impl From<&Book> for Graph {
|
||||||
@ -122,13 +124,17 @@ impl From<&Book> for Graph {
|
|||||||
let mut graph = Self::new();
|
let mut graph = Self::new();
|
||||||
|
|
||||||
for (r#ref, net) in book.iter() {
|
for (r#ref, net) in book.iter() {
|
||||||
// Collect active refs from root.
|
// Collect active refs from the root.
|
||||||
collect_refs(r#ref.clone(), &net.root, &mut graph);
|
collect_refs(r#ref.clone(), &net.root, &mut graph);
|
||||||
for (left, _) in net.redexes.iter() {
|
|
||||||
// If left is an active reference, add to the graph.
|
// Collect active refs from redexes.
|
||||||
|
for (left, right) in net.redexes.iter() {
|
||||||
if let Tree::Ref { nam } = left {
|
if let Tree::Ref { nam } = left {
|
||||||
graph.add(r#ref.clone(), nam.clone());
|
graph.add(r#ref.clone(), nam.clone());
|
||||||
}
|
}
|
||||||
|
if let Tree::Ref { nam } = right {
|
||||||
|
graph.add(r#ref.clone(), nam.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
120
src/hvmc_net/reorder_redexes.rs
Normal file
120
src/hvmc_net/reorder_redexes.rs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
use hvmc::ast::{Book, Net, Tree};
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
use crate::maybe_grow;
|
||||||
|
|
||||||
|
/// Reorder redexes in the book to have more efficient execution.
|
||||||
|
///
|
||||||
|
/// Especially for hvm-cuda, we want to keep the number of nodes/vars/redexes
|
||||||
|
/// low so we put redexes with recursive refs last (at the bottom of the stack).
|
||||||
|
pub fn reorder_redexes_recursive_last(book: &mut Book) {
|
||||||
|
// Direct dependencies
|
||||||
|
let deps = book.iter().map(|(nam, net)| (nam.clone(), dependencies(net))).collect::<HashMap<_, _>>();
|
||||||
|
|
||||||
|
// Look at dependencies to find if recursive
|
||||||
|
let recursive_nets = cycles(&deps).into_iter().flatten().collect::<HashSet<_>>();
|
||||||
|
|
||||||
|
for net in book.values_mut() {
|
||||||
|
reorder_redexes_net(net, &recursive_nets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reorder redexes to have recursive last (bottom of the stack).
|
||||||
|
fn reorder_redexes_net(net: &mut Net, recursive_nets: &HashSet<String>) {
|
||||||
|
let mut recursive_redexes = vec![];
|
||||||
|
let mut non_recursive_redexes = vec![];
|
||||||
|
|
||||||
|
for (a, b) in std::mem::take(&mut net.redexes) {
|
||||||
|
if tree_has_recursive(&a, recursive_nets) || tree_has_recursive(&b, recursive_nets) {
|
||||||
|
recursive_redexes.push((a, b));
|
||||||
|
} else {
|
||||||
|
non_recursive_redexes.push((a, b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut redexes = recursive_redexes;
|
||||||
|
redexes.append(&mut non_recursive_redexes);
|
||||||
|
net.redexes = redexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether a tree has a reference to a recursive net or not.
|
||||||
|
fn tree_has_recursive(tree: &Tree, recursive_nets: &HashSet<String>) -> bool {
|
||||||
|
maybe_grow(|| {
|
||||||
|
if let Tree::Ref { nam } = tree {
|
||||||
|
recursive_nets.contains(nam)
|
||||||
|
} else {
|
||||||
|
for child in tree.children() {
|
||||||
|
if tree_has_recursive(child, recursive_nets) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type DepGraph = HashMap<String, HashSet<String>>;
|
||||||
|
type Cycles = Vec<Vec<String>>;
|
||||||
|
|
||||||
|
/// Find all cycles in the dependency graph.
|
||||||
|
pub fn cycles(deps: &DepGraph) -> Cycles {
|
||||||
|
let mut cycles = vec![];
|
||||||
|
let mut stack = vec![];
|
||||||
|
let mut visited = HashSet::new();
|
||||||
|
for nam in deps.keys() {
|
||||||
|
if !visited.contains(nam) {
|
||||||
|
find_cycles(deps, nam, &mut visited, &mut stack, &mut cycles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cycles
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_cycles(
|
||||||
|
deps: &DepGraph,
|
||||||
|
nam: &String,
|
||||||
|
visited: &mut HashSet<String>,
|
||||||
|
stack: &mut Vec<String>,
|
||||||
|
cycles: &mut Cycles,
|
||||||
|
) {
|
||||||
|
maybe_grow(|| {
|
||||||
|
// Check if the current ref is already in the stack, which indicates a cycle.
|
||||||
|
if let Some(cycle_start) = stack.iter().position(|n| n == nam) {
|
||||||
|
// If found, add the cycle to the cycles vector.
|
||||||
|
cycles.push(stack[cycle_start ..].to_vec());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If the ref has not been visited yet, mark it as visited.
|
||||||
|
if visited.insert(nam.clone()) {
|
||||||
|
// Add the current ref to the stack to keep track of the path.
|
||||||
|
stack.push(nam.clone());
|
||||||
|
// Get the dependencies of the current ref.
|
||||||
|
if let Some(dependencies) = deps.get(nam) {
|
||||||
|
// Search for cycles from each dependency.
|
||||||
|
for dep in dependencies {
|
||||||
|
find_cycles(deps, dep, visited, stack, cycles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gather the set of net that this net directly depends on (has a ref in the net).
|
||||||
|
fn dependencies(net: &Net) -> HashSet<String> {
|
||||||
|
let mut deps = HashSet::new();
|
||||||
|
dependencies_tree(&net.root, &mut deps);
|
||||||
|
for (a, b) in &net.redexes {
|
||||||
|
dependencies_tree(a, &mut deps);
|
||||||
|
dependencies_tree(b, &mut deps);
|
||||||
|
}
|
||||||
|
deps
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dependencies_tree(tree: &Tree, deps: &mut HashSet<String>) {
|
||||||
|
if let Tree::Ref { nam } = tree {
|
||||||
|
deps.insert(nam.clone());
|
||||||
|
} else {
|
||||||
|
for subtree in tree.children() {
|
||||||
|
dependencies_tree(subtree, deps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
src/lib.rs
60
src/lib.rs
@ -6,6 +6,7 @@ use hvmc::ast::Net;
|
|||||||
use hvmc_net::{
|
use hvmc_net::{
|
||||||
check_net_size::{check_net_sizes, MAX_NET_SIZE},
|
check_net_size::{check_net_sizes, MAX_NET_SIZE},
|
||||||
mutual_recursion,
|
mutual_recursion,
|
||||||
|
reorder_redexes::reorder_redexes_recursive_last,
|
||||||
};
|
};
|
||||||
use net::hvmc_to_net::hvmc_to_net;
|
use net::hvmc_to_net::hvmc_to_net;
|
||||||
use std::{process::Output, str::FromStr};
|
use std::{process::Output, str::FromStr};
|
||||||
@ -38,6 +39,7 @@ pub fn compile_book(
|
|||||||
args: Option<Vec<Term>>,
|
args: Option<Vec<Term>>,
|
||||||
) -> Result<CompileResult, Diagnostics> {
|
) -> Result<CompileResult, Diagnostics> {
|
||||||
let mut diagnostics = desugar_book(book, opts.clone(), diagnostics_cfg, args)?;
|
let mut diagnostics = desugar_book(book, opts.clone(), diagnostics_cfg, args)?;
|
||||||
|
|
||||||
let (mut core_book, labels) = book_to_nets(book, &mut diagnostics)?;
|
let (mut core_book, labels) = book_to_nets(book, &mut diagnostics)?;
|
||||||
|
|
||||||
if opts.eta {
|
if opts.eta {
|
||||||
@ -45,7 +47,6 @@ pub fn compile_book(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutual_recursion::check_cycles(&core_book, &mut diagnostics)?;
|
mutual_recursion::check_cycles(&core_book, &mut diagnostics)?;
|
||||||
|
|
||||||
if opts.eta {
|
if opts.eta {
|
||||||
core_book.values_mut().for_each(Net::eta_reduce);
|
core_book.values_mut().for_each(Net::eta_reduce);
|
||||||
}
|
}
|
||||||
@ -65,6 +66,10 @@ pub fn compile_book(
|
|||||||
|
|
||||||
check_net_sizes(&core_book, &mut diagnostics)?;
|
check_net_sizes(&core_book, &mut diagnostics)?;
|
||||||
|
|
||||||
|
if opts.recursive_last {
|
||||||
|
reorder_redexes_recursive_last(&mut core_book);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(CompileResult { core_book, labels, diagnostics })
|
Ok(CompileResult { core_book, labels, diagnostics })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,8 +108,8 @@ pub fn desugar_book(
|
|||||||
// Auto match linearization
|
// Auto match linearization
|
||||||
match opts.linearize_matches {
|
match opts.linearize_matches {
|
||||||
OptLevel::Disabled => (),
|
OptLevel::Disabled => (),
|
||||||
OptLevel::Enabled => ctx.book.linearize_match_binds(),
|
OptLevel::Alt => ctx.book.linearize_match_binds(),
|
||||||
OptLevel::Extra => ctx.book.linearize_matches(),
|
OptLevel::Enabled => ctx.book.linearize_matches(),
|
||||||
}
|
}
|
||||||
// Manual match linearization
|
// Manual match linearization
|
||||||
ctx.book.linearize_match_with();
|
ctx.book.linearize_match_with();
|
||||||
@ -175,7 +180,7 @@ pub fn run_book(
|
|||||||
return Err(format!("Error reading result from hvm. Output :\n{}{}{}", err, status, out).into());
|
return Err(format!("Error reading result from hvm. Output :\n{}{}{}", err, status, out).into());
|
||||||
};
|
};
|
||||||
|
|
||||||
let (term, diags) = readback_hvm_net(&net, &book, &labels, run_opts.linear);
|
let (term, diags) = readback_hvm_net(&net, &book, &labels, run_opts.linear_readback);
|
||||||
Ok((term, stats.to_string(), diags))
|
Ok((term, stats.to_string(), diags))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,23 +194,16 @@ pub fn readback_hvm_net(net: &Net, book: &Book, labels: &Labels, linear: bool) -
|
|||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct RunOpts {
|
pub struct RunOpts {
|
||||||
pub linear: bool,
|
pub linear_readback: bool,
|
||||||
pub lazy_mode: bool,
|
|
||||||
pub pretty: bool,
|
pub pretty: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RunOpts {
|
|
||||||
pub fn lazy() -> Self {
|
|
||||||
Self { lazy_mode: true, ..Self::default() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub enum OptLevel {
|
pub enum OptLevel {
|
||||||
#[default]
|
|
||||||
Disabled,
|
Disabled,
|
||||||
|
#[default]
|
||||||
Enabled,
|
Enabled,
|
||||||
Extra,
|
Alt,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OptLevel {
|
impl OptLevel {
|
||||||
@ -214,7 +212,7 @@ impl OptLevel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_extra(&self) -> bool {
|
pub fn is_extra(&self) -> bool {
|
||||||
matches!(self, OptLevel::Extra)
|
matches!(self, OptLevel::Enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,6 +235,9 @@ pub struct CompileOpts {
|
|||||||
|
|
||||||
/// Enables [term::transform::inline].
|
/// Enables [term::transform::inline].
|
||||||
pub inline: bool,
|
pub inline: bool,
|
||||||
|
|
||||||
|
/// Enables [hvmc_net::reorder_redexes::reorder_redexes_recursive_last].
|
||||||
|
pub recursive_last: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompileOpts {
|
impl CompileOpts {
|
||||||
@ -249,24 +250,23 @@ impl CompileOpts {
|
|||||||
float_combinators: true,
|
float_combinators: true,
|
||||||
merge: true,
|
merge: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
linearize_matches: OptLevel::Extra,
|
recursive_last: true,
|
||||||
|
linearize_matches: OptLevel::Enabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set all opts as false and keep the current adt encoding.
|
/// Set all opts as false and keep the current adt encoding.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn set_no_all(self) -> Self {
|
pub fn set_no_all(self) -> Self {
|
||||||
Self::default()
|
Self {
|
||||||
}
|
eta: false,
|
||||||
|
prune: false,
|
||||||
/// All optimizations disabled, except float_combinators and linearize_matches
|
linearize_matches: OptLevel::Disabled,
|
||||||
pub fn default_strict() -> Self {
|
float_combinators: false,
|
||||||
Self { float_combinators: true, linearize_matches: OptLevel::Extra, eta: true, ..Self::default() }
|
merge: false,
|
||||||
}
|
inline: false,
|
||||||
|
recursive_last: false,
|
||||||
// Disable optimizations that don't work or are unnecessary on lazy mode
|
}
|
||||||
pub fn default_lazy() -> Self {
|
|
||||||
Self::default()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_for_strict(&self) {
|
pub fn check_for_strict(&self) {
|
||||||
@ -284,14 +284,16 @@ impl CompileOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CompileOpts {
|
impl Default for CompileOpts {
|
||||||
|
/// Enables eta, linearize_matches, float_combinators and reorder_redexes_recursive_last.
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
eta: false,
|
eta: true,
|
||||||
prune: false,
|
prune: false,
|
||||||
linearize_matches: OptLevel::Enabled,
|
linearize_matches: OptLevel::Enabled,
|
||||||
float_combinators: false,
|
float_combinators: true,
|
||||||
merge: false,
|
merge: false,
|
||||||
inline: false,
|
inline: false,
|
||||||
|
recursive_last: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
80
src/main.rs
80
src/main.rs
@ -34,9 +34,6 @@ enum Mode {
|
|||||||
)]
|
)]
|
||||||
comp_opts: Vec<OptArgs>,
|
comp_opts: Vec<OptArgs>,
|
||||||
|
|
||||||
#[arg(short = 'L', help = "Lazy mode")]
|
|
||||||
lazy_mode: bool,
|
|
||||||
|
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
warn_opts: CliWarnOpts,
|
warn_opts: CliWarnOpts,
|
||||||
|
|
||||||
@ -54,9 +51,6 @@ enum Mode {
|
|||||||
)]
|
)]
|
||||||
comp_opts: Vec<OptArgs>,
|
comp_opts: Vec<OptArgs>,
|
||||||
|
|
||||||
#[arg(short = 'L', help = "Lazy mode")]
|
|
||||||
lazy_mode: bool,
|
|
||||||
|
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
warn_opts: CliWarnOpts,
|
warn_opts: CliWarnOpts,
|
||||||
|
|
||||||
@ -65,9 +59,6 @@ enum Mode {
|
|||||||
},
|
},
|
||||||
/// Compiles the program and runs it with the hvm.
|
/// Compiles the program and runs it with the hvm.
|
||||||
Run {
|
Run {
|
||||||
#[arg(short = 'L', help = "Lazy mode")]
|
|
||||||
lazy_mode: bool,
|
|
||||||
|
|
||||||
#[arg(short = 'p', help = "Debug and normalization pretty printing")]
|
#[arg(short = 'p', help = "Debug and normalization pretty printing")]
|
||||||
pretty: bool,
|
pretty: bool,
|
||||||
|
|
||||||
@ -106,9 +97,6 @@ enum Mode {
|
|||||||
#[arg(short = 'p', help = "Debug and normalization pretty printing")]
|
#[arg(short = 'p', help = "Debug and normalization pretty printing")]
|
||||||
pretty: bool,
|
pretty: bool,
|
||||||
|
|
||||||
#[arg(short = 'L', help = "Lazy mode")]
|
|
||||||
lazy_mode: bool,
|
|
||||||
|
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
warn_opts: CliWarnOpts,
|
warn_opts: CliWarnOpts,
|
||||||
|
|
||||||
@ -166,7 +154,7 @@ pub enum OptArgs {
|
|||||||
Prune,
|
Prune,
|
||||||
NoPrune,
|
NoPrune,
|
||||||
LinearizeMatches,
|
LinearizeMatches,
|
||||||
LinearizeMatchesExtra,
|
LinearizeMatchesAlt,
|
||||||
NoLinearizeMatches,
|
NoLinearizeMatches,
|
||||||
FloatCombinators,
|
FloatCombinators,
|
||||||
NoFloatCombinators,
|
NoFloatCombinators,
|
||||||
@ -174,11 +162,13 @@ pub enum OptArgs {
|
|||||||
NoMerge,
|
NoMerge,
|
||||||
Inline,
|
Inline,
|
||||||
NoInline,
|
NoInline,
|
||||||
|
RecursiveLast,
|
||||||
|
NoRecursiveLast,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_opts_from_cli(args: &Vec<OptArgs>, lazy_mode: bool) -> CompileOpts {
|
fn compile_opts_from_cli(args: &Vec<OptArgs>) -> CompileOpts {
|
||||||
use OptArgs::*;
|
use OptArgs::*;
|
||||||
let mut opts = if lazy_mode { CompileOpts::default_lazy() } else { CompileOpts::default_strict() };
|
let mut opts = CompileOpts::default();
|
||||||
|
|
||||||
for arg in args {
|
for arg in args {
|
||||||
match arg {
|
match arg {
|
||||||
@ -194,9 +184,11 @@ fn compile_opts_from_cli(args: &Vec<OptArgs>, lazy_mode: bool) -> CompileOpts {
|
|||||||
NoMerge => opts.merge = false,
|
NoMerge => opts.merge = false,
|
||||||
Inline => opts.inline = true,
|
Inline => opts.inline = true,
|
||||||
NoInline => opts.inline = false,
|
NoInline => opts.inline = false,
|
||||||
|
RecursiveLast => opts.recursive_last = true,
|
||||||
|
NoRecursiveLast => opts.recursive_last = false,
|
||||||
|
|
||||||
LinearizeMatches => opts.linearize_matches = OptLevel::Enabled,
|
LinearizeMatches => opts.linearize_matches = OptLevel::Enabled,
|
||||||
LinearizeMatchesExtra => opts.linearize_matches = OptLevel::Extra,
|
LinearizeMatchesAlt => opts.linearize_matches = OptLevel::Alt,
|
||||||
NoLinearizeMatches => opts.linearize_matches = OptLevel::Disabled,
|
NoLinearizeMatches => opts.linearize_matches = OptLevel::Disabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,26 +234,18 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Diagnostics> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match cli.mode {
|
match cli.mode {
|
||||||
Mode::Check { comp_opts, lazy_mode, warn_opts, path } => {
|
Mode::Check { comp_opts, warn_opts, path } => {
|
||||||
let diagnostics_cfg = set_warning_cfg_from_cli(
|
let diagnostics_cfg = set_warning_cfg_from_cli(DiagnosticsConfig::default(), warn_opts);
|
||||||
if lazy_mode { DiagnosticsConfig::default_lazy() } else { DiagnosticsConfig::default_strict() },
|
let compile_opts = compile_opts_from_cli(&comp_opts);
|
||||||
lazy_mode,
|
|
||||||
warn_opts,
|
|
||||||
);
|
|
||||||
let compile_opts = compile_opts_from_cli(&comp_opts, lazy_mode);
|
|
||||||
|
|
||||||
let mut book = load_book(&path)?;
|
let mut book = load_book(&path)?;
|
||||||
let diagnostics = check_book(&mut book, diagnostics_cfg, compile_opts)?;
|
let diagnostics = check_book(&mut book, diagnostics_cfg, compile_opts)?;
|
||||||
eprintln!("{}", diagnostics);
|
eprintln!("{}", diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mode::Compile { path, comp_opts, warn_opts, lazy_mode } => {
|
Mode::Compile { path, comp_opts, warn_opts } => {
|
||||||
let diagnostics_cfg = set_warning_cfg_from_cli(
|
let diagnostics_cfg = set_warning_cfg_from_cli(DiagnosticsConfig::default(), warn_opts);
|
||||||
if lazy_mode { DiagnosticsConfig::default_lazy() } else { DiagnosticsConfig::default_strict() },
|
let opts = compile_opts_from_cli(&comp_opts);
|
||||||
lazy_mode,
|
|
||||||
warn_opts,
|
|
||||||
);
|
|
||||||
let opts = compile_opts_from_cli(&comp_opts, lazy_mode);
|
|
||||||
|
|
||||||
let mut book = load_book(&path)?;
|
let mut book = load_book(&path)?;
|
||||||
let compile_res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
let compile_res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
||||||
@ -270,14 +254,10 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Diagnostics> {
|
|||||||
println!("{}", compile_res.core_book);
|
println!("{}", compile_res.core_book);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mode::Desugar { path, comp_opts, warn_opts, pretty, lazy_mode } => {
|
Mode::Desugar { path, comp_opts, warn_opts, pretty } => {
|
||||||
let diagnostics_cfg = set_warning_cfg_from_cli(
|
let diagnostics_cfg = set_warning_cfg_from_cli(DiagnosticsConfig::default(), warn_opts);
|
||||||
if lazy_mode { DiagnosticsConfig::default_lazy() } else { DiagnosticsConfig::default_strict() },
|
|
||||||
lazy_mode,
|
|
||||||
warn_opts,
|
|
||||||
);
|
|
||||||
|
|
||||||
let opts = compile_opts_from_cli(&comp_opts, lazy_mode);
|
let opts = compile_opts_from_cli(&comp_opts);
|
||||||
|
|
||||||
let mut book = load_book(&path)?;
|
let mut book = load_book(&path)?;
|
||||||
let diagnostics = desugar_book(&mut book, opts, diagnostics_cfg, None)?;
|
let diagnostics = desugar_book(&mut book, opts, diagnostics_cfg, None)?;
|
||||||
@ -290,17 +270,17 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Diagnostics> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mode::Run { lazy_mode, run_opts, pretty, comp_opts, warn_opts, arguments, path } => {
|
Mode::Run { run_opts, pretty, comp_opts, warn_opts, arguments, path } => {
|
||||||
let RunArgs { linear, print_stats } = run_opts;
|
let RunArgs { linear, print_stats } = run_opts;
|
||||||
|
|
||||||
let diagnostics_cfg =
|
let diagnostics_cfg =
|
||||||
set_warning_cfg_from_cli(DiagnosticsConfig::new(Severity::Allow, arg_verbose), lazy_mode, warn_opts);
|
set_warning_cfg_from_cli(DiagnosticsConfig::new(Severity::Allow, arg_verbose), warn_opts);
|
||||||
|
|
||||||
let compile_opts = compile_opts_from_cli(&comp_opts, lazy_mode);
|
let compile_opts = compile_opts_from_cli(&comp_opts);
|
||||||
|
|
||||||
compile_opts.check_for_strict();
|
compile_opts.check_for_strict();
|
||||||
|
|
||||||
let run_opts = RunOpts { linear, lazy_mode, pretty };
|
let run_opts = RunOpts { linear_readback: linear, pretty };
|
||||||
|
|
||||||
let book = load_book(&path)?;
|
let book = load_book(&path)?;
|
||||||
let (term, stats, diags) = run_book(book, run_opts, compile_opts, diagnostics_cfg, arguments)?;
|
let (term, stats, diags) = run_book(book, run_opts, compile_opts, diagnostics_cfg, arguments)?;
|
||||||
@ -319,12 +299,8 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Diagnostics> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_warning_cfg_from_cli(
|
fn set_warning_cfg_from_cli(mut cfg: DiagnosticsConfig, warn_opts: CliWarnOpts) -> DiagnosticsConfig {
|
||||||
mut cfg: DiagnosticsConfig,
|
fn set(cfg: &mut DiagnosticsConfig, severity: Severity, cli_val: WarningArgs) {
|
||||||
lazy_mode: bool,
|
|
||||||
warn_opts: CliWarnOpts,
|
|
||||||
) -> DiagnosticsConfig {
|
|
||||||
fn set(cfg: &mut DiagnosticsConfig, severity: Severity, cli_val: WarningArgs, lazy_mode: bool) {
|
|
||||||
match cli_val {
|
match cli_val {
|
||||||
WarningArgs::All => {
|
WarningArgs::All => {
|
||||||
cfg.irrefutable_match = severity;
|
cfg.irrefutable_match = severity;
|
||||||
@ -332,9 +308,7 @@ fn set_warning_cfg_from_cli(
|
|||||||
cfg.unreachable_match = severity;
|
cfg.unreachable_match = severity;
|
||||||
cfg.unused_definition = severity;
|
cfg.unused_definition = severity;
|
||||||
cfg.repeated_bind = severity;
|
cfg.repeated_bind = severity;
|
||||||
if !lazy_mode {
|
cfg.recursion_cycle = severity;
|
||||||
cfg.recursion_cycle = severity;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
WarningArgs::IrrefutableMatch => cfg.irrefutable_match = severity,
|
WarningArgs::IrrefutableMatch => cfg.irrefutable_match = severity,
|
||||||
WarningArgs::RedundantMatch => cfg.redundant_match = severity,
|
WarningArgs::RedundantMatch => cfg.redundant_match = severity,
|
||||||
@ -356,9 +330,9 @@ fn set_warning_cfg_from_cli(
|
|||||||
let mut denies = warn_opts.denies.into_iter();
|
let mut denies = warn_opts.denies.into_iter();
|
||||||
for id in warn_opts_ids {
|
for id in warn_opts_ids {
|
||||||
match id.as_ref() {
|
match id.as_ref() {
|
||||||
"allows" => set(&mut cfg, Severity::Allow, allows.next().unwrap(), lazy_mode),
|
"allows" => set(&mut cfg, Severity::Allow, allows.next().unwrap()),
|
||||||
"denies" => set(&mut cfg, Severity::Error, denies.next().unwrap(), lazy_mode),
|
"denies" => set(&mut cfg, Severity::Error, denies.next().unwrap()),
|
||||||
"warns" => set(&mut cfg, Severity::Warning, warns.next().unwrap(), lazy_mode),
|
"warns" => set(&mut cfg, Severity::Warning, warns.next().unwrap()),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ use super::{num_to_name, FanKind, Op};
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ViciousCycleErr;
|
pub struct ViciousCycleErr;
|
||||||
|
|
||||||
pub fn book_to_nets(book: &Book, info: &mut Diagnostics) -> Result<(hvmc::ast::Book, Labels), Diagnostics> {
|
pub fn book_to_nets(book: &Book, diags: &mut Diagnostics) -> Result<(hvmc::ast::Book, Labels), Diagnostics> {
|
||||||
info.start_pass();
|
diags.start_pass();
|
||||||
|
|
||||||
let mut hvmc = hvmc::ast::Book::default();
|
let mut hvmc = hvmc::ast::Book::default();
|
||||||
let mut labels = Labels::default();
|
let mut labels = Labels::default();
|
||||||
@ -31,8 +31,11 @@ pub fn book_to_nets(book: &Book, info: &mut Diagnostics) -> Result<(hvmc::ast::B
|
|||||||
|
|
||||||
let name = if def.name == *main { book.hvmc_entrypoint().to_string() } else { def.name.0.to_string() };
|
let name = if def.name == *main { book.hvmc_entrypoint().to_string() } else { def.name.0.to_string() };
|
||||||
|
|
||||||
if let Some(net) = info.take_inet_err(net, name.clone()) {
|
match net {
|
||||||
hvmc.insert(name, net);
|
Ok(net) => {
|
||||||
|
hvmc.insert(name, net);
|
||||||
|
}
|
||||||
|
Err(err) => diags.add_inet_error(err, name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,7 +43,7 @@ pub fn book_to_nets(book: &Book, info: &mut Diagnostics) -> Result<(hvmc::ast::B
|
|||||||
labels.con.finish();
|
labels.con.finish();
|
||||||
labels.dup.finish();
|
labels.dup.finish();
|
||||||
|
|
||||||
Ok((hvmc, labels))
|
diags.fatal((hvmc, labels))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts an LC term into an IC net.
|
/// Converts an LC term into an IC net.
|
||||||
|
@ -117,9 +117,8 @@ fn compile_term() {
|
|||||||
fn compile_file() {
|
fn compile_file() {
|
||||||
run_golden_test_dir(function_name!(), &|code, path| {
|
run_golden_test_dir(function_name!(), &|code, path| {
|
||||||
let mut book = do_parse_book(code, path)?;
|
let mut book = do_parse_book(code, path)?;
|
||||||
let compile_opts = CompileOpts::default_strict();
|
let compile_opts = CompileOpts::default();
|
||||||
let mut diagnostics_cfg = DiagnosticsConfig::default_strict();
|
let diagnostics_cfg = DiagnosticsConfig { unused_definition: Severity::Allow, ..Default::default() };
|
||||||
diagnostics_cfg.unused_definition = Severity::Allow;
|
|
||||||
|
|
||||||
let res = compile_book(&mut book, compile_opts, diagnostics_cfg, None)?;
|
let res = compile_book(&mut book, compile_opts, diagnostics_cfg, None)?;
|
||||||
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
||||||
@ -130,10 +129,12 @@ fn compile_file() {
|
|||||||
fn compile_file_o_all() {
|
fn compile_file_o_all() {
|
||||||
run_golden_test_dir(function_name!(), &|code, path| {
|
run_golden_test_dir(function_name!(), &|code, path| {
|
||||||
let mut book = do_parse_book(code, path)?;
|
let mut book = do_parse_book(code, path)?;
|
||||||
let opts = CompileOpts::default_strict().set_all();
|
let opts = CompileOpts::default().set_all();
|
||||||
let mut diagnostics_cfg = DiagnosticsConfig::default_strict();
|
let diagnostics_cfg = DiagnosticsConfig {
|
||||||
diagnostics_cfg.recursion_cycle = Severity::Warning;
|
recursion_cycle: Severity::Warning,
|
||||||
diagnostics_cfg.unused_definition = Severity::Allow;
|
unused_definition: Severity::Allow,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
let res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
let res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
||||||
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
||||||
@ -144,8 +145,8 @@ fn compile_file_o_all() {
|
|||||||
fn compile_file_o_no_all() {
|
fn compile_file_o_no_all() {
|
||||||
run_golden_test_dir(function_name!(), &|code, path| {
|
run_golden_test_dir(function_name!(), &|code, path| {
|
||||||
let mut book = do_parse_book(code, path)?;
|
let mut book = do_parse_book(code, path)?;
|
||||||
let compile_opts = CompileOpts::default_strict().set_no_all();
|
let compile_opts = CompileOpts::default().set_no_all();
|
||||||
let diagnostics_cfg = DiagnosticsConfig::default_strict();
|
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||||
let res = compile_book(&mut book, compile_opts, diagnostics_cfg, None)?;
|
let res = compile_book(&mut book, compile_opts, diagnostics_cfg, None)?;
|
||||||
Ok(format!("{}", res.core_book))
|
Ok(format!("{}", res.core_book))
|
||||||
})
|
})
|
||||||
@ -154,11 +155,17 @@ fn compile_file_o_no_all() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn linear_readback() {
|
fn linear_readback() {
|
||||||
run_golden_test_dir(function_name!(), &|code, path| {
|
run_golden_test_dir(function_name!(), &|code, path| {
|
||||||
|
let _guard = RUN_MUTEX.lock().unwrap();
|
||||||
let book = do_parse_book(code, path)?;
|
let book = do_parse_book(code, path)?;
|
||||||
let compile_opts = CompileOpts::default_strict().set_all();
|
let compile_opts = CompileOpts::default().set_all();
|
||||||
let diagnostics_cfg = DiagnosticsConfig::default_strict();
|
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||||
let (term, _, diags) =
|
let (term, _, diags) = run_book(
|
||||||
run_book(book, RunOpts { linear: true, ..Default::default() }, compile_opts, diagnostics_cfg, None)?;
|
book,
|
||||||
|
RunOpts { linear_readback: true, ..Default::default() },
|
||||||
|
compile_opts,
|
||||||
|
diagnostics_cfg,
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
let res = format!("{diags}{term}");
|
let res = format!("{diags}{term}");
|
||||||
Ok(res)
|
Ok(res)
|
||||||
});
|
});
|
||||||
@ -169,7 +176,7 @@ fn run_file() {
|
|||||||
run_golden_test_dir_multiple(function_name!(), &[(&|code, path| {
|
run_golden_test_dir_multiple(function_name!(), &[(&|code, path| {
|
||||||
let _guard = RUN_MUTEX.lock().unwrap();
|
let _guard = RUN_MUTEX.lock().unwrap();
|
||||||
let book = do_parse_book(code, path)?;
|
let book = do_parse_book(code, path)?;
|
||||||
let compile_opts = CompileOpts::default_strict();
|
let compile_opts = CompileOpts::default();
|
||||||
let diagnostics_cfg = DiagnosticsConfig {
|
let diagnostics_cfg = DiagnosticsConfig {
|
||||||
unused_definition: Severity::Allow,
|
unused_definition: Severity::Allow,
|
||||||
..DiagnosticsConfig::new(Severity::Error, true)
|
..DiagnosticsConfig::new(Severity::Error, true)
|
||||||
@ -185,8 +192,9 @@ fn run_file() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore = "while lazy execution is not implemented for hvm32"]
|
#[ignore = "while lazy execution is not implemented for hvm32"]
|
||||||
fn run_lazy() {
|
fn run_lazy() {
|
||||||
run_golden_test_dir(function_name!(), &|code, path| {
|
run_golden_test_dir(function_name!(), &|_code, _path| {
|
||||||
let _guard = RUN_MUTEX.lock().unwrap();
|
todo!()
|
||||||
|
/* let _guard = RUN_MUTEX.lock().unwrap();
|
||||||
let book = do_parse_book(code, path)?;
|
let book = do_parse_book(code, path)?;
|
||||||
let compile_opts = CompileOpts::default_lazy();
|
let compile_opts = CompileOpts::default_lazy();
|
||||||
let diagnostics_cfg = DiagnosticsConfig {
|
let diagnostics_cfg = DiagnosticsConfig {
|
||||||
@ -198,7 +206,7 @@ fn run_lazy() {
|
|||||||
|
|
||||||
let (term, _, diags) = run_book(book, run_opts, compile_opts, diagnostics_cfg, None)?;
|
let (term, _, diags) = run_book(book, run_opts, compile_opts, diagnostics_cfg, None)?;
|
||||||
let res = format!("{diags}{term}");
|
let res = format!("{diags}{term}");
|
||||||
Ok(res)
|
Ok(res) */
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,7 +263,7 @@ fn parse_file() {
|
|||||||
fn encode_pattern_match() {
|
fn encode_pattern_match() {
|
||||||
run_golden_test_dir(function_name!(), &|code, path| {
|
run_golden_test_dir(function_name!(), &|code, path| {
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
let diagnostics_cfg = DiagnosticsConfig::default_strict();
|
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||||
let mut book = do_parse_book(code, path)?;
|
let mut book = do_parse_book(code, path)?;
|
||||||
let mut ctx = Ctx::new(&mut book, diagnostics_cfg);
|
let mut ctx = Ctx::new(&mut book, diagnostics_cfg);
|
||||||
ctx.check_shared_names();
|
ctx.check_shared_names();
|
||||||
@ -286,7 +294,7 @@ fn encode_pattern_match() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn desugar_file() {
|
fn desugar_file() {
|
||||||
run_golden_test_dir(function_name!(), &|code, path| {
|
run_golden_test_dir(function_name!(), &|code, path| {
|
||||||
let compile_opts = CompileOpts::default_strict();
|
let compile_opts = CompileOpts::default();
|
||||||
let diagnostics_cfg = DiagnosticsConfig {
|
let diagnostics_cfg = DiagnosticsConfig {
|
||||||
unused_definition: Severity::Allow,
|
unused_definition: Severity::Allow,
|
||||||
..DiagnosticsConfig::new(Severity::Error, true)
|
..DiagnosticsConfig::new(Severity::Error, true)
|
||||||
@ -305,7 +313,7 @@ fn hangs() {
|
|||||||
run_golden_test_dir(function_name!(), &move |code, path| {
|
run_golden_test_dir(function_name!(), &move |code, path| {
|
||||||
let _guard = RUN_MUTEX.lock().unwrap();
|
let _guard = RUN_MUTEX.lock().unwrap();
|
||||||
let book = do_parse_book(code, path)?;
|
let book = do_parse_book(code, path)?;
|
||||||
let compile_opts = CompileOpts::default_strict().set_all();
|
let compile_opts = CompileOpts::default().set_all();
|
||||||
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Allow, false);
|
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Allow, false);
|
||||||
|
|
||||||
let thread =
|
let thread =
|
||||||
@ -328,7 +336,7 @@ fn compile_entrypoint() {
|
|||||||
let mut book = do_parse_book(code, path)?;
|
let mut book = do_parse_book(code, path)?;
|
||||||
book.entrypoint = Some(Name::new("foo"));
|
book.entrypoint = Some(Name::new("foo"));
|
||||||
let diagnostics_cfg = DiagnosticsConfig { ..DiagnosticsConfig::new(Severity::Error, true) };
|
let diagnostics_cfg = DiagnosticsConfig { ..DiagnosticsConfig::new(Severity::Error, true) };
|
||||||
let res = compile_book(&mut book, CompileOpts::default_strict(), diagnostics_cfg, None)?;
|
let res = compile_book(&mut book, CompileOpts::default(), diagnostics_cfg, None)?;
|
||||||
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -340,7 +348,7 @@ fn run_entrypoint() {
|
|||||||
let _guard = RUN_MUTEX.lock().unwrap();
|
let _guard = RUN_MUTEX.lock().unwrap();
|
||||||
let mut book = do_parse_book(code, path)?;
|
let mut book = do_parse_book(code, path)?;
|
||||||
book.entrypoint = Some(Name::new("foo"));
|
book.entrypoint = Some(Name::new("foo"));
|
||||||
let compile_opts = CompileOpts::default_strict().set_all();
|
let compile_opts = CompileOpts::default().set_all();
|
||||||
let diagnostics_cfg = DiagnosticsConfig { ..DiagnosticsConfig::new(Severity::Error, true) };
|
let diagnostics_cfg = DiagnosticsConfig { ..DiagnosticsConfig::new(Severity::Error, true) };
|
||||||
let (term, _, diags) = run_book(book, RunOpts::default(), compile_opts, diagnostics_cfg, None)?;
|
let (term, _, diags) = run_book(book, RunOpts::default(), compile_opts, diagnostics_cfg, None)?;
|
||||||
let res = format!("{diags}{term}");
|
let res = format!("{diags}{term}");
|
||||||
@ -374,8 +382,7 @@ fn mutual_recursion() {
|
|||||||
let diagnostics_cfg =
|
let diagnostics_cfg =
|
||||||
DiagnosticsConfig { recursion_cycle: Severity::Error, ..DiagnosticsConfig::new(Severity::Allow, true) };
|
DiagnosticsConfig { recursion_cycle: Severity::Error, ..DiagnosticsConfig::new(Severity::Allow, true) };
|
||||||
let mut book = do_parse_book(code, path)?;
|
let mut book = do_parse_book(code, path)?;
|
||||||
let mut opts = CompileOpts::default_strict();
|
let opts = CompileOpts { merge: true, ..CompileOpts::default() };
|
||||||
opts.merge = true;
|
|
||||||
let res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
let res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
||||||
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
||||||
})
|
})
|
||||||
@ -400,8 +407,8 @@ fn io() {
|
|||||||
(&|code, path| {
|
(&|code, path| {
|
||||||
let _guard = RUN_MUTEX.lock().unwrap();
|
let _guard = RUN_MUTEX.lock().unwrap();
|
||||||
let book = do_parse_book(code, path)?;
|
let book = do_parse_book(code, path)?;
|
||||||
let compile_opts = CompileOpts::default_strict();
|
let compile_opts = CompileOpts::default();
|
||||||
let diagnostics_cfg = DiagnosticsConfig::default_strict();
|
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||||
let (term, _, diags) = run_book(book, RunOpts::default(), compile_opts, diagnostics_cfg, None)?;
|
let (term, _, diags) = run_book(book, RunOpts::default(), compile_opts, diagnostics_cfg, None)?;
|
||||||
let res = format!("{diags}{term}");
|
let res = format!("{diags}{term}");
|
||||||
Ok(format!("Strict mode:\n{res}"))
|
Ok(format!("Strict mode:\n{res}"))
|
||||||
@ -410,7 +417,6 @@ fn io() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
//#[ignore = "while execution is not implemented for hvm32"]
|
|
||||||
fn examples() -> Result<(), Diagnostics> {
|
fn examples() -> Result<(), Diagnostics> {
|
||||||
let examples_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples");
|
let examples_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples");
|
||||||
|
|
||||||
@ -426,8 +432,8 @@ fn examples() -> Result<(), Diagnostics> {
|
|||||||
let code = std::fs::read_to_string(path).map_err(|e| e.to_string())?;
|
let code = std::fs::read_to_string(path).map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
let book = do_parse_book(&code, path).unwrap();
|
let book = do_parse_book(&code, path).unwrap();
|
||||||
let compile_opts = CompileOpts::default_strict();
|
let compile_opts = CompileOpts::default();
|
||||||
let diagnostics_cfg = DiagnosticsConfig::default_strict();
|
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||||
let (term, _, diags) = run_book(book, RunOpts::default(), compile_opts, diagnostics_cfg, None)?;
|
let (term, _, diags) = run_book(book, RunOpts::default(), compile_opts, diagnostics_cfg, None)?;
|
||||||
let res = format!("{diags}{term}");
|
let res = format!("{diags}{term}");
|
||||||
|
|
||||||
@ -448,9 +454,9 @@ fn examples() -> Result<(), Diagnostics> {
|
|||||||
fn scott_triggers_unused() {
|
fn scott_triggers_unused() {
|
||||||
run_golden_test_dir(function_name!(), &|code, path| {
|
run_golden_test_dir(function_name!(), &|code, path| {
|
||||||
let mut book = do_parse_book(code, path)?;
|
let mut book = do_parse_book(code, path)?;
|
||||||
let opts = CompileOpts::default_strict();
|
let opts = CompileOpts::default();
|
||||||
let diagnostics_cfg =
|
let diagnostics_cfg =
|
||||||
DiagnosticsConfig { unused_definition: Severity::Error, ..DiagnosticsConfig::default_strict() };
|
DiagnosticsConfig { unused_definition: Severity::Error, ..DiagnosticsConfig::default() };
|
||||||
let res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
let res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
||||||
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
||||||
})
|
})
|
||||||
|
@ -1 +1 @@
|
|||||||
main = λa λb switch a { 0: b; _: b }
|
main = λa λb λc switch a { 0: b; _: c }
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
desugar
|
||||||
|
tests/golden_tests/cli/desugar_linearize_matches_alt.hvm
|
||||||
|
-Olinearize-matches-alt
|
1
tests/golden_tests/cli/desugar_linearize_matches_alt.hvm
Normal file
1
tests/golden_tests/cli/desugar_linearize_matches_alt.hvm
Normal file
@ -0,0 +1 @@
|
|||||||
|
main = λa λb switch a { 0: b; _: b }
|
@ -1,3 +0,0 @@
|
|||||||
desugar
|
|
||||||
tests/golden_tests/cli/desugar_linearize_matches_extra.hvm
|
|
||||||
-Olinearize-matches-extra
|
|
@ -1 +0,0 @@
|
|||||||
main = λa λb λc switch a { 0: b; _: c }
|
|
@ -1,4 +1,4 @@
|
|||||||
tail_recursive = @a (a @x (+ 1 (tail_recursive x)) 0)
|
tail_recursive = @x (x @pred @acc (tail_recursive pred (+ 1 acc)) @acc 0)
|
||||||
|
|
||||||
fold = @bm (bm
|
fold = @bm (bm
|
||||||
@lft @rgt (add (fold lft) (fold rgt))
|
@lft @rgt (add (fold lft) (fold rgt))
|
||||||
|
@ -3,7 +3,7 @@ source: tests/golden_tests.rs
|
|||||||
input_file: tests/golden_tests/cli/compile_no_opts.hvm
|
input_file: tests/golden_tests/cli/compile_no_opts.hvm
|
||||||
---
|
---
|
||||||
error: invalid value 'no-pre-reduce' for '-O <COMP_OPTS>'
|
error: invalid value 'no-pre-reduce' for '-O <COMP_OPTS>'
|
||||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-extra, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline]
|
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline, recursive-last, no-recursive-last]
|
||||||
|
|
||||||
tip: a similar value exists: 'no-prune'
|
tip: a similar value exists: 'no-prune'
|
||||||
|
|
||||||
|
@ -3,6 +3,6 @@ source: tests/golden_tests.rs
|
|||||||
input_file: tests/golden_tests/cli/compile_pre_reduce.hvm
|
input_file: tests/golden_tests/cli/compile_pre_reduce.hvm
|
||||||
---
|
---
|
||||||
error: invalid value 'pre-reduce' for '-O <COMP_OPTS>'
|
error: invalid value 'pre-reduce' for '-O <COMP_OPTS>'
|
||||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-extra, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline]
|
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline, recursive-last, no-recursive-last]
|
||||||
|
|
||||||
For more information, try '--help'.
|
For more information, try '--help'.
|
||||||
|
@ -3,7 +3,7 @@ source: tests/golden_tests.rs
|
|||||||
input_file: tests/golden_tests/cli/compile_wrong_opt.hvm
|
input_file: tests/golden_tests/cli/compile_wrong_opt.hvm
|
||||||
---
|
---
|
||||||
error: invalid value 'foo' for '-O <COMP_OPTS>'
|
error: invalid value 'foo' for '-O <COMP_OPTS>'
|
||||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-extra, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline]
|
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline, recursive-last, no-recursive-last]
|
||||||
|
|
||||||
tip: a similar value exists: 'float-combinators'
|
tip: a similar value exists: 'float-combinators'
|
||||||
|
|
||||||
|
@ -3,6 +3,6 @@ source: tests/golden_tests.rs
|
|||||||
input_file: tests/golden_tests/cli/desugar_bool_scott.hvm
|
input_file: tests/golden_tests/cli/desugar_bool_scott.hvm
|
||||||
---
|
---
|
||||||
error: invalid value 'adt-scott' for '-O <COMP_OPTS>'
|
error: invalid value 'adt-scott' for '-O <COMP_OPTS>'
|
||||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-extra, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline]
|
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline, recursive-last, no-recursive-last]
|
||||||
|
|
||||||
For more information, try '--help'.
|
For more information, try '--help'.
|
||||||
|
@ -3,6 +3,6 @@ source: tests/golden_tests.rs
|
|||||||
input_file: tests/golden_tests/cli/desugar_bool_tagged.hvm
|
input_file: tests/golden_tests/cli/desugar_bool_tagged.hvm
|
||||||
---
|
---
|
||||||
error: invalid value 'adt-tagged-scott' for '-O <COMP_OPTS>'
|
error: invalid value 'adt-tagged-scott' for '-O <COMP_OPTS>'
|
||||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-extra, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline]
|
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline, recursive-last, no-recursive-last]
|
||||||
|
|
||||||
For more information, try '--help'.
|
For more information, try '--help'.
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
source: tests/golden_tests.rs
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/cli/desugar_linearize_matches.hvm
|
input_file: tests/golden_tests/cli/desugar_linearize_matches.hvm
|
||||||
---
|
---
|
||||||
(main) = λa switch a { 0: λb b; _: λ* λc c; }
|
(main) = λa λb λc (switch a { 0: λd λ* d; _: λ* λ* λe e; } b c)
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
source: tests/golden_tests.rs
|
||||||
|
input_file: tests/golden_tests/cli/desugar_linearize_matches_alt.hvm
|
||||||
|
---
|
||||||
|
(main) = λa switch a { 0: λb b; _: λ* λc c; }
|
@ -18,8 +18,8 @@ input_file: tests/golden_tests/compile_file/redex_order_recursive.hvm
|
|||||||
|
|
||||||
@main = *
|
@main = *
|
||||||
|
|
||||||
@tail_recursive = ((@tail_recursive__C0 (0 a)) a)
|
@tail_recursive = ((@tail_recursive__C0 ((* 0) a)) a)
|
||||||
|
|
||||||
@tail_recursive__C0 = (a c)
|
@tail_recursive__C0 = (a (b d))
|
||||||
|
& @tail_recursive ~ (a (c d))
|
||||||
& $(b c) ~ [+1]
|
& $(b c) ~ [+1]
|
||||||
& @tail_recursive ~ (a b)
|
|
||||||
|
@ -7,5 +7,3 @@ In compiled inet 'disconnected_self_lam':
|
|||||||
Found term that compiles into an inet with a vicious cycle
|
Found term that compiles into an inet with a vicious cycle
|
||||||
In compiled inet 'dup_self':
|
In compiled inet 'dup_self':
|
||||||
Found term that compiles into an inet with a vicious cycle
|
Found term that compiles into an inet with a vicious cycle
|
||||||
|
|
||||||
@main = (@dup_self @disconnected_self_lam)
|
|
||||||
|
@ -16,8 +16,8 @@ input_file: tests/golden_tests/compile_file_o_all/ex2.hvm
|
|||||||
& @low ~ a
|
& @low ~ a
|
||||||
|
|
||||||
@decO = (a c)
|
@decO = (a c)
|
||||||
& @I ~ (b c)
|
|
||||||
& @dec ~ (a b)
|
& @dec ~ (a b)
|
||||||
|
& @I ~ (b c)
|
||||||
|
|
||||||
@low = ((@lowO (@lowI (@E a))) a)
|
@low = ((@lowO (@lowI (@E a))) a)
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ input_file: tests/golden_tests/compile_file_o_all/list_merge_sort.hvm
|
|||||||
@Map = ((@Map__C0 ((* @False__M_Nil) a)) a)
|
@Map = ((@Map__C0 ((* @False__M_Nil) a)) a)
|
||||||
|
|
||||||
@Map__C0 = (a (c ({(a b) d} f)))
|
@Map__C0 = (a (c ({(a b) d} f)))
|
||||||
& @Cons ~ (b (e f))
|
|
||||||
& @Map ~ (c (d e))
|
& @Map ~ (c (d e))
|
||||||
|
& @Cons ~ (b (e f))
|
||||||
|
|
||||||
@Merge = (b ((@Merge__C2 ((* (a a)) (b c))) c))
|
@Merge = (b ((@Merge__C2 ((* (a a)) (b c))) c))
|
||||||
|
|
||||||
@ -22,9 +22,9 @@ input_file: tests/golden_tests/compile_file_o_all/list_merge_sort.hvm
|
|||||||
& @Cons ~ (a (@False__M_Nil b))
|
& @Cons ~ (a (@False__M_Nil b))
|
||||||
|
|
||||||
@MergePair__C1 = (c (f ({a e} (b h))))
|
@MergePair__C1 = (c (f ({a e} (b h))))
|
||||||
& @Cons ~ (d (g h))
|
|
||||||
& @Merge ~ (a (b (c d)))
|
& @Merge ~ (a (b (c d)))
|
||||||
& @MergePair ~ (e (f g))
|
& @MergePair ~ (e (f g))
|
||||||
|
& @Cons ~ (d (g h))
|
||||||
|
|
||||||
@MergePair__C2 = (b ((@MergePair__C1 (@MergePair__C0 (a (b c)))) (a c)))
|
@MergePair__C2 = (b ((@MergePair__C1 (@MergePair__C0 (a (b c)))) (a c)))
|
||||||
|
|
||||||
@ -36,12 +36,12 @@ input_file: tests/golden_tests/compile_file_o_all/list_merge_sort.hvm
|
|||||||
& @Cons ~ a
|
& @Cons ~ a
|
||||||
|
|
||||||
@Merge__C1 = ({b {g l}} ({h q} ({(a (b c)) {e m}} ({a {d n}} ({f o} t)))))
|
@Merge__C1 = ({b {g l}} ({h q} ({(a (b c)) {e m}} ({a {d n}} ({f o} t)))))
|
||||||
|
& @Merge ~ (e (f (i j)))
|
||||||
|
& @Merge ~ (m (p (q r)))
|
||||||
& @If ~ (c (k (s t)))
|
& @If ~ (c (k (s t)))
|
||||||
& @Cons ~ (d (j k))
|
& @Cons ~ (d (j k))
|
||||||
& @Merge ~ (e (f (i j)))
|
|
||||||
& @Cons ~ (g (h i))
|
& @Cons ~ (g (h i))
|
||||||
& @Cons ~ (l (r s))
|
& @Cons ~ (l (r s))
|
||||||
& @Merge ~ (m (p (q r)))
|
|
||||||
& @Cons ~ (n (o p))
|
& @Cons ~ (n (o p))
|
||||||
|
|
||||||
@Merge__C2 = (b (c (a ((@Merge__C1 (@Merge__C0 (a (b (c d))))) d))))
|
@Merge__C2 = (b (c (a ((@Merge__C1 (@Merge__C0 (a (b (c d))))) d))))
|
||||||
|
@ -5,8 +5,8 @@ input_file: tests/golden_tests/compile_file_o_all/list_reverse.hvm
|
|||||||
@concat = ((@concat__C0 ((a a) b)) b)
|
@concat = ((@concat__C0 ((a a) b)) b)
|
||||||
|
|
||||||
@concat__C0 = (a (b (c e)))
|
@concat__C0 = (a (b (c e)))
|
||||||
& @cons ~ (a (d e))
|
|
||||||
& @concat ~ (b (c d))
|
& @concat ~ (b (c d))
|
||||||
|
& @cons ~ (a (d e))
|
||||||
|
|
||||||
@cons = (a (b ((a (b c)) (* c))))
|
@cons = (a (b ((a (b c)) (* c))))
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ input_file: tests/golden_tests/mutual_recursion/len.hvm
|
|||||||
@Len = ((@Len__C0 (0 a)) a)
|
@Len = ((@Len__C0 (0 a)) a)
|
||||||
|
|
||||||
@Len__C0 = (* (a c))
|
@Len__C0 = (* (a c))
|
||||||
& $(b c) ~ [+1]
|
|
||||||
& @Len ~ (a b)
|
& @Len ~ (a b)
|
||||||
|
& $(b c) ~ [+1]
|
||||||
|
|
||||||
@List.cons = (a (b ((a (b c)) (* c))))
|
@List.cons = (a (b ((a (b c)) (* c))))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user