init commit

This commit is contained in:
Skye Terran 2021-12-07 18:22:06 -08:00
parent 1a0dccbfc8
commit 212b353558
2 changed files with 177 additions and 0 deletions

8
Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "slipcode"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

169
src/main.rs Normal file
View File

@ -0,0 +1,169 @@
use std::io;
fn main() {
println!("Slipcode | Skye Terran, 2021");
let mut instructions: Vec<u8> = vec![];
let mut values: Vec<i32> = vec![];
loop {
let input = get_input();
let mut iter = input.iter();
loop {
let byte_opt = iter.next();
if byte_opt.is_some() {
let byte = byte_opt.unwrap();
instructions.push(*byte);
} else {
break;
}
}
execute(&mut instructions, &mut values);
}
}
fn get_input() -> Vec<u8> {
println!("\nEnter instruction:");
let mut input = String::new();
io::stdin().read_line(&mut input)
.expect("Couldn't read input!");
println!("\n");
input.truncate(input.len() - 2);
let bytes = input.as_bytes();
bytes.to_vec()
}
fn execute(instructions: &mut Vec<u8>, values: &mut Vec<i32>) {
debug_instructions(instructions);
let mut iter = instructions.iter();
// Handle literals
let mut is_literal = false;
let mut literal = [0u8; 8];
let mut lit_digit = 0;
loop {
let byte_opt = iter.next();
if is_literal {
if byte_opt.is_some() {
let byte = byte_opt.unwrap();
// Record another of the literal's bytes
literal[lit_digit] = *byte;
// Continue consuming the literal
if lit_digit >= 7 {
let num = f32::from_bits()
is_literal = false;
} else {
lit_digit += 1;
}
} else {
break;
}
} else {
if byte_opt.is_some() {
let byte = byte_opt.unwrap();
match byte {
65 => add(values),
75 => kill(values),
76 => is_literal = true,
83 => sub(values),
88 => swap(values),
_ => break
}
} else {
break;
}
}
}
instructions.clear();
println!("Values: {:?}", values);
}
fn debug_instructions(instructions: &Vec<u8>) {
let mut readable_stack: Vec<String> = Vec::new();
let mut iter = instructions.iter();
loop {
let mut name = "";
let value = iter.next();
if value.is_some() {
let byte = value.unwrap();
let byte_array = [*byte];
match byte {
45 => name = "MINUS",
46 => name = "POINT",
48..=57 => name = std::str::from_utf8(&byte_array).unwrap(),
65 => name = "ADD",
70 => name = "LITERAL_FLOAT",
73 => name = "LITERAL_INT",
75 => name = "KILL",
76 => name = "LITERAL",
83 => name = "SUB",
88 => name = "SWAP",
_ => name = "NULL"
}
readable_stack.push(name.to_string());
} else {
break;
}
}
println!("Bytes: {:?}", instructions);
println!("Instructions: {:?}", readable_stack);
}
fn add(values: &mut Vec<i32>) {
let b_opt = values.pop();
let a_opt = values.pop();
if a_opt.is_some() && b_opt.is_some() {
let a = a_opt.unwrap();
let b = b_opt.unwrap();
values.push(a + b);
} else {
println!("Not enough values.");
}
}
fn sub(values: &mut Vec<i32>) {
let b_opt = values.pop();
let a_opt = values.pop();
if a_opt.is_some() && b_opt.is_some() {
let a = a_opt.unwrap();
let b = b_opt.unwrap();
values.push(a - b);
} else {
println!("Not enough values.");
}
}
fn kill(values: &mut Vec<i32>) {
values.pop();
}
fn swap(values: &mut Vec<i32>) {
let b_opt = values.pop();
let a_opt = values.pop();
if a_opt.is_some() && b_opt.is_some() {
let a = a_opt.unwrap();
let b = b_opt.unwrap();
values.push(b);
values.push(a);
} else {
println!("Not enough values.");
}
}
// Instruction codes
// null (0) = NULL
// - (45) = MINUS
// . (46) = POINT
// 0..9 (48..57) = numbers 0..9
// F (70) = LIT_FLOAT
// I (73) = LIT_INT
// A (65) = ADD
// K (75) = KILL (removes top value from stack)
// L (76) = LITERAL
// S (83) = SUB
// X (88) = SWAP (switches the order of the last two values in the stack)