use std::fmt; use std::fmt::Display; use std::ops::{Add, Sub}; pub type FuncID = u16; pub type HeapID = u16; pub type RegID = u8; #[derive(Debug, Clone)] pub enum Command { InitializeVariable(HeapID, VariableType), // Initializes new variable to HeapID at VariableType BeginScope, // Begins new Scope EndScope, // Ends Scope Pop(RegID), // Pop into registery at RegID Push(RegID), // Push out of registery at RegID AssignVariable(HeapID, RegID), // Assign variable from registery at RegID VarToReg(HeapID, RegID), // Bring Variable to registery at RegID StringLit(String), // Bring String Literal to Stack I32Lit(i32), // Bring i32 Literal to Stack FunctionCall(FuncID), // Call Function at FuncID Add, // Add last two items on stack Subtract, // Subtract last two items on stack Mult, // Subtract last two items on stack } #[derive(Debug)] pub struct CompiledReid { pub list: Vec, } #[derive(Clone, Debug, PartialEq, Eq)] pub enum Value { StringVal(String), I32Val(i32), } impl Value { pub fn get_type(&self) -> VariableType { match self { Value::StringVal(_) => VariableType::TypeString, Value::I32Val(_) => VariableType::TypeI32, } } pub fn add(self, other: Value) -> Option { match self { Value::StringVal(string) => match other { Value::StringVal(string2) => Some(Value::StringVal(string + &string2)), Value::I32Val(val) => Some(Value::StringVal(string + &val.to_string())), }, Value::I32Val(val) => match other { Value::StringVal(string) => Some(Value::StringVal(val.to_string() + &string)), Value::I32Val(val2) => Some(Value::I32Val(val + val2)), }, } } pub fn sub(self, other: Value) -> Option { match self { Value::StringVal(_) => None, Value::I32Val(val) => match other { Value::I32Val(val2) => Some(Value::I32Val(val - val2)), _ => None, }, } } pub fn mul(self, other: Value) -> Option { match self { Value::StringVal(_) => None, Value::I32Val(val) => match other { Value::I32Val(val2) => Some(Value::I32Val(val * val2)), _ => None, }, } } } #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum VariableType { TypeString, TypeI32, } impl ToString for VariableType { fn to_string(&self) -> String { match self { VariableType::TypeString => "String".to_string(), VariableType::TypeI32 => "i32".to_string(), } } } #[derive(Debug, Copy, Clone)] pub struct Position(pub usize, pub usize); impl Display for Position { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "line {}, column {}", self.0, self.1) } }