Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add no_std support #123

Merged
merged 3 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
- run: RUSTFLAGS="-D warnings" cargo check --all-targets
- run: RUSTFLAGS="-D warnings" cargo check --all-targets --features trace
- run: RUSTFLAGS="-D warnings" cargo check --all-targets --features _fuzz
- run: RUSTFLAGS="-D warnings" cargo check --all-targets --no-default-features
test:
runs-on: ubuntu-latest
timeout-minutes: 10
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,19 @@ TSPL = "0.0.9"
arrayvec = "0.7.4"
clap = { version = "4.5.1", features = ["derive"], optional = true }
nohash-hasher = { version = "0.2.0" }
parking_lot = "0.12.1"
stacker = "0.1.15"
thiserror = "1.0.58"

##--COMPILER-CUTOFF--##

[features]
default = ["cli", "_full_cli"]
cli = ["dep:clap"]
std = []
cli = ["std", "dep:clap"]
trace = []
_full_cli = []
_fuzz = []
_fuzz = ["std"]
_fuzz_no_free = ["_fuzz"]

[dev-dependencies]
Expand Down
14 changes: 9 additions & 5 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
//!
//! [interaction calculus]: https://en.wikipedia.org/wiki/Interaction_nets#Interaction_calculus

use arrayvec::ArrayVec;
use crate::prelude::*;

use crate::{
ops::Op,
run::Lab,
util::{array_vec, deref, maybe_grow},
};
use std::{collections::BTreeMap, fmt, mem, str::FromStr};
use alloc::collections::BTreeMap;
use arrayvec::ArrayVec;
use core::str::FromStr;
use TSPL::{new_parser, Parser};

/// The top level AST node, representing a collection of named nets.
Expand Down Expand Up @@ -147,10 +149,10 @@ pub const MAX_ADT_FIELDS: usize = MAX_ARITY - 1;

impl Net {
pub fn trees(&self) -> impl Iterator<Item = &Tree> {
std::iter::once(&self.root).chain(self.redexes.iter().map(|(x, y)| [x, y]).flatten())
iter::once(&self.root).chain(self.redexes.iter().map(|(x, y)| [x, y]).flatten())
}
pub fn trees_mut(&mut self) -> impl Iterator<Item = &mut Tree> {
std::iter::once(&mut self.root).chain(self.redexes.iter_mut().map(|(x, y)| [x, y]).flatten())
iter::once(&mut self.root).chain(self.redexes.iter_mut().map(|(x, y)| [x, y]).flatten())
}
}

