Fix it using my god-tier big brain programming strats

This commit is contained in:
Garen Tyler 2020-11-29 23:11:59 -07:00
parent 16de6c4f75
commit f03b303bdb
4 changed files with 28 additions and 11 deletions

View File

@ -6,3 +6,5 @@ extern crate regex;
pub mod ast;
pub mod parse;
pub use parse::parse;

View File

@ -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);
}

View File

@ -14,6 +14,7 @@ pub enum ParserKind {
RepeatRange(Range<usize>),
Error(String),
Map(Rc<Box<dyn Fn(String) -> Result<String, ron::Error>>>),
Custom(Rc<Box<dyn Fn(String) -> 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<F: 'static>(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 {

View File

@ -6,6 +6,9 @@ use ron::{from_str, to_string};
pub fn parse<T: Into<String>>(src: T) -> AstNode {
let src: String = src.into();
from_str::<AstNode>(&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<T: Into<String>>(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<T: Into<String>>(src: T) -> AstNode {
.repeat_range(0..usize::MAX),
)
.map(|matched| {
println!("{}", matched);
let mut args = vec![];
let data = from_str::<Vec<String>>(&matched)?;
args.push(data[0].clone());
@ -97,11 +99,12 @@ pub fn parse<T: Into<String>>(src: T) -> AstNode {
let data = from_str::<Vec<String>>(&matched)?;
let callee = data[0].clone();
let args = from_str::<Vec<String>>(&data[1])?;
for arg in args {
println!("{}", arg);
let mut ast_args = vec![];
for arg in &args {
ast_args.push(from_str::<AstNode>(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<T: Into<String>>(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::<AstNode>(&expression.parse(src).unwrap().0).unwrap()
// AstNode::block(vec![])
comparison.parse(src)
}