Skip to content

Commit

Permalink
Reader && Undoable Instructions (#90)
Browse files Browse the repository at this point in the history
- Added input instructions
- Added transformations model of instructions to allow for undo operations
- Added cheese!

---------

Co-authored-by: michaelni678 <[email protected]>
Co-authored-by: Trevor Brunette <[email protected]>
Co-authored-by: Aleks Bekker <[email protected]>
  • Loading branch information
4 people authored Apr 18, 2024
1 parent d4c9b30 commit 5a4708e
Show file tree
Hide file tree
Showing 36 changed files with 1,254 additions and 262 deletions.
30 changes: 30 additions & 0 deletions example/terminal.ez
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Read an integer.
prints "Input an integer: "
readi $t0
# Print the read integer.
printi $t0
prints "\n"
# Allocate memory according to what was inputted.
alloc $s0 $t0
# Subtract 1 from the allocation size. This is because room is needed for the null terminator.
sub $t0 $t0 1
# Read string (sized).
prints "Input a string: "
reads $s0 $t0
# Print the read string.
prints $s0
prints "\n"
# Read a float.
prints "Input a float: "
readf $fs0
printf $fs0
prints "\n"
prints "Input a char: "
readc $t1
printc $t1
prints "\n"
alloc $t2 100
prints "Input a line: "
readln $t2 100
prints $t2
printc '\n'
11 changes: 2 additions & 9 deletions rezasm-app/rezasm-cli/src/util/application.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::util::cli_io::InputSource;
use rezasm_core::parser::lexer;
use rezasm_core::simulation::registry;
use rezasm_core::simulation::simulator::Simulator;
Expand All @@ -8,19 +7,13 @@ use rezasm_core::util::io::RezasmFileReader;
pub struct Application {
simulator: Simulator,
code_file: RezasmFileReader,
input_file: InputSource,
}

impl Application {
pub fn new(
simulator: Simulator,
code_file: RezasmFileReader,
input_file: InputSource,
) -> Application {
pub fn new(simulator: Simulator, code_file: RezasmFileReader) -> Application {
Application {
simulator,
code_file,
input_file,
}
}

Expand All @@ -40,7 +33,7 @@ impl Application {
}

while !self.simulator.is_done() {
self.simulator.run_line_from_pc()?
self.simulator.run_line_from_pc()?;
}

let r = self
Expand Down
11 changes: 8 additions & 3 deletions rezasm-app/rezasm-cli/src/util/cli_arguments.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::util::application::Application;
use crate::util::cli::Arguments;
use crate::util::cli_io::{InputSource, OutputSink};
use rezasm_core::simulation::reader_cell::ReaderCell;
use rezasm_core::simulation::simulator::Simulator;
use rezasm_core::util::error::{EzasmError, IoError, SimulatorError};
use rezasm_core::util::io::{RezasmFileReader, RezasmFileWriter};
Expand Down Expand Up @@ -60,8 +61,12 @@ pub fn handle_arguments(arguments: Arguments) -> Result<Application, EzasmError>
None => OutputSink::new_console(),
};

let simulator: Simulator =
Simulator::new_custom(&word_size, memory_size, Box::new(output_file));
let simulator: Simulator = Simulator::new_custom(
&word_size,
memory_size,
ReaderCell::new(input_file),
Box::new(output_file),
);

Ok(Application::new(simulator, code_file, input_file))
Ok(Application::new(simulator, code_file))
}
71 changes: 39 additions & 32 deletions rezasm-app/rezasm-cli/src/util/cli_io.rs
Original file line number Diff line number Diff line change
@@ -1,62 +1,69 @@
use crate::util::cli_io::InputSource::{ConsoleInput, FileInput};
use crate::util::cli_io::OutputSink::{ConsoleOutput, FileOutput};
use rezasm_core::simulation::reader::Reader;
use rezasm_core::simulation::writer::Writer;
use rezasm_core::util::as_any::AsAny;
use rezasm_core::util::error::IoError;
use rezasm_core::util::io::{RezasmFileReader, RezasmFileWriter};
use scanner_rust::Scanner;
use scanner_rust::{Scanner, ScannerAscii};
use std::any::Any;
use std::io::{stdin, stdout, Stdin, Write};
use std::io::{self, stdin, stdout, Stdin, Write};

#[derive(Debug)]
pub enum InputSource {
FileInput(Scanner<RezasmFileReader>),
ConsoleInput(Scanner<Stdin>),
ConsoleInput(Stdin),
}

impl InputSource {
pub fn new_console() -> InputSource {
ConsoleInput(Scanner::new(stdin()))
ConsoleInput(stdin())
}

pub fn new_file(file: RezasmFileReader) -> InputSource {
FileInput(Scanner::new(file))
}

pub fn read_line(&mut self) -> Result<String, IoError> {
let s = match self {
FileInput(s) => s.next_line()?,
ConsoleInput(s) => s.next_line()?,
pub fn read_raw(&mut self) -> Result<u8, IoError> {
let b = match self {
FileInput(s) => s.next_bytes(1)?,
ConsoleInput(s) => ScannerAscii::new(s).next_bytes(1)?,
};
Ok(s.ok_or(IoError::OutOfBoundsError)?.trim().to_string())
Ok(b.ok_or(IoError::OutOfBoundsError)?[0])
}
}

pub fn read_word(&mut self) -> Result<String, IoError> {
let s = match self {
FileInput(s) => s.next()?,
ConsoleInput(s) => s.next()?,
};
s.ok_or(IoError::OutOfBoundsError)
}
impl Reader for InputSource {}

pub fn read_char(&mut self) -> Result<char, IoError> {
let c = match self {
FileInput(s) => s.next_char()?,
ConsoleInput(s) => s.next_char()?,
}
.ok_or(IoError::OutOfBoundsError)?;
if char::is_whitespace(c) {
self.read_char()
} else {
Ok(c)
impl io::Read for InputSource {
fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
match self {
ConsoleInput(readable) => readable.read(buf),
FileInput(file) => {
let next = file.next().unwrap().unwrap();
buf.write(next.as_bytes())
}
}
}
}

pub fn read_raw(&mut self) -> Result<u8, IoError> {
let b = match self {
FileInput(s) => s.next_bytes(1)?,
ConsoleInput(s) => s.next_bytes(1)?,
};
Ok(b.ok_or(IoError::OutOfBoundsError)?[0])
impl io::Write for InputSource {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
Ok(0)
}

fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}

impl AsAny for InputSource {
fn as_any(&self) -> &dyn Any {
self
}

fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}

Expand Down
28 changes: 23 additions & 5 deletions rezasm-app/rezasm-tauri/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

mod tauri_reader;
mod tauri_writer;

extern crate lazy_static;
extern crate tauri;

use lazy_static::lazy_static;
use rezasm_core::instructions::implementation::register_instructions;
use rezasm_core::simulation::reader_cell::ReaderCell;
use rezasm_web_core::{
get_exit_status, get_memory_bounds, get_memory_slice, get_register_names, get_register_value,
get_register_values, get_word_size, is_completed, load, receive_input, register_writer, reset,
step, stop,
get_register_values, get_simulator_mut, get_word_size, initialize_simulator, is_completed,
load, reset, step, step_back, stop,
};
use tauri::{Manager, Window};
use tauri_reader::TauriReader;

use crate::tauri_writer::TauriWriter;
use std::sync::{Arc, RwLock};
use std::{
io::Write,
sync::{Arc, RwLock},
};

lazy_static! {
static ref WINDOW: Arc<RwLock<Option<Window>>> = Arc::new(RwLock::new(None));
Expand Down Expand Up @@ -58,6 +64,11 @@ fn tauri_step() -> Result<(), String> {
step()
}

#[tauri::command()]
fn tauri_step_back() -> Result<(), String> {
step_back()
}

#[tauri::command]
fn tauri_is_completed() -> bool {
is_completed()
Expand Down Expand Up @@ -100,19 +111,26 @@ fn tauri_get_word_size() -> usize {

#[tauri::command]
fn tauri_receive_input(data: &str) {
receive_input(data);
let mut simulator = get_simulator_mut();
let reader = simulator.get_reader_mut();
reader.write(data.as_bytes()).unwrap();
reader.write(&[b'\n']).unwrap();
}

fn main() {
register_instructions();
register_writer(Box::new(TauriWriter::new()));
initialize_simulator(
Some(ReaderCell::new(TauriReader::new())),
Some(Box::new(TauriWriter::new())),
);

tauri::Builder::default()
.setup(|app| Ok(set_window(app.get_window(WINDOW_NAME).unwrap())))
.invoke_handler(tauri::generate_handler![
tauri_load,
tauri_reset,
tauri_step,
tauri_step_back,
tauri_stop,
tauri_is_completed,
tauri_get_exit_status,
Expand Down
45 changes: 45 additions & 0 deletions rezasm-app/rezasm-tauri/src/tauri_reader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::collections::VecDeque;
use std::io::{Read, Write};

use rezasm_core::{simulation::reader::Reader, util::as_any::AsAny};

#[derive(Debug)]
pub struct TauriReader {
buffer: VecDeque<u8>,
}

impl TauriReader {
pub fn new() -> TauriReader {
TauriReader {
buffer: VecDeque::new(),
}
}
}

impl Reader for TauriReader {}

impl Read for TauriReader {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.buffer.read(buf)
}
}

impl Write for TauriReader {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.buffer.write(buf)
}

fn flush(&mut self) -> std::io::Result<()> {
self.buffer.flush()
}
}

impl AsAny for TauriReader {
fn as_any(&self) -> &dyn std::any::Any {
self
}

fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
}
18 changes: 14 additions & 4 deletions rezasm-app/rezasm-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ extern crate wasm_bindgen;

use crate::wasm_writer::WasmWriter;
use rezasm_core::instructions::implementation::register_instructions;
use rezasm_core::simulation::reader::DummyReader;
use rezasm_core::simulation::reader_cell::ReaderCell;
use rezasm_core::util::as_any::AsAny;
use rezasm_web_core::{
get_exit_status, get_memory_bounds, get_memory_slice, get_register_names, get_register_value,
get_register_values, get_word_size, is_completed, load, receive_input, register_writer, reset,
step, stop,
get_register_values, get_simulator_mut, get_word_size, initialize_simulator, is_completed,
load, reset, step, stop,
};
use wasm_bindgen::prelude::*;

Expand Down Expand Up @@ -76,11 +79,18 @@ pub fn wasm_get_word_size() -> usize {

#[wasm_bindgen]
pub fn wasm_receive_input(data: &str) {
receive_input(data);
let mut simulator = get_simulator_mut();
let reader = simulator.get_reader_mut();
// TODO make wasm_reader and expand buffer for it, then use it here
let _ = reader.as_any_mut().downcast_mut::<DummyReader>().unwrap();
let _ = data;
}

#[wasm_bindgen(start)]
pub fn wasm_initialize_backend() {
register_instructions();
register_writer(Box::new(WasmWriter::new()));
initialize_simulator(
Some(ReaderCell::new(DummyReader::new())),
Some(Box::new(WasmWriter::new())),
);
}
Loading

0 comments on commit 5a4708e

Please sign in to comment.