mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-07-14 15:10:25 +03:00
[sc-630] Rename the crate to bend and update docs for it
This commit is contained in:
parent
02e0c3ba26
commit
cf680f559d
38
Cargo.lock
generated
38
Cargo.lock
generated
@ -79,6 +79,25 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
@ -205,25 +224,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
|
@ -1,14 +1,14 @@
|
||||
[package]
|
||||
name = "hvm-lang"
|
||||
name = "bend"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
name = "hvml"
|
||||
name = "bend"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "hvml"
|
||||
name = "bend"
|
||||
path = "src/main.rs"
|
||||
required-features = ["cli"]
|
||||
|
||||
|
18
cspell.json
18
cspell.json
@ -19,6 +19,7 @@
|
||||
"Dall",
|
||||
"datatypes",
|
||||
"Deque",
|
||||
"destructures",
|
||||
"desugared",
|
||||
"desugars",
|
||||
"dref",
|
||||
@ -29,7 +30,6 @@
|
||||
"hexdigit",
|
||||
"hvm's",
|
||||
"hvmc",
|
||||
"hvml",
|
||||
"indexmap",
|
||||
"inet",
|
||||
"inets",
|
||||
@ -40,6 +40,7 @@
|
||||
"insta",
|
||||
"interner",
|
||||
"itertools",
|
||||
"ITRS",
|
||||
"kwargs",
|
||||
"lcons",
|
||||
"linearization",
|
||||
@ -58,10 +59,11 @@
|
||||
"opre",
|
||||
"oprune",
|
||||
"oref",
|
||||
"parallelizable",
|
||||
"peekable",
|
||||
"postcondition",
|
||||
"prec",
|
||||
"powi",
|
||||
"prec",
|
||||
"readback",
|
||||
"recursively",
|
||||
"redex",
|
||||
@ -77,6 +79,7 @@
|
||||
"scrutinee",
|
||||
"snil",
|
||||
"stdext",
|
||||
"struct",
|
||||
"subcmd",
|
||||
"submatch",
|
||||
"subpattern",
|
||||
@ -94,6 +97,13 @@
|
||||
"walkdir",
|
||||
"wopts"
|
||||
],
|
||||
"files": ["**/*.rs", "**/*.md"],
|
||||
"ignoreRegExpList": ["HexValues", "/λ/g", "/-O/g"]
|
||||
"files": [
|
||||
"**/*.rs",
|
||||
"**/*.md"
|
||||
],
|
||||
"ignoreRegExpList": [
|
||||
"HexValues",
|
||||
"/λ/g",
|
||||
"/-O/g"
|
||||
]
|
||||
}
|
||||
|
@ -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
|
@ -1,33 +1,41 @@
|
||||
# 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
|
||||
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:
|
||||
|
||||
```js
|
||||
main x1 x2 x3 = (MainBody x1 x2 x3)
|
||||
```py
|
||||
// Core syntax
|
||||
main(x1, x2, x3):
|
||||
MainBody(x1 x2 x3)
|
||||
|
||||
// Calling with `hvml run <file> arg1 arg2 arg3 argN`, it becomes:
|
||||
|
||||
main = (λx1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3 argN)
|
||||
// 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)
|
||||
```
|
||||
|
||||
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
|
||||
// Can receive 2 CLI arguments
|
||||
main x y = (+ x y)
|
||||
|
||||
// Can't receive CLI arguments
|
||||
main = λx λy (+ x y)
|
||||
// Expects 2 CLI arguments
|
||||
def main(x, y):
|
||||
{x - y, y - x}
|
||||
|
||||
// Calling with just one argument
|
||||
hvml run <path> 5
|
||||
λa (+ a 5)
|
||||
bend norm <path> +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}
|
||||
```
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
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`.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
- The `Number` node uses the label to store it's number.
|
||||
- An `Op2` 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.
|
||||
- An `Operation` node uses the label to store it's operation.
|
||||
|
||||
A duplication `dup a b = x` compiles into a Constructor node too, but with a different label.
|
||||
A superposition `{a b}` compiles to a Constructor 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.
|
||||
A duplication `let {a b} = x` compiles into a Duplicator node.
|
||||
A superposition `{a b}` compiles to a Duplicator node too. The difference here comes from context too.
|
||||
|
||||
```
|
||||
0 - Points to the sup occurrence 0 - Points to the duplicated value
|
||||
|
@ -17,7 +17,7 @@ main = (if true 42 37)
|
||||
// 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
|
||||
not = λboolean (boolean false true)
|
||||
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
|
||||
|
||||
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).
|
||||
```rs
|
||||
true = λt λf t
|
||||
false = λt λf f
|
||||
|
||||
not = λboolean (boolean false true)
|
||||
|
||||
fusing_not = λboolean λt λf (boolean f t)
|
||||
|
||||
// Creates a Church numeral out of a native number
|
||||
to_church n = switch n {
|
||||
0: λf λx x
|
||||
_: λf λx (f (to_church n-1 f x))
|
||||
}
|
||||
|
||||
main =
|
||||
let two = λf λx (f (f x))
|
||||
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?
|
||||
((to_church 0xFFFFFF) fusing_not) // try replacing this by regular not. Will it still work?
|
||||
```
|
||||
Here is the program's output:
|
||||
```bash
|
||||
$ hvml run -s fuse_magic.hvm
|
||||
λa λb λc (a b c)
|
||||
|
||||
RWTS : 15374
|
||||
- ANNI : 8193
|
||||
- COMM : 5116
|
||||
- ERAS : 521
|
||||
- DREF : 1031
|
||||
- OPER : 513
|
||||
TIME : 0.002 s
|
||||
RPS : 9.537 m
|
||||
$ bend norm -s fuse_magic.hvm
|
||||
Result: λa λb λc (a c b)
|
||||
- ITRS: 285212661
|
||||
- TIME: 5.67s
|
||||
- MIPS: 50.28
|
||||
```
|
||||
Only 15374 rewrites! Fusing is really powerful.
|
||||
A lot of rewrites, but most of those are just to create the church number.
|
||||
|
@ -1,11 +1,11 @@
|
||||
use clap::{Args, CommandFactory, Parser, Subcommand};
|
||||
use hvml::{
|
||||
use bend::{
|
||||
check_book, compile_book, desugar_book,
|
||||
diagnostics::{Diagnostics, DiagnosticsConfig, Severity},
|
||||
load_file_to_book, run_book,
|
||||
term::{Book, Name},
|
||||
CompileOpts, OptLevel, RunOpts,
|
||||
};
|
||||
use clap::{Args, CommandFactory, Parser, Subcommand};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
@ -80,8 +80,8 @@ enum Mode {
|
||||
#[arg(help = "Path to the input file")]
|
||||
path: PathBuf,
|
||||
|
||||
#[arg(value_parser = |arg: &str| hvml::term::parser::TermParser::new(arg).parse_term())]
|
||||
arguments: Option<Vec<hvml::term::Term>>,
|
||||
#[arg(value_parser = |arg: &str| bend::term::parser::TermParser::new(arg).parse_term())]
|
||||
arguments: Option<Vec<bend::term::Term>>,
|
||||
},
|
||||
/// Runs the lambda-term level desugaring passes.
|
||||
Desugar {
|
||||
|
@ -1,7 +1,7 @@
|
||||
pub mod hvmc_to_net;
|
||||
|
||||
use crate::term::Name;
|
||||
pub type HvmlLab = u16;
|
||||
pub type BendLab = u16;
|
||||
use NodeKind::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -41,13 +41,13 @@ pub enum NodeKind {
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum CtrKind {
|
||||
Con(Option<HvmlLab>),
|
||||
Tup(Option<HvmlLab>),
|
||||
Dup(HvmlLab),
|
||||
Con(Option<BendLab>),
|
||||
Tup(Option<BendLab>),
|
||||
Dup(BendLab),
|
||||
}
|
||||
|
||||
impl CtrKind {
|
||||
pub fn to_lab(self) -> HvmlLab {
|
||||
pub fn to_lab(self) -> BendLab {
|
||||
#[allow(clippy::identity_op)]
|
||||
match self {
|
||||
CtrKind::Con(None) => 0,
|
||||
|
@ -85,7 +85,7 @@ impl<'a> PyParser<'a> {
|
||||
} else if self.try_consume("False") {
|
||||
return Ok(Term::Num { val: 0 });
|
||||
}
|
||||
Term::Var { nam: self.parse_hvml_name()? }
|
||||
Term::Var { nam: self.parse_bend_name()? }
|
||||
}
|
||||
};
|
||||
Ok(res)
|
||||
@ -95,7 +95,7 @@ impl<'a> PyParser<'a> {
|
||||
self.consume("[")?;
|
||||
let head = self.parse_term_py()?;
|
||||
if self.try_consume_keyword("for") {
|
||||
let bind = self.parse_hvml_name()?;
|
||||
let bind = self.parse_bend_name()?;
|
||||
self.consume("in")?;
|
||||
let iter = self.parse_term_py()?;
|
||||
let mut cond = None;
|
||||
@ -116,7 +116,7 @@ impl<'a> PyParser<'a> {
|
||||
fn parse_term_py(&mut self) -> Result<Term, String> {
|
||||
self.skip_trivia();
|
||||
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()?;
|
||||
Ok(Term::Lam { names, bod: Box::new(bod) })
|
||||
} else {
|
||||
@ -254,7 +254,7 @@ impl<'a> PyParser<'a> {
|
||||
if self.starts_with("(") {
|
||||
self.parse_assignment_py(indent)
|
||||
} else {
|
||||
let name = self.parse_hvml_name()?;
|
||||
let name = self.parse_bend_name()?;
|
||||
if self.skip_starts_with("=") {
|
||||
// it's actually an assignment
|
||||
self.consume("=")?;
|
||||
@ -316,7 +316,7 @@ impl<'a> PyParser<'a> {
|
||||
fn parse_as_bind(&mut self) -> Result<Option<Name>, String> {
|
||||
let mut bind = None;
|
||||
if self.try_consume_keyword("as") {
|
||||
bind = Some(self.parse_hvml_name()?);
|
||||
bind = Some(self.parse_bend_name()?);
|
||||
}
|
||||
Ok(bind)
|
||||
}
|
||||
@ -343,7 +343,7 @@ impl<'a> PyParser<'a> {
|
||||
if p.try_consume("_") {
|
||||
Ok(None)
|
||||
} else {
|
||||
let nam = p.parse_hvml_name()?;
|
||||
let nam = p.parse_bend_name()?;
|
||||
Ok(Some(nam))
|
||||
}
|
||||
},
|
||||
@ -405,7 +405,7 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
|
||||
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 bind = self.parse_as_bind()?;
|
||||
self.consume(":")?;
|
||||
@ -422,7 +422,7 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
|
||||
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(":")?;
|
||||
|
||||
let mut block = Vec::new();
|
||||
@ -458,14 +458,14 @@ impl<'a> PyParser<'a> {
|
||||
|
||||
fn parse_assign_pattern_py(&mut self) -> Result<AssignPattern, String> {
|
||||
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 {
|
||||
Ok(AssignPattern::Var(std::mem::take(&mut binds[0])))
|
||||
} else {
|
||||
Ok(AssignPattern::Tup(binds))
|
||||
}
|
||||
} 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> {
|
||||
let name = self.parse_hvml_name()?;
|
||||
let params = self.list_like(|p| p.parse_hvml_name(), "(", ")", ",", true, 0)?;
|
||||
let name = self.parse_bend_name()?;
|
||||
let params = self.list_like(|p| p.parse_bend_name(), "(", ")", ",", true, 0)?;
|
||||
self.consume(":")?;
|
||||
indent.enter_level();
|
||||
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> {
|
||||
let name = self.parse_hvml_name()?;
|
||||
let name = self.parse_bend_name()?;
|
||||
let mut variants = Vec::new();
|
||||
self.consume(":")?;
|
||||
indent.enter_level();
|
||||
@ -499,10 +499,10 @@ impl<'a> PyParser<'a> {
|
||||
if !self.skip_exact_indent(indent, true)? {
|
||||
break;
|
||||
}
|
||||
let name = self.parse_hvml_name()?;
|
||||
let name = self.parse_bend_name()?;
|
||||
let mut fields = Vec::new();
|
||||
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 }));
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||
use highlight_error::highlight_error;
|
||||
use TSPL::Parser;
|
||||
|
||||
// hvml grammar description:
|
||||
// Bend grammar description:
|
||||
// <Book> ::= (<Data> | <Rule>)*
|
||||
// <Data> ::= "data" <Name> "=" ( <Name> | "(" <Name> (<Name>)* ")" )+
|
||||
// <Rule> ::= ("(" <Name> <Pattern>* ")" | <Name> <Pattern>*) "=" <Term>
|
||||
@ -95,7 +95,7 @@ impl<'a> TermParser<'a> {
|
||||
if self.try_consume("(") {
|
||||
// (name field*)
|
||||
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)?;
|
||||
Ok((name, fields))
|
||||
} else {
|
||||
@ -194,7 +194,7 @@ impl<'a> TermParser<'a> {
|
||||
if self.starts_with("$") {
|
||||
unexpected_tag(self)?;
|
||||
self.advance_one();
|
||||
let name = self.parse_hvml_name()?;
|
||||
let name = self.parse_bend_name()?;
|
||||
return Ok(Pattern::Chn(name));
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ impl<'a> TermParser<'a> {
|
||||
if self.starts_with("$") {
|
||||
self.consume("$")?;
|
||||
unexpected_tag(self)?;
|
||||
let nam = self.parse_hvml_name()?;
|
||||
let nam = self.parse_bend_name()?;
|
||||
return Ok(Term::Lnk { nam });
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ impl<'a> TermParser<'a> {
|
||||
// Use
|
||||
if self.try_consume_keyword("use") {
|
||||
unexpected_tag(self)?;
|
||||
let nam = self.parse_hvml_name()?;
|
||||
let nam = self.parse_bend_name()?;
|
||||
self.consume("=")?;
|
||||
let val = self.parse_term()?;
|
||||
self.try_consume(";");
|
||||
@ -421,7 +421,7 @@ impl<'a> TermParser<'a> {
|
||||
|
||||
// Var
|
||||
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 })
|
||||
})
|
||||
}
|
||||
@ -443,7 +443,7 @@ impl<'a> TermParser<'a> {
|
||||
|
||||
fn parse_top_level_name(&mut self) -> Result<Name, String> {
|
||||
let ini_idx = *self.index();
|
||||
let nam = self.parse_hvml_name()?;
|
||||
let nam = self.parse_bend_name()?;
|
||||
let end_idx = *self.index();
|
||||
if nam.contains("__") {
|
||||
let ctx = highlight_error(ini_idx, end_idx, self.input());
|
||||
@ -459,7 +459,7 @@ impl<'a> TermParser<'a> {
|
||||
if p.try_consume("*") {
|
||||
Ok(None)
|
||||
} else {
|
||||
let nam = p.parse_hvml_name()?;
|
||||
let nam = p.parse_bend_name()?;
|
||||
Ok(Some(nam))
|
||||
}
|
||||
},
|
||||
@ -477,9 +477,6 @@ impl<'a> TermParser<'a> {
|
||||
{
|
||||
let ctx = highlight_error(index, index + 1, self.input);
|
||||
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 {
|
||||
None
|
||||
};
|
||||
@ -496,13 +493,13 @@ impl<'a> TermParser<'a> {
|
||||
}
|
||||
|
||||
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 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("{") {
|
||||
self.try_consume(",");
|
||||
with.push(self.parse_hvml_name()?);
|
||||
with.push(self.parse_bend_name()?);
|
||||
}
|
||||
with
|
||||
} 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()?;
|
||||
Ok(Name::new(nam))
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ impl Ctx<'_> {
|
||||
/// ```hvm
|
||||
/// 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
|
||||
/// main = (λx1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3)
|
||||
/// ```
|
||||
|
@ -7,7 +7,7 @@ impl Book {
|
||||
/// Inline copies of the declared bind in the `use` expression.
|
||||
///
|
||||
/// Example:
|
||||
/// ```hvml
|
||||
/// ```bend
|
||||
/// use id = λx x
|
||||
/// (id id id)
|
||||
///
|
||||
|
@ -1,4 +1,4 @@
|
||||
use hvml::{
|
||||
use bend::{
|
||||
compile_book, desugar_book,
|
||||
diagnostics::{Diagnostics, DiagnosticsConfig, Severity},
|
||||
net::hvmc_to_net::hvmc_to_net,
|
||||
@ -107,7 +107,7 @@ fn compile_term() {
|
||||
|
||||
term.make_var_names_unique();
|
||||
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))
|
||||
})
|
||||
@ -369,7 +369,7 @@ fn cli() {
|
||||
let args = args_buf.lines();
|
||||
|
||||
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 =
|
||||
format!("{}{}", String::from_utf8_lossy(&output.stderr), String::from_utf8_lossy(&output.stdout));
|
||||
Ok(res)
|
||||
|
@ -6,6 +6,6 @@ error: unexpected argument '-d' found
|
||||
|
||||
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'.
|
||||
|
@ -6,6 +6,6 @@ error: unexpected argument '-d' found
|
||||
|
||||
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'.
|
||||
|
Loading…
Reference in New Issue
Block a user