Skip to content

Commit

Permalink
Merge pull request #501 from HigherOrderCO/475-use-the-hvm-ast-for-re…
Browse files Browse the repository at this point in the history
…presenting-inets-inside-the-compiler

Use the hvm ast for representing inets inside the compiler
  • Loading branch information
developedby authored May 25, 2024
2 parents 1460251 + bc610d1 commit 948eaf0
Show file tree
Hide file tree
Showing 48 changed files with 667 additions and 1,651 deletions.
55 changes: 39 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "bend-lang"
description = "A high-level, massively parallel programming language"
license = "Apache-2.0"
version = "0.2.20"
version = "0.2.21"
edition = "2021"
exclude = ["tests/snapshots/"]

Expand All @@ -24,9 +24,9 @@ cli = ["dep:clap"]

[dependencies]
TSPL = "0.0.12"
arrayvec = "0.7.4"
clap = { version = "4.4.1", features = ["derive"], optional = true }
highlight_error = "0.1.1"
hvm = "2.0.16"
indexmap = "2.2.3"
interner = "0.2.1"
itertools = "0.11.0"
Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"Pythonish",
"quadtree",
"quadtrees",
"rbag",
"readback",
"recursively",
"redex",
Expand Down
2 changes: 1 addition & 1 deletion docs/lazy-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ If you have a set of mutually recursive functions, you only need to make one of

### Automatic optimization

