@@ -68,6 +68,9 @@ impl AstWalkInterpreter {
68
68
match s. data {
69
69
Stmt :: VarDecl ( ref variable, ref expr) => self . eval_stmt_var_decl ( variable, expr) ,
70
70
Stmt :: Assign ( ref lhs_expr, ref expr) => self . eval_stmt_assign ( lhs_expr, expr) ,
71
+ Stmt :: AssignOp ( ref lhs_expr, ref op, ref expr) => {
72
+ self . eval_stmt_assign_with_op ( lhs_expr, op, expr, s)
73
+ }
71
74
Stmt :: Block ( ref statements) => self . eval_stmt_block ( statements) ,
72
75
Stmt :: Expr ( ref expr) => {
73
76
let val = self . eval_expr ( expr) ?;
@@ -149,6 +152,42 @@ impl AstWalkInterpreter {
149
152
Ok ( StmtResult :: None )
150
153
}
151
154
155
+ fn eval_stmt_assign_with_op ( & mut self ,
156
+ lhs_expr : & LhsExprNode ,
157
+ op : & BinOp ,
158
+ expr : & ExprNode ,
159
+ stmt : & StmtNode )
160
+ -> Result < StmtResult , RuntimeErrorWithPosition > {
161
+ let val = self . eval_expr_as_value ( expr) ?;
162
+ match lhs_expr. data {
163
+ LhsExpr :: Identifier ( ref id) => {
164
+ let prev_expr_val = match self . env . borrow_mut ( ) . get_value ( id) {
165
+ Some ( v) => v,
166
+ None => {
167
+ return Err ( ( RuntimeError :: ReferenceError ( id. to_owned ( ) ) , lhs_expr. pos ) ) ;
168
+ }
169
+ } ;
170
+ let retval = match * op {
171
+ BinOp :: Add => operations:: add ( prev_expr_val, val) ,
172
+ BinOp :: Sub => operations:: subtract ( prev_expr_val, val) ,
173
+ BinOp :: Mul => operations:: multiply ( prev_expr_val, val) ,
174
+ BinOp :: Div => operations:: divide ( prev_expr_val, val) ,
175
+ BinOp :: Mod => operations:: modulo ( prev_expr_val, val) ,
176
+ BinOp :: Lt | BinOp :: Lte | BinOp :: Gt | BinOp :: Gte | BinOp :: Eq => unreachable ! ( ) ,
177
+ } ;
178
+ let new_val = match retval {
179
+ Ok ( val) => val,
180
+ Err ( e) => {
181
+ return Err ( ( e, stmt. pos ) ) ;
182
+ }
183
+ } ;
184
+ // id must exist, because it was checked above
185
+ self . env . borrow_mut ( ) . set ( id, new_val) ;
186
+ }
187
+ } ;
188
+ Ok ( StmtResult :: None )
189
+ }
190
+
152
191
fn eval_stmt_block ( & mut self ,
153
192
statements : & [ StmtNode ] )
154
193
-> Result < StmtResult , RuntimeErrorWithPosition > {
0 commit comments