init commit
This commit is contained in:
parent
1a0dccbfc8
commit
212b353558
|
@ -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]
|
|
@ -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