HVM-lang carries out [match linearization](compiler-options.md#linearize-matches) and [combinator floating](compiler-options.md#float-combinators) optimizations, enabled through the CLI, which are active by default in strict mode.
Bend carries out [match linearization](compiler-options.md#linearize-matches) and [combinator floating](compiler-options.md#float-combinators) optimizations, enabled through the CLI, which are active by default in strict mode.

Consider the code below:

Expand Down
2 changes: 1 addition & 1 deletion docs/native-numbers.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Operation | Description | Accepted types | Return type

### Pattern matching

HVM-lang also includes a `switch` syntax for pattern-matching U24 numbers.
Bend also includes a `switch` syntax for pattern-matching U24 numbers.

```rs
Number.to_church = λn λf λx
Expand Down
2 changes: 1 addition & 1 deletion docs/pattern-matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ UnwrapOrZero x = (x λx.val x.val 0)

### Pattern Matching functions

Besides `match`and `switch` terms, hvm-lang also supports equational-style pattern matching functions.
Besides `match`and `switch` terms, Bend also supports equational-style pattern matching functions.

```py
And True b = b
Expand Down
2 changes: 1 addition & 1 deletion examples/radix_sort.bend
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def radix(n):
r = swap(n & 512, r, Map_/Free)
return radix2(n, r)

# At the moment, we need to manually break very large functiions into smaller ones
# At the moment, we need to manually break very large functions into smaller ones
# if we want to run this program on the GPU.
# In a future version of Bend, we will be able to do this automatically.
def radix2(n, r):
Expand Down
58 changes: 9 additions & 49 deletions src/fun/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::{
diagnostics::{Diagnostics, DiagnosticsConfig},
hvm::{self, ast::get_typ},
maybe_grow, ENTRY_POINT,
maybe_grow, multi_iterator, ENTRY_POINT,
};
// use hvmc::ast::get_typ;
use indexmap::{IndexMap, IndexSet};
Expand All @@ -19,7 +18,7 @@ pub mod term_to_net;
pub mod transform;

pub use net_to_term::{net_to_term, ReadbackError};
pub use term_to_net::{book_to_nets, term_to_net};
pub use term_to_net::{book_to_hvm, term_to_hvm};

pub static STRINGS: GlobalPool<String> = GlobalPool::new();
#[derive(Debug)]
Expand Down Expand Up @@ -247,45 +246,6 @@ pub struct Name(GlobalString);

/* Implementations */

/// A macro for creating iterators that can have statically known
/// different types. Useful for iterating over tree children, where
/// each tree node variant yields a different iterator type.
#[macro_export]
macro_rules! multi_iterator {
($Iter:ident { $($Variant:ident),* $(,)? }) => {
#[derive(Debug, Clone)]
enum $Iter<$($Variant),*> {
$($Variant { iter: $Variant }),*
}

impl<$($Variant),*> $Iter<$($Variant),*> {
$(
#[allow(non_snake_case)]
fn $Variant(iter: impl IntoIterator<IntoIter = $Variant>) -> Self {
$Iter::$Variant { iter: iter.into_iter() }
}
)*
}

impl<T, $($Variant: Iterator<Item = T>),*> Iterator for $Iter<$($Variant),*> {
type Item = T;
fn next(&mut self) -> Option<T> {
match self { $($Iter::$Variant { iter } => iter.next()),* }
}

fn size_hint(&self) -> (usize, Option<usize>) {
match self { $($Iter::$Variant { iter } => iter.size_hint()),* }
}
}

impl<T, $($Variant: DoubleEndedIterator<Item = T>),*> DoubleEndedIterator for $Iter<$($Variant),*> {
fn next_back(&mut self) -> Option<T> {
match self { $($Iter::$Variant { iter } => iter.next_back()),* }
}
}
};
}

impl PartialEq<str> for Name {
fn eq(&self, other: &str) -> bool {
&**self == other
Expand Down Expand Up @@ -901,17 +861,17 @@ impl Num {

pub fn to_bits(&self) -> u32 {
match self {
Num::U24(val) => hvm::ast::new_u24(*val),
Num::I24(val) => hvm::ast::new_i24(*val),
Num::F24(val) => hvm::ast::new_f24(*val),
Num::U24(val) => hvm::hvm::Numb::new_u24(*val).0,
Num::I24(val) => hvm::hvm::Numb::new_i24(*val).0,
Num::F24(val) => hvm::hvm::Numb::new_f24(*val).0,
}
}

pub fn from_bits(bits: u32) -> Self {
match get_typ(bits) {
hvm::ast::TY_U24 => Num::U24(hvm::ast::get_u24(bits)),
hvm::ast::TY_I24 => Num::I24(hvm::ast::get_i24(bits)),
hvm::ast::TY_F24 => Num::F24(hvm::ast::get_f24(bits)),
match hvm::hvm::Numb::get_typ(&hvm::hvm::Numb(bits)) {
hvm::hvm::TY_U24 => Num::U24(hvm::hvm::Numb::get_u24(&hvm::hvm::Numb(bits))),
hvm::hvm::TY_I24 => Num::I24(hvm::hvm::Numb::get_i24(&hvm::hvm::Numb(bits))),
hvm::hvm::TY_F24 => Num::F24(hvm::hvm::Numb::get_f24(&hvm::hvm::Numb(bits))),
_ => unreachable!("Invalid Num bits"),
}
}
Expand Down
50 changes: 24 additions & 26 deletions src/fun/net_to_term.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
use hvm::ast::{get_f24, get_i24, get_typ, get_u24};

use crate::{
diagnostics::{DiagnosticOrigin, Diagnostics, Severity},
fun::{term_to_net::Labels, Book, FanKind, Name, Op, Pattern, Tag, Term},
hvm, maybe_grow,
fun::{term_to_net::Labels, Book, FanKind, Name, Num, Op, Pattern, Tag, Term},
maybe_grow,
net::{CtrKind, INet, NodeId, NodeKind, Port, SlotId, ROOT},
};
use hvm::hvm::Numb;
use std::collections::{BTreeSet, HashMap, HashSet};

use super::Num;

/// Converts an Interaction-INet to a Lambda Calculus term
pub fn net_to_term(
net: &INet,
Expand Down Expand Up @@ -224,11 +221,12 @@ impl Reader<'_> {
let opr_node = self.net.enter_port(Port(port0_node, 0)).node();
let opr_kind = self.net.node(opr_node).kind.clone();
let opr = if let NodeKind::Num { val } = opr_kind {
if get_typ(val) != hvm::ast::TY_SYM {
let typ = hvm::hvm::Numb::get_typ(&Numb(val));
if typ != hvm::hvm::TY_SYM {
self.error(ReadbackError::InvalidNumericOp);
return Term::Err;
}
if let Some(op) = Op::from_native_tag(val, NumType::U24) {
if let Some(op) = Op::from_native_tag(typ, NumType::U24) {
op
} else {
self.error(ReadbackError::InvalidNumericOp);
Expand Down Expand Up @@ -378,32 +376,32 @@ enum NumType {
}

impl Op {
fn from_native_tag(val: u32, typ: NumType) -> Option<Op> {
fn from_native_tag(val: hvm::hvm::Tag, typ: NumType) -> Option<Op> {
let op = match val {
0x4 => Op::ADD,
0x5 => Op::SUB,
0x6 => Op::MUL,
0x7 => Op::DIV,
0x8 => Op::REM,
0x9 => Op::EQ,
0xa => Op::NEQ,
0xb => Op::LT,
0xc => Op::GT,
0xd => {
hvm::hvm::OP_ADD => Op::ADD,
hvm::hvm::OP_SUB => Op::SUB,
hvm::hvm::OP_MUL => Op::MUL,
hvm::hvm::OP_DIV => Op::DIV,
hvm::hvm::OP_REM => Op::REM,
hvm::hvm::OP_EQ => Op::EQ,
hvm::hvm::OP_NEQ => Op::NEQ,
hvm::hvm::OP_LT => Op::LT,
hvm::hvm::OP_GT => Op::GT,
hvm::hvm::OP_AND => {
if typ == NumType::F24 {
Op::ATN
} else {
Op::AND
}
}
0xe => {
hvm::hvm::OP_OR => {
if typ == NumType::F24 {
Op::LOG
} else {
Op::OR
}
}
0xf => {
hvm::hvm::OP_XOR => {
if typ == NumType::F24 {
Op::POW
} else {
Expand Down Expand Up @@ -477,12 +475,12 @@ impl Term {
}

fn num_from_bits_with_type(val: u32, typ: u32) -> Term {
match get_typ(typ) {
match hvm::hvm::Numb::get_typ(&Numb(typ)) {
// No type information, assume u24 by default
hvm::ast::TY_SYM => Term::Num { val: Num::U24(get_u24(val)) },
hvm::ast::TY_U24 => Term::Num { val: Num::U24(get_u24(val)) },
hvm::ast::TY_I24 => Term::Num { val: Num::I24(get_i24(val)) },
hvm::ast::TY_F24 => Term::Num { val: Num::F24(get_f24(val)) },
hvm::hvm::TY_SYM => Term::Num { val: Num::U24(Numb::get_u24(&Numb(val))) },
hvm::hvm::TY_U24 => Term::Num { val: Num::U24(Numb::get_u24(&Numb(val))) },
hvm::hvm::TY_I24 => Term::Num { val: Num::I24(Numb::get_i24(&Numb(val))) },
hvm::hvm::TY_F24 => Term::Num { val: Num::F24(Numb::get_f24(&Numb(val))) },
_ => Term::Err,
}
}
Expand Down
Loading

0 comments on commit 948eaf0

Please sign in to comment.