diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs
index 172f5ad9dd74462507415caffaeb07b720d2e908..b0bdef63bc0e603ff1ae3a42b3cd6782b493b68b 100644
--- a/hercules_ir/src/ir.rs
+++ b/hercules_ir/src/ir.rs
@@ -17,7 +17,7 @@ pub struct Function {
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Type {
-    Control(u64),
+    Control(ConstantID),
     Integer8,
     Integer16,
     Integer32,
@@ -28,6 +28,8 @@ pub enum Type {
     UnsignedInteger64,
     Float32,
     Float64,
+    Product(Box<[TypeID]>),
+    Summation(Box<[TypeID]>),
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -56,11 +58,11 @@ pub enum Node {
     },
     Fork {
         control: NodeID,
-        factor: usize,
+        factor: ConstantID,
     },
     Join {
         control: NodeID,
-        factor: usize,
+        factor: ConstantID,
     },
     Phi {
         control: NodeID,
diff --git a/hercules_ir/src/parse.rs b/hercules_ir/src/parse.rs
index ff3bfa4d2eba9b48feac2d3d6fd014bdb4444ec8..af17d27db69a4a9a4a22fea5b965cbb17e7419c6 100644
--- a/hercules_ir/src/parse.rs
+++ b/hercules_ir/src/parse.rs
@@ -77,7 +77,7 @@ fn parse_module<'a>(ir_text: &'a str, mut context: Context<'a>) -> nom::IResult<
         let function_id = context.function_ids.remove(function_name.as_str()).unwrap();
         fixed_functions[function_id.idx()] = function;
     }
-    let mut types = vec![Type::Control(0); context.interned_types.len()];
+    let mut types = vec![Type::Control(ConstantID::new(0)); context.interned_types.len()];
     for (ty, id) in context.interned_types {
         types[id.idx()] = ty;
     }
@@ -276,8 +276,23 @@ fn parse_type_id<'a>(ir_text: &'a str, context: &mut Context<'a>) -> nom::IResul
 fn parse_type<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Type> {
     let ir_text = nom::character::complete::multispace0(ir_text)?.0;
     let (ir_text, ty) = nom::branch::alt((
+        //nom::sequence::tuple((nom::bytes::complete::tag(""))),
         nom::combinator::map(nom::bytes::complete::tag("i8"), |_| Type::Integer8),
+        nom::combinator::map(nom::bytes::complete::tag("i16"), |_| Type::Integer16),
         nom::combinator::map(nom::bytes::complete::tag("i32"), |_| Type::Integer32),
+        nom::combinator::map(nom::bytes::complete::tag("i64"), |_| Type::Integer64),
+        nom::combinator::map(nom::bytes::complete::tag("u8"), |_| Type::UnsignedInteger8),
+        nom::combinator::map(nom::bytes::complete::tag("u16"), |_| {
+            Type::UnsignedInteger16
+        }),
+        nom::combinator::map(nom::bytes::complete::tag("u32"), |_| {
+            Type::UnsignedInteger32
+        }),
+        nom::combinator::map(nom::bytes::complete::tag("u64"), |_| {
+            Type::UnsignedInteger64
+        }),
+        nom::combinator::map(nom::bytes::complete::tag("f32"), |_| Type::Float32),
+        nom::combinator::map(nom::bytes::complete::tag("f64"), |_| Type::Float64),
     ))(ir_text)?;
     Ok((ir_text, ty))
 }