diff --git a/src/attribute.rs b/src/attribute.rs index eec2560..0bf9f46 100644 --- a/src/attribute.rs +++ b/src/attribute.rs @@ -207,11 +207,11 @@ impl Parsable for AttrId { where Self: Sized, { - let parser = DialectName::parser(()) + let mut parser = DialectName::parser(()) .skip(parser::char::char('.')) .and(AttrName::parser(())) .map(|(dialect, name)| AttrId { dialect, name }); - spaced(parser).parse_stream(state_stream) + parser.parse_stream(state_stream) } } @@ -220,9 +220,9 @@ pub fn attr_parse<'a>( state_stream: &mut StateStream<'a>, ) -> ParseResult>> { let position = state_stream.stream.position(); - let attr_id_parser = AttrId::parser(()); + let attr_id_parser = spaced(AttrId::parser(())); - let attr_parser = attr_id_parser.then(|attr_id: AttrId| { + let mut attr_parser = attr_id_parser.then(|attr_id: AttrId| { combine::parser(move |parsable_state: &mut StateStream<'a>| { let state = &parsable_state.state; let dialect = state @@ -237,13 +237,12 @@ pub fn attr_parse<'a>( ) .into_result(); }; - attr_parser(&(), ()) + spaced(attr_parser(&(), ())) .parse_stream(parsable_state) .into_result() }) }); - let mut attr_parser = spaced(attr_parser); attr_parser.parse_stream(state_stream) } diff --git a/src/basic_block.rs b/src/basic_block.rs index ef7fd60..5e3ae68 100644 --- a/src/basic_block.rs +++ b/src/basic_block.rs @@ -1,6 +1,6 @@ //! A [BasicBlock] is a list of [Operation]s. -use combine::{between, parser::Parser, sep_by, token, Positioned}; +use combine::{attempt, between, parser::Parser, sep_by, token, Positioned}; use rustc_hash::FxHashMap; use crate::{ @@ -13,7 +13,7 @@ use crate::{ indented_block, linked_list::{private, ContainsLinkedList, LinkedList}, operation::Operation, - parsable::{self, to_parse_result, Parsable}, + parsable::{self, spaced, to_parse_result, Parsable}, printable::{self, indented_nl, ListSeparator, Printable, PrintableIter}, r#type::{type_parser, TypeObj}, region::Region, @@ -293,7 +293,7 @@ impl Printable for BasicBlock { ) -> core::fmt::Result { write!( f, - "{}({}):", + "^{}({}):", self.unique_name(ctx), self.args .iter() @@ -329,16 +329,19 @@ impl Parsable for BasicBlock { ) -> combine::ParseResult>> { let position = state_stream.position(); - let arg = (Identifier::parser(()).skip(token(':')), type_parser()); - let args = between( + let arg = ( + spaced(Identifier::parser(())).skip(token(':')), + spaced(type_parser()), + ); + let args = spaced(between( token('('), token(')'), sep_by::, _, _, _>(arg, token(',')), - ) + )) .skip(token(':')); - let ops = sep_by::, _, _, _>(Operation::parser(()), token(';')); + let ops = sep_by::, _, _, _>(attempt(spaced(Operation::parser(()))), token(';')); - let label = Identifier::parser(()); + let label = spaced(token('^').with(Identifier::parser(()))); let parsed = (label, args, ops).parse_stream(state_stream); // We've parsed the components. Now construct the result. parsed.and_then(|(label, args, ops)| { diff --git a/src/dialects/builtin/attributes.rs b/src/dialects/builtin/attributes.rs index b43e8ae..bbd5a7b 100644 --- a/src/dialects/builtin/attributes.rs +++ b/src/dialects/builtin/attributes.rs @@ -164,17 +164,12 @@ impl Parsable for IntegerAttr { token('<'), token('>'), string("0x") - .with(many1::, _, _>(hex_digit())) + .with(many1::(hex_digit())) .skip(token(':')) .and(type_parser()), ) .parse_stream(state_stream) - .map(|(digits, ty)| { - IntegerAttr::create( - ty, - ApInt::from_str_radix(16, digits.iter().collect::()).unwrap(), - ) - }) + .map(|(digits, ty)| IntegerAttr::create(ty, ApInt::from_str_radix(16, digits).unwrap())) } } @@ -437,7 +432,7 @@ impl Parsable for TypeAttr { state_stream: &mut StateStream<'a>, _arg: Self::Arg, ) -> ParseResult>> { - between(spaced(token('<')), spaced(token('>')), type_parser()) + between(token('<'), token('>'), spaced(type_parser())) .map(TypeAttr::create) .parse_stream(state_stream) } diff --git a/src/dialects/builtin/ops.rs b/src/dialects/builtin/ops.rs index ff11fb3..449af9a 100644 --- a/src/dialects/builtin/ops.rs +++ b/src/dialects/builtin/ops.rs @@ -91,9 +91,8 @@ impl Parsable for ModuleOp { vec![], 0, ); - let mut parser = token('@') - .with(Identifier::parser(())) - .and(Region::parser(op)); + let mut parser = + spaced(token('@').with(Identifier::parser(()))).and(spaced(Region::parser(op))); parser .parse_stream(state_stream) .map(|(name, _region)| -> OpObj { @@ -252,11 +251,9 @@ impl Parsable for FuncOp { ); let mut parser = ( - token('@') - .with(Identifier::parser(())) - .skip(spaced(token(':'))), - type_parser(), - Region::parser(op), + spaced(token('@').with(Identifier::parser(()))).skip(spaced(token(':'))), + spaced(type_parser()), + spaced(Region::parser(op)), ); // Parse and build the function, providing name and type details. diff --git a/src/dialects/builtin/types.rs b/src/dialects/builtin/types.rs index bda7535..b23be9b 100644 --- a/src/dialects/builtin/types.rs +++ b/src/dialects/builtin/types.rs @@ -72,7 +72,7 @@ impl Parsable for IntegerType { let parser = choicer .and(many1::(digit()).map(|digits| digits.parse::().unwrap())); - let mut parser = between(spaced(token('<')), spaced(token('>')), parser); + let mut parser = between(token('<'), token('>'), spaced(parser)); parser .parse_stream(&mut state_stream.stream) .map(|(signedness, width)| IntegerType::get(state_stream.state.ctx, width, signedness)) @@ -177,16 +177,16 @@ impl Parsable for FunctionType { spaced(between( token('('), token(')'), - sep_by::, _, _, _>(type_parser(), token(',')), + sep_by::, _, _, _>(spaced(type_parser()), token(',')), )) }; - let mut parser = between( + let mut parser = spaced(between( token('<'), token('>'), type_list_parser() - .skip(string("->")) + .skip(spaced(string("->"))) .and(type_list_parser()), - ); + )); parser .parse_stream(state_stream) .map(|(inputs, results)| Self::get(state_stream.state.ctx, inputs, results)) @@ -325,7 +325,7 @@ mod tests { let expected_err_msg = expect![[r#" Parse error at line: 1, column: 2 Unexpected `a` - Expected whitespace, si, ui or i + Expected whitespaces, si, ui or i "#]]; expected_err_msg.assert_eq(&err_msg); } diff --git a/src/dialects/llvm/types.rs b/src/dialects/llvm/types.rs index b302a86..db5c997 100644 --- a/src/dialects/llvm/types.rs +++ b/src/dialects/llvm/types.rs @@ -262,33 +262,25 @@ impl Parsable for StructType { Self: Sized, { let body_parser = || { - combine::parser(|parsable_state: &mut StateStream<'a>| { - // Parse multiple type annotated fields separated by ','. - let fields_parser = sep_by::, _, _, _>(StructField::parser(()), token(',')); - - // The body is multiple type annotated fields surrounded by '{' and '}'. - let mut body = between(spaced(token('{')), spaced(token('}')), fields_parser); - - // Finally parse the whole thing. - body.parse_stream(parsable_state).into_result() - }) + // Parse multiple type annotated fields separated by ','. + let fields_parser = + sep_by::, _, _, _>(spaced(StructField::parser(())), token(',')); + // The body is multiple type annotated fields surrounded by '{' and '}'. + between(token('{'), token('}'), fields_parser) }; - let named = spaced(Identifier::parser(())) - .and(optional(body_parser())) - .map(|(name, body_opt)| (Some(name), body_opt)); - let anonymous = body_parser().map(|body| (None::, Some(body))); + let named = spaced((combine::position(), Identifier::parser(()))) + .and(optional(spaced(body_parser()))) + .map(|((position, name), body_opt)| (position, Some(name), body_opt)); + let anonymous = spaced((combine::position(), body_parser())) + .map(|(position, body)| (position, None::, Some(body))); // A struct type is named or anonymous. - let mut struct_parser = between( - spaced(token('<')), - spaced(token('>')), - (combine::position(), named.or(anonymous)), - ); + let mut struct_parser = between(token('<'), token('>'), named.or(anonymous)); struct_parser .parse_stream(state_stream) - .and_then(|(position, (name_opt, body_opt))| { + .and_then(|(position, name_opt, body_opt)| { let ctx = &mut state_stream.state.ctx; if let Some(name) = name_opt { to_parse_result(StructType::get_named(ctx, &name, body_opt), position) @@ -356,7 +348,7 @@ impl Parsable for PointerType { where Self: Sized, { - spaced(combine::between(token('<'), token('>'), type_parser())) + combine::between(token('<'), token('>'), spaced(type_parser())) .parse_stream(state_stream) .map(|pointee_ty| PointerType::get(state_stream.state.ctx, pointee_ty)) } @@ -508,10 +500,7 @@ mod tests { ); let res = type_parser().parse(state_stream).unwrap().0; - assert_eq!( - &res.disp(&ctx).to_string(), - "llvm.ptr >" - ); + assert_eq!(&res.disp(&ctx).to_string(), "llvm.ptr >"); } #[test] diff --git a/src/identifier.rs b/src/identifier.rs index e6c455b..6590c50 100644 --- a/src/identifier.rs +++ b/src/identifier.rs @@ -9,7 +9,7 @@ use crate::{ common_traits::Verify, context::Context, error, - parsable::{self, spaced, Parsable}, + parsable::{self, Parsable}, printable::{self, Printable}, verify_err, }; @@ -90,8 +90,6 @@ impl Parsable for Identifier { .and(many::(char::alpha_num().or(char::char('_')))) .map(|(c, rest)| c.to_string() + &rest); - spaced(parser) - .map(|str| str.into()) - .parse_stream(state_stream) + parser.map(|str| str.into()).parse_stream(state_stream) } } diff --git a/src/op.rs b/src/op.rs index 522144f..d5b614e 100644 --- a/src/op.rs +++ b/src/op.rs @@ -35,7 +35,7 @@ use crate::{ error::Result, identifier::Identifier, operation::Operation, - parsable::{spaced, Parsable, ParserFn, StateStream}, + parsable::{Parsable, ParserFn, StateStream}, printable::{self, Printable}, }; @@ -122,11 +122,11 @@ impl Parsable for OpId { where Self: Sized, { - let parser = DialectName::parser(()) + let mut parser = DialectName::parser(()) .skip(parser::char::char('.')) .and(OpName::parser(())) .map(|(dialect, name)| OpId { dialect, name }); - spaced(parser).parse_stream(state_stream) + parser.parse_stream(state_stream) } } diff --git a/src/operation.rs b/src/operation.rs index ef56267..9e10263 100644 --- a/src/operation.rs +++ b/src/operation.rs @@ -19,7 +19,7 @@ use crate::{ input_err, linked_list::{private, LinkedList}, op::{self, OpId, OpObj}, - parsable::{self, to_parse_result, Parsable, StateStream}, + parsable::{self, spaced, to_parse_result, Parsable, StateStream}, printable::{self, Printable}, r#type::TypeObj, region::Region, @@ -496,9 +496,10 @@ impl Parsable for Operation { let position = state_stream.stream.position(); let results_opid = combine::optional(attempt( - combine::sep_by::, _, _, _>(Identifier::parser(()), token(',')).skip(token('=')), + combine::sep_by::, _, _, _>(spaced(Identifier::parser(())), token(',')) + .skip(spaced(token('='))), )) - .and(OpId::parser(())); + .and(spaced(OpId::parser(()))); results_opid .then(|(results, opid)| { diff --git a/src/region.rs b/src/region.rs index 8383ae7..fd6dd9c 100644 --- a/src/region.rs +++ b/src/region.rs @@ -138,9 +138,10 @@ impl Parsable for Region { .name_tracker .enter_region(state_stream.state.ctx, parent_op); - let block_list_parser = combine::many::, _, _>(attempt(BasicBlock::parser(()))); + let block_list_parser = + combine::many::, _, _>(attempt(spaced(BasicBlock::parser(())))); let braces_bounded_region_parser = - combine::between(token('{'), token('}'), spaced(block_list_parser)); + combine::between(token('{'), token('}'), block_list_parser); let mut region_parser = braces_bounded_region_parser.then(|blocks| { combine::parser(move |state_stream: &mut parsable::StateStream| { diff --git a/src/type.rs b/src/type.rs index 88bad1c..31f8501 100644 --- a/src/type.rs +++ b/src/type.rs @@ -185,11 +185,11 @@ impl Parsable for TypeId { where Self: Sized, { - let parser = DialectName::parser(()) + let mut parser = DialectName::parser(()) .skip(parser::char::char('.')) .and(TypeName::parser(())) .map(|(dialect, name)| TypeId { dialect, name }); - spaced(parser).parse_stream(state_stream) + parser.parse_stream(state_stream) } } @@ -328,9 +328,9 @@ pub fn type_parse<'a>( state_stream: &mut StateStream<'a>, ) -> ParseResult, easy::ParseError>> { let position = state_stream.stream.position(); - let type_id_parser = TypeId::parser(()); + let type_id_parser = spaced(TypeId::parser(())); - let type_parser = type_id_parser.then(|type_id: TypeId| { + let mut type_parser = type_id_parser.then(|type_id: TypeId| { combine::parser(move |parsable_state: &mut StateStream<'a>| { let state = &parsable_state.state; let dialect = state @@ -345,13 +345,12 @@ pub fn type_parse<'a>( ) .into_result(); }; - type_parser(&(), ()) + spaced(type_parser(&(), ())) .parse_stream(parsable_state) .into_result() }) }); - let mut type_parser = spaced(type_parser); type_parser.parse_stream(state_stream) } @@ -400,7 +399,7 @@ mod test { let expected_err_msg = expect![[r#" Parse error at line: 1, column: 13 Unexpected `a` - Expected whitespaces or `<` + Expected `<` or whitespaces "#]]; expected_err_msg.assert_eq(&err_msg); diff --git a/tests/ir_construct.rs b/tests/ir_construct.rs index 8eabf62..042605a 100644 --- a/tests/ir_construct.rs +++ b/tests/ir_construct.rs @@ -9,11 +9,12 @@ use pliron::{ error::Result, op::Op, operation::Operation, - parsable::{self, state_stream_from_iterator, Parsable}, + parsable::{self, spaced, state_stream_from_iterator, Parsable}, printable::Printable, }; use crate::common::{const_ret_in_mod, setup_context_dialects}; +use combine::parser::Parser; mod common; @@ -85,9 +86,9 @@ fn replace_c0_with_c1_operand() -> Result<()> { let printed = format!("{}", module_op.disp(ctx)); expect![[r#" builtin.module @bar { - block_0_0(): + ^block_0_0(): builtin.func @foo: builtin.function <() -> (builtin.int )> { - entry_block_1_0(): + ^entry_block_1_0(): c0_op_2_0_res0 = builtin.constant builtin.integer <0x0: builtin.int >; c1_op_4_0_res0 = builtin.constant builtin.integer <0x1: builtin.int >; llvm.return c0_op_2_0_res0 @@ -104,9 +105,9 @@ fn replace_c0_with_c1_operand() -> Result<()> { let printed = format!("{}", module_op.disp(ctx)); expect![[r#" builtin.module @bar { - block_0_0(): + ^block_0_0(): builtin.func @foo: builtin.function <() -> (builtin.int )> { - entry_block_1_0(): + ^entry_block_1_0(): c1_op_4_0_res0 = builtin.constant builtin.integer <0x1: builtin.int >; llvm.return c1_op_4_0_res0 } @@ -126,9 +127,9 @@ fn print_simple() -> Result<()> { let printed = format!("{}", module_op.disp(ctx)); expect![[r#" builtin.module @bar { - block_0_0(): + ^block_0_0(): builtin.func @foo: builtin.function <() -> (builtin.int )> { - entry_block_1_0(): + ^entry_block_1_0(): c0_op_2_0_res0 = builtin.constant builtin.integer <0x0: builtin.int >; llvm.return c0_op_2_0_res0 } @@ -142,18 +143,19 @@ fn print_simple() -> Result<()> { fn parse_simple() -> Result<()> { let input = r#" builtin.module @bar { - block_0_0(): + ^block_0_0(): builtin.func @foo: builtin.function <() -> (builtin.int )> { - entry_block_1_0(): + ^entry_block_1_0(): c0_op_2_0_res0 = builtin.constant builtin.integer <0x0: builtin.int >; llvm.return c0_op_2_0_res0 + ^exit(): } }"#; let ctx = &mut setup_context_dialects(); let op = { let state_stream = state_stream_from_iterator(input.chars(), parsable::State::new(ctx)); - Operation::parser(()).parse(state_stream).unwrap().0 + spaced(Operation::parser(())).parse(state_stream).unwrap().0 }; println!("{}", op.disp(ctx)); Ok(())