#![no_std]
#![feature(generic_arg_infer)]
#![feature(error_in_core)]
#[macro_use]
extern crate disclose;
#[cfg(feature="std")]
mod foundation {
extern crate std;
pub use std::{any, array, borrow, boxed, convert, num, ops, rc, result, slice, string, sync, vec};
}
#[cfg(not(feature="std"))]
mod foundation {
extern crate alloc;
pub use alloc::{boxed, rc, string, vec};
pub use core::{array, borrow, convert, num, result, ops, slice, any};
}
use foundation::num::Wrapping;
use foundation::*;
#[allow(unused_imports)]
use self::boxed::Box;
use self::rc::Rc;
mod chip;
#[cfg(feature="_cpp")]
mod cpp;
#[allow(non_camel_case_types)]
mod raw {
pub type u8 = core::primitive::u8;
pub type u16 = core::primitive::u16;
}
#[allow(non_camel_case_types)]
mod bits {
use super::*;
pub type u8 = crate::num::Wrapping<raw::u8>;
pub type u16 = crate::num::Wrapping<raw::u16>;
}
#[cfg(any(feature="open", doc))]
pub use chip::State;
#[cfg(any(feature="open", doc))]
pub mod internal {
use super::*;
pub use chip::access::*;
pub use crate::chip::opcode::{Op::{self, *}, Flag::*, Test::*};
}
pub trait Harness {
fn read(&self, from: bits::u16) -> bits::u8;
fn read_word(&self, from: bits::u16) -> bits::u16 {
Wrapping(u16::from_le_bytes([self.read(from).0, self.read(from + Wrapping(1)).0]))
}
fn write(&mut self, to: bits::u16, value: bits::u8) { let _ = (value, to); }
fn write_word(&mut self, to: bits::u16, value: bits::u16) {
for (index, byte) in value.0.to_le_bytes().into_iter().enumerate() {
self.write(to + num::Wrapping(index as u16), num::Wrapping(byte))
}
}
fn input(&mut self, port: u8) -> bits::u8;
fn output(&mut self, port: u8, value: bits::u8);
#[cfg(any(feature="open", doc))]
fn did_execute(&mut self, client: &chip::State, did: chip::opcode::Op) -> Result<Option<chip::opcode::Op>, string::String> { let _ = (client, did); Ok( None ) }
fn as_any(&self) -> Option<&dyn any::Any> { None }
}
#[cfg(feature="std")]
use crate::sync::{Arc, Mutex};
use core::{borrow::BorrowMut, cell::RefCell, marker::PhantomData, ops::{Deref, DerefMut}};
type Shared<H, C> = Rc<RefCell<(C, PhantomData<H>)>>;
impl<H: Harness + ?Sized, C: BorrowMut<H>> Harness for Shared<H, C> {
fn read(&self, address: bits::u16) -> bits::u8 { self.deref().borrow().0.borrow().read(address) }
fn read_word(&self, address: bits::u16) -> bits::u16 { self.deref().borrow().0.borrow().read_word(address) }
fn write(&mut self, address: bits::u16, value: bits::u8) { (**self).borrow_mut().0.borrow_mut().write(address, value) }
fn write_word(&mut self, address: bits::u16, value: bits::u16) { (**self).borrow_mut().0.borrow_mut().write_word(address, value) }
fn input(&mut self, port: u8) -> bits::u8 { (**self).borrow_mut().0.borrow_mut().input(port) }
fn output(&mut self, port: u8, value: bits::u8) { (**self).borrow_mut().0.borrow_mut().output(port, value) }
#[cfg(feature="cfg")]
fn did_execute(&mut self, client: &chip::State, did: chip::opcode::Op) -> Result<Option<chip::opcode::Op>, string::String> {
(**self).borrow_mut().0.borrow_mut().did_execute(client, did)
}
}
#[cfg(feature="std")]
type Synced<H, C> = Arc<Mutex<(C, PhantomData<H>)>>;
#[cfg(feature="std")]
impl<H: Harness + ?Sized, C: BorrowMut<H>> Harness for Synced<H, C> {
fn read(&self, address: bits::u16) -> bits::u8 { self.deref().lock().unwrap().0.borrow().read(address) }
fn read_word(&self, address: bits::u16) -> bits::u16 { self.deref().lock().unwrap().0.borrow().read_word(address) }
fn write(&mut self, address: bits::u16, value: bits::u8) { (**self).lock().unwrap().0.borrow_mut().write(address, value) }
fn write_word(&mut self, address: bits::u16, value: bits::u16) { (**self).lock().unwrap().0.borrow_mut().write_word(address, value) }
fn input(&mut self, port: u8) -> bits::u8 { (**self).lock().unwrap().0.borrow_mut().input(port) }
fn output(&mut self, port: u8, value: bits::u8) { (**self).lock().unwrap().0.borrow_mut().output(port, value) }
#[cfg(feature="cfg")]
fn did_execute(&mut self, client: &chip::State, did: chip::opcode::Op) -> Result<Option<chip::opcode::Op>, string::String> {
(**self).lock().unwrap().0.borrow_mut().did_execute(client, did)
}
}
#[repr(C)]
pub struct SimpleBoard {
ram: [u8; 65536],
pub port_out: [u8; 256],
pub port_in: [u8; 256]
}
mod simple;
pub struct Machine<H: Harness + ?Sized, C: BorrowMut<H>> {
chip: chip::State,
board: C,
_grammar: PhantomData<H>,
}
impl<H: Harness + ?Sized, C: BorrowMut<H>> Machine<H, C> {
pub fn new(board: C) -> Self {
Self { board, chip: chip::State::new(), _grammar: PhantomData::default() }
}
fn split_mut(&mut self) -> (&mut chip::State, &mut H) { (&mut self.chip, self.board.borrow_mut() )}
}
impl<H: Harness + ?Sized, C: BorrowMut<H>> Machine<Shared<H, C>, Shared<H, C>> {
pub fn fork(&self) -> Self { Self::new(self.board.clone()) }
}
#[cfg(feature="std")]
impl<H: Harness + ?Sized, C: BorrowMut<H>> Machine<Synced<H, C>, Synced<H, C>> {
pub fn fork(&self) -> Self { Self::new(self.board.clone()) }
}
impl<H: Harness + ?Sized, C: BorrowMut<H>> Deref for Machine<H, C> {
type Target = H;
fn deref(&self) -> &Self::Target { self.board.borrow() }
}
impl<H: Harness + ?Sized, C: BorrowMut<H>> DerefMut for Machine<H, C> {
fn deref_mut(&mut self) -> &mut Self::Target { self.board.borrow_mut() }
}
pub struct Install<H: Harness + ?Sized>(PhantomData<H>);
impl<H: Harness + ?Sized> Install<H> {
pub fn new<C: BorrowMut<H>>(board: C) -> Machine<H, C> {
Machine::new( board )
}
pub fn new_shared<C: BorrowMut<H>>(board: C) -> Machine<Shared<H, C>, Shared<H, C>> {
Machine::new(Rc::new(RefCell::new( (board, PhantomData::default()) )))
}
#[cfg(feature="std")]
pub fn new_synced<C: BorrowMut<H>>(board: C) -> Machine<Synced<H, C>, Synced<H, C>> {
Machine::new(Arc::new(Mutex::new( (board, PhantomData::default()) )))
}
}
#[allow(dead_code)]
impl<H: Harness + ?Sized, C: BorrowMut<H>> Machine<H, C> {
fn as_ref(&self) -> &chip::State { &self.chip }
}
#[allow(dead_code)]
impl<H: Harness + ?Sized, C: BorrowMut<H>> Machine<H, C> {
fn as_mut(&mut self) -> &mut chip::State { &mut self.chip }
}
#[cfg(feature="open")]
impl<H: Harness + ?Sized, C: BorrowMut<H>> AsRef<chip::State> for Machine<H, C> {
fn as_ref(&self) -> &chip::State { self.as_ref() }
}
#[cfg(feature="open")]
impl<H: Harness + ?Sized, C: BorrowMut<H>> AsMut<chip::State> for Machine<H, C> {
fn as_mut(&mut self) -> &mut chip::State { self.as_mut() }
}