refactored logic with Opcode enum, starting to support typed literals

This commit is contained in:
Skye Terran 2021-12-09 17:50:16 -08:00
parent cc04958955
commit 3cad6aa362

View File

@ -29,7 +29,20 @@ use std::env;
// 0x1e: MIN // 0x1e: MIN
// 0x1f: MAX // 0x1f: MAX
// ./slipcode Q:/Code/slipcompiler/Test.slb // Contextual: literal types
// 0x00: BOOL (boolean) # Example: LIT BOOL 0
// 0x01: INT (int) # Example: LIT INT 69
// 0x02: FLT (float) # Example: LIT FLT -90.0
// 0x03: VEC (vector) # Example: LIT VEC 1.0 -7.01 2.7
// ./slipcode Q:/Code/slipcompiler/Test.vcr
// Opcode enum
enum Opcode {
Generic,
Type,
Value
}
fn main() { fn main() {
println!("Slipcode | Skye Terran, 2021\n"); println!("Slipcode | Skye Terran, 2021\n");
@ -42,32 +55,31 @@ fn main() {
execute(&mut instructions, &mut values); 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<f32>) { fn execute(instructions: &mut Vec<u8>, values: &mut Vec<f32>) {
println!("Executing bytecode instructions...\n"); println!("Executing bytecode instructions...\n");
let mut iter = instructions.iter(); let mut iter = instructions.iter();
// Handle literals // Handle literals
let mut is_literal = false; let mut op_type: Opcode = Opcode::Generic;
let mut literal = [0u8; 4]; let mut literal = [0u8; 4];
let mut lit_digit = 0; let mut lit_digit = 0;
// Handle each opcode in order
loop { loop {
let byte_opt = iter.next(); let byte_opt = iter.next();
if is_literal { // Contextually handle opcodes depending on their type
match op_type {
// Treat the opcode as a literal type declaration
Opcode::Type => {
// Consume the literal type
let byte = byte_opt.unwrap();
// The following opcodes are expected to be a literal value
op_type = Opcode::Value;
},
// Treat the opcode as a literal value
Opcode::Value => {
if byte_opt.is_some() { if byte_opt.is_some() {
let byte = byte_opt.unwrap(); let byte = byte_opt.unwrap();
// Record another of the literal's bytes // Record another of the literal's bytes
@ -79,7 +91,7 @@ fn execute(instructions: &mut Vec<u8>, values: &mut Vec<f32>) {
values.push(num); values.push(num);
println!("LIT {:?}", num); println!("LIT {:?}", num);
println!("Values: {:?}\n", values); println!("Values: {:?}\n", values);
is_literal = false; op_type = Opcode::Generic;
lit_digit = 0; lit_digit = 0;
} else { } else {
lit_digit += 1; lit_digit += 1;
@ -87,11 +99,13 @@ fn execute(instructions: &mut Vec<u8>, values: &mut Vec<f32>) {
} else { } else {
break; break;
} }
} else { },
// Treat the opcode as a generic command
_ => {
if byte_opt.is_some() { if byte_opt.is_some() {
let byte = byte_opt.unwrap(); let byte = byte_opt.unwrap();
match byte { match byte {
0x01 => is_literal = true, 0x01 => op_type = Opcode::Type,
0x02 => swap(values), 0x02 => swap(values),
0x03 => del(values), 0x03 => del(values),
0x04 => copy(values), 0x04 => copy(values),
@ -101,7 +115,8 @@ fn execute(instructions: &mut Vec<u8>, values: &mut Vec<f32>) {
0x19 => floor(values), 0x19 => floor(values),
_ => break _ => break
} }
if !is_literal { // DEBUG - show the value stack upon every generic command
if let Opcode::Generic = op_type {
println!("Values: {:?}\n", values); println!("Values: {:?}\n", values);
} }
} else { } else {
@ -109,6 +124,7 @@ fn execute(instructions: &mut Vec<u8>, values: &mut Vec<f32>) {
} }
} }
} }
}
instructions.clear(); instructions.clear();
} }