Skip to content

Commit 8a0d8ab

Browse files
committed
Add += and -=
1 parent e648d2c commit 8a0d8ab

6 files changed

Lines changed: 90 additions & 9 deletions

File tree

parser/src/ast.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ pub enum Statement {
4242
targets: Vec<Expression>,
4343
value: Expression,
4444
},
45+
AugAssign {
46+
target: Expression,
47+
op: Operator,
48+
value: Expression,
49+
},
4550
Expression {
4651
expression: Expression,
4752
},
@@ -74,7 +79,7 @@ pub enum Statement {
7479
},
7580
}
7681

77-
#[derive(Debug, PartialEq)]
82+
#[derive(Debug, PartialEq, Clone)]
7883
pub enum Expression {
7984
Binop {
8085
a: Box<Expression>,
@@ -121,7 +126,7 @@ pub enum Expression {
121126
None,
122127
}
123128

124-
#[derive(Debug, PartialEq)]
129+
#[derive(Debug, PartialEq, Clone)]
125130
pub enum Operator {
126131
Add,
127132
Sub,
@@ -138,14 +143,17 @@ pub enum Operator {
138143
FloorDiv,
139144
// TODO: is this a binop?
140145
Subscript,
146+
147+
And,
148+
Or,
141149
}
142150

143-
#[derive(Debug, PartialEq)]
151+
#[derive(Debug, PartialEq, Clone)]
144152
pub enum UnaryOperator {
145153
Neg,
146154
}
147155

148-
#[derive(Debug, PartialEq)]
156+
#[derive(Debug, PartialEq, Clone)]
149157
pub enum Comparison {
150158
Equal,
151159
NotEqual,

parser/src/lexer.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,13 @@ impl<'input> Lexer<'input> {
267267
}
268268
Some('*') => {
269269
self.next_char();
270-
return Some(Ok((tok_start, Tok::DoubleStar, self.location + 1)));
270+
match self.chr0 {
271+
Some('=') => {
272+
self.next_char();
273+
return Some(Ok((tok_start, Tok::DoubleStarEqual, self.location + 1)));
274+
},
275+
_ => return Some(Ok((tok_start, Tok::DoubleStar, self.location + 1))),
276+
}
271277
}
272278
_ => return Some(Ok((tok_start, Tok::Star, self.location + 1))),
273279
}

parser/src/python.lalrpop

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,33 @@ ExpressionStatement: ast::Statement = {
6161
}
6262
}
6363
},
64+
<e1:Test> <op:AugAssign> <e2:TestList> => {
65+
// TODO: this works in most cases:
66+
let rhs = e2.into_iter().next().unwrap();
67+
ast::Statement::AugAssign { target: e1, op: op, value: rhs }
68+
},
6469
};
6570

6671
AssignSuffix: Vec<ast::Expression> = {
6772
"=" <e:TestList> => e,
6873
};
6974

75+
AugAssign: ast::Operator = {
76+
"+=" => ast::Operator::Add,
77+
"-=" => ast::Operator::Sub,
78+
"*=" => ast::Operator::Mult,
79+
"@=" => ast::Operator::MatMult,
80+
"/=" => ast::Operator::Div,
81+
"%=" => ast::Operator::Mod,
82+
"&=" => ast::Operator::BitAnd,
83+
"|=" => ast::Operator::BitOr,
84+
"^=" => ast::Operator::BitXor,
85+
"<<=" => ast::Operator::LShift,
86+
">>=" => ast::Operator::RShift,
87+
"**=" => ast::Operator::Pow,
88+
"//=" => ast::Operator::FloorDiv,
89+
};
90+
7091
FlowStatement: ast::Statement = {
7192
"break" => ast::Statement::Break,
7293
"continue" => ast::Statement::Continue,
@@ -132,10 +153,12 @@ Test: ast::Expression = {
132153

133154
OrTest: ast::Expression = {
134155
<e:AndTest> => e,
156+
<e1:OrTest> "or" <e2:AndTest> => ast::Expression::Binop { a: Box::new(e1), op: ast::Operator::Or, b: Box::new(e2) },
135157
};
136158

137159
AndTest: ast::Expression = {
138160
<e:NotTest> => e,
161+
<e1:AndTest> "and" <e2:NotTest> => ast::Expression::Binop { a: Box::new(e1), op: ast::Operator::And, b: Box::new(e2) },
139162
};
140163

141164
NotTest: ast::Expression = {
@@ -299,12 +322,24 @@ extern {
299322
"=" => lexer::Tok::Equal,
300323
"+=" => lexer::Tok::PlusEqual,
301324
"-=" => lexer::Tok::MinusEqual,
325+
"*=" => lexer::Tok::StarEqual,
326+
"@=" => lexer::Tok::AtEqual,
327+
"/=" => lexer::Tok::SlashEqual,
328+
"%=" => lexer::Tok::PercentEqual,
329+
"&=" => lexer::Tok::AmperEqual,
330+
"|=" => lexer::Tok::VbarEqual,
331+
"^=" => lexer::Tok::CircumflexEqual,
332+
"<<=" => lexer::Tok::LeftShiftEqual,
333+
">>=" => lexer::Tok::RightShiftEqual,
334+
"**=" => lexer::Tok::DoubleStarEqual,
335+
"//=" => lexer::Tok::DoubleSlashEqual,
302336
"==" => lexer::Tok::EqEqual,
303337
"!=" => lexer::Tok::NotEqual,
304338
"<" => lexer::Tok::Less,
305339
"<=" => lexer::Tok::LessEqual,
306340
">" => lexer::Tok::Greater,
307341
">=" => lexer::Tok::GreaterEqual,
342+
"and" => lexer::Tok::And,
308343
"as" => lexer::Tok::As,
309344
"assert" => lexer::Tok::Assert,
310345
"break" => lexer::Tok::Break,
@@ -317,6 +352,7 @@ extern {
317352
"is" => lexer::Tok::Is,
318353
"import" => lexer::Tok::Import,
319354
"not" => lexer::Tok::Not,
355+
"or" => lexer::Tok::Or,
320356
"pass" => lexer::Tok::Pass,
321357
"return" => lexer::Tok::Return,
322358
"while" => lexer::Tok::While,

parser/src/token.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub enum Tok {
3838
LeftShift,
3939
RightShift,
4040
DoubleStar,
41+
DoubleStarEqual, // '**='
4142
PlusEqual,
4243
MinusEqual,
4344
StarEqual,

vm/src/compile.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,39 @@ impl Compiler {
250250
}
251251
}
252252
}
253+
ast::Statement::AugAssign { target, op, value } => {
254+
self.compile_expression(target.clone());
255+
self.compile_expression(value);
256+
257+
// Perform operation:
258+
let i = match op {
259+
ast::Operator::Add => bytecode::BinaryOperator::Add,
260+
ast::Operator::Sub => bytecode::BinaryOperator::Subtract,
261+
ast::Operator::Mult => bytecode::BinaryOperator::Multiply,
262+
ast::Operator::MatMult => bytecode::BinaryOperator::MatrixMultiply,
263+
ast::Operator::Div => bytecode::BinaryOperator::Divide,
264+
ast::Operator::FloorDiv => bytecode::BinaryOperator::FloorDivide,
265+
ast::Operator::Mod => bytecode::BinaryOperator::Modulo,
266+
ast::Operator::Pow => bytecode::BinaryOperator::Power,
267+
ast::Operator::LShift => bytecode::BinaryOperator::Lshift,
268+
ast::Operator::RShift => bytecode::BinaryOperator::Rshift,
269+
ast::Operator::BitOr => bytecode::BinaryOperator::Or,
270+
ast::Operator::BitXor => bytecode::BinaryOperator::Xor,
271+
ast::Operator::BitAnd => bytecode::BinaryOperator::And,
272+
ast::Operator::Subscript => bytecode::BinaryOperator::Subscript,
273+
ast::Operator::And | ast::Operator::Or => { panic!("Not possible") },
274+
};
275+
self.emit(Instruction::BinaryOperation { op: i });
276+
277+
match target {
278+
ast::Expression::Identifier { name } => {
279+
self.emit(Instruction::StoreName { name: name });
280+
}
281+
_ => {
282+
panic!("WTF");
283+
}
284+
}
285+
}
253286
ast::Statement::Delete { targets } => {
254287
// Remove the given names from the scope
255288
// self.emit(Instruction::DeleteName);
@@ -291,6 +324,7 @@ impl Compiler {
291324
ast::Operator::BitXor => bytecode::BinaryOperator::Xor,
292325
ast::Operator::BitAnd => bytecode::BinaryOperator::And,
293326
ast::Operator::Subscript => bytecode::BinaryOperator::Subscript,
327+
ast::Operator::And | ast::Operator::Or => { panic!("Implement boolean short circuit?") },
294328
};
295329
let i = Instruction::BinaryOperation { op: i };
296330
self.emit(i);

vm/src/vm.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,6 @@ impl VirtualMachine {
125125

126126
// Container of the virtual machine state:
127127
pub fn evaluate(&mut self, code: bytecode::CodeObject) -> PyResult {
128-
// Register built in function:
129-
// vm.scope.insert(String::from("print"), PyObject::RustFunction { function: builtins::print }.into_ref());
130-
131-
// { stack: Vec::new() };
132128
self.run(Rc::new(code))
133129
}
134130

0 commit comments

Comments
 (0)