diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs index 2589e0bd0d45cc735da800c3a012104fa8bcf9e2..005de05091789f50b4b48a4508d4230d15625a55 100644 --- a/hercules_ir/src/ir.rs +++ b/hercules_ir/src/ir.rs @@ -1,13 +1,13 @@ extern crate ordered_float; -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct Module { pub functions: Vec<Function>, pub types: Vec<Type>, pub constants: Vec<Constant>, } -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct Function { pub name: String, pub param_types: Vec<TypeID>, @@ -15,7 +15,7 @@ pub struct Function { pub nodes: Vec<Node>, } -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Control(u64), Integer8, @@ -26,7 +26,7 @@ pub enum Type { Float64, } -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Constant { Integer8(u8), Integer16(u16), @@ -36,7 +36,7 @@ pub enum Constant { Float64(ordered_float::OrderedFloat<f64>), } -#[derive(Clone)] +#[derive(Debug, Clone)] pub enum Node { Start, Region { @@ -93,7 +93,7 @@ pub enum Node { }, } -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct FunctionID(u32); impl FunctionID { @@ -106,7 +106,7 @@ impl FunctionID { } } -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct NodeID(u32); impl NodeID { @@ -119,7 +119,7 @@ impl NodeID { } } -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct ConstantID(u32); impl ConstantID { @@ -132,7 +132,7 @@ impl ConstantID { } } -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct TypeID(u32); impl TypeID { diff --git a/hercules_ir/src/parse.rs b/hercules_ir/src/parse.rs index e854ddb14536eeea34738ce7a7ba93ba93e308f1..e70e608ae4b2213fef7497cec3ebf28568dd1518 100644 --- a/hercules_ir/src/parse.rs +++ b/hercules_ir/src/parse.rs @@ -16,6 +16,18 @@ struct Context<'a> { interned_constants: HashMap<Constant, ConstantID>, } +impl<'a> Context<'a> { + fn get_node_id(&mut self, name: &'a str) -> NodeID { + if let Some(id) = self.node_ids.get(name) { + *id + } else { + let id = NodeID::new(self.node_ids.len()); + self.node_ids.insert(name, id); + id + } + } +} + fn parse_module<'a>(ir_text: &'a str, mut context: Context<'a>) -> nom::IResult<&'a str, Module> { let (rest, functions) = nom::combinator::all_consuming(nom::multi::many0(|x| parse_function(x, &mut context)))( @@ -47,22 +59,25 @@ fn parse_function<'a>( 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, function_name) = nom::character::complete::alphanumeric1(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::multispace0, nom::character::complete::alphanumeric1, nom::character::complete::multispace0, nom::character::complete::char(':'), nom::character::complete::multispace0, |x| parse_type(x, context), + nom::character::complete::multispace0, )), )(ir_text)?; + context.node_ids.insert("start", NodeID::new(0)); for param in params.iter() { context .node_ids - .insert(param.0, NodeID::new(context.node_ids.len())); + .insert(param.1, 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; @@ -74,13 +89,15 @@ fn parse_function<'a>( 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() } + if id.idx() != 0 { + fixed_nodes[id.idx()] = Node::Parameter { index: id.idx() } + } } Ok(( ir_text, Function { name: String::from(function_name), - param_types: params.into_iter().map(|x| x.4).collect(), + param_types: params.into_iter().map(|x| x.5).collect(), return_type, nodes: fixed_nodes, }, @@ -91,10 +108,73 @@ fn parse_node<'a>( ir_text: &'a str, context: &mut Context<'a>, ) -> nom::IResult<&'a str, (&'a str, Node)> { - todo!() + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let (ir_text, node_name) = nom::character::complete::alphanumeric1(ir_text)?; + 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, node_kind) = nom::character::complete::alphanumeric1(ir_text)?; + let (ir_text, node) = match node_kind { + "return" => { + let (ir_text, comps) = nom::sequence::tuple(( + nom::character::complete::multispace0, + nom::character::complete::char('('), + nom::character::complete::multispace0, + nom::character::complete::alphanumeric1, + nom::character::complete::multispace0, + nom::character::complete::char(','), + nom::character::complete::multispace0, + nom::character::complete::alphanumeric1, + nom::character::complete::multispace0, + nom::character::complete::char(')'), + ))(ir_text)?; + let control_id = context.get_node_id(comps.3); + let value_id = context.get_node_id(comps.7); + ( + ir_text, + Node::Return { + control: control_id, + value: value_id, + }, + ) + } + "add" => { + let (ir_text, comps) = nom::sequence::tuple(( + nom::character::complete::multispace0, + nom::character::complete::char('('), + nom::character::complete::multispace0, + nom::character::complete::alphanumeric1, + nom::character::complete::multispace0, + nom::character::complete::char(','), + nom::character::complete::multispace0, + nom::character::complete::alphanumeric1, + nom::character::complete::multispace0, + nom::character::complete::char(','), + nom::character::complete::multispace0, + nom::character::complete::alphanumeric1, + nom::character::complete::multispace0, + nom::character::complete::char(')'), + ))(ir_text)?; + let control_id = context.get_node_id(comps.3); + let left_id = context.get_node_id(comps.7); + let right_id = context.get_node_id(comps.11); + ( + ir_text, + Node::Add { + control: control_id, + left: left_id, + right: right_id, + }, + ) + } + _ => todo!(), + }; + context.get_node_id(node_name); + Ok((ir_text, (node_name, node))) } fn parse_type<'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) = nom::combinator::map(nom::bytes::complete::tag("i32"), |_| Type::Integer32)(ir_text)?; let id = if let Some(id) = context.interned_types.get(&ty) { @@ -120,6 +200,8 @@ mod tests { #[test] fn parse_ir1() { - parse("fn add(x: i32, y: i32) -> i32 r = return(z) z = add(start, x, y)"); + let module = + parse("fn add(x: i32, y: i32) -> i32 r = return(start, z) z = add(start, x, y)"); + println!("{:?}", module); } }