init commit
This commit is contained in:
parent
1a0dccbfc8
commit
212b353558
8
Cargo.toml
Normal file
8
Cargo.toml
Normal 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
169
src/main.rs
Normal 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)
|
Loading…
Reference in New Issue
Block a user