diff --git a/Cargo.toml b/Cargo.toml index 771cf1c..7528f71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "tea" +name = "matcha" version = "0.1.0" edition = "2024" diff --git a/src/interpret/opchain.rs b/src/interpret/opchain.rs new file mode 100644 index 0000000..4ff9751 --- /dev/null +++ b/src/interpret/opchain.rs @@ -0,0 +1,10 @@ + +use crate::parse::ASTNode; + +fn get_domain(ast: &mut Vec) -> Vec { + ast.iter().take_while(|x| !matches!(x, ASTNode::StatementEnd)).cloned().collect() +} + +pub fn operator_chain(ast: &mut Vec) { + let tree = get_domain(ast); +} diff --git a/src/lex/operator.rs b/src/lex/operator.rs index c67a811..9241339 100644 --- a/src/lex/operator.rs +++ b/src/lex/operator.rs @@ -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..]; diff --git a/src/parse.rs b/src/parse.rs index f5d1336..91c0336 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -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 { fn parse_expr(tokens: &[Token]) -> Result<(Vec, usize), ParseError> { let mut ast = vec![]; let mut index = 0; + let mut op_stack: Vec = 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, 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, usize), ParseError> { }); ast.push(ASTNode::BinOp(op.clone())); index += 1; - } + }*/ + }, } index += 1; diff --git a/test.tea b/test.matcha similarity index 100% rename from test.tea rename to test.matcha