renamed language, added operator precedence
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tea"
|
name = "matcha"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
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
|
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)> {
|
pub fn parse_operator(input: &str) -> Option<(Token, &str)> {
|
||||||
let c: char = input.chars().next()?;
|
let c: char = input.chars().next()?;
|
||||||
let input = &input[1..];
|
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) => {
|
($matchee:expr, $pattern:pat, $ret:expr) => {
|
||||||
match $matchee {
|
match $matchee {
|
||||||
Some($pattern) => (),
|
Some($pattern) => (),
|
||||||
_ => return Err($ret),
|
_ => return Err($ret),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
fn next_expr_end(tokens: &[Token]) -> usize {
|
fn next_expr_end(tokens: &[Token]) -> usize {
|
||||||
let mut index = 0;
|
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> {
|
fn parse_expr(tokens: &[Token]) -> Result<(Vec<ASTNode>, usize), ParseError> {
|
||||||
let mut ast = vec![];
|
let mut ast = vec![];
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
let mut op_stack: Vec<Operator> = vec![];
|
||||||
loop {
|
loop {
|
||||||
match tokens.get(index) {
|
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::Lit(v)) => ast.push(ASTNode::Val(Value::Lit(v.clone()))),
|
||||||
Some(Token::Id(v)) => ast.push(ASTNode::Val(Value::Id(v.clone()))),
|
Some(Token::Id(v)) => ast.push(ASTNode::Val(Value::Id(v.clone()))),
|
||||||
Some(Token::Kw(Keyword::Let)) => {
|
Some(Token::Kw(Keyword::Let)) => {
|
||||||
@@ -125,10 +131,25 @@ fn parse_expr(tokens: &[Token]) -> Result<(Vec<ASTNode>, usize), ParseError> {
|
|||||||
return Err(ParseError::new("unexpected }"));
|
return Err(ParseError::new("unexpected }"));
|
||||||
},
|
},
|
||||||
Some(Token::Sym(Symbol::Semicolon)) => {
|
Some(Token::Sym(Symbol::Semicolon)) => {
|
||||||
|
while !op_stack.is_empty() {
|
||||||
|
ast.push(ASTNode::BinOp(op_stack.pop().unwrap()));
|
||||||
|
}
|
||||||
ast.push(ASTNode::StatementEnd);
|
ast.push(ASTNode::StatementEnd);
|
||||||
},
|
},
|
||||||
Some(Token::Op(op)) => {
|
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) {
|
ast.push(match tokens.get(index + 1) {
|
||||||
Some(Token::Id(v)) => ASTNode::Val(Value::Id(v.clone())),
|
Some(Token::Id(v)) => ASTNode::Val(Value::Id(v.clone())),
|
||||||
Some(Token::Lit(v)) => ASTNode::Val(Value::Lit(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()));
|
ast.push(ASTNode::BinOp(op.clone()));
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
index += 1;
|
index += 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user