cairo_lang_sierra_generator/
pre_sierra.rsuse std::hash::Hash;
use cairo_lang_debug::DebugWithDb;
use cairo_lang_defs::diagnostic_utils::StableLocation;
use cairo_lang_lowering::ids::ConcreteFunctionWithBodyId;
use cairo_lang_sierra as sierra;
use cairo_lang_sierra::ids::ConcreteTypeId;
use cairo_lang_sierra::program;
use cairo_lang_utils::{define_short_id, write_comma_separated, LookupIntern};
use crate::db::SierraGenGroup;
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct LabelLongId {
pub parent: ConcreteFunctionWithBodyId,
pub id: usize,
}
define_short_id!(LabelId, LabelLongId, SierraGenGroup, lookup_intern_label_id, intern_label_id);
pub struct LabelIdWithDb<'db> {
db: &'db dyn SierraGenGroup,
label_id: LabelId,
}
impl<'db> std::fmt::Display for LabelIdWithDb<'db> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let LabelLongId { parent, id } = self.label_id.lookup_intern(self.db);
let parent = parent.function_id(self.db.upcast()).unwrap();
let dbg = format!("{:?}", parent.debug(self.db));
write!(f, "label_{}::{}", dbg, id)
}
}
impl LabelId {
pub fn with_db<'db>(&self, db: &'db dyn SierraGenGroup) -> LabelIdWithDb<'db> {
LabelIdWithDb { db, label_id: *self }
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Function {
pub id: sierra::ids::FunctionId,
pub body: Vec<StatementWithLocation>,
pub entry_point: LabelId,
pub parameters: Vec<program::Param>,
pub ret_types: Vec<sierra::ids::ConcreteTypeId>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Statement {
Sierra(program::GenStatement<LabelId>),
Label(Label),
PushValues(Vec<PushValue>),
}
impl Statement {
pub fn into_statement_without_location(self) -> StatementWithLocation {
StatementWithLocation { statement: self, location: vec![] }
}
pub fn to_string(&self, db: &dyn SierraGenGroup) -> String {
StatementWithDb { db, statement: self.clone() }.to_string()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct StatementWithLocation {
pub statement: Statement,
pub location: Vec<StableLocation>,
}
impl StatementWithLocation {
pub fn set_location(&mut self, location: Vec<StableLocation>) {
self.location = location;
}
}
struct StatementWithDb<'db> {
db: &'db dyn SierraGenGroup,
statement: Statement,
}
impl<'db> std::fmt::Display for StatementWithDb<'db> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.statement {
Statement::Sierra(value) => {
write!(f, "{}", value.clone().map(|label_id| label_id.with_db(self.db)))
}
Statement::Label(Label { id }) => {
write!(f, "{}:", id.with_db(self.db))
}
Statement::PushValues(values) => {
write!(f, "PushValues(")?;
write_comma_separated(
f,
values.iter().map(|PushValue { var, ty, .. }| format!("{var}: {ty}")),
)?;
write!(f, ") -> (")?;
write_comma_separated(
f,
values.iter().map(|PushValue { var_on_stack, dup, .. }| {
if *dup { format!("{var_on_stack}*") } else { format!("{var_on_stack}") }
}),
)?;
write!(f, ")")
}
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PushValue {
pub var: sierra::ids::VarId,
pub var_on_stack: sierra::ids::VarId,
pub ty: ConcreteTypeId,
pub dup: bool,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Label {
pub id: LabelId,
}