mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-10-26 05:50:18 +03:00
Merge pull request #303 from HigherOrderCO/feature/sc-678/add-run-c-and-run-cuda-commands-to-bend
[sc-678] Add run-c and run-cuda commands to bend
This commit is contained in:
commit
a0c1ea4bd5
57
README.md
57
README.md
@ -1,6 +1,6 @@
|
||||
# Bend
|
||||
|
||||
*Note: The latest version of Bend targets an unreleased version of HVM. If you want to use Bend right now, use branch [hvm-core](https://github.com/HigherOrderCO/bend/tree/hvm-core)*.
|
||||
_Note: The latest version of Bend targets an unreleased version of HVM. If you want to use Bend right now, use branch [hvm-core](https://github.com/HigherOrderCO/bend/tree/hvm-core)_.
|
||||
|
||||
Bend is a programming language that can run massively parallel programs on the GPU or the CPU using the power of interaction nets and the [HVM](https://github.com/HigherOrderCO/hvm).
|
||||
With Bend, you can write programs for the GPU as easily as you'd write a normal program in your favorite language.
|
||||
@ -9,10 +9,10 @@ It is based on the [Interaction-Calculus](https://github.com/VictorTaelin/Intera
|
||||
|
||||
Currently Bend only supports strict/eager evaluation. If you need lazy, optimal evaluation, we recommend using [HVM1](https://github.com/HigherOrderCO/HVM1) for now.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
With the nightly version of rust installed, clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/HigherOrderCO/bend.git
|
||||
|
||||
@ -20,32 +20,37 @@ cd bend
|
||||
```
|
||||
|
||||
Install using cargo:
|
||||
|
||||
```bash
|
||||
cargo install --path . --locked
|
||||
```
|
||||
|
||||
If you want to run programs directly from Bend, you also need to have [HVM](https://github.com/HigherOrderCO/hvm2) installed.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Command | Usage | Description
|
||||
--------- | --------------------- | ---
|
||||
Check | `bend check <file>` | Checks if a program is valid
|
||||
Compile | `bend compile <file>` | Compiles a program to HVM and outputs it to stdout
|
||||
Run | `bend run <file>` | Compiles and then runs a program in HVM
|
||||
Normalize | `bend norm <file>` | Compiles and then normalizes a program in HVM, outputting the result to stdout
|
||||
Desugar | `bend desugar <file>` | Desugars a program to the core syntax and outputs it to stdout
|
||||
| Command | Usage | Description |
|
||||
| ------- | --------------------- | ----------------------------------------------------------------- |
|
||||
| Check | `bend check <file>` | Checks if a program is valid |
|
||||
| GenHvm | `bend gen-hvm <file>` | Compiles a program to HVM and outputs it to stdout |
|
||||
| Run | `bend run <file>` | Compiles and then runs a program with the Rust HVM implementation |
|
||||
| Run-C | `bend run-c <file>` | Compiles and then runs a program with the C HVM implementation |
|
||||
| Run-Cu | `bend run-cu <file>` | Compiles and then runs a program with the Cuda HVM implementation |
|
||||
| Gen-C | `bend gen-c <file>` | Compiles the program to standalone C |
|
||||
| Gen-Cu | `bend gen-cu <file>` | Compiles the program to standalone Cuda |
|
||||
| Desugar | `bend desugar <file>` | Desugars a program to the core syntax and outputs it to stdout |
|
||||
|
||||
If your program uses IO, it should return an IO value and you need to run it with --io. See [using io](docs/using-io.md), for more details.
|
||||
If your program doesn't return an IO value, then you should not run it with --io
|
||||
|
||||
If you want to compile a file to a file, just redirect the output with `>`:
|
||||
|
||||
```bash
|
||||
bend compile <file.bend> > <file.hvm>
|
||||
```
|
||||
|
||||
There are many compiler options that can be passed through the CLI. You can see the list of options [here](docs/compiler-options.md).
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
Bend offers two flavors of syntax, a user-friendly python-like syntax (the default) and the core ML/Haskell-like syntax that's used internally by the compiler.
|
||||
@ -53,19 +58,20 @@ You can read the full reference for both of them [here](docs/syntax.md), but the
|
||||
|
||||
To see some more complex examples programs, check out the [examples](examples/) folder.
|
||||
|
||||
|
||||
We can start with a basic program that adds the numbers 3 and 2.
|
||||
|
||||
```py
|
||||
def main:
|
||||
return 2 + 3
|
||||
```
|
||||
|
||||
Normalizing this program will show the number 5.
|
||||
Be careful with `run` and `norm`, since they will not show any warnings by default. Before running a new program it's useful to first `check` it.
|
||||
|
||||
Bend programs consist of a series of function definitions, always starting with a function called `main` or `Main`.
|
||||
|
||||
Functions can receive arguments both directly and using a lambda abstraction.
|
||||
|
||||
```py
|
||||
// These two are equivalent
|
||||
def add(x, y):
|
||||
@ -76,6 +82,7 @@ def add2:
|
||||
```
|
||||
|
||||
You can then call this function like this:
|
||||
|
||||
```py
|
||||
def main:
|
||||
sum = add(2, 3)
|
||||
@ -83,6 +90,7 @@ def main:
|
||||
```
|
||||
|
||||
You can bundle multiple values into a single value using a tuple or a struct.
|
||||
|
||||
```py
|
||||
// With a tuple
|
||||
def Tuple.fst(x):
|
||||
@ -105,6 +113,7 @@ def Pair.fst_2(x: Pair):
|
||||
```
|
||||
|
||||
For more complicated data structures, we can use `enum` to define a algebraic data types.
|
||||
|
||||
```py
|
||||
enum MyTree:
|
||||
Node(val, ~left, ~right)
|
||||
@ -112,6 +121,7 @@ enum MyTree:
|
||||
```
|
||||
|
||||
We can then pattern match on the enum to perform different actions depending on the variant of the value.
|
||||
|
||||
```py
|
||||
def Maybe.or_default(x, default):
|
||||
match x:
|
||||
@ -124,6 +134,7 @@ def Maybe.or_default(x, default):
|
||||
|
||||
We use `~` to indicate that a field is recursive.
|
||||
This allows us to easily create and consume these recursive data structures with `bend` and `fold`:
|
||||
|
||||
```py
|
||||
def MyTree.sum(x):
|
||||
// Sum all the values in the tree.
|
||||
@ -146,6 +157,7 @@ def main:
|
||||
```
|
||||
|
||||
These are equivalent to inline recursive functions that create a tree and consume it.
|
||||
|
||||
```py
|
||||
def MyTree.sum(x):
|
||||
match x:
|
||||
@ -163,10 +175,12 @@ def main_bend(val):
|
||||
def main:
|
||||
return main_bend(0)
|
||||
```
|
||||
|
||||
Making your program around trees is a very good way of making it parallelizable, since each core can be dispatched to work on a different branch of the tree.
|
||||
|
||||
*Attention*: Note that despite the ADT syntax sugars, Bend is an *untyped* language and the compiler will not stop you from using values incorrectly, which can lead to very unexpected results.
|
||||
_Attention_: Note that despite the ADT syntax sugars, Bend is an _untyped_ language and the compiler will not stop you from using values incorrectly, which can lead to very unexpected results.
|
||||
For example, the following program will compile just fine even though `!=` is only defined for native numbers:
|
||||
|
||||
```py
|
||||
def main:
|
||||
bend val = [0, 1, 2, 3] while val != []:
|
||||
@ -179,6 +193,7 @@ def main:
|
||||
x = 0
|
||||
return x
|
||||
```
|
||||
|
||||
Normalizing this program will show `λ* *` and not the expected `6`.
|
||||
|
||||
It's also important to note that Bend is linear (technically affine), meaning that every variable is only used once. When a variable is used more than once, the compiler will automatically insert a duplication.
|
||||
@ -187,6 +202,7 @@ You can read more about it in [Dups and sups](docs/dups-and-sups.md) and learn h
|
||||
|
||||
To use a variable twice without duplicating it, you can use a `use` statement.
|
||||
It inlines clones of some value in the statements that follow it.
|
||||
|
||||
```py
|
||||
def foo(x):
|
||||
use result = bar(1, x)
|
||||
@ -196,10 +212,11 @@ def foo(x):
|
||||
def foo(x):
|
||||
return (bar(1, x), bar(1, x))
|
||||
```
|
||||
|
||||
Note that any variable in the `use` will end up being duplicated.
|
||||
|
||||
|
||||
Bend supports recursive functions of unrestricted depth:
|
||||
|
||||
```py
|
||||
def native_num_to_adt(n):
|
||||
if n == 0:
|
||||
@ -207,12 +224,13 @@ def native_num_to_adt(n):
|
||||
else:
|
||||
return Nat.succ(native_num_to_adt(n - 1))
|
||||
```
|
||||
|
||||
If your recursive function is not based on pattern matching syntax (like `if`, `match`, `fold`, etc) you have to be careful to avoid an infinite loop.
|
||||
Since Bend is eagerly executed, some situations will cause function applications to always be expanded, which can lead to looping situations.
|
||||
You can read how to avoid this in [Lazy definitions](docs/lazy-definitions.md).
|
||||
|
||||
|
||||
Bend has native numbers and operations.
|
||||
|
||||
```py
|
||||
def main:
|
||||
a = 1 // A 24 bit unsigned integer.
|
||||
@ -224,6 +242,7 @@ def main:
|
||||
```
|
||||
|
||||
`switch` pattern matches on unsigned native numbers:
|
||||
|
||||
```py
|
||||
switch x = 4:
|
||||
// From '0' to n, ending with the default case '_'.
|
||||
@ -237,19 +256,22 @@ switch x = 4:
|
||||
```
|
||||
|
||||
Bend has Lists and Strings, which support Unicode characters.
|
||||
|
||||
```rs
|
||||
def main:
|
||||
return ["You: Hello, 🌎", "🌎: Hello, user"]
|
||||
```
|
||||
|
||||
A string is desugared to a String data type containing two constructors, `String.cons` and `String.nil`.
|
||||
List also becomes a type with two constructors, `List.cons` and `List.nil`.
|
||||
|
||||
```rs
|
||||
// These two are equivalent
|
||||
def StrEx:
|
||||
"Hello"
|
||||
|
||||
def ids:
|
||||
[1, 2, 3]
|
||||
[1, 2, 3]
|
||||
|
||||
// These types are builtin.
|
||||
enum String:
|
||||
@ -265,6 +287,7 @@ def ids:
|
||||
```
|
||||
|
||||
Characters are delimited by `'` `'` and support Unicode escape sequences. They are encoded as a U24 with the unicode codepoint as their value.
|
||||
|
||||
```
|
||||
// These two are equivalent
|
||||
def chars:
|
||||
@ -274,10 +297,10 @@ def chars2:
|
||||
[65, 0x4242, 0x1F30E]
|
||||
```
|
||||
|
||||
|
||||
### More features
|
||||
|
||||
Key:
|
||||
|
||||
- 📗: Basic resources
|
||||
- 📙: Intermediate resources
|
||||
- 📕: Advanced resources
|
||||
|
39
src/lib.rs
39
src/lib.rs
@ -144,13 +144,15 @@ pub fn desugar_book(
|
||||
if !ctx.info.has_errors() { Ok(ctx.info) } else { Err(ctx.info) }
|
||||
}
|
||||
|
||||
pub fn run_book(
|
||||
pub fn run_book_with_fn(
|
||||
mut book: Book,
|
||||
run_opts: RunOpts,
|
||||
compile_opts: CompileOpts,
|
||||
diagnostics_cfg: DiagnosticsConfig,
|
||||
args: Option<Vec<Term>>,
|
||||
) -> Result<(Term, String, Diagnostics), Diagnostics> {
|
||||
cmd: &str,
|
||||
arg_io: bool,
|
||||
) -> Result<Option<(Term, String, Diagnostics)>, Diagnostics> {
|
||||
let CompileResult { core_book, labels, diagnostics } =
|
||||
compile_book(&mut book, compile_opts.clone(), diagnostics_cfg, args)?;
|
||||
|
||||
@ -161,16 +163,27 @@ pub fn run_book(
|
||||
|
||||
let out_path = ".out.hvm";
|
||||
std::fs::write(out_path, core_book.to_string()).map_err(|x| x.to_string())?;
|
||||
let Output { status, stdout, stderr } = std::process::Command::new("hvm")
|
||||
.arg("run")
|
||||
.arg(out_path)
|
||||
.output()
|
||||
.map_err(|x| format!("While running hvm: {x}"))?;
|
||||
let run_fn = |out_path: &str| {
|
||||
let mut process = std::process::Command::new("hvm");
|
||||
process.arg(cmd).arg(out_path);
|
||||
if arg_io {
|
||||
process.arg("--io");
|
||||
process.stdout(std::process::Stdio::inherit());
|
||||
process.spawn()?.wait_with_output()
|
||||
} else {
|
||||
process.output()
|
||||
}
|
||||
};
|
||||
let Output { status, stdout, stderr } = run_fn(out_path).map_err(|e| format!("While running hvm: {e}"))?;
|
||||
|
||||
let out = String::from_utf8_lossy(&stdout);
|
||||
let err = String::from_utf8_lossy(&stderr);
|
||||
let status = if !status.success() { status.to_string() } else { String::new() };
|
||||
|
||||
if arg_io {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let Some((_, result)) = out.split_once("Result: ") else {
|
||||
return Err(format!("Error reading result from hvm. Output :\n{}{}{}", err, status, out).into());
|
||||
};
|
||||
@ -182,7 +195,17 @@ pub fn run_book(
|
||||
};
|
||||
|
||||
let (term, diags) = readback_hvm_net(&net, &book, &labels, run_opts.linear_readback);
|
||||
Ok((term, stats.to_string(), diags))
|
||||
Ok(Some((term, stats.to_string(), diags)))
|
||||
}
|
||||
|
||||
pub fn run_book(
|
||||
book: Book,
|
||||
run_opts: RunOpts,
|
||||
compile_opts: CompileOpts,
|
||||
diagnostics_cfg: DiagnosticsConfig,
|
||||
args: Option<Vec<Term>>,
|
||||
) -> Result<(Term, String, Diagnostics), Diagnostics> {
|
||||
run_book_with_fn(book, run_opts, compile_opts, diagnostics_cfg, args, "run", false).map(Option::unwrap)
|
||||
}
|
||||
|
||||
pub fn readback_hvm_net(net: &Net, book: &Book, labels: &Labels, linear: bool) -> (Term, Diagnostics) {
|
||||
|
185
src/main.rs
185
src/main.rs
@ -2,7 +2,7 @@ use bend::{
|
||||
check_book, compile_book, desugar_book,
|
||||
diagnostics::{Diagnostics, DiagnosticsConfig, Severity},
|
||||
fun::{Book, Name},
|
||||
load_file_to_book, run_book, CompileOpts, OptLevel, RunOpts,
|
||||
load_file_to_book, run_book_with_fn, CompileOpts, OptLevel, RunOpts,
|
||||
};
|
||||
use clap::{Args, CommandFactory, Parser, Subcommand};
|
||||
use std::path::{Path, PathBuf};
|
||||
@ -39,49 +39,18 @@ enum Mode {
|
||||
#[arg(help = "Path to the input file")]
|
||||
path: PathBuf,
|
||||
},
|
||||
/// Compiles the program and runs it with the Rust HVM implementation.
|
||||
Run(RunArgs),
|
||||
/// Compiles the program and runs it with the C HVM implementation.
|
||||
RunC(RunArgs),
|
||||
/// Compiles the program and runs it with the Cuda HVM implementation.
|
||||
RunCu(RunArgs),
|
||||
/// Compiles the program to hvmc and prints to stdout.
|
||||
Compile {
|
||||
#[arg(
|
||||
short = 'O',
|
||||
value_delimiter = ' ',
|
||||
action = clap::ArgAction::Append,
|
||||
long_help = r#"Enables or disables the given optimizations
|
||||
float_combinators is enabled by default on strict mode."#,
|
||||
)]
|
||||
comp_opts: Vec<OptArgs>,
|
||||
|
||||
#[command(flatten)]
|
||||
warn_opts: CliWarnOpts,
|
||||
|
||||
#[arg(help = "Path to the input file")]
|
||||
path: PathBuf,
|
||||
},
|
||||
/// Compiles the program and runs it with the hvm.
|
||||
Run {
|
||||
#[arg(short = 'p', help = "Debug and normalization pretty printing")]
|
||||
pretty: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
run_opts: RunArgs,
|
||||
|
||||
#[arg(
|
||||
short = 'O',
|
||||
value_delimiter = ' ',
|
||||
action = clap::ArgAction::Append,
|
||||
long_help = r#"Enables or disables the given optimizations
|
||||
float_combinators is enabled by default on strict mode."#,
|
||||
)]
|
||||
comp_opts: Vec<OptArgs>,
|
||||
|
||||
#[command(flatten)]
|
||||
warn_opts: CliWarnOpts,
|
||||
|
||||
#[arg(help = "Path to the input file")]
|
||||
path: PathBuf,
|
||||
|
||||
#[arg(value_parser = |arg: &str| bend::fun::parser::TermParser::new(arg).parse_term())]
|
||||
arguments: Option<Vec<bend::fun::Term>>,
|
||||
},
|
||||
GenHvm(GenArgs),
|
||||
/// Compiles the program to standalone C and prints to stdout.
|
||||
GenC(GenArgs),
|
||||
/// Compiles the program to standalone Cuda and prints to stdout.
|
||||
GenCu(GenArgs),
|
||||
/// Runs the lambda-term level desugaring passes.
|
||||
Desugar {
|
||||
#[arg(
|
||||
@ -106,6 +75,57 @@ enum Mode {
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
struct RunArgs {
|
||||
#[arg(short = 'p', help = "Debug and normalization pretty printing")]
|
||||
pretty: bool,
|
||||
|
||||
#[arg(long, help = "Run with IO enabled")]
|
||||
io: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
run_opts: CliRunOpts,
|
||||
|
||||
#[arg(
|
||||
short = 'O',
|
||||
value_delimiter = ' ',
|
||||
action = clap::ArgAction::Append,
|
||||
long_help = r#"Enables or disables the given optimizations
|
||||
float_combinators is enabled by default on strict mode."#,
|
||||
)]
|
||||
comp_opts: Vec<OptArgs>,
|
||||
|
||||
#[command(flatten)]
|
||||
warn_opts: CliWarnOpts,
|
||||
|
||||
#[arg(help = "Path to the input file")]
|
||||
path: PathBuf,
|
||||
|
||||
#[arg(value_parser = |arg: &str| bend::fun::parser::TermParser::new(arg).parse_term())]
|
||||
arguments: Option<Vec<bend::fun::Term>>,
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
struct GenArgs {
|
||||
#[arg(
|
||||
short = 'O',
|
||||
value_delimiter = ' ',
|
||||
action = clap::ArgAction::Append,
|
||||
long_help = r#"Enables or disables the given optimizations
|
||||
float_combinators is enabled by default on strict mode."#,
|
||||
)]
|
||||
comp_opts: Vec<OptArgs>,
|
||||
|
||||
#[arg(long, help = "Generate with IO enabled")]
|
||||
io: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
warn_opts: CliWarnOpts,
|
||||
|
||||
#[arg(help = "Path to the input file")]
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
struct CliRunOpts {
|
||||
#[arg(short = 'l', help = "Linear readback (show explicit dups)")]
|
||||
linear: bool,
|
||||
|
||||
@ -228,6 +248,18 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Diagnostics> {
|
||||
Ok(book)
|
||||
};
|
||||
|
||||
let (gen_cmd, gen_supports_io) = match &cli.mode {
|
||||
Mode::GenC(..) => ("gen-c", true),
|
||||
Mode::GenCu(..) => ("gen-cu", false),
|
||||
_ => ("gen", false),
|
||||
};
|
||||
|
||||
let (run_cmd, run_supports_io) = match &cli.mode {
|
||||
Mode::RunC(..) => ("run-c", true),
|
||||
Mode::RunCu(..) => ("run-cu", false),
|
||||
_ => ("run", false),
|
||||
};
|
||||
|
||||
match cli.mode {
|
||||
Mode::Check { comp_opts, warn_opts, path } => {
|
||||
let diagnostics_cfg = set_warning_cfg_from_cli(DiagnosticsConfig::default(), warn_opts);
|
||||
@ -238,7 +270,7 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Diagnostics> {
|
||||
eprintln!("{}", diagnostics);
|
||||
}
|
||||
|
||||
Mode::Compile { path, comp_opts, warn_opts } => {
|
||||
Mode::GenHvm(GenArgs { comp_opts, warn_opts, path, .. }) => {
|
||||
let diagnostics_cfg = set_warning_cfg_from_cli(DiagnosticsConfig::default(), warn_opts);
|
||||
let opts = compile_opts_from_cli(&comp_opts);
|
||||
|
||||
@ -249,6 +281,39 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Diagnostics> {
|
||||
println!("{}", compile_res.core_book);
|
||||
}
|
||||
|
||||
Mode::GenC(GenArgs { comp_opts, io, warn_opts, path })
|
||||
| Mode::GenCu(GenArgs { comp_opts, io, warn_opts, path }) => {
|
||||
if io && !gen_supports_io {
|
||||
Err("Selected mode does not support io.".to_string())?;
|
||||
}
|
||||
let diagnostics_cfg = set_warning_cfg_from_cli(DiagnosticsConfig::default(), warn_opts);
|
||||
let opts = compile_opts_from_cli(&comp_opts);
|
||||
|
||||
let mut book = load_book(&path)?;
|
||||
let compile_res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
||||
|
||||
let out_path = ".out.hvm";
|
||||
std::fs::write(out_path, compile_res.core_book.to_string()).map_err(|x| x.to_string())?;
|
||||
|
||||
let gen_fn = |out_path: &str| {
|
||||
let mut process = std::process::Command::new("hvm");
|
||||
process.arg(gen_cmd).arg(out_path);
|
||||
if io {
|
||||
process.arg("--io");
|
||||
}
|
||||
process.output().map_err(|e| format!("While running hvm: {e}"))
|
||||
};
|
||||
|
||||
let std::process::Output { stdout, stderr, status } = gen_fn(out_path)?;
|
||||
let out = String::from_utf8_lossy(&stdout);
|
||||
let err = String::from_utf8_lossy(&stderr);
|
||||
let status = if !status.success() { status.to_string() } else { String::new() };
|
||||
|
||||
eprintln!("{err}");
|
||||
println!("{out}");
|
||||
println!("{status}");
|
||||
}
|
||||
|
||||
Mode::Desugar { path, comp_opts, warn_opts, pretty } => {
|
||||
let diagnostics_cfg = set_warning_cfg_from_cli(DiagnosticsConfig::default(), warn_opts);
|
||||
|
||||
@ -265,8 +330,14 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Diagnostics> {
|
||||
}
|
||||
}
|
||||
|
||||
Mode::Run { run_opts, pretty, comp_opts, warn_opts, arguments, path } => {
|
||||
let RunArgs { linear, print_stats } = run_opts;
|
||||
Mode::Run(RunArgs { pretty, io, run_opts, comp_opts, warn_opts, path, arguments })
|
||||
| Mode::RunC(RunArgs { pretty, io, run_opts, comp_opts, warn_opts, path, arguments })
|
||||
| Mode::RunCu(RunArgs { pretty, io, run_opts, comp_opts, warn_opts, path, arguments }) => {
|
||||
let CliRunOpts { linear, print_stats } = run_opts;
|
||||
|
||||
if io && !run_supports_io {
|
||||
Err("Selected mode does not support io.".to_string())?;
|
||||
}
|
||||
|
||||
let diagnostics_cfg =
|
||||
set_warning_cfg_from_cli(DiagnosticsConfig::new(Severity::Allow, arg_verbose), warn_opts);
|
||||
@ -278,16 +349,18 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Diagnostics> {
|
||||
let run_opts = RunOpts { linear_readback: linear, pretty };
|
||||
|
||||
let book = load_book(&path)?;
|
||||
let (term, stats, diags) = run_book(book, run_opts, compile_opts, diagnostics_cfg, arguments)?;
|
||||
|
||||
eprint!("{diags}");
|
||||
if pretty {
|
||||
println!("Result:\n{}", term.display_pretty(0));
|
||||
} else {
|
||||
println!("Result: {}", term);
|
||||
}
|
||||
if print_stats {
|
||||
println!("{stats}");
|
||||
if let Some((term, stats, diags)) =
|
||||
run_book_with_fn(book, run_opts, compile_opts, diagnostics_cfg, arguments, run_cmd, io)?
|
||||
{
|
||||
eprint!("{diags}");
|
||||
if pretty {
|
||||
println!("Result:\n{}", term.display_pretty(0));
|
||||
} else {
|
||||
println!("Result: {}", term);
|
||||
}
|
||||
if print_stats {
|
||||
println!("{stats}");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,3 +1,3 @@
|
||||
compile
|
||||
gen-hvm
|
||||
tests/golden_tests/cli/compile_all.hvm
|
||||
-Oall
|
||||
|
@ -1,3 +1,3 @@
|
||||
compile
|
||||
gen-hvm
|
||||
tests/golden_tests/cli/compile_inline.hvm
|
||||
-Oinline
|
||||
|
@ -1,4 +1,4 @@
|
||||
compile
|
||||
gen-hvm
|
||||
tests/golden_tests/cli/compile_no_opts.hvm
|
||||
-Ono-all
|
||||
-Ono-eta
|
||||
|
@ -1,3 +1,3 @@
|
||||
compile
|
||||
gen-hvm
|
||||
tests/golden_tests/cli/compile_pre_reduce.hvm
|
||||
-Opre-reduce
|
||||
|
@ -1,4 +1,4 @@
|
||||
compile
|
||||
gen-hvm
|
||||
tests/golden_tests/cli/compile_strict_loop.hvm
|
||||
-Ono-all
|
||||
-Arecursion-cycle
|
||||
-Arecursion-cycle
|
||||
|
@ -1,3 +1,3 @@
|
||||
compile
|
||||
gen-hvm
|
||||
tests/golden_tests/cli/compile_wrong_opt.hvm
|
||||
-Ofoo
|
||||
|
@ -1,2 +1,2 @@
|
||||
compile
|
||||
gen-hvm
|
||||
tests/golden_tests/cli/warn_and_err.hvm
|
||||
|
Loading…
Reference in New Issue
Block a user