Skip to content

Commit

Permalink
basic ivy repl (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
tjjfvi authored Sep 24, 2024
1 parent 9ccbec5 commit b107545
Show file tree
Hide file tree
Showing 15 changed files with 541 additions and 22 deletions.
154 changes: 154 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2021"
[dependencies]
anyhow = "1.0.87"
clap = { version = "4.5.17", features = ["derive", "env"] }
rustyline = "14.0.0"

ivm = { path = "../ivm" }
ivy = { path = "../ivy" }
Expand Down
4 changes: 2 additions & 2 deletions cli/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use clap::Args;

use ivm::{heap::Heap, IVM};
use ivy::{ast::Nets, optimize::Optimizer};
use ivy::{ast::Nets, optimize::Optimizer, serialize::Labels};

#[derive(Debug, Default, Args)]
pub struct Optimizations {
Expand All @@ -26,7 +26,7 @@ pub struct RunArgs {
impl RunArgs {
pub fn run(self, nets: Nets) {
let mut globals = Vec::new();
let globals = nets.serialize(&mut globals);
let globals = nets.serialize(&mut globals, &mut Labels::default());
let main = &globals[nets.get_index_of("::main").expect("missing main")];
let heap = Heap::new();
let mut ivm = IVM::new(&heap);
Expand Down
42 changes: 41 additions & 1 deletion cli/src/ivy_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use std::{fs, path::PathBuf};

use anyhow::Result;
use clap::{Args, Parser};
use ivy::parser::IvyParser;
use rustyline::DefaultEditor;

use ivm::{heap::Heap, IVM};
use ivy::{parser::IvyParser, repl::Repl, serialize::Labels};

use crate::{Optimizations, RunArgs};

Expand All @@ -13,13 +16,15 @@ pub enum IvyCommand {
Run(IvyRunCommand),
#[command(about = "Optimize an Ivy program")]
Optimize(IvyOptimizeCommand),
Repl(IvyReplCommand),
}

impl IvyCommand {
pub fn execute() -> Result<()> {
match Self::parse() {
IvyCommand::Run(run) => run.execute(),
IvyCommand::Optimize(optimize) => optimize.execute(),
IvyCommand::Repl(repl) => repl.execute(),
}
}
}
Expand Down Expand Up @@ -56,3 +61,38 @@ impl IvyOptimizeCommand {
unimplemented!()
}
}

#[derive(Debug, Args)]
pub struct IvyReplCommand {
#[arg()]
src: Option<PathBuf>,
#[command(flatten)]
run_args: RunArgs,
}

impl IvyReplCommand {
pub fn execute(self) -> Result<()> {
let src = self.src.map(fs::read_to_string).unwrap_or(Ok(String::new()))?;
let nets = IvyParser::parse(&src).unwrap();
let mut globals = Vec::new();
let mut labels = Labels::default();
let globals = nets.serialize(&mut globals, &mut labels);
let heap = Heap::new();
let mut ivm = IVM::new(&heap);
let mut repl = Repl::new(&mut ivm, &nets, globals, &mut labels);
let mut rl = DefaultEditor::new()?;
loop {
print!("\n{repl}");
match rl.readline("> ") {
Ok(line) => {
_ = rl.add_history_entry(&line);
if let Err(err) = repl.exec(&line) {
println!("{err:?}");
}
}
Err(_) => break,
}
}
Ok(())
}
}
2 changes: 2 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
"nilary",
"nonoverlapping",
"readback",
"readline",
"repr",
"rotr",
"rustyline",
"scrutinee",
"sixel",
"strs"
Expand Down
2 changes: 1 addition & 1 deletion ivm/src/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
};

/// The address of a port, a pointer of only-externally-known interpretation.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct Addr(pub *const ());

Expand Down
15 changes: 10 additions & 5 deletions ivm/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,20 @@ impl<'ivm> IVM<'ivm> {
/// `tag` must be the tag of a binary node, and `label` must comply with its
/// requirements.
#[inline(always)]
pub(crate) unsafe fn new_node(
&mut self,
tag: Tag,
label: u16,
) -> (Port<'ivm>, Wire<'ivm>, Wire<'ivm>) {
pub unsafe fn new_node(&mut self, tag: Tag, label: u16) -> (Port<'ivm>, Wire<'ivm>, Wire<'ivm>) {
let addr = self.alloc_node();
(Port::new(tag, label, addr), Wire::from_addr(addr), Wire::from_addr(addr.other_half()))
}

/// Allocates a new wire, returning both of its ends.
pub fn new_wire(&mut self) -> (Wire<'ivm>, Wire<'ivm>) {
unsafe {
let addr = self.alloc_node();
self.free_wire(Wire::from_addr(addr.other_half()));
(Wire::from_addr(addr), Wire::from_addr(addr))
}
}

/// Frees the memory backing a wire.
#[inline]
pub(crate) fn free_wire(&mut self, wire: Wire<'ivm>) {
Expand Down
Loading

0 comments on commit b107545

Please sign in to comment.