103 lines
3.2 KiB
Rust
103 lines
3.2 KiB
Rust
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<Command>,
|
|
}
|
|
|
|
#[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<Value> {
|
|
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<Value> {
|
|
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<Value> {
|
|
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)
|
|
}
|
|
}
|