96 lines
2.2 KiB
Rust
96 lines
2.2 KiB
Rust
use crate::{
|
|
functions::{Function, ir::Instruction},
|
|
types::Type,
|
|
};
|
|
use bitflags::bitflags;
|
|
use derive_more::{Debug, Display, *};
|
|
use std::hash::Hash;
|
|
|
|
mod constants;
|
|
pub use constants::*;
|
|
|
|
bitflags! {
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub struct ValueFlags: u16 {
|
|
const Mutable = 0b00000000_00000001;
|
|
const Volatile = 0b00000000_00000010;
|
|
const LValue = 0b00000000_00000100;
|
|
const Const = 0b00000001_00000000;
|
|
const ConstOnly = 0b00000011_00000000;
|
|
const Type = 0b00000111_00000000;
|
|
const Function = 0b00001011_00000000;
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Display, Clone, Copy, From, TryInto, PartialEq, Eq, Hash)]
|
|
pub enum AnyValue<'l> {
|
|
#[display("{_0}")]
|
|
Constant(AnyConst<'l>),
|
|
#[display("{_0}")]
|
|
Instruction(&'l Instruction<'l>),
|
|
|
|
#[debug("${_0}")]
|
|
#[display("${_0}")]
|
|
Parameter(usize, &'l Function<'l>),
|
|
}
|
|
|
|
impl From<Int> for AnyValue<'_> {
|
|
fn from(value: Int) -> Self {
|
|
AnyValue::Constant(AnyConst::Int(value))
|
|
}
|
|
}
|
|
|
|
pub trait Value<'l> {
|
|
fn ty(&self) -> Type<'l>;
|
|
fn flags(&self) -> ValueFlags;
|
|
fn get_associated_value(&self, name: &str) -> Option<AnyValue<'l>>;
|
|
fn as_any_value(&self) -> AnyValue<'l>;
|
|
|
|
#[inline]
|
|
fn is_const(&self) -> bool {
|
|
self.flags().contains(ValueFlags::Const)
|
|
}
|
|
|
|
#[inline]
|
|
fn is_lvalue(&self) -> bool {
|
|
self.flags().contains(ValueFlags::LValue)
|
|
}
|
|
}
|
|
|
|
impl<'l> Value<'l> for AnyValue<'l> {
|
|
fn ty(&self) -> Type<'l> {
|
|
match self {
|
|
AnyValue::Constant(v) => v.ty(),
|
|
AnyValue::Instruction(v) => v.ty(),
|
|
AnyValue::Parameter(i, f) => f.ty.par_t[*i],
|
|
}
|
|
}
|
|
|
|
fn flags(&self) -> ValueFlags {
|
|
match self {
|
|
AnyValue::Instruction(v) => v.flags(),
|
|
AnyValue::Parameter(_, _) => ValueFlags::empty(),
|
|
AnyValue::Constant(c) => c.flags(),
|
|
}
|
|
}
|
|
|
|
fn get_associated_value(&self, name: &str) -> Option<AnyValue<'l>> {
|
|
match self {
|
|
AnyValue::Constant(v) => v.get_associated_value(name),
|
|
AnyValue::Instruction(v) => todo!(),
|
|
AnyValue::Parameter(_, _) => default_associated_values(self, name),
|
|
}
|
|
}
|
|
|
|
fn as_any_value(&self) -> AnyValue<'l> {
|
|
*self
|
|
}
|
|
}
|
|
|
|
pub(crate) fn default_associated_values<'l>(v: &dyn Value<'l>, name: &str) -> Option<AnyValue<'l>> {
|
|
match name {
|
|
"#type" => Some(AnyValue::Constant(AnyConst::Type(v.ty()))),
|
|
_ => None,
|
|
}
|
|
}
|