Expand Down Expand Up @@ -187,7 +189,7 @@ impl Tree {

pub fn legacy_mat(mut arms: Tree, out: Tree) -> Option<Tree> {
let Tree::Ctr { lab: 0, ports } = &mut arms else { None? };
let ports = std::mem::take(ports);
let ports = mem::take(ports);
let Ok([zero, succ]) = <[_; 2]>::try_from(ports) else { None? };
let zero = Box::new(zero);
let succ = Box::new(succ);
Expand Down Expand Up @@ -513,6 +515,8 @@ impl Drop for Tree {

#[test]
fn test_tree_drop() {
use alloc::vec;

drop(Tree::from_str("((* (* *)) (* *))"));

let mut long_tree = Tree::Era;
Expand Down
10 changes: 6 additions & 4 deletions src/compile.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#![cfg(feature = "std")]

use crate::prelude::*;

use crate::{
host::Host,
run::{Instruction, InterpretedDef, LabSet, Port, Tag},
stdlib::HostedDef,
};
use std::{
fmt::{self, Write},
hash::{DefaultHasher, Hasher},
};
use core::hash::Hasher;
use std::{fmt::Write, hash::DefaultHasher};

/// Compiles a [`Host`] to Rust, returning a file to replace `gen.rs`.
pub fn compile_host(host: &Host) -> String {
Expand Down
11 changes: 9 additions & 2 deletions src/fuzz.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![cfg(feature = "std")]
//! An 'atomic fuzzer' to exhaustively test an atomic algorithm for correctness.
//!
//! This fuzzer can test an algorithm with every possible ordering of parallel
Expand Down Expand Up @@ -69,14 +70,20 @@
//! algorithm is changed (particularly, the atomic instructions it executes),
//! old paths may no longer be valid.)

use std::{
use crate::prelude::*;

use core::{
any::Any,
cell::{OnceCell, RefCell},
fmt::Debug,
marker::PhantomData,
ops::Add,
sync::{atomic, Arc, Condvar, Mutex},
sync::atomic,
};
use std::{
sync::{Arc, Condvar, Mutex},
thread::{self, Scope, ThreadId},
thread_local,
};

use nohash_hasher::IntMap;
Expand Down
19 changes: 11 additions & 8 deletions src/host.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
//! The runtime's host, which acts as a translation layer between the AST and
//! the runtime.

use crate::prelude::*;

use crate::{
ast::{Book, Net, Tree},
run::{self, Addr, Def, Instruction, InterpretedDef, LabSet, Mode, Port, Tag, TrgId, Wire},
stdlib::HostedDef,
util::create_var,
};
use std::{
collections::{hash_map::Entry, HashMap},
ops::{Deref, DerefMut, RangeFrom},
};
use core::ops::{Deref, DerefMut, RangeFrom};

mod calc_labels;
mod encode;
Expand All @@ -22,9 +21,9 @@ use calc_labels::calculate_label_sets;
#[derive(Default)]
pub struct Host {
/// the forward mapping, from a name to the runtime def
pub defs: HashMap<String, DefRef>,
pub defs: Map<String, DefRef>,
/// the backward mapping, from the address of a runtime def to the name
pub back: HashMap<Addr, String>,
pub back: Map<Addr, String>,
}

/// A potentially-owned reference to a [`Def`]. Vitally, the address of the
Expand Down Expand Up @@ -63,8 +62,12 @@ impl Host {
/// will be run when the name of a definition is not found in the book.
/// The return value of the function will be inserted into the host.
pub fn insert_book_with_default(&mut self, book: &Book, default_def: &mut dyn FnMut(&str) -> DefRef) {
self.defs.reserve(book.len());
self.back.reserve(book.len());
#[cfg(feature = "std")]
{
self.defs.reserve(book.len());
self.back.reserve(book.len());
}

// Because there may be circular dependencies, inserting the definitions
// must be done in two phases:

Expand Down
18 changes: 13 additions & 5 deletions src/host/calc_labels.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::util::maybe_grow;
use crate::prelude::*;

use super::*;
use crate::util::maybe_grow;

/// Calculates the labels used in each definition of a book.
///
Expand Down Expand Up @@ -76,7 +77,14 @@ use super::*;
/// This algorithm runs in linear time (as refs are traversed at most twice),
/// and requires no more space than the naive algorithm.
pub(crate) fn calculate_label_sets<'b, 'l>(book: &'b Book, lookup: impl FnMut(&'b str) -> LabSet) -> LabelSets<'b> {
let mut state = State { book, lookup, labels: HashMap::with_capacity(book.len()) };
let mut state = State {
book,
lookup,
#[cfg(feature = "std")]
labels: Map::with_capacity(book.len()),
#[cfg(not(feature = "std"))]
labels: Map::new(),
};

for name in book.keys() {
state.visit_def(name, Some(0), None);
Expand All @@ -85,7 +93,7 @@ pub(crate) fn calculate_label_sets<'b, 'l>(book: &'b Book, lookup: impl FnMut(&'
LabelSets(state.labels)
}

pub(crate) struct LabelSets<'b>(HashMap<&'b str, LabelState>);
pub(crate) struct LabelSets<'b>(Map<&'b str, LabelState>);

impl<'b> LabelSets<'b> {
pub(crate) fn into_iter(self) -> impl Iterator<Item = (&'b str, LabSet)> {
Expand All @@ -99,7 +107,7 @@ impl<'b> LabelSets<'b> {
struct State<'b, F> {
book: &'b Book,
lookup: F,
labels: HashMap<&'b str, LabelState>,
labels: Map<&'b str, LabelState>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -188,7 +196,7 @@ impl<'b, F: FnMut(&'b str) -> LabSet> State<'b, F> {

#[test]
fn test_calculate_labels() {
use std::collections::BTreeMap;
use alloc::collections::BTreeMap;
assert_eq!(
calculate_label_sets(
&"
Expand Down
4 changes: 3 additions & 1 deletion src/host/encode.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::prelude::*;

use super::*;
use crate::{ops::Op, run::Lab, util::maybe_grow};

Expand Down Expand Up @@ -33,7 +35,7 @@ impl Host {
struct State<'a, E: Encoder> {
host: &'a Host,
encoder: &'a mut E,
scope: HashMap<&'a str, E::Trg>,
scope: Map<&'a str, E::Trg>,
}

impl<'a, E: Encoder> State<'a, E> {
Expand Down
4 changes: 3 additions & 1 deletion src/host/readback.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::prelude::*;

use super::*;
use crate::util::maybe_grow;

Expand Down Expand Up @@ -28,7 +30,7 @@ impl Host {
/// See [`Host::readback`].
struct ReadbackState<'a> {
host: &'a Host,
vars: HashMap<Addr, usize>,
vars: Map<Addr, usize>,
var_id: RangeFrom<usize>,
}

Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#![feature(const_type_id, extern_types, inline_const, generic_const_exprs, new_uninit)]
#![cfg_attr(feature = "trace", feature(const_type_name))]
#![allow(non_snake_case, incomplete_features)]
#![cfg_attr(not(feature = "std"), no_std)]

extern crate alloc;

mod prelude;

pub mod ast;
pub mod compile;
Expand Down
12 changes: 7 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ use hvmc::{
*,
};

use parking_lot::Mutex;
use std::{
fs, io,
path::Path,
process::{self, Stdio},
str::FromStr,
sync::{Arc, Mutex},
sync::Arc,
time::{Duration, Instant},
};

Expand Down Expand Up @@ -236,15 +237,15 @@ fn reduce_exprs(host: Arc<Mutex<Host>>, exprs: &[Net], opts: &RuntimeOpts) {
for expr in exprs {
let mut net = DynNet::new(&heap, opts.lazy_mode);
dispatch_dyn_net!(&mut net => {
host.lock().unwrap().encode_net(net, Trg::port(run::Port::new_var(net.root.addr())), expr);
host.lock().encode_net(net, Trg::port(run::Port::new_var(net.root.addr())), expr);
let start_time = Instant::now();
if opts.single_core {
net.normal();
} else {
net.parallel_normal();
}
let elapsed = start_time.elapsed();
println!("{}", host.lock().unwrap().readback(net));
println!("{}", host.lock().readback(net));
if opts.show_stats {
print_stats(net, elapsed);
}
Expand Down Expand Up @@ -275,14 +276,14 @@ fn pretty_num(n: u64) -> String {
}

fn compile_executable(target: &str, host: Arc<Mutex<host::Host>>) -> Result<(), io::Error> {
let gen = compile::compile_host(&host.lock().unwrap());
let gen = compile::compile_host(&host.lock());
let outdir = ".hvm";
if Path::new(&outdir).exists() {
fs::remove_dir_all(outdir)?;
}
let cargo_toml = include_str!("../Cargo.toml");
let mut cargo_toml = cargo_toml.split_once("##--COMPILER-CUTOFF--##").unwrap().0.to_owned();
cargo_toml.push_str("[features]\ndefault = ['cli']\ncli = ['dep:clap']");
cargo_toml.push_str("[features]\ndefault = ['cli']\ncli = ['std', 'dep:clap']\nstd = []");

macro_rules! include_files {
($([$($prefix:ident)*])? $mod:ident {$($sub:tt)*} $($rest:tt)*) => {
Expand Down Expand Up @@ -316,6 +317,7 @@ fn compile_executable(target: &str, host: Arc<Mutex<host::Host>>) -> Result<(),
lib
main
ops
prelude
run {
addr
allocator
Expand Down
9 changes: 5 additions & 4 deletions src/ops.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::prelude::*;

use crate::util::bi_enum;
use std::{
use core::{
cmp::{Eq, Ord},
fmt::Display,
str::FromStr,
};

Expand Down Expand Up @@ -163,8 +164,8 @@ pub struct Op {
pub op: IntOp,
}

impl Display for Op {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl fmt::Display for Op {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.ty {
Ty::U60 => write!(f, "{}", self.op),
_ => write!(f, "{}.{}", self.ty, self.op),
Expand Down
20 changes: 20 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
pub use alloc::{
borrow::ToOwned,
boxed::Box,
format,
string::{String, ToString},
vec,
vec::Vec,
};
pub use core::{fmt, iter, mem, ptr};

#[cfg(feature = "std")]
pub use std::collections::{hash_map::Entry, HashMap as Map, HashSet as Set};

#[cfg(not(feature = "std"))]
pub use alloc::collections::{btree_map::Entry, BTreeMap as Map, BTreeSet as Set};

#[cfg(feature = "std")]
pub use std::error::Error;
#[cfg(feature = "std")]
pub use thiserror::Error;
Loading
Loading