From 7521db33f2f303dbd6b093bb52060610a944237a Mon Sep 17 00:00:00 2001
From: Russel Arbore <russel.jma@gmail.com>
Date: Sun, 10 Sep 2023 15:26:38 -0500
Subject: [PATCH] Introduce dynamic constant type

---
 hercules_ir/src/ir.rs    | 26 +++++++++++++++++++---
 hercules_ir/src/parse.rs | 48 +++++++++++++++++++++++++++++++++++-----
 2 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs
index b0bdef63..ea239fdd 100644
--- a/hercules_ir/src/ir.rs
+++ b/hercules_ir/src/ir.rs
@@ -5,6 +5,7 @@ pub struct Module {
     pub functions: Vec<Function>,
     pub types: Vec<Type>,
     pub constants: Vec<Constant>,
+    pub dynamic_constants: Vec<DynamicConstant>,
 }
 
 #[derive(Debug, Clone)]
@@ -13,11 +14,12 @@ pub struct Function {
     pub param_types: Vec<TypeID>,
     pub return_type: TypeID,
     pub nodes: Vec<Node>,
+    pub num_dynamic_constants: u32,
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Type {
-    Control(ConstantID),
+    Control(DynamicConstantID),
     Integer8,
     Integer16,
     Integer32,
@@ -46,6 +48,11 @@ pub enum Constant {
     Float64(ordered_float::OrderedFloat<f64>),
 }
 
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum DynamicConstant {
+    Constant(usize),
+}
+
 #[derive(Debug, Clone)]
 pub enum Node {
     Start,
@@ -58,11 +65,11 @@ pub enum Node {
     },
     Fork {
         control: NodeID,
-        factor: ConstantID,
+        factor: DynamicConstantID,
     },
     Join {
         control: NodeID,
-        factor: ConstantID,
+        factor: DynamicConstantID,
     },
     Phi {
         control: NodeID,
@@ -156,3 +163,16 @@ impl TypeID {
         self.0 as usize
     }
 }
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct DynamicConstantID(u32);
+
+impl DynamicConstantID {
+    pub fn new(x: usize) -> Self {
+        DynamicConstantID(x as u32)
+    }
+
+    pub fn idx(&self) -> usize {
+        self.0 as usize
+    }
+}
diff --git a/hercules_ir/src/parse.rs b/hercules_ir/src/parse.rs
index af17d27d..1c2f67aa 100644
--- a/hercules_ir/src/parse.rs
+++ b/hercules_ir/src/parse.rs
@@ -14,6 +14,7 @@ struct Context<'a> {
     node_ids: HashMap<&'a str, NodeID>,
     interned_types: HashMap<Type, TypeID>,
     interned_constants: HashMap<Constant, ConstantID>,
+    interned_dynamic_constants: HashMap<DynamicConstant, DynamicConstantID>,
 }
 
 impl<'a> Context<'a> {
@@ -56,6 +57,16 @@ impl<'a> Context<'a> {
             id
         }
     }
+
+    fn get_dynamic_constant_id(&mut self, dynamic_constant: DynamicConstant) -> DynamicConstantID {
+        if let Some(id) = self.interned_dynamic_constants.get(&dynamic_constant) {
+            *id
+        } else {
+            let id = DynamicConstantID::new(self.interned_dynamic_constants.len());
+            self.interned_dynamic_constants.insert(dynamic_constant, id);
+            id
+        }
+    }
 }
 
 fn parse_module<'a>(ir_text: &'a str, mut context: Context<'a>) -> nom::IResult<&'a str, Module> {
@@ -68,7 +79,8 @@ fn parse_module<'a>(ir_text: &'a str, mut context: Context<'a>) -> nom::IResult<
             name: String::from(""),
             param_types: vec![],
             return_type: TypeID::new(0),
-            nodes: vec![]
+            nodes: vec![],
+            num_dynamic_constants: 0
         };
         context.function_ids.len()
     ];
@@ -77,7 +89,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(ConstantID::new(0)); context.interned_types.len()];
+    let mut types = vec![Type::Control(DynamicConstantID::new(0)); context.interned_types.len()];
     for (ty, id) in context.interned_types {
         types[id.idx()] = ty;
     }
@@ -85,12 +97,18 @@ fn parse_module<'a>(ir_text: &'a str, mut context: Context<'a>) -> nom::IResult<
     for (constant, id) in context.interned_constants {
         constants[id.idx()] = constant;
     }
+    let mut dynamic_constants =
+        vec![DynamicConstant::Constant(0); context.interned_dynamic_constants.len()];
+    for (dynamic_constant, id) in context.interned_dynamic_constants {
+        dynamic_constants[id.idx()] = dynamic_constant;
+    }
     Ok((
         rest,
         Module {
             functions: fixed_functions,
             types,
             constants,
+            dynamic_constants,
         },
     ))
 }
@@ -146,6 +164,7 @@ fn parse_function<'a>(
             param_types: params.into_iter().map(|x| x.5).collect(),
             return_type,
             nodes: fixed_nodes,
+            num_dynamic_constants: 0,
         },
     ))
 }
@@ -198,7 +217,7 @@ fn parse_constant_node<'a>(
     let ir_text = nom::character::complete::multispace0(ir_text)?.0;
     let ir_text = nom::character::complete::char('(')(ir_text)?.0;
     let ir_text = nom::character::complete::multispace0(ir_text)?.0;
-    let (ir_text, ty) = parse_type(ir_text)?;
+    let (ir_text, ty) = parse_type(ir_text, context)?;
     let ir_text = nom::character::complete::multispace0(ir_text)?.0;
     let ir_text = nom::character::complete::char(',')(ir_text)?.0;
     let ir_text = nom::character::complete::multispace0(ir_text)?.0;
@@ -268,15 +287,25 @@ fn parse_call<'a>(ir_text: &'a str, context: &mut Context<'a>) -> nom::IResult<&
 
 fn parse_type_id<'a>(ir_text: &'a str, context: &mut Context<'a>) -> nom::IResult<&'a str, TypeID> {
     let ir_text = nom::character::complete::multispace0(ir_text)?.0;
-    let (ir_text, ty) = parse_type(ir_text)?;
+    let (ir_text, ty) = parse_type(ir_text, context)?;
     let id = context.get_type_id(ty);
     Ok((ir_text, id))
 }
 
-fn parse_type<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Type> {
+fn parse_type<'a>(ir_text: &'a str, context: &mut Context<'a>) -> 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::sequence::tuple((
+                nom::bytes::complete::tag("ctrl"),
+                nom::character::complete::multispace0,
+                nom::character::complete::char('('),
+                |x| parse_dynamic_constant_id(x, context),
+                nom::character::complete::multispace0,
+                nom::character::complete::char(')'),
+            )),
+            |(_, _, _, id, _, _)| Type::Control(id),
+        ),
         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),
@@ -297,6 +326,13 @@ fn parse_type<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Type> {
     Ok((ir_text, ty))
 }
 
+fn parse_dynamic_constant_id<'a>(
+    ir_text: &'a str,
+    context: &mut Context<'a>,
+) -> nom::IResult<&'a str, DynamicConstantID> {
+    todo!()
+}
+
 fn parse_constant_id<'a>(
     ir_text: &'a str,
     ty: Type,
-- 
GitLab