refactored logic with Opcode enum, starting to support typed literals
This commit is contained in:
parent
cc04958955
commit
3cad6aa362
58
src/main.rs
58
src/main.rs
@ -29,7 +29,20 @@ use std::env;
|
||||
// 0x1e: MIN
|
||||
// 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() {
|
||||
println!("Slipcode | Skye Terran, 2021\n");
|
||||
@ -42,32 +55,31 @@ fn main() {
|
||||
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>) {
|
||||
println!("Executing bytecode instructions...\n");
|
||||
let mut iter = instructions.iter();
|
||||
|
||||
// Handle literals
|
||||
let mut is_literal = false;
|
||||
let mut op_type: Opcode = Opcode::Generic;
|
||||
let mut literal = [0u8; 4];
|
||||
let mut lit_digit = 0;
|
||||
|
||||
// Handle each opcode in order
|
||||
loop {
|
||||
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() {
|
||||
let byte = byte_opt.unwrap();
|
||||
// Record another of the literal's bytes
|
||||
@ -79,7 +91,7 @@ fn execute(instructions: &mut Vec<u8>, values: &mut Vec<f32>) {
|
||||
values.push(num);
|
||||
println!("LIT {:?}", num);
|
||||
println!("Values: {:?}\n", values);
|
||||
is_literal = false;
|
||||
op_type = Opcode::Generic;
|
||||
lit_digit = 0;
|
||||
} else {
|
||||
lit_digit += 1;
|
||||
@ -87,11 +99,13 @@ fn execute(instructions: &mut Vec<u8>, values: &mut Vec<f32>) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
},
|
||||
// Treat the opcode as a generic command
|
||||
_ => {
|
||||
if byte_opt.is_some() {
|
||||
let byte = byte_opt.unwrap();
|
||||
match byte {
|
||||
0x01 => is_literal = true,
|
||||
0x01 => op_type = Opcode::Type,
|
||||
0x02 => swap(values),
|
||||
0x03 => del(values),
|
||||
0x04 => copy(values),
|
||||
@ -101,7 +115,8 @@ fn execute(instructions: &mut Vec<u8>, values: &mut Vec<f32>) {
|
||||
0x19 => floor(values),
|
||||
_ => break
|
||||
}
|
||||
if !is_literal {
|
||||
// DEBUG - show the value stack upon every generic command
|
||||
if let Opcode::Generic = op_type {
|
||||
println!("Values: {:?}\n", values);
|
||||
}
|
||||
} else {
|
||||
@ -109,6 +124,7 @@ fn execute(instructions: &mut Vec<u8>, values: &mut Vec<f32>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
instructions.clear();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user