diff --git a/console/network/environment/src/lib.rs b/console/network/environment/src/lib.rs index 4a7aad0f81..6f7140ab66 100644 --- a/console/network/environment/src/lib.rs +++ b/console/network/environment/src/lib.rs @@ -126,8 +126,10 @@ pub mod prelude { bytes::{complete::tag, streaming::take}, character::complete::{alpha1, alphanumeric1, char, one_of}, combinator::{complete, fail, map, map_res, opt, recognize}, + error::{make_error, ErrorKind}, multi::{count, many0, many0_count, many1, separated_list0, separated_list1}, sequence::{pair, terminated}, + Err, }; pub use num_traits::{AsPrimitive, One, Pow, Zero}; pub use rand::{ diff --git a/console/program/src/data_types/record_type/parse.rs b/console/program/src/data_types/record_type/parse.rs index d995622e7c..386b6ac0e3 100644 --- a/console/program/src/data_types/record_type/parse.rs +++ b/console/program/src/data_types/record_type/parse.rs @@ -45,8 +45,6 @@ impl Parser for RecordType { Ok((string, (identifier, value_type))) } - // Parse the whitespace and comments from the string. - let (string, _) = Sanitizer::parse(string)?; // Parse the type name from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/console/program/src/data_types/struct_type/parse.rs b/console/program/src/data_types/struct_type/parse.rs index 42ad3b7ca0..a047d5ec2a 100644 --- a/console/program/src/data_types/struct_type/parse.rs +++ b/console/program/src/data_types/struct_type/parse.rs @@ -45,8 +45,6 @@ impl Parser for StructType { Ok((string, (identifier, plaintext_type))) } - // Parse the whitespace and comments from the string. - let (string, _) = Sanitizer::parse(string)?; // Parse the type name from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/closure/parse.rs b/synthesizer/program/src/closure/parse.rs index 9560dfc924..66dd889739 100644 --- a/synthesizer/program/src/closure/parse.rs +++ b/synthesizer/program/src/closure/parse.rs @@ -18,8 +18,6 @@ impl> Parser for ClosureCore ParserResult { - // Parse the whitespace and comments from the string. - let (string, _) = Sanitizer::parse(string)?; // Parse the 'closure' keyword from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/function/parse.rs b/synthesizer/program/src/function/parse.rs index 48258a3e0b..e6a912e4b4 100644 --- a/synthesizer/program/src/function/parse.rs +++ b/synthesizer/program/src/function/parse.rs @@ -20,8 +20,6 @@ impl, Command: CommandTrait> Par /// Parses a string into a function. #[inline] fn parse(string: &str) -> ParserResult { - // Parse the whitespace and comments from the string. - let (string, _) = Sanitizer::parse(string)?; // Parse the 'function' keyword from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/lib.rs b/synthesizer/program/src/lib.rs index 6058ffa3ca..4dc7b39569 100644 --- a/synthesizer/program/src/lib.rs +++ b/synthesizer/program/src/lib.rs @@ -48,13 +48,13 @@ mod serialize; use console::{ network::prelude::{ - alt, anyhow, bail, de, ensure, error, fmt, + make_error, many0, many1, map, @@ -65,7 +65,9 @@ use console::{ Deserialize, Deserializer, Display, + Err, Error, + ErrorKind, Formatter, FromBytes, FromBytesDeserializer, diff --git a/synthesizer/program/src/mapping/parse.rs b/synthesizer/program/src/mapping/parse.rs index 4f25ed546c..dc546d8e9f 100644 --- a/synthesizer/program/src/mapping/parse.rs +++ b/synthesizer/program/src/mapping/parse.rs @@ -18,8 +18,6 @@ impl Parser for Mapping { /// Parses a string into a mapping. #[inline] fn parse(string: &str) -> ParserResult { - // Parse the whitespace and comments from the string. - let (string, _) = Sanitizer::parse(string)?; // Parse the 'mapping' keyword from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/parse.rs b/synthesizer/program/src/parse.rs index 40929f4341..f2da6a0035 100644 --- a/synthesizer/program/src/parse.rs +++ b/synthesizer/program/src/parse.rs @@ -44,58 +44,70 @@ impl, Command: CommandTrait> Par // Parse the semicolon ';' keyword from the string. let (string, _) = tag(";")(string)?; + fn intermediate, Command: CommandTrait>( + string: &str, + ) -> ParserResult> { + // Parse the whitespace and comments from the string. + let (string, _) = Sanitizer::parse(string)?; + + if string.starts_with(Mapping::::type_name()) { + map(Mapping::parse, |mapping| P::::M(mapping))(string) + } else if string.starts_with(StructType::::type_name()) { + map(StructType::parse, |struct_| P::::I(struct_))(string) + } else if string.starts_with(RecordType::::type_name()) { + map(RecordType::parse, |record| P::::R(record))(string) + } else if string.starts_with(ClosureCore::::type_name()) { + map(ClosureCore::parse, |closure| P::::C(closure))(string) + } else if string.starts_with(FunctionCore::::type_name()) { + map(FunctionCore::parse, |function| P::::F(function))(string) + } else { + Err(Err::Error(make_error(string, ErrorKind::Alt))) + } + } + // Parse the struct or function from the string. - let (string, components) = many1(alt(( - map(Mapping::parse, |mapping| P::::M(mapping)), - map(StructType::parse, |struct_| P::::I(struct_)), - map(RecordType::parse, |record| P::::R(record)), - map(ClosureCore::parse, |closure| P::::C(closure)), - map(FunctionCore::parse, |function| P::::F(function)), - )))(string)?; + let (string, components) = many1(intermediate)(string)?; // Parse the whitespace and comments from the string. let (string, _) = Sanitizer::parse(string)?; - // Return the program. - map_res(take(0usize), move |_| { - // Initialize a new program. - let mut program = match ProgramCore::::new(id) { - Ok(program) => program, + // Initialize a new program. + let mut program = match ProgramCore::::new(id) { + Ok(program) => program, + Err(error) => { + eprintln!("{error}"); + return map_res(take(0usize), move |error| Err(error))(string); + } + }; + // Construct the program with the parsed components. + for component in components { + let result = match component { + P::M(mapping) => program.add_mapping(mapping), + P::I(struct_) => program.add_struct(struct_), + P::R(record) => program.add_record(record), + P::C(closure) => program.add_closure(closure), + P::F(function) => program.add_function(function), + }; + + match result { + Ok(_) => (), Err(error) => { eprintln!("{error}"); - return Err(error); - } - }; - // Construct the program with the parsed components. - for component in components.iter() { - let result = match component { - P::M(mapping) => program.add_mapping(mapping.clone()), - P::I(struct_) => program.add_struct(struct_.clone()), - P::R(record) => program.add_record(record.clone()), - P::C(closure) => program.add_closure(closure.clone()), - P::F(function) => program.add_function(function.clone()), - }; - - match result { - Ok(_) => (), - Err(error) => { - eprintln!("{error}"); - return Err(error); - } + return map_res(take(0usize), move |error| Err(error))(string); } } - // Lastly, add the imports (if any) to the program. - for import in imports.iter() { - match program.add_import(import.clone()) { - Ok(_) => (), - Err(error) => { - eprintln!("{error}"); - return Err(error); - } + } + // Lastly, add the imports (if any) to the program. + for import in imports { + match program.add_import(import) { + Ok(_) => (), + Err(error) => { + eprintln!("{error}"); + return map_res(take(0usize), move |error| Err(error))(string); } } - // Output the program. - Ok::<_, Error>(program) - })(string) + } + + Ok((string, program)) } }