diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs index febb35e6beb593735b1132422976207e52411e04..f5eb4a6882d2da039978d7f1d7e6a49f598c825b 100644 --- a/hercules_ir/src/ir.rs +++ b/hercules_ir/src/ir.rs @@ -8,6 +8,8 @@ pub struct Module { #[derive(Clone)] pub struct Function { pub name: String, + pub param_types: Vec<TypeID>, + pub return_type: TypeID, pub nodes: Vec<Node>, } @@ -44,11 +46,11 @@ pub enum Node { }, Fork { control: NodeID, - factor: u64, + factor: usize, }, Join { control: NodeID, - factor: u64, + factor: usize, }, Phi { control: NodeID, @@ -59,7 +61,7 @@ pub enum Node { value: NodeID, }, Parameter { - index: u64, + index: usize, }, Constant { id: ConstantID, @@ -93,6 +95,10 @@ pub enum Node { pub struct FunctionID(u32); impl FunctionID { + pub fn new(x: usize) -> Self { + FunctionID(x as u32) + } + pub fn idx(&self) -> usize { self.0 as usize } @@ -102,6 +108,10 @@ impl FunctionID { pub struct NodeID(u32); impl NodeID { + pub fn new(x: usize) -> Self { + NodeID(x as u32) + } + pub fn idx(&self) -> usize { self.0 as usize } @@ -111,6 +121,10 @@ impl NodeID { pub struct ConstantID(u32); impl ConstantID { + pub fn new(x: usize) -> Self { + ConstantID(x as u32) + } + pub fn idx(&self) -> usize { self.0 as usize } @@ -120,6 +134,10 @@ impl ConstantID { pub struct TypeID(u32); impl TypeID { + pub fn new(x: usize) -> Self { + TypeID(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 0f27a411b810c7432bb0fd6bfbb3fe70fe77ef45..d6245d8e27fb4024392c45298f415f7e348dc50d 100644 --- a/hercules_ir/src/parse.rs +++ b/hercules_ir/src/parse.rs @@ -17,8 +17,10 @@ struct Context<'a> { } fn parse_module<'a>(ir_text: &'a str, mut context: Context<'a>) -> nom::IResult<&'a str, Module> { - let (rest, functions) = nom::multi::many0(|x| parse_function(x, &mut context))(ir_text)?; - nom::combinator::eof(rest)?; + let (rest, functions) = + nom::combinator::all_consuming(nom::multi::many0(|x| parse_function(x, &mut context)))( + ir_text, + )?; let mut types = vec![Type::Control(0); context.interned_types.len()]; for (ty, id) in context.interned_types { types[id.idx()] = ty; @@ -41,6 +43,65 @@ fn parse_function<'a>( ir_text: &'a str, context: &mut Context<'a>, ) -> nom::IResult<&'a str, Function> { + context.node_ids.clear(); + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::bytes::complete::tag("fn")(ir_text)?.0; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let (ir_text, function_name) = nom::character::complete::alphanumeric0(ir_text)?; + let ir_text = nom::character::complete::char('(')(ir_text)?.0; + let (ir_text, params) = nom::multi::separated_list0( + nom::character::complete::char(','), + nom::sequence::tuple(( + nom::character::complete::alphanumeric1, + nom::character::complete::multispace0, + nom::character::complete::char(':'), + nom::character::complete::multispace0, + |x| parse_type(x, context), + )), + )(ir_text)?; + for param in params.iter() { + context + .node_ids + .insert(param.0, NodeID::new(context.node_ids.len())); + } + let ir_text = nom::character::complete::char(')')(ir_text)?.0; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::bytes::complete::tag("->")(ir_text)?.0; + let (ir_text, return_type) = parse_type(ir_text, context)?; + let (ir_text, nodes) = nom::multi::many1(|x| parse_node(x, context))(ir_text)?; + let mut fixed_nodes = vec![Node::Start; context.node_ids.len()]; + for (name, node) in nodes { + fixed_nodes[context.node_ids.remove(name).unwrap().idx()] = node; + } + for (_, id) in context.node_ids.iter() { + fixed_nodes[id.idx()] = Node::Parameter { index: id.idx() } + } + return Ok(( + ir_text, + Function { + name: String::from(function_name), + param_types: params.into_iter().map(|x| x.4).collect(), + return_type, + nodes: fixed_nodes, + }, + )); +} + +fn parse_node<'a>( + ir_text: &'a str, + context: &mut Context<'a>, +) -> nom::IResult<&'a str, (&'a str, Node)> { + todo!() +} + +fn parse_type<'a>(ir_text: &'a str, context: &mut Context<'a>) -> nom::IResult<&'a str, TypeID> { + todo!() +} + +fn parse_constant<'a>( + ir_text: &'a str, + context: &mut Context<'a>, +) -> nom::IResult<&'a str, ConstantID> { todo!() }