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

Parse constants

parent 347e4f03
No related branches found
No related tags found
No related merge requests found
...@@ -17,6 +17,16 @@ struct Context<'a> { ...@@ -17,6 +17,16 @@ struct Context<'a> {
} }
impl<'a> Context<'a> { impl<'a> Context<'a> {
fn get_function_id(&mut self, name: &'a str) -> FunctionID {
if let Some(id) = self.function_ids.get(name) {
*id
} else {
let id = FunctionID::new(self.function_ids.len());
self.function_ids.insert(name, id);
id
}
}
fn get_node_id(&mut self, name: &'a str) -> NodeID { fn get_node_id(&mut self, name: &'a str) -> NodeID {
if let Some(id) = self.node_ids.get(name) { if let Some(id) = self.node_ids.get(name) {
*id *id
...@@ -26,6 +36,26 @@ impl<'a> Context<'a> { ...@@ -26,6 +36,26 @@ impl<'a> Context<'a> {
id id
} }
} }
fn get_type_id(&mut self, ty: Type) -> TypeID {
if let Some(id) = self.interned_types.get(&ty) {
*id
} else {
let id = TypeID::new(self.interned_types.len());
self.interned_types.insert(ty, id);
id
}
}
fn get_constant_id(&mut self, constant: Constant) -> ConstantID {
if let Some(id) = self.interned_constants.get(&constant) {
*id
} else {
let id = ConstantID::new(self.interned_constants.len());
self.interned_constants.insert(constant, id);
id
}
}
} }
fn parse_module<'a>(ir_text: &'a str, mut context: Context<'a>) -> nom::IResult<&'a str, Module> { fn parse_module<'a>(ir_text: &'a str, mut context: Context<'a>) -> nom::IResult<&'a str, Module> {
...@@ -69,7 +99,7 @@ fn parse_function<'a>( ...@@ -69,7 +99,7 @@ fn parse_function<'a>(
nom::character::complete::multispace0, nom::character::complete::multispace0,
nom::character::complete::char(':'), nom::character::complete::char(':'),
nom::character::complete::multispace0, nom::character::complete::multispace0,
|x| parse_type(x, context), |x| parse_type_id(x, context),
nom::character::complete::multispace0, nom::character::complete::multispace0,
)), )),
)(ir_text)?; )(ir_text)?;
...@@ -82,7 +112,7 @@ fn parse_function<'a>( ...@@ -82,7 +112,7 @@ fn parse_function<'a>(
let ir_text = nom::character::complete::char(')')(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 = nom::character::complete::multispace0(ir_text)?.0;
let ir_text = nom::bytes::complete::tag("->")(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, return_type) = parse_type_id(ir_text, context)?;
let (ir_text, nodes) = nom::multi::many1(|x| parse_node(x, context))(ir_text)?; 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()]; let mut fixed_nodes = vec![Node::Start; context.node_ids.len()];
for (name, node) in nodes { for (name, node) in nodes {
...@@ -151,7 +181,11 @@ fn parse_constant_node<'a>( ...@@ -151,7 +181,11 @@ fn parse_constant_node<'a>(
let ir_text = nom::character::complete::multispace0(ir_text)?.0; 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::char('(')(ir_text)?.0;
let ir_text = nom::character::complete::multispace0(ir_text)?.0; let ir_text = nom::character::complete::multispace0(ir_text)?.0;
let (ir_text, id) = parse_constant(ir_text, context)?; let (ir_text, ty) = parse_type(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, id) = parse_constant_id(ir_text, ty, context)?;
let ir_text = nom::character::complete::multispace0(ir_text)?.0; 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::char(')')(ir_text)?.0;
Ok((ir_text, Node::Constant { id })) Ok((ir_text, Node::Constant { id }))
...@@ -182,35 +216,46 @@ fn parse_add<'a>(ir_text: &'a str, context: &mut Context<'a>) -> nom::IResult<&' ...@@ -182,35 +216,46 @@ fn parse_add<'a>(ir_text: &'a str, context: &mut Context<'a>) -> nom::IResult<&'
)) ))
} }
fn parse_type<'a>(ir_text: &'a str, context: &mut Context<'a>) -> nom::IResult<&'a str, TypeID> { 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 = nom::character::complete::multispace0(ir_text)?.0;
let (ir_text, ty) = let (ir_text, ty) = parse_type(ir_text)?;
nom::combinator::map(nom::bytes::complete::tag("i32"), |_| Type::Integer32)(ir_text)?; let id = context.get_type_id(ty);
let id = if let Some(id) = context.interned_types.get(&ty) {
*id
} else {
let id = TypeID::new(context.interned_types.len());
context.interned_types.insert(ty, id);
id
};
Ok((ir_text, id)) Ok((ir_text, id))
} }
fn parse_constant<'a>( 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::combinator::map(nom::bytes::complete::tag("i8"), |_| Type::Integer8),
nom::combinator::map(nom::bytes::complete::tag("i32"), |_| Type::Integer32),
))(ir_text)?;
Ok((ir_text, ty))
}
fn parse_constant_id<'a>(
ir_text: &'a str, ir_text: &'a str,
ty: Type,
context: &mut Context<'a>, context: &mut Context<'a>,
) -> nom::IResult<&'a str, ConstantID> { ) -> nom::IResult<&'a str, ConstantID> {
let (ir_text, constant) = nom::branch::alt((parse_integer8,))(ir_text)?; let (ir_text, constant) = parse_constant(ir_text, ty, context)?;
let id = if let Some(id) = context.interned_constants.get(&constant) { let id = context.get_constant_id(constant);
*id
} else {
let id = ConstantID::new(context.interned_constants.len());
context.interned_constants.insert(constant, id);
id
};
Ok((ir_text, id)) Ok((ir_text, id))
} }
fn parse_constant<'a>(
ir_text: &'a str,
ty: Type,
context: &mut Context<'a>,
) -> nom::IResult<&'a str, Constant> {
let (ir_text, constant) = match ty {
Type::Integer8 => parse_integer8(ir_text)?,
Type::Integer32 => parse_integer32(ir_text)?,
_ => todo!(),
};
context.get_type_id(ty);
Ok((ir_text, constant))
}
fn parse_integer8<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { fn parse_integer8<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> {
let (ir_text, num_text) = nom::bytes::complete::is_a("-1234567890")(ir_text)?; let (ir_text, num_text) = nom::bytes::complete::is_a("-1234567890")(ir_text)?;
let num = num_text.parse::<i8>().map_err(|_| { let num = num_text.parse::<i8>().map_err(|_| {
...@@ -222,6 +267,17 @@ fn parse_integer8<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { ...@@ -222,6 +267,17 @@ fn parse_integer8<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> {
Ok((ir_text, Constant::Integer8(num))) Ok((ir_text, Constant::Integer8(num)))
} }
fn parse_integer32<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> {
let (ir_text, num_text) = nom::bytes::complete::is_a("-1234567890")(ir_text)?;
let num = num_text.parse::<i32>().map_err(|_| {
nom::Err::Error(nom::error::Error {
input: num_text,
code: nom::error::ErrorKind::IsNot,
})
})?;
Ok((ir_text, Constant::Integer32(num)))
}
mod tests { mod tests {
#[allow(unused_imports)] #[allow(unused_imports)]
use super::*; use super::*;
...@@ -229,7 +285,7 @@ mod tests { ...@@ -229,7 +285,7 @@ mod tests {
#[test] #[test]
fn parse_ir1() { fn parse_ir1() {
let module = let module =
parse("fn add(x: i32, y: i32) -> i32 r = return(start, z) z = add(start, x, y)"); parse("fn add(x: i32, y: i32) -> i32 c = constant(i8, 5) r = return(start, w) w = add(start, z, c) z = add(start, x, y)");
println!("{:?}", module); 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