Skip to content
Snippets Groups Projects
Commit a736842d authored by Russel Arbore's avatar Russel Arbore
Browse files

Minimal code to parse simple example

parent 30d607ac
No related branches found
No related tags found
No related merge requests found
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 {
......
......@@ -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);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment