feat: 添加取模运算符支持,更新解析器、解释器、词法分析器和相关示例以处理相关语法

This commit is contained in:
0264408
2026-06-16 09:36:32 +08:00
parent 259dcf1af9
commit bd052699f5
6 changed files with 33 additions and 3 deletions
+5
View File
@@ -0,0 +1,5 @@
let a = 7
let b = a % 3
print("b=", b)
a %= 4
print("a=", a)
+2
View File
@@ -106,6 +106,7 @@ pub enum BinaryOp {
Sub, Sub,
Mul, Mul,
Div, Div,
Mod,
Greater, Greater,
GreaterEqual, GreaterEqual,
@@ -129,4 +130,5 @@ pub enum AssignOp {
MinusEqual, // -= MinusEqual, // -=
StarEqual, // *= StarEqual, // *=
SlashEqual, // /= SlashEqual, // /=
PercentEqual, // %=
} }
+12
View File
@@ -314,6 +314,13 @@ impl Interpreter {
token: None, token: None,
}), }),
}, },
crate::ast::expr::BinaryOp::Mod => match (l,r) {
(Value::Number(a), Value::Number(b)) => Ok(Value::Number(a%b)),
_ => Err(RuntimeError::RuntimeError {
message: "Invalid '%' operands".to_string(),
token: None,
}),
},
crate::ast::expr::BinaryOp::Greater => Ok(Value::Bool(self.as_number(&l)? > self.as_number(&r)?)), crate::ast::expr::BinaryOp::Greater => Ok(Value::Bool(self.as_number(&l)? > self.as_number(&r)?)),
crate::ast::expr::BinaryOp::GreaterEqual => Ok(Value::Bool(self.as_number(&l)? >= self.as_number(&r)?)), crate::ast::expr::BinaryOp::GreaterEqual => Ok(Value::Bool(self.as_number(&l)? >= self.as_number(&r)?)),
crate::ast::expr::BinaryOp::Less => Ok(Value::Bool(self.as_number(&l)? < self.as_number(&r)?)), crate::ast::expr::BinaryOp::Less => Ok(Value::Bool(self.as_number(&l)? < self.as_number(&r)?)),
@@ -443,6 +450,11 @@ impl Interpreter {
let right_num = self.as_number(&right)?; let right_num = self.as_number(&right)?;
Ok(Value::Number(left_num / right_num)) Ok(Value::Number(left_num / right_num))
} }
AssignOp::PercentEqual => {
let left_num = self.as_number(&left)?;
let right_num = self.as_number(&right)?;
Ok(Value::Number(left_num % right_num))
}
} }
} }
+8
View File
@@ -96,6 +96,14 @@ impl Lexer {
} }
} }
'%' => {
if self.match_char('=') {
TokenKind::PercentEqual
} else {
TokenKind::Percent
}
}
'!' => { '!' => {
if self.match_char('=') { if self.match_char('=') {
TokenKind::BangEqual TokenKind::BangEqual
+2 -2
View File
@@ -9,14 +9,14 @@ pub enum TokenKind {
Colon, Colon,
// 运算符 // 运算符
Plus, Minus, Star, Slash, Plus, Minus, Star, Slash, Percent,
Bang, Bang,
Equal, Equal,
Greater, GreaterEqual, Greater, GreaterEqual,
Less, LessEqual, Less, LessEqual,
EqualEqual, BangEqual, EqualEqual, BangEqual,
AndAnd, OrOr, AndAnd, OrOr,
PlusEqual, MinusEqual, StarEqual, SlashEqual, PlusEqual, MinusEqual, StarEqual, SlashEqual, PercentEqual,
// 字面量 // 字面量
Identifier(String), Identifier(String),
+4 -1
View File
@@ -212,6 +212,8 @@ impl Parser {
Some(AssignOp::StarEqual) Some(AssignOp::StarEqual)
} else if self.match_kind(&[TokenKind::SlashEqual]) { } else if self.match_kind(&[TokenKind::SlashEqual]) {
Some(AssignOp::SlashEqual) Some(AssignOp::SlashEqual)
} else if self.match_kind(&[TokenKind::PercentEqual]) {
Some(AssignOp::PercentEqual)
} else { } else {
None None
}; };
@@ -324,10 +326,11 @@ impl Parser {
fn factor(&mut self) -> Expr { fn factor(&mut self) -> Expr {
let mut expr = self.unary(); let mut expr = self.unary();
while self.match_kind(&[TokenKind::Star, TokenKind::Slash]) { while self.match_kind(&[TokenKind::Star, TokenKind::Slash, TokenKind::Percent]) {
let op = match self.previous().kind { let op = match self.previous().kind {
TokenKind::Star => BinaryOp::Mul, TokenKind::Star => BinaryOp::Mul,
TokenKind::Slash => BinaryOp::Div, TokenKind::Slash => BinaryOp::Div,
TokenKind::Percent => BinaryOp::Mod,
_ => unreachable!(), _ => unreachable!(),
}; };
let right = self.unary(); let right = self.unary();