renamed language, added operator precedence
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "tea"
|
||||
name = "matcha"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
use crate::parse::ASTNode;
|
||||
|
||||
fn get_domain(ast: &mut Vec<ASTNode>) -> Vec<ASTNode> {
|
||||
ast.iter().take_while(|x| !matches!(x, ASTNode::StatementEnd)).cloned().collect()
|
||||
}
|
||||
|
||||
pub fn operator_chain(ast: &mut Vec<ASTNode>) {
|
||||
let tree = get_domain(ast);
|
||||
}
|
||||
@@ -8,6 +8,15 @@ pub enum Operator {
|
||||
Slash, // division
|
||||
}
|
||||
|
||||
impl Operator {
|
||||
pub fn get_precedence(&self) -> usize {
|
||||
match self {
|
||||
Operator::Plus | Operator::Minus => 0,
|
||||
Operator::Star | Operator::Slash => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_operator(input: &str) -> Option<(Token, &str)> {
|
||||
let c: char = input.chars().next()?;
|
||||
let input = &input[1..];
|
||||
|
||||
+27
-5
@@ -45,14 +45,14 @@ macro_rules! match_or_return {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! assert_match {
|
||||
/*macro_rules! assert_match {
|
||||
($matchee:expr, $pattern:pat, $ret:expr) => {
|
||||
match $matchee {
|
||||
Some($pattern) => (),
|
||||
_ => return Err($ret),
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
fn next_expr_end(tokens: &[Token]) -> usize {
|
||||
let mut index = 0;
|
||||
@@ -86,9 +86,15 @@ fn next_block_end(tokens: &[Token]) -> Result<usize, ParseError> {
|
||||
fn parse_expr(tokens: &[Token]) -> Result<(Vec<ASTNode>, usize), ParseError> {
|
||||
let mut ast = vec![];
|
||||
let mut index = 0;
|
||||
let mut op_stack: Vec<Operator> = vec![];
|
||||
loop {
|
||||
match tokens.get(index) {
|
||||
None => return Ok((ast, index)),
|
||||
None => {
|
||||
while !op_stack.is_empty() {
|
||||
ast.push(ASTNode::BinOp(op_stack.pop().unwrap()));
|
||||
}
|
||||
return Ok((ast, index));
|
||||
}
|
||||
Some(Token::Lit(v)) => ast.push(ASTNode::Val(Value::Lit(v.clone()))),
|
||||
Some(Token::Id(v)) => ast.push(ASTNode::Val(Value::Id(v.clone()))),
|
||||
Some(Token::Kw(Keyword::Let)) => {
|
||||
@@ -125,10 +131,25 @@ fn parse_expr(tokens: &[Token]) -> Result<(Vec<ASTNode>, usize), ParseError> {
|
||||
return Err(ParseError::new("unexpected }"));
|
||||
},
|
||||
Some(Token::Sym(Symbol::Semicolon)) => {
|
||||
while !op_stack.is_empty() {
|
||||
ast.push(ASTNode::BinOp(op_stack.pop().unwrap()));
|
||||
}
|
||||
ast.push(ASTNode::StatementEnd);
|
||||
},
|
||||
Some(Token::Op(op)) => {
|
||||
if ast.is_empty() && matches!(op, Operator::Minus) {
|
||||
match op_stack.last() {
|
||||
None => op_stack.push(op.clone()),
|
||||
Some(last_op) if last_op.get_precedence() < op.get_precedence() => {
|
||||
op_stack.push(op.clone())
|
||||
},
|
||||
Some(_) => {
|
||||
while op_stack.last().is_some_and(|l| l.get_precedence() < op.get_precedence()) {
|
||||
ast.push(ASTNode::BinOp(op_stack.pop().unwrap()));
|
||||
}
|
||||
op_stack.push(op.clone())
|
||||
}
|
||||
}
|
||||
/*if ast.is_empty() && matches!(op, Operator::Minus) {
|
||||
ast.push(match tokens.get(index + 1) {
|
||||
Some(Token::Id(v)) => ASTNode::Val(Value::Id(v.clone())),
|
||||
Some(Token::Lit(v)) => ASTNode::Val(Value::Lit(v.clone())),
|
||||
@@ -145,7 +166,8 @@ fn parse_expr(tokens: &[Token]) -> Result<(Vec<ASTNode>, usize), ParseError> {
|
||||
});
|
||||
ast.push(ASTNode::BinOp(op.clone()));
|
||||
index += 1;
|
||||
}
|
||||
}*/
|
||||
|
||||
},
|
||||
}
|
||||
index += 1;
|
||||
|
||||
Reference in New Issue
Block a user