Fix it using my god-tier big brain programming strats
This commit is contained in:
parent
16de6c4f75
commit
f03b303bdb
@ -6,3 +6,5 @@ extern crate regex;
|
||||
|
||||
pub mod ast;
|
||||
pub mod parse;
|
||||
|
||||
pub use parse::parse;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user