Files
leaf/assembly/src/values/mod.rs
T
2026-03-07 18:21:48 +01:00

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(_) => default_associated_values(self, name),
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,
}
}