use std::fmt;
use super::ir::{IRNode, serialize};
#[derive(Debug)]
#[allow(dead_code)]
pub struct Symbol {
pub symbol_name: String,
pub symbol_type: SymbolType,
pub symbol_value: Value,
}
#[derive(Debug)]
#[allow(dead_code)]
pub enum SymbolType {
Function,
Variable,
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum Value {
Void,
Function {
return_type: Type,
labels: Vec<String>,
},
Int(i64),
Float(f64)
}
#[allow(dead_code)]
impl Value {
pub fn to_ir(&self, expect: &str) -> IRNode {
match self {
Self::Int(int) => IRNode::ConstInt(*int),
Self::Float(float) => IRNode::ConstFloat(*float),
_ => panic!("{}", expect)
}
}
}
#[derive(Debug, Clone, Copy)]
#[allow(dead_code)]
pub enum Type {
Void,
Int,
Float
}
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Void => write!(f, "void"),
Self::Int => write!(f, "int"),
Self::Float => write!(f, "float")
}
}
}
#[derive(Debug, Clone)]
#[must_use = "Program should be used (serialized or processed)"]
pub struct Program {
pub program: Vec<IRNode>
}
impl fmt::Display for Program {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", serialize(&self.program))
}
}