[sc-630] Rename the crate to bend and update docs for it

This commit is contained in:
Nicolas Abril 2024-05-06 21:14:23 +02:00
parent 02e0c3ba26
commit cf680f559d
16 changed files with 122 additions and 173 deletions

38
Cargo.lock generated
View File

@ -79,6 +79,25 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "bend"
version = "0.1.0"
dependencies = [
"TSPL 0.0.9 (git+https://github.com/developedby/TSPL.git?branch=fix-hvml-bugs)",
"clap",
"highlight_error",
"hvm-core",
"indexmap",
"insta",
"interner",
"itertools",
"loaned",
"parking_lot",
"stacker",
"stdext",
"walkdir",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.5.0" version = "2.5.0"
@ -205,25 +224,6 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "hvm-lang"
version = "0.1.0"
dependencies = [
"TSPL 0.0.9 (git+https://github.com/developedby/TSPL.git?branch=fix-hvml-bugs)",
"clap",
"highlight_error",
"hvm-core",
"indexmap",
"insta",
"interner",
"itertools",
"loaned",
"parking_lot",
"stacker",
"stdext",
"walkdir",
]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.2.6" version = "2.2.6"

View File

@ -1,14 +1,14 @@
[package] [package]
name = "hvm-lang" name = "bend"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[lib] [lib]
name = "hvml" name = "bend"
path = "src/lib.rs" path = "src/lib.rs"
[[bin]] [[bin]]
name = "hvml" name = "bend"
path = "src/main.rs" path = "src/main.rs"
required-features = ["cli"] required-features = ["cli"]

View File

@ -19,6 +19,7 @@
"Dall", "Dall",
"datatypes", "datatypes",
"Deque", "Deque",
"destructures",
"desugared", "desugared",
"desugars", "desugars",
"dref", "dref",
@ -29,7 +30,6 @@
"hexdigit", "hexdigit",
"hvm's", "hvm's",
"hvmc", "hvmc",
"hvml",
"indexmap", "indexmap",
"inet", "inet",
"inets", "inets",
@ -40,6 +40,7 @@
"insta", "insta",
"interner", "interner",
"itertools", "itertools",
"ITRS",
"kwargs", "kwargs",
"lcons", "lcons",
"linearization", "linearization",
@ -58,10 +59,11 @@
"opre", "opre",
"oprune", "oprune",
"oref", "oref",
"parallelizable",
"peekable", "peekable",
"postcondition", "postcondition",
"prec",
"powi", "powi",
"prec",
"readback", "readback",
"recursively", "recursively",
"redex", "redex",
@ -77,6 +79,7 @@
"scrutinee", "scrutinee",
"snil", "snil",
"stdext", "stdext",
"struct",
"subcmd", "subcmd",
"submatch", "submatch",
"subpattern", "subpattern",
@ -94,6 +97,13 @@
"walkdir", "walkdir",
"wopts" "wopts"
], ],
"files": ["**/*.rs", "**/*.md"], "files": [
"ignoreRegExpList": ["HexValues", "/λ/g", "/-O/g"] "**/*.rs",
"**/*.md"
],
"ignoreRegExpList": [
"HexValues",
"/λ/g",
"/-O/g"
]
} }

View File

