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,
|
Sub,
|
||||||
Mul,
|
Mul,
|
||||||
Div,
|
Div,
|
||||||
|
Mod,
|
||||||
|
|
||||||
Greater,
|
Greater,
|
||||||
GreaterEqual,
|
GreaterEqual,
|
||||||
@@ -129,4 +130,5 @@ pub enum AssignOp {
|
|||||||
MinusEqual, // -=
|
MinusEqual, // -=
|
||||||
StarEqual, // *=
|
StarEqual, // *=
|
||||||
SlashEqual, // /=
|
SlashEqual, // /=
|
||||||
|
PercentEqual, // %=
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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),
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user