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 ast;
|
||||||
pub mod parse;
|
pub mod parse;
|
||||||
|
|
||||||
|
pub use parse::parse;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
let ast = pivot::parse::parse(r"log(2)");
|
let src = "log(2 + 4, variable)";
|
||||||
|
let ast = pivot::parse(src);
|
||||||
println!("{}", ast);
|
println!("{}", ast);
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ pub enum ParserKind {
|
|||||||
RepeatRange(Range<usize>),
|
RepeatRange(Range<usize>),
|
||||||
Error(String),
|
Error(String),
|
||||||
Map(Rc<Box<dyn Fn(String) -> Result<String, ron::Error>>>),
|
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 {
|
impl std::fmt::Debug for ParserKind {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
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),
|
RepeatRange(range) => write!(f, "RepeatRange {:?}", range),
|
||||||
Error(msg) => write!(f, "Error \"{}\"", msg),
|
Error(msg) => write!(f, "Error \"{}\"", msg),
|
||||||
Map(_) => write!(f, "Map"),
|
Map(_) => write!(f, "Map"),
|
||||||
|
Custom(_) => write!(f, "Custom"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,6 +53,7 @@ impl Clone for ParserKind {
|
|||||||
RepeatRange(range) => RepeatRange(range.clone()),
|
RepeatRange(range) => RepeatRange(range.clone()),
|
||||||
Error(msg) => Error(msg.clone()),
|
Error(msg) => Error(msg.clone()),
|
||||||
Map(cfn) => Map(Rc::clone(cfn)),
|
Map(cfn) => Map(Rc::clone(cfn)),
|
||||||
|
Custom(cfn) => Custom(Rc::clone(cfn)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,6 +165,9 @@ impl Parser {
|
|||||||
Err(rest)
|
Err(rest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Custom(cfn) => {
|
||||||
|
cfn(s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,6 +196,15 @@ impl Parser {
|
|||||||
subparsers: vec![],
|
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
|
// Instance
|
||||||
pub fn and(self, r: Parser) -> Parser {
|
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 {
|
pub fn parse<T: Into<String>>(src: T) -> AstNode {
|
||||||
let src: String = src.into();
|
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 whitespace = Parser::regex(r"[ \n\r\t]+");
|
||||||
let comments = Parser::regex(r"[/][/].*").or(Parser::regex(r"[/][*].*[*][/]"));
|
let comments = Parser::regex(r"[/][/].*").or(Parser::regex(r"[/][*].*[*][/]"));
|
||||||
let ignored = whitespace.or(comments).repeat_range(0..usize::MAX);
|
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.
|
// Expression parser.
|
||||||
let mut expression = Parser::constant("").map(|matched| Ok(to_string(&AstNode::null())?));
|
let expression = Parser::custom(parse_expression);
|
||||||
// Call parser.
|
// Call parser.
|
||||||
let args = expression
|
let args = expression
|
||||||
.clone()
|
.clone()
|
||||||
@ -78,7 +81,6 @@ pub fn parse<T: Into<String>>(src: T) -> AstNode {
|
|||||||
.repeat_range(0..usize::MAX),
|
.repeat_range(0..usize::MAX),
|
||||||
)
|
)
|
||||||
.map(|matched| {
|
.map(|matched| {
|
||||||
println!("{}", matched);
|
|
||||||
let mut args = vec![];
|
let mut args = vec![];
|
||||||
let data = from_str::<Vec<String>>(&matched)?;
|
let data = from_str::<Vec<String>>(&matched)?;
|
||||||
args.push(data[0].clone());
|
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 data = from_str::<Vec<String>>(&matched)?;
|
||||||
let callee = data[0].clone();
|
let callee = data[0].clone();
|
||||||
let args = from_str::<Vec<String>>(&data[1])?;
|
let args = from_str::<Vec<String>>(&data[1])?;
|
||||||
for arg in args {
|
let mut ast_args = vec![];
|
||||||
println!("{}", arg);
|
for arg in &args {
|
||||||
|
ast_args.push(from_str::<AstNode>(arg)?);
|
||||||
}
|
}
|
||||||
Ok(to_string(
|
Ok(to_string(
|
||||||
&AstNode::function_call(callee, vec![]), // TODO: recursively make into AstNodes
|
&AstNode::function_call(callee, ast_args),
|
||||||
)?)
|
)?)
|
||||||
});
|
});
|
||||||
// Atom parser.
|
// 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 product = infix(STAR.clone().or(SLASH.clone()), unary.clone());
|
||||||
let sum = infix(PLUS.clone().or(MINUS.clone()), product.clone());
|
let sum = infix(PLUS.clone().or(MINUS.clone()), product.clone());
|
||||||
let comparison = infix(EQUAL.clone().or(NOT_EQUAL.clone()), sum.clone());
|
let comparison = infix(EQUAL.clone().or(NOT_EQUAL.clone()), sum.clone());
|
||||||
// Close the recursive definition.
|
comparison.parse(src)
|
||||||
// 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![])
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user