@ -1,59 +0,0 @@
# Automatic vectorization with tagged lambdas
We have seen in [Dups and Sups](dups-and-sups.md) that duplications and superpositions can have labels. In HVM, lambdas and applications can have labels too.
Tagged applications will only annihilate lambdas with the same tag.
```rs
// V application's tag
#A(#A λx(body) arg)
// ^ lambda's tag
// The tag must go before the term.
// This reduces to
x = arg; body
```
For example, data types can be encoded as tagged lambdas:
```rs
// data Bool = T | F
T = #Bool λt #Bool λf t
F = #Bool λt #Bool λf f
// data List = (Cons x xs) | Nil
Cons = λx λxs #List λc #List λn #List.Cons.xs(#List.Cons.x(c x) xs)
Nil = #List λc #List λn n
```
When encoding the pattern matching, the application can then use the same label:
```rs
// not = λbool match bool { T: (F) F: (T) }
not = λbool #Bool(bool F T)
```
In fact, `match` is syntax sugar for a tagged application like the one above. This means that it is not possible to match without using tagged applications.
When an application and a lambda with different tags interact, the application "commutes" through the lambda instead of beta-reducing it. Here is how it works, roughly:
```rs
#A (#B λx (b x) a)
// Reduces to
#B λc #A((b #A λ$d c) #B(a $d))
```
This reduction can be hard to grasp, but an accurate way to understand it is that "the application goes through the lambda".
This allows, in some limited scenarios, automatic vectorization. See "limitations" for a description of the limitations.
```rs
// vectorizes to: (Cons F (Cons T (Cons F Nil)))
main = (not (Cons T (Cons F (Cons T Nil))))
```
This works because the `Bool`-tagged application in `not` passes through the `List`-tagged lambdas in `Cons` until it gets to `T` and `F`.
The tagged lambda and applications are compiled to `inet` nodes with different tag values for each data type. This allows them to commute, read [HVM-Core](https://github.com/HigherOrderCO/hvm-core/tree/main#language) to learn more about it.
### Limitations
To be able to vectorize as described here:
- The function must not be recursive
- There must not be labels in common between the function and what you want to vectorize over

View File

@ -1,33 +1,41 @@
# CLI arguments # CLI arguments
It's possible to pass arguments to a program executed with `hvml run`: It's possible to pass arguments to a program executed with `bend run` or `bend norm`:
```sh ```sh
hvml run <Path to program> [Arguments in expression form]... bend run <Path to program> [Arguments in expression form]...
``` ```
It accepts any expression that would also be valid inside an hvm-lang function. It accepts any expression that would also be valid inside a bend function.
Arguments are passed to programs by applying them to the entrypoint function: Arguments are passed to programs by applying them to the entrypoint function:
```js ```py
main x1 x2 x3 = (MainBody x1 x2 x3) // Core syntax
main(x1, x2, x3):
MainBody(x1 x2 x3)
// Calling with `hvml run <file> arg1 arg2 arg3 argN`, it becomes: // Calling with `bend run <file> arg1 arg2 arg3 argN`, it becomes (in core syntax):
main = (x1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3 argN)
main = (λx1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3 argN)
``` ```
There are no restrictions on the number of arguments passed to the program. There are no restrictions on the number of arguments passed to the program.
You can even pass more arguments than the function expects, although that can lead to unexpected results.
```rust ```rust
// Can receive 2 CLI arguments // Expects 2 CLI arguments
main x y = (+ x y) def main(x, y):
{x - y, y - x}
// Can't receive CLI arguments
main = λx λy (+ x y)
// Calling with just one argument // Calling with just one argument
hvml run <path> 5 bend norm <path> +5
λa (+ a 5) λa {(- a 5) (- a +5)}
// Calling with two argument
bend norm <path> +5 +3
{+2 -2}
// Calling with three argument
// In this case, the third argument doesn't do anything due to the underlying interaction rules.
bend norm <path> +5 +3 +1
{+2 -2}
``` ```

View File

@ -2,10 +2,10 @@
How are terms compiled to interaction net nodes? How are terms compiled to interaction net nodes?
HVM-Core has a bunch of useful nodes to write IC programs. HVM has a bunch of useful nodes to write IC programs.
Every node contains one `main` port `0` and two `auxiliary` ports, `1` and `2`. Every node contains one `main` port `0` and two `auxiliary` ports, `1` and `2`.
There are 6 kinds of nodes, Eraser, Constructor, Reference, Number, Operation and Match. There are 7 kinds of nodes, Eraser, Constructor, Duplicator, Reference, Number, Operation and Match.
A lambda `λx x` compiles into a Constructor node. A lambda `λx x` compiles into a Constructor node.
An application `((λx x) (λx x))` also compiles into a Constructor node. An application `((λx x) (λx x))` also compiles into a Constructor node.
@ -23,13 +23,10 @@ Points to the lambda variable Points to the argument
When reading back, if we visit a Constructor via port 0 then we know it's a lambda, and if we visit it via port 2 it's an application. When reading back, if we visit a Constructor via port 0 then we know it's a lambda, and if we visit it via port 2 it's an application.
- The `Number` node uses the label to store it's number. - The `Number` node uses the label to store it's number.
- An `Op2` node uses the label to store it's operation. - An `Operation` node uses the label to store it's operation.
- And a `Constructor` node can have a label too! This is used for `dup` and [lambda tags](automatic-vectorization-with-tagged-lambdas.md.
A duplication `dup a b = x` compiles into a Constructor node too, but with a different label. A duplication `let {a b} = x` compiles into a Duplicator node.
A superposition `{a b}` compiles to a Constructor node too. The difference here comes from context too. A superposition `{a b}` compiles to a Duplicator node too. The difference here comes from context too.
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 occurrence 0 - Points to the duplicated value 0 - Points to the sup occurrence 0 - Points to the duplicated value

View File

@ -17,7 +17,7 @@ main = (if true 42 37)
// so (true 42 37) will do the same thing. // so (true 42 37) will do the same thing.
``` ```
This is how a`Not` function that acts on this encoding can be defined This is how a `Not` function that acts on this encoding can be defined
```rs ```rs
not = λboolean (boolean false true) not = λboolean (boolean false true)
main = (not true) // Outputs λtλf f. main = (not true) // Outputs λtλf f.
@ -120,37 +120,33 @@ Broadly speaking, a good rule of thumb in HVM is **push linear lambdas to the to
## Example ## Example
To show the power of fusing, here is a program that self-composes `fusing_not` 2^512 times and prints the result. `2^512` is larger than amount of atoms in the observable universe, and yet HVM is still able to work with it due to its optimal sharing capabilities. To show the power of fusing, here is a program that self-composes `fusing_not` 2^24 times and prints the result.
Currently hvm is not able to handle operations between church numbers so we explicitly convert the native number to a church number in this example (which is very slow).
This program uses [native numbers, which are described here](native-numbers.md). This program uses [native numbers, which are described here](native-numbers.md).
```rs ```rs
true = λt λf t true = λt λf t
false = λt λf f false = λt λf f
not = λboolean (boolean false true) not = λboolean (boolean false true)
fusing_not = λboolean λt λf (boolean f t) fusing_not = λboolean λt λf (boolean f t)
// Creates a Church numeral out of a native number // Creates a Church numeral out of a native number
to_church n = switch n { to_church n = switch n {
0: λf λx x 0: λf λx x
_: λf λx (f (to_church n-1 f x)) _: λf λx (f (to_church n-1 f x))
} }
main = main =
let two = λf λx (f (f x)) ((to_church 0xFFFFFF) fusing_not) // try replacing this by regular not. Will it still work?
let two_pow_512 = ((to_church 512) two) // Composition of church-encoded numbers is equivalent to exponentiation.
// Self-composes `not` 2^512 times and prints the result.
(two_pow_512 fusing_not) // try replacing this by regular not. Will it still work?
``` ```
Here is the program's output: Here is the program's output:
```bash ```bash
$ hvml run -s fuse_magic.hvm $ bend norm -s fuse_magic.hvm
λa λb λc (a b c) Result: λa λb λc (a c b)
- ITRS: 285212661
RWTS : 15374 - TIME: 5.67s
- ANNI : 8193 - MIPS: 50.28
- COMM : 5116
- ERAS : 521
- DREF : 1031
- OPER : 513
TIME : 0.002 s
RPS : 9.537 m
``` ```
Only 15374 rewrites! Fusing is really powerful. A lot of rewrites, but most of those are just to create the church number.

View File

@ -1,11 +1,11 @@
use clap::{Args, CommandFactory, Parser, Subcommand}; use bend::{
use hvml::{
check_book, compile_book, desugar_book, check_book, compile_book, desugar_book,
diagnostics::{Diagnostics, DiagnosticsConfig, Severity}, diagnostics::{Diagnostics, DiagnosticsConfig, Severity},
load_file_to_book, run_book, load_file_to_book, run_book,
term::{Book, Name}, term::{Book, Name},
CompileOpts, OptLevel, RunOpts, CompileOpts, OptLevel, RunOpts,
}; };
use clap::{Args, CommandFactory, Parser, Subcommand};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@ -80,8 +80,8 @@ enum Mode {
#[arg(help = "Path to the input file")] #[arg(help = "Path to the input file")]
path: PathBuf, path: PathBuf,
#[arg(value_parser = |arg: &str| hvml::term::parser::TermParser::new(arg).parse_term())] #[arg(value_parser = |arg: &str| bend::term::parser::TermParser::new(arg).parse_term())]
arguments: Option<Vec<hvml::term::Term>>, arguments: Option<Vec<bend::term::Term>>,
}, },
/// Runs the lambda-term level desugaring passes. /// Runs the lambda-term level desugaring passes.
Desugar { Desugar {

View File

@ -1,7 +1,7 @@
pub mod hvmc_to_net; pub mod hvmc_to_net;
use crate::term::Name; use crate::term::Name;
pub type HvmlLab = u16; pub type BendLab = u16;
use NodeKind::*; use NodeKind::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -41,13 +41,13 @@ pub enum NodeKind {
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CtrKind { pub enum CtrKind {
Con(Option<HvmlLab>), Con(Option<BendLab>),
Tup(Option<HvmlLab>), Tup(Option<BendLab>),
Dup(HvmlLab), Dup(BendLab),
} }
impl CtrKind { impl CtrKind {
pub fn to_lab(self) -> HvmlLab { pub fn to_lab(self) -> BendLab {
#[allow(clippy::identity_op)] #[allow(clippy::identity_op)]
match self { match self {
CtrKind::Con(None) => 0, CtrKind::Con(None) => 0,

View File

@ -85,7 +85,7 @@ impl<'a> PyParser<'a> {
} else if self.try_consume("False") { } else if self.try_consume("False") {
return Ok(Term::Num { val: 0 }); return Ok(Term::Num { val: 0 });
} }
Term::Var { nam: self.parse_hvml_name()? } Term::Var { nam: self.parse_bend_name()? }
} }
}; };
Ok(res) Ok(res)
@ -95,7 +95,7 @@ impl<'a> PyParser<'a> {
self.consume("[")?; self.consume("[")?;
let head = self.parse_term_py()?; let head = self.parse_term_py()?;
if self.try_consume_keyword("for") { if self.try_consume_keyword("for") {
let bind = self.parse_hvml_name()?; let bind = self.parse_bend_name()?;
self.consume("in")?; self.consume("in")?;
let iter = self.parse_term_py()?; let iter = self.parse_term_py()?;
let mut cond = None; let mut cond = None;
@ -116,7 +116,7 @@ impl<'a> PyParser<'a> {
fn parse_term_py(&mut self) -> Result<Term, String> { fn parse_term_py(&mut self) -> Result<Term, String> {
self.skip_trivia(); self.skip_trivia();
if self.try_consume_keyword("lambda") { if self.try_consume_keyword("lambda") {
let names = self.list_like(|p| p.parse_hvml_name(), "", ":", ",", true, 1)?; let names = self.list_like(|p| p.parse_bend_name(), "", ":", ",", true, 1)?;
let bod = self.parse_term_py()?; let bod = self.parse_term_py()?;
Ok(Term::Lam { names, bod: Box::new(bod) }) Ok(Term::Lam { names, bod: Box::new(bod) })
} else { } else {
@ -254,7 +254,7 @@ impl<'a> PyParser<'a> {
if self.starts_with("(") { if self.starts_with("(") {
self.parse_assignment_py(indent) self.parse_assignment_py(indent)
} else { } else {
let name = self.parse_hvml_name()?; let name = self.parse_bend_name()?;
if self.skip_starts_with("=") { if self.skip_starts_with("=") {
// it's actually an assignment // it's actually an assignment
self.consume("=")?; self.consume("=")?;
@ -316,7 +316,7 @@ impl<'a> PyParser<'a> {
fn parse_as_bind(&mut self) -> Result<Option<Name>, String> { fn parse_as_bind(&mut self) -> Result<Option<Name>, String> {
let mut bind = None; let mut bind = None;
if self.try_consume_keyword("as") { if self.try_consume_keyword("as") {
bind = Some(self.parse_hvml_name()?); bind = Some(self.parse_bend_name()?);
} }
Ok(bind) Ok(bind)
} }
@ -343,7 +343,7 @@ impl<'a> PyParser<'a> {
if p.try_consume("_") { if p.try_consume("_") {
Ok(None) Ok(None)
} else { } else {
let nam = p.parse_hvml_name()?; let nam = p.parse_bend_name()?;
Ok(Some(nam)) Ok(Some(nam))
} }
}, },
@ -405,7 +405,7 @@ impl<'a> PyParser<'a> {
} }
fn parse_fold_py(&mut self, indent: &mut Indent) -> Result<Stmt, String> { fn parse_fold_py(&mut self, indent: &mut Indent) -> Result<Stmt, String> {
let fun = self.parse_hvml_name()?; let fun = self.parse_bend_name()?;
let arg = self.parse_term_py()?; let arg = self.parse_term_py()?;
let bind = self.parse_as_bind()?; let bind = self.parse_as_bind()?;
self.consume(":")?; self.consume(":")?;
@ -422,7 +422,7 @@ impl<'a> PyParser<'a> {
} }
fn parse_do_py(&mut self, indent: &mut Indent) -> Result<Stmt, String> { fn parse_do_py(&mut self, indent: &mut Indent) -> Result<Stmt, String> {
let fun = self.parse_hvml_name()?; let fun = self.parse_bend_name()?;
self.consume(":")?; self.consume(":")?;
let mut block = Vec::new(); let mut block = Vec::new();
@ -458,14 +458,14 @@ impl<'a> PyParser<'a> {
fn parse_assign_pattern_py(&mut self) -> Result<AssignPattern, String> { fn parse_assign_pattern_py(&mut self) -> Result<AssignPattern, String> {
if self.skip_starts_with("(") { if self.skip_starts_with("(") {
let mut binds = self.list_like(|p| p.parse_hvml_name(), "(", ")", ",", true, 1)?; let mut binds = self.list_like(|p| p.parse_bend_name(), "(", ")", ",", true, 1)?;
if binds.len() == 1 { if binds.len() == 1 {
Ok(AssignPattern::Var(std::mem::take(&mut binds[0]))) Ok(AssignPattern::Var(std::mem::take(&mut binds[0])))
} else { } else {
Ok(AssignPattern::Tup(binds)) Ok(AssignPattern::Tup(binds))
} }
} else { } else {
self.parse_hvml_name().map(AssignPattern::Var) self.parse_bend_name().map(AssignPattern::Var)
} }
} }
@ -481,8 +481,8 @@ impl<'a> PyParser<'a> {
} }
fn parse_def_py(&mut self, indent: &mut Indent) -> Result<Definition, String> { fn parse_def_py(&mut self, indent: &mut Indent) -> Result<Definition, String> {
let name = self.parse_hvml_name()?; let name = self.parse_bend_name()?;
let params = self.list_like(|p| p.parse_hvml_name(), "(", ")", ",", true, 0)?; let params = self.list_like(|p| p.parse_bend_name(), "(", ")", ",", true, 0)?;
self.consume(":")?; self.consume(":")?;
indent.enter_level(); indent.enter_level();
let body = self.parse_stmt_py(indent)?; let body = self.parse_stmt_py(indent)?;
@ -491,7 +491,7 @@ impl<'a> PyParser<'a> {
} }
fn parse_enum_py(&mut self, indent: &mut Indent) -> Result<Enum, String> { fn parse_enum_py(&mut self, indent: &mut Indent) -> Result<Enum, String> {
let name = self.parse_hvml_name()?; let name = self.parse_bend_name()?;
let mut variants = Vec::new(); let mut variants = Vec::new();
self.consume(":")?; self.consume(":")?;
indent.enter_level(); indent.enter_level();
@ -499,10 +499,10 @@ impl<'a> PyParser<'a> {
if !self.skip_exact_indent(indent, true)? { if !self.skip_exact_indent(indent, true)? {
break; break;
} }
let name = self.parse_hvml_name()?; let name = self.parse_bend_name()?;
let mut fields = Vec::new(); let mut fields = Vec::new();
if self.skip_starts_with("(") { if self.skip_starts_with("(") {
fields = self.list_like(|p| p.parse_hvml_name(), "(", ")", ",", true, 0)?; fields = self.list_like(|p| p.parse_bend_name(), "(", ")", ",", true, 0)?;
} }
variants.push((name.clone(), Variant { name, fields })); variants.push((name.clone(), Variant { name, fields }));
} }

View File

@ -8,7 +8,7 @@ use crate::{
use highlight_error::highlight_error; use highlight_error::highlight_error;
use TSPL::Parser; use TSPL::Parser;
// hvml grammar description: // Bend grammar description:
// <Book> ::= (<Data> | <Rule>)* // <Book> ::= (<Data> | <Rule>)*
// <Data> ::= "data" <Name> "=" ( <Name> | "(" <Name> (<Name>)* ")" )+ // <Data> ::= "data" <Name> "=" ( <Name> | "(" <Name> (<Name>)* ")" )+
// <Rule> ::= ("(" <Name> <Pattern>* ")" | <Name> <Pattern>*) "=" <Term> // <Rule> ::= ("(" <Name> <Pattern>* ")" | <Name> <Pattern>*) "=" <Term>
@ -95,7 +95,7 @@ impl<'a> TermParser<'a> {
if self.try_consume("(") { if self.try_consume("(") {
// (name field*) // (name field*)
let name = self.parse_top_level_name()?; let name = self.parse_top_level_name()?;
let field_parser = |p: &mut Self| p.labelled(|p| p.parse_hvml_name(), "datatype constructor field"); let field_parser = |p: &mut Self| p.labelled(|p| p.parse_bend_name(), "datatype constructor field");
let fields = self.list_like(field_parser, "", ")", "", false, 0)?; let fields = self.list_like(field_parser, "", ")", "", false, 0)?;
Ok((name, fields)) Ok((name, fields))
} else { } else {
@ -194,7 +194,7 @@ impl<'a> TermParser<'a> {
if self.starts_with("$") { if self.starts_with("$") {
unexpected_tag(self)?; unexpected_tag(self)?;
self.advance_one(); self.advance_one();
let name = self.parse_hvml_name()?; let name = self.parse_bend_name()?;
return Ok(Pattern::Chn(name)); return Ok(Pattern::Chn(name));
} }
@ -286,7 +286,7 @@ impl<'a> TermParser<'a> {
if self.starts_with("$") { if self.starts_with("$") {
self.consume("$")?; self.consume("$")?;
unexpected_tag(self)?; unexpected_tag(self)?;
let nam = self.parse_hvml_name()?; let nam = self.parse_bend_name()?;
return Ok(Term::Lnk { nam }); return Ok(Term::Lnk { nam });
} }
@ -376,7 +376,7 @@ impl<'a> TermParser<'a> {
// Use // Use
if self.try_consume_keyword("use") { if self.try_consume_keyword("use") {
unexpected_tag(self)?; unexpected_tag(self)?;
let nam = self.parse_hvml_name()?; let nam = self.parse_bend_name()?;
self.consume("=")?; self.consume("=")?;
let val = self.parse_term()?; let val = self.parse_term()?;
self.try_consume(";"); self.try_consume(";");
@ -421,7 +421,7 @@ impl<'a> TermParser<'a> {
// Var // Var
unexpected_tag(self)?; unexpected_tag(self)?;
let nam = self.labelled(|p| p.parse_hvml_name(), "term")?; let nam = self.labelled(|p| p.parse_bend_name(), "term")?;
Ok(Term::Var { nam }) Ok(Term::Var { nam })
}) })
} }
@ -443,7 +443,7 @@ impl<'a> TermParser<'a> {
fn parse_top_level_name(&mut self) -> Result<Name, String> { fn parse_top_level_name(&mut self) -> Result<Name, String> {
let ini_idx = *self.index(); let ini_idx = *self.index();
let nam = self.parse_hvml_name()?; let nam = self.parse_bend_name()?;
let end_idx = *self.index(); let end_idx = *self.index();
if nam.contains("__") { if nam.contains("__") {
let ctx = highlight_error(ini_idx, end_idx, self.input()); let ctx = highlight_error(ini_idx, end_idx, self.input());
@ -459,7 +459,7 @@ impl<'a> TermParser<'a> {
if p.try_consume("*") { if p.try_consume("*") {
Ok(None) Ok(None)
} else { } else {
let nam = p.parse_hvml_name()?; let nam = p.parse_bend_name()?;
Ok(Some(nam)) Ok(Some(nam))
} }
}, },
@ -477,9 +477,6 @@ impl<'a> TermParser<'a> {
{ {
let ctx = highlight_error(index, index + 1, self.input); let ctx = highlight_error(index, index + 1, self.input);
return Err(format!("Tagged terms not supported for hvm32.\n{ctx}")); return Err(format!("Tagged terms not supported for hvm32.\n{ctx}"));
/* self.advance_one();
let nam = self.labelled(|p| p.parse_hvml_name(), "tag name")?;
Some(Tag::Named(nam)) */
} else { } else {
None None
}; };
@ -496,13 +493,13 @@ impl<'a> TermParser<'a> {
} }
fn parse_match_arg(&mut self) -> Result<(Name, Term, Vec<Name>), String> { fn parse_match_arg(&mut self) -> Result<(Name, Term, Vec<Name>), String> {
let bnd = self.parse_hvml_name()?; let bnd = self.parse_bend_name()?;
let arg = if self.try_consume("=") { self.parse_term()? } else { Term::Var { nam: bnd.clone() } }; let arg = if self.try_consume("=") { self.parse_term()? } else { Term::Var { nam: bnd.clone() } };
let with = if self.try_consume_keyword("with") { let with = if self.try_consume_keyword("with") {
let mut with = vec![self.parse_hvml_name()?]; let mut with = vec![self.parse_bend_name()?];
while !self.skip_starts_with("{") { while !self.skip_starts_with("{") {
self.try_consume(","); self.try_consume(",");
with.push(self.parse_hvml_name()?); with.push(self.parse_bend_name()?);
} }
with with
} else { } else {
@ -755,7 +752,7 @@ pub trait ParserCommons<'a>: Parser<'a> {
} }
} }
fn parse_hvml_name(&mut self) -> Result<Name, String> { fn parse_bend_name(&mut self) -> Result<Name, String> {
let nam = self.parse_name()?; let nam = self.parse_name()?;
Ok(Name::new(nam)) Ok(Name::new(nam))
} }

View File

@ -10,7 +10,7 @@ impl Ctx<'_> {
/// ```hvm /// ```hvm
/// main x1 x2 x3 = (MainBody x1 x2 x3) /// main x1 x2 x3 = (MainBody x1 x2 x3)
/// ``` /// ```
/// Calling with `hvml run <file> arg1 arg2 arg3`, it becomes: /// Calling with `bend run <file> arg1 arg2 arg3`, it becomes:
/// ```hvm /// ```hvm
/// main = (λx1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3) /// main = (λx1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3)
/// ``` /// ```

View File

@ -7,7 +7,7 @@ impl Book {
/// Inline copies of the declared bind in the `use` expression. /// Inline copies of the declared bind in the `use` expression.
/// ///
/// Example: /// Example:
/// ```hvml /// ```bend
/// use id = λx x /// use id = λx x
/// (id id id) /// (id id id)
/// ///

View File

@ -1,4 +1,4 @@
use hvml::{ use bend::{
compile_book, desugar_book, compile_book, desugar_book,
diagnostics::{Diagnostics, DiagnosticsConfig, Severity}, diagnostics::{Diagnostics, DiagnosticsConfig, Severity},
net::hvmc_to_net::hvmc_to_net, net::hvmc_to_net::hvmc_to_net,
@ -107,7 +107,7 @@ fn compile_term() {
term.make_var_names_unique(); term.make_var_names_unique();
term.linearize_vars(); term.linearize_vars();
let net = hvml::term::term_to_net(&term, &mut Default::default()).map_err(|e| e.to_string())?; let net = bend::term::term_to_net(&term, &mut Default::default()).map_err(|e| e.to_string())?;
Ok(format!("{}", net)) Ok(format!("{}", net))
}) })
@ -369,7 +369,7 @@ fn cli() {
let args = args_buf.lines(); let args = args_buf.lines();
let output = let output =
std::process::Command::new(env!("CARGO_BIN_EXE_hvml")).args(args).output().expect("Run command"); std::process::Command::new(env!("CARGO_BIN_EXE_bend")).args(args).output().expect("Run command");
let res = let res =
format!("{}{}", String::from_utf8_lossy(&output.stderr), String::from_utf8_lossy(&output.stdout)); format!("{}{}", String::from_utf8_lossy(&output.stderr), String::from_utf8_lossy(&output.stdout));
Ok(res) Ok(res)

View File

@ -6,6 +6,6 @@ error: unexpected argument '-d' found
tip: to pass '-d' as a value, use '-- -d' tip: to pass '-d' as a value, use '-- -d'
Usage: hvml run [OPTIONS] <PATH> [ARGUMENTS]... Usage: bend run [OPTIONS] <PATH> [ARGUMENTS]...
For more information, try '--help'. For more information, try '--help'.

View File

@ -6,6 +6,6 @@ error: unexpected argument '-d' found
tip: to pass '-d' as a value, use '-- -d' tip: to pass '-d' as a value, use '-- -d'
Usage: hvml run [OPTIONS] <PATH> [ARGUMENTS]... Usage: bend run [OPTIONS] <PATH> [ARGUMENTS]...
For more information, try '--help'. For more information, try '--help'.