Compare commits

..

2 Commits

7 changed files with 34 additions and 7 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,
Mul,
Div,
Mod,
Greater,
GreaterEqual,
@@ -129,4 +130,5 @@ pub enum AssignOp {
MinusEqual, // -=
StarEqual, // *=
SlashEqual, // /=
PercentEqual, // %=
}
+1 -4
View File
@@ -3,10 +3,7 @@
use crate::interpreter::Value;
pub fn print(args: Vec<Value>) -> Value {
for (i, arg) in args.iter().enumerate() {
if i > 0 {
print!(" ");
}
for arg in args.iter() {
print!("{}", arg);
}
println!();
+12
View File
@@ -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))
}
}
}
+8
View File
@@ -96,6 +96,14 @@ impl Lexer {
}
}
'%' => {
if self.match_char('=') {
TokenKind::PercentEqual
} else {
TokenKind::Percent
}
}
'!' => {
if self.match_char('=') {
TokenKind::BangEqual
+2 -2
View File
@@ -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),
+4 -1
View File
@@ -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();