mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-11-04 01:20:56 +03:00
configure ci (#204)
This commit is contained in:
parent
20b01400aa
commit
244acd19a2
67
.github/workflows/checks.yml
vendored
Normal file
67
.github/workflows/checks.yml
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
name: Checks
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
target
|
||||||
|
key: ${{ runner.os }}-check-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
- run: RUSTFLAGS="-D warnings" cargo check --all-targets
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
target
|
||||||
|
key: ${{ runner.os }}-test-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
- run: cargo test
|
||||||
|
clippy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
|
with:
|
||||||
|
components: clippy
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
target
|
||||||
|
key: ${{ runner.os }}-clippy-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
- run: cargo clippy
|
||||||
|
fmt:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
|
with:
|
||||||
|
components: rustfmt
|
||||||
|
- run: cargo fmt --check
|
||||||
|
cspell:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: streetsidesoftware/cspell-action@v5
|
||||||
|
with:
|
||||||
|
incremental_files_only: false
|
||||||
|
config: ./cspell.json
|
||||||
|
files: "**/*.rs **/*.md"
|
83
cspell.json
Normal file
83
cspell.json
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2",
|
||||||
|
"language": "en",
|
||||||
|
"words": [
|
||||||
|
"anni",
|
||||||
|
"annihilations",
|
||||||
|
"arities",
|
||||||
|
"arity",
|
||||||
|
"behaviour",
|
||||||
|
"bitand",
|
||||||
|
"builtins",
|
||||||
|
"callcc",
|
||||||
|
"chumsky",
|
||||||
|
"combinators",
|
||||||
|
"ctrs",
|
||||||
|
"datatypes",
|
||||||
|
"desugared",
|
||||||
|
"dref",
|
||||||
|
"dups",
|
||||||
|
"effectful",
|
||||||
|
"foldl",
|
||||||
|
"hasher",
|
||||||
|
"hvm's",
|
||||||
|
"hvmc",
|
||||||
|
"hvml",
|
||||||
|
"indexmap",
|
||||||
|
"inet",
|
||||||
|
"inets",
|
||||||
|
"inlineable",
|
||||||
|
"inlineables",
|
||||||
|
"inlines",
|
||||||
|
"inodes",
|
||||||
|
"insta",
|
||||||
|
"interner",
|
||||||
|
"itertools",
|
||||||
|
"lcons",
|
||||||
|
"linearizes",
|
||||||
|
"linearizing",
|
||||||
|
"lnet",
|
||||||
|
"lnil",
|
||||||
|
"mult",
|
||||||
|
"namegen",
|
||||||
|
"nams",
|
||||||
|
"numop",
|
||||||
|
"oper",
|
||||||
|
"opre",
|
||||||
|
"oprune",
|
||||||
|
"oref",
|
||||||
|
"postcondition",
|
||||||
|
"rdex",
|
||||||
|
"redex",
|
||||||
|
"redexes",
|
||||||
|
"readback",
|
||||||
|
"redexes",
|
||||||
|
"resugar",
|
||||||
|
"resugared",
|
||||||
|
"resugaring",
|
||||||
|
"rfold",
|
||||||
|
"rsplit",
|
||||||
|
"rwts",
|
||||||
|
"scons",
|
||||||
|
"scopeless",
|
||||||
|
"scrutinee",
|
||||||
|
"snil",
|
||||||
|
"stdext",
|
||||||
|
"subcmd",
|
||||||
|
"submatch",
|
||||||
|
"subpattern",
|
||||||
|
"subpatterns",
|
||||||
|
"subterm",
|
||||||
|
"subterms",
|
||||||
|
"succ",
|
||||||
|
"supercombinator",
|
||||||
|
"supercombinators",
|
||||||
|
"unbounds",
|
||||||
|
"vectorize",
|
||||||
|
"vectorizes",
|
||||||
|
"walkdir",
|
||||||
|
"wopts"
|
||||||
|
],
|
||||||
|
"files": ["**/*.rs", "**/*.md"],
|
||||||
|
"ignoreRegExpList": ["HexValues", "/λ/g", "/-O/g"]
|
||||||
|
}
|
@ -5,7 +5,7 @@ We have seen in [Dups and Sups](dups-and-sups.md) that duplications and superpos
|
|||||||
Tagged applications will only annihilate lambdas with the same tag.
|
Tagged applications will only annihilate lambdas with the same tag.
|
||||||
```rs
|
```rs
|
||||||
|
|
||||||
// V appllication's tag
|
// V application's tag
|
||||||
#A(#A λx(body) arg)
|
#A(#A λx(body) arg)
|
||||||
// ^ lambda's tag
|
// ^ lambda's tag
|
||||||
// The tag must go before the term.
|
// The tag must go before the term.
|
||||||
|
@ -32,7 +32,7 @@ A superposition `{a b}` compiles to a Constructor node too. The difference here
|
|||||||
Additionally, nodes have labels. We use the label to store data in the node's memory, which can be used for various purposes.
|
Additionally, nodes have labels. We use the label to store data in the node's memory, which can be used for various purposes.
|
||||||
|
|
||||||
```
|
```
|
||||||
0 - Points to the sup occurence 0 - Points to the duplicated value
|
0 - Points to the sup occurrence 0 - Points to the duplicated value
|
||||||
| |
|
| |
|
||||||
# Superposition # Duplication
|
# Superposition # Duplication
|
||||||
/ \ / \
|
/ \ / \
|
||||||
|
@ -15,7 +15,7 @@ data Option = (Some val) | None
|
|||||||
|
|
||||||
If the data type has a single constructor, it can be destructured using `let`:
|
If the data type has a single constructor, it can be destructured using `let`:
|
||||||
```rs
|
```rs
|
||||||
// A Box is a wrapper around a valuee.
|
// A Box is a wrapper around a value.
|
||||||
data Boxed = (Box val)
|
data Boxed = (Box val)
|
||||||
|
|
||||||
let (Box value) = boxed; value
|
let (Box value) = boxed; value
|
||||||
|
@ -56,7 +56,7 @@ enum Mode {
|
|||||||
#[arg(short = 'm', long = "mem", help = "How much memory to allocate for the runtime", default_value = "1G", value_parser = mem_parser)]
|
#[arg(short = 'm', long = "mem", help = "How much memory to allocate for the runtime", default_value = "1G", value_parser = mem_parser)]
|
||||||
max_mem: u64,
|
max_mem: u64,
|
||||||
|
|
||||||
#[arg(short = 'r', long = "rwts", help = "Maximium amount of rewrites", value_parser = mem_parser)]
|
#[arg(short = 'r', long = "rwts", help = "Maximum amount of rewrites", value_parser = mem_parser)]
|
||||||
max_rwts: Option<u64>,
|
max_rwts: Option<u64>,
|
||||||
|
|
||||||
#[arg(short = 'd', help = "Debug mode (print each reduction step)")]
|
#[arg(short = 'd', help = "Debug mode (print each reduction step)")]
|
||||||
@ -195,7 +195,7 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Info> {
|
|||||||
Mode::Desugar { path, comp_opts } => {
|
Mode::Desugar { path, comp_opts } => {
|
||||||
let opts = OptArgs::opts_from_cli(&comp_opts);
|
let opts = OptArgs::opts_from_cli(&comp_opts);
|
||||||
let mut book = load_book(&path)?;
|
let mut book = load_book(&path)?;
|
||||||
// TODO: Shoudn't the desugar have `warn_opts` too? maybe WarningOpts::allow_all() by default
|
// TODO: Shouldn't the desugar have `warn_opts` too? maybe WarningOpts::allow_all() by default
|
||||||
let _warns = desugar_book(&mut book, opts)?;
|
let _warns = desugar_book(&mut book, opts)?;
|
||||||
println!("{}", book);
|
println!("{}", book);
|
||||||
}
|
}
|
||||||
@ -264,9 +264,9 @@ impl CliWarnOpts {
|
|||||||
let matches = cmd.get_matches();
|
let matches = cmd.get_matches();
|
||||||
|
|
||||||
let subcmd_name = matches.subcommand_name().expect("To have a subcommand");
|
let subcmd_name = matches.subcommand_name().expect("To have a subcommand");
|
||||||
let argm = matches.subcommand_matches(subcmd_name).expect("To have a subcommand");
|
let arg_matches = matches.subcommand_matches(subcmd_name).expect("To have a subcommand");
|
||||||
|
|
||||||
if let Some(wopts_id_seq) = argm.get_many::<clap::Id>("CliWarnOpts") {
|
if let Some(wopts_id_seq) = arg_matches.get_many::<clap::Id>("CliWarnOpts") {
|
||||||
let allows = &mut self.allows.into_iter();
|
let allows = &mut self.allows.into_iter();
|
||||||
let denies = &mut self.denies.into_iter();
|
let denies = &mut self.denies.into_iter();
|
||||||
let warns = &mut self.warns.into_iter();
|
let warns = &mut self.warns.into_iter();
|
||||||
|
@ -16,7 +16,7 @@ pub fn nets_to_hvmc(nets: HashMap<String, INet>) -> Result<Book, String> {
|
|||||||
|
|
||||||
/// Convert an inet-encoded definition into an hvmc AST inet.
|
/// Convert an inet-encoded definition into an hvmc AST inet.
|
||||||
pub fn net_to_hvmc(inet: &INet) -> Result<Net, String> {
|
pub fn net_to_hvmc(inet: &INet) -> Result<Net, String> {
|
||||||
let (net_root, redxs) = get_tree_roots(inet)?;
|
let (net_root, redexes) = get_tree_roots(inet)?;
|
||||||
let mut port_to_var_id: HashMap<Port, VarId> = HashMap::new();
|
let mut port_to_var_id: HashMap<Port, VarId> = HashMap::new();
|
||||||
let root = if let Some(net_root) = net_root {
|
let root = if let Some(net_root) = net_root {
|
||||||
// If there is a root tree connected to the root node
|
// If there is a root tree connected to the root node
|
||||||
@ -27,7 +27,7 @@ pub fn net_to_hvmc(inet: &INet) -> Result<Net, String> {
|
|||||||
Tree::Var { nam: num_to_name(0) }
|
Tree::Var { nam: num_to_name(0) }
|
||||||
};
|
};
|
||||||
let mut rdex = vec![];
|
let mut rdex = vec![];
|
||||||
for [root0, root1] in redxs {
|
for [root0, root1] in redexes {
|
||||||
let rdex0 = net_tree_to_hvmc_tree(inet, root0, &mut port_to_var_id);
|
let rdex0 = net_tree_to_hvmc_tree(inet, root0, &mut port_to_var_id);
|
||||||
let rdex1 = net_tree_to_hvmc_tree(inet, root1, &mut port_to_var_id);
|
let rdex1 = net_tree_to_hvmc_tree(inet, root1, &mut port_to_var_id);
|
||||||
rdex.push((rdex0, rdex1));
|
rdex.push((rdex0, rdex1));
|
||||||
@ -99,7 +99,7 @@ type VarId = NodeId;
|
|||||||
/// Returns them as the root of the root tree and the active pairs of the net.
|
/// Returns them as the root of the root tree and the active pairs of the net.
|
||||||
/// Active pairs are found by a right-to-left, depth-first search.
|
/// Active pairs are found by a right-to-left, depth-first search.
|
||||||
fn get_tree_roots(inet: &INet) -> Result<(Option<NodeId>, Vec<[NodeId; 2]>), String> {
|
fn get_tree_roots(inet: &INet) -> Result<(Option<NodeId>, Vec<[NodeId; 2]>), String> {
|
||||||
let mut redx_roots: Vec<[NodeId; 2]> = vec![];
|
let mut redex_roots: Vec<[NodeId; 2]> = vec![];
|
||||||
let mut movements: Vec<Movement> = vec![];
|
let mut movements: Vec<Movement> = vec![];
|
||||||
let mut root_set = HashSet::from([ROOT.node()]);
|
let mut root_set = HashSet::from([ROOT.node()]);
|
||||||
let mut explored_nodes = vec![false; inet.nodes.len()];
|
let mut explored_nodes = vec![false; inet.nodes.len()];
|
||||||
@ -124,12 +124,12 @@ fn get_tree_roots(inet: &INet) -> Result<(Option<NodeId>, Vec<[NodeId; 2]>), Str
|
|||||||
match movement {
|
match movement {
|
||||||
Movement::Down(node_id) => explore_down_link(inet, node_id, &mut explored_nodes, &mut movements),
|
Movement::Down(node_id) => explore_down_link(inet, node_id, &mut explored_nodes, &mut movements),
|
||||||
Movement::Side(node_id) => {
|
Movement::Side(node_id) => {
|
||||||
explore_side_link(inet, node_id, &mut movements, &mut redx_roots, &mut root_set)?;
|
explore_side_link(inet, node_id, &mut movements, &mut redex_roots, &mut root_set)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((root_tree_root, redx_roots))
|
Ok((root_tree_root, redex_roots))
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Movement {
|
enum Movement {
|
||||||
@ -164,7 +164,7 @@ fn explore_side_link(
|
|||||||
inet: &INet,
|
inet: &INet,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
movements: &mut Vec<Movement>,
|
movements: &mut Vec<Movement>,
|
||||||
redx_roots: &mut Vec<[NodeId; 2]>,
|
redex_roots: &mut Vec<[NodeId; 2]>,
|
||||||
root_set: &mut HashSet<NodeId>,
|
root_set: &mut HashSet<NodeId>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let new_roots = go_up_tree(inet, node_id)?;
|
let new_roots = go_up_tree(inet, node_id)?;
|
||||||
@ -172,7 +172,7 @@ fn explore_side_link(
|
|||||||
if !root_set.contains(&new_roots[0]) && !root_set.contains(&new_roots[1]) {
|
if !root_set.contains(&new_roots[0]) && !root_set.contains(&new_roots[1]) {
|
||||||
movements.push(Movement::Down(new_roots[0]));
|
movements.push(Movement::Down(new_roots[0]));
|
||||||
movements.push(Movement::Down(new_roots[1]));
|
movements.push(Movement::Down(new_roots[1]));
|
||||||
redx_roots.push(new_roots);
|
redex_roots.push(new_roots);
|
||||||
root_set.insert(new_roots[0]);
|
root_set.insert(new_roots[0]);
|
||||||
root_set.insert(new_roots[1]);
|
root_set.insert(new_roots[1]);
|
||||||
}
|
}
|
||||||
@ -183,18 +183,18 @@ fn explore_side_link(
|
|||||||
/// Returns the active pair at the root of this tree.
|
/// Returns the active pair at the root of this tree.
|
||||||
fn go_up_tree(inet: &INet, start_node: NodeId) -> Result<[NodeId; 2], String> {
|
fn go_up_tree(inet: &INet, start_node: NodeId) -> Result<[NodeId; 2], String> {
|
||||||
let mut explored_nodes = HashSet::new();
|
let mut explored_nodes = HashSet::new();
|
||||||
let mut crnt_node = start_node;
|
let mut cur_node = start_node;
|
||||||
loop {
|
loop {
|
||||||
if !explored_nodes.insert(crnt_node) {
|
if !explored_nodes.insert(cur_node) {
|
||||||
return Err("Found term that compiles into an inet with a vicious cycle".to_string());
|
return Err("Found term that compiles into an inet with a vicious cycle".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let up = inet.enter_port(Port(crnt_node, 0));
|
let up = inet.enter_port(Port(cur_node, 0));
|
||||||
|
|
||||||
if up.slot() == 0 || up == ROOT {
|
if up.slot() == 0 || up == ROOT {
|
||||||
return Ok([up.node(), crnt_node]);
|
return Ok([up.node(), cur_node]);
|
||||||
}
|
}
|
||||||
|
|
||||||
crnt_node = up.node();
|
cur_node = up.node();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,8 +156,8 @@ impl<'a> EncodeTermState<'a> {
|
|||||||
"Unbound variable {nam}. Expected this check to be already done"
|
"Unbound variable {nam}. Expected this check to be already done"
|
||||||
);
|
);
|
||||||
let var_stack = &self.scope[nam];
|
let var_stack = &self.scope[nam];
|
||||||
let crnt_var = *var_stack.last().unwrap();
|
let cur_var = *var_stack.last().unwrap();
|
||||||
let (declare_port, use_port) = self.vars.get_mut(crnt_var).unwrap();
|
let (declare_port, use_port) = self.vars.get_mut(cur_var).unwrap();
|
||||||
debug_assert!(use_port.is_none(), "Variable {nam} used more than once");
|
debug_assert!(use_port.is_none(), "Variable {nam} used more than once");
|
||||||
self.inet.link(up, *declare_port);
|
self.inet.link(up, *declare_port);
|
||||||
*use_port = Some(up);
|
*use_port = Some(up);
|
||||||
|
@ -260,7 +260,7 @@ fn switch_rule_submatch(
|
|||||||
let args = new_args.clone().chain(old_args).collect::<Vec<_>>();
|
let args = new_args.clone().chain(old_args).collect::<Vec<_>>();
|
||||||
|
|
||||||
// Make the match cases of the nested submatch, filtering out the rules
|
// Make the match cases of the nested submatch, filtering out the rules
|
||||||
// that don't match the crnt ctr.
|
// that don't match the current ctr.
|
||||||
let rules =
|
let rules =
|
||||||
rules.iter().filter_map(|rule| switch_rule_submatch_arm(rule, ctr, nested_fields)).collect::<Vec<_>>();
|
rules.iter().filter_map(|rule| switch_rule_submatch_arm(rule, ctr, nested_fields)).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user