From f03b303bdb9cdbfd1f06fa17dca63e462152e09f Mon Sep 17 00:00:00 2001 From: Garen Tyler Date: Sun, 29 Nov 2020 23:11:59 -0700 Subject: [PATCH] Fix it using my god-tier big brain programming strats --- src/lib.rs | 2 ++ src/main.rs | 3 ++- src/parse/combinators.rs | 15 +++++++++++++++ src/parse/mod.rs | 19 +++++++++---------- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9c06b34..08a0ac2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,3 +6,5 @@ extern crate regex; pub mod ast; pub mod parse; + +pub use parse::parse; diff --git a/src/main.rs b/src/main.rs index b6f26e2..3d34452 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ fn main() { - let ast = pivot::parse::parse(r"log(2)"); + let src = "log(2 + 4, variable)"; + let ast = pivot::parse(src); println!("{}", ast); } diff --git a/src/parse/combinators.rs b/src/parse/combinators.rs index 5072be5..c60fb13 100644 --- a/src/parse/combinators.rs +++ b/src/parse/combinators.rs @@ -14,6 +14,7 @@ pub enum ParserKind { RepeatRange(Range), Error(String), Map(Rc Result>>), + Custom(Rc Result<(String, String), String>>>), } impl std::fmt::Debug for ParserKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -34,6 +35,7 @@ impl std::fmt::Display for ParserKind { RepeatRange(range) => write!(f, "RepeatRange {:?}", range), Error(msg) => write!(f, "Error \"{}\"", msg), Map(_) => write!(f, "Map"), + Custom(_) => write!(f, "Custom"), } } } @@ -51,6 +53,7 @@ impl Clone for ParserKind { RepeatRange(range) => RepeatRange(range.clone()), Error(msg) => Error(msg.clone()), Map(cfn) => Map(Rc::clone(cfn)), + Custom(cfn) => Custom(Rc::clone(cfn)), } } } @@ -162,6 +165,9 @@ impl Parser { Err(rest) } } + Custom(cfn) => { + cfn(s) + } } } @@ -190,6 +196,15 @@ impl Parser { subparsers: vec![], } } + pub fn custom(cfn: F) -> Parser + where + F: Fn(String) -> Result<(String, String), String>, + { + Parser { + kind: ParserKind::Custom(Rc::new(Box::new(cfn))), + subparsers: vec![], + } + } // Instance pub fn and(self, r: Parser) -> Parser { diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 87d6501..af4781b 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -6,6 +6,9 @@ use ron::{from_str, to_string}; pub fn parse>(src: T) -> AstNode { let src: String = src.into(); + from_str::(&parse_expression(src).unwrap().0).unwrap() +} +fn parse_expression(src: String) -> Result<(String, String), String> { let whitespace = Parser::regex(r"[ \n\r\t]+"); let comments = Parser::regex(r"[/][/].*").or(Parser::regex(r"[/][*].*[*][/]")); let ignored = whitespace.or(comments).repeat_range(0..usize::MAX); @@ -68,7 +71,7 @@ pub fn parse>(src: T) -> AstNode { ))?) }); // Expression parser. - let mut expression = Parser::constant("").map(|matched| Ok(to_string(&AstNode::null())?)); + let expression = Parser::custom(parse_expression); // Call parser. let args = expression .clone() @@ -78,7 +81,6 @@ pub fn parse>(src: T) -> AstNode { .repeat_range(0..usize::MAX), ) .map(|matched| { - println!("{}", matched); let mut args = vec![]; let data = from_str::>(&matched)?; args.push(data[0].clone()); @@ -97,11 +99,12 @@ pub fn parse>(src: T) -> AstNode { let data = from_str::>(&matched)?; let callee = data[0].clone(); let args = from_str::>(&data[1])?; - for arg in args { - println!("{}", arg); + let mut ast_args = vec![]; + for arg in &args { + ast_args.push(from_str::(arg)?); } Ok(to_string( - &AstNode::function_call(callee, vec![]), // TODO: recursively make into AstNodes + &AstNode::function_call(callee, ast_args), )?) }); // Atom parser. @@ -149,9 +152,5 @@ pub fn parse>(src: T) -> AstNode { let product = infix(STAR.clone().or(SLASH.clone()), unary.clone()); let sum = infix(PLUS.clone().or(MINUS.clone()), product.clone()); let comparison = infix(EQUAL.clone().or(NOT_EQUAL.clone()), sum.clone()); - // Close the recursive definition. - // OR NOT! IT WORKS IN JS BECAUSE IT GETS HOISTED - expression = comparison.clone(); - from_str::(&expression.parse(src).unwrap().0).unwrap() - // AstNode::block(vec![]) + comparison.parse(src) }