feat: 添加取模运算符支持,更新解析器、解释器、词法分析器和相关示例以处理相关语法
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
let a = 7
|
||||
let b = a % 3
|
||||
print("b=", b)
|
||||
a %= 4
|
||||
print("a=", a)
|
||||
@@ -106,6 +106,7 @@ pub enum BinaryOp {
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Mod,
|
||||
|
||||
Greater,
|
||||
GreaterEqual,
|
||||
@@ -129,4 +130,5 @@ pub enum AssignOp {
|
||||
MinusEqual, // -=
|
||||
StarEqual, // *=
|
||||
SlashEqual, // /=
|
||||
PercentEqual, // %=
|
||||
}
|
||||
|
||||
@@ -314,6 +314,13 @@ impl Interpreter {
|
||||
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::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)?)),
|
||||
@@ -443,6 +450,11 @@ impl Interpreter {
|
||||
let right_num = self.as_number(&right)?;
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,14 @@ impl Lexer {
|
||||
}
|
||||
}
|
||||
|
||||
'%' => {
|
||||
if self.match_char('=') {
|
||||
TokenKind::PercentEqual
|
||||
} else {
|
||||
TokenKind::Percent
|
||||
}
|
||||
}
|
||||
|
||||
'!' => {
|
||||
if self.match_char('=') {
|
||||
TokenKind::BangEqual
|
||||
|
||||
+2
-2
@@ -9,14 +9,14 @@ pub enum TokenKind {
|
||||
Colon,
|
||||
|
||||
// 运算符
|
||||
Plus, Minus, Star, Slash,
|
||||
Plus, Minus, Star, Slash, Percent,
|
||||
Bang,
|
||||
Equal,
|
||||
Greater, GreaterEqual,
|
||||
Less, LessEqual,
|
||||
EqualEqual, BangEqual,
|
||||
AndAnd, OrOr,
|
||||
PlusEqual, MinusEqual, StarEqual, SlashEqual,
|
||||
PlusEqual, MinusEqual, StarEqual, SlashEqual, PercentEqual,
|
||||
|
||||
// 字面量
|
||||
Identifier(String),
|
||||
|
||||
@@ -212,6 +212,8 @@ impl Parser {
|
||||
Some(AssignOp::StarEqual)
|
||||
} else if self.match_kind(&[TokenKind::SlashEqual]) {
|
||||
Some(AssignOp::SlashEqual)
|
||||
} else if self.match_kind(&[TokenKind::PercentEqual]) {
|
||||
Some(AssignOp::PercentEqual)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -324,10 +326,11 @@ impl Parser {
|
||||
fn factor(&mut self) -> Expr {
|
||||
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 {
|
||||
TokenKind::Star => BinaryOp::Mul,
|
||||
TokenKind::Slash => BinaryOp::Div,
|
||||
TokenKind::Percent => BinaryOp::Mod,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let right = self.unary();
|
||||
|
||||
Reference in New Issue
Block a user