use crate::parser::Parser;
use crate::typ::APInt;
use crate::typ::IntegerType;
use crate::Parse;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result;
pub trait Attribute {
fn new(name: &str, value: &str) -> Self
where
Self: Sized;
fn parse<T: Parse>(parser: &mut Parser<T>, name: &str) -> Option<Self>
where
Self: Sized;
fn as_any(&self) -> &dyn std::any::Any;
fn value(&self) -> String;
fn display(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{}", self.value())
}
}
impl Display for dyn Attribute {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
self.display(f)
}
}
pub struct Attributes {
attrs: Vec<Box<dyn Attribute>>,
}
impl Attributes {
fn new(attrs: Vec<Box<dyn Attribute>>) -> Self {
Self { attrs }
}
}
impl Display for Attributes {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
for attribute in &self.attrs {
write!(f, "{}", attribute)?;
}
Ok(())
}
}
pub struct IntegerAttr {
typ: IntegerType,
value: APInt,
}
impl IntegerAttr {
pub fn new(typ: IntegerType, value: APInt) -> Self {
Self { typ, value }
}
pub fn typ(&self) -> &IntegerType {
&self.typ
}
pub fn i64(&self) -> i64 {
let int = &self.value;
assert!(int.is_signed(), "must be signed integer");
int.value() as i64
}
pub fn u64(&self) -> u64 {
assert!(!self.value.is_signed(), "must be unsigned integer");
self.value.value()
}
}
impl Display for IntegerAttr {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
self.display(f)
}
}
impl Attribute for IntegerAttr {
fn new(_name: &str, value: &str) -> Self {
Self {
typ: IntegerType::new(64),
value: APInt::new(64, value.parse::<u64>().unwrap(), true),
}
}
fn parse<T: Parse>(_parser: &mut Parser<T>, _name: &str) -> Option<Self> {
todo!()
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn value(&self) -> String {
self.value.to_string()
}
fn display(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{} : {}", self.value, self.typ)
}
}
impl IntegerAttr {
pub fn add(a: &IntegerAttr, b: &IntegerAttr) -> IntegerAttr {
let a_value = a.value().parse::<u64>().unwrap();
let b_value = b.value().parse::<u64>().unwrap();
let value = a_value + b_value;
let value = APInt::new(64, value, true);
IntegerAttr::new(a.typ, value)
}
}
pub struct StrAttr {
name: String,
value: String,
}
impl Attribute for StrAttr {
fn new(name: &str, value: &str) -> Self {
Self {
name: name.to_string(),
value: value.to_string(),
}
}
fn parse<T: Parse>(parser: &mut Parser<T>, name: &str) -> Option<Self> {
let value = parser.advance();
Some(Self {
name: name.to_string(),
value: value.lexeme.to_string(),
})
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn value(&self) -> String {
self.value.clone()
}
fn display(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{}", self.value)
}
}
impl StrAttr {
fn symbol_name(&self) -> String {
self.value.clone()
}
}
pub struct AnyAttr {
name: String,
value: String,
}
impl Attribute for AnyAttr {
fn new(name: &str, value: &str) -> Self {
Self {
name: name.to_string(),
value: value.to_string(),
}
}
fn parse<T: Parse>(parser: &mut Parser<T>, name: &str) -> Option<Self> {
let value = parser.advance();
Some(Self {
name: name.to_string(),
value: value.lexeme.to_string(),
})
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn value(&self) -> String {
self.value.clone()
}
fn display(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{}", self.value)
}
}