diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs index 2ba4f19dcd85510463fcdcaa8f5e258eff41ec98..fb25875ae9656e6f397b7af907a8c7f384d1c0a1 100644 --- a/hercules_ir/src/ir.rs +++ b/hercules_ir/src/ir.rs @@ -47,6 +47,9 @@ pub enum Constant { UnsignedInteger64(u64), Float32(ordered_float::OrderedFloat<f32>), Float64(ordered_float::OrderedFloat<f64>), + Product(TypeID, Box<[ConstantID]>), + Summation(TypeID, u32, ConstantID), + Array(TypeID, Box<[ConstantID]>), } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/hercules_ir/src/parse.rs b/hercules_ir/src/parse.rs index f3ade2dc9c6dd340dcdfe25d15e7885a6fa96466..3cd73720d1df4ee0854e57b1d29e32febc009b88 100644 --- a/hercules_ir/src/parse.rs +++ b/hercules_ir/src/parse.rs @@ -15,6 +15,7 @@ struct Context<'a> { function_ids: HashMap<&'a str, FunctionID>, node_ids: HashMap<&'a str, NodeID>, interned_types: HashMap<Type, TypeID>, + reverse_type_map: HashMap<TypeID, Type>, interned_constants: HashMap<Constant, ConstantID>, interned_dynamic_constants: HashMap<DynamicConstant, DynamicConstantID>, } @@ -45,7 +46,8 @@ impl<'a> Context<'a> { *id } else { let id = TypeID::new(self.interned_types.len()); - self.interned_types.insert(ty, id); + self.interned_types.insert(ty.clone(), id); + self.reverse_type_map.insert(id, ty); id } } @@ -477,7 +479,7 @@ fn parse_constant<'a>( ty: Type, context: &RefCell<Context<'a>>, ) -> nom::IResult<&'a str, Constant> { - let (ir_text, constant) = match ty { + let (ir_text, constant) = match ty.clone() { Type::Integer8 => parse_integer8(ir_text)?, Type::Integer16 => parse_integer16(ir_text)?, Type::Integer32 => parse_integer32(ir_text)?, @@ -488,6 +490,12 @@ fn parse_constant<'a>( Type::UnsignedInteger64 => parse_unsigned_integer64(ir_text)?, Type::Float32 => parse_float32(ir_text)?, Type::Float64 => parse_float64(ir_text)?, + Type::Product(tys) => parse_product_constant( + ir_text, + context.borrow_mut().get_type_id(ty.clone()), + tys, + context, + )?, _ => todo!(), }; context.borrow_mut().get_type_id(ty); @@ -561,6 +569,39 @@ fn parse_float64<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { )) } +fn parse_product_constant<'a>( + ir_text: &'a str, + prod_ty: TypeID, + tys: Box<[TypeID]>, + context: &RefCell<Context<'a>>, +) -> nom::IResult<&'a str, Constant> { + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::bytes::complete::tag("prod")(ir_text)?.0; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let mut ir_text = nom::character::complete::char('(')(ir_text)?.0; + let mut subconstants = vec![]; + for ty in tys.iter() { + if !subconstants.is_empty() { + ir_text = nom::character::complete::multispace0(ir_text)?.0; + ir_text = nom::character::complete::char(',')(ir_text)?.0; + } + ir_text = nom::character::complete::multispace0(ir_text)?.0; + let (ir_text_tmp, id) = parse_constant_id( + ir_text, + context.borrow().reverse_type_map.get(ty).unwrap().clone(), + context, + )?; + subconstants.push(id); + ir_text = ir_text_tmp; + } + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char(')')(ir_text)?.0; + Ok(( + ir_text, + Constant::Product(prod_ty, subconstants.into_boxed_slice()), + )) +} + mod tests { #[allow(unused_imports)] use super::*;