Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbddaf3e

Browse files
committed
Implement while-else and for-else. Call __neg__ and __invert__ methods on unary operation.
1 parentcb4d66b commitbddaf3e

File tree

7 files changed

+81
-69
lines changed

7 files changed

+81
-69
lines changed

‎tests/snippets/for.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
x=0
2-
foriin [1,2,3,4]:
2+
foriin [1,2,3,4]:
33
x+=1
44

55
assertx==4
66

7+
foriin [1,2,3]:
8+
x=i+5
9+
else:
10+
x=3
11+
12+
assertx==3

‎vm/src/bytecode.rs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ pub enum Instruction {
124124
CallFunction{
125125
typ:CallType,
126126
},
127-
ForIter,
127+
ForIter{
128+
target:Label,
129+
},
128130
ReturnValue,
129131
YieldValue,
130132
YieldFrom,

‎vm/src/compile.rs‎

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -199,13 +199,9 @@ impl Compiler {
199199
}
200200
self.set_label(end_label);
201201
}
202-
ast::Statement::While{
203-
test,
204-
body,
205-
orelse: _,
206-
} =>{
207-
// TODO: Handle while-loop else clauses
202+
ast::Statement::While{ test, body, orelse} =>{
208203
let start_label =self.new_label();
204+
let else_label =self.new_label();
209205
let end_label =self.new_label();
210206
self.emit(Instruction::SetupLoop{
211207
start: start_label,
@@ -214,12 +210,17 @@ impl Compiler {
214210

215211
self.set_label(start_label);
216212

217-
self.compile_test(test,None,Some(end_label),EvalContext::Statement)?;
213+
self.compile_test(test,None,Some(else_label),EvalContext::Statement)?;
218214
self.compile_statements(body)?;
219215
self.emit(Instruction::Jump{
220216
target: start_label,
221217
});
218+
self.set_label(else_label);
219+
ifletSome(orelse) = orelse{
220+
self.compile_statements(orelse)?;
221+
}
222222
self.set_label(end_label);
223+
self.emit(Instruction::PopBlock);
223224
}
224225
ast::Statement::With{ items, body} =>{
225226
let end_label =self.new_label();
@@ -246,9 +247,8 @@ impl Compiler {
246247
target,
247248
iter,
248249
body,
249-
orelse: _,
250+
orelse,
250251
} =>{
251-
// TODO: Handle for loop else clauses
252252
// The thing iterated:
253253
for iin iter{
254254
self.compile_expression(i)?;
@@ -259,13 +259,14 @@ impl Compiler {
259259

260260
// Start loop
261261
let start_label =self.new_label();
262+
let else_label =self.new_label();
262263
let end_label =self.new_label();
263264
self.emit(Instruction::SetupLoop{
264265
start: start_label,
265266
end: end_label,
266267
});
267268
self.set_label(start_label);
268-
self.emit(Instruction::ForIter);
269+
self.emit(Instruction::ForIter{target: else_label});
269270

270271
// Start of loop iteration, set targets:
271272
self.compile_store(target)?;
@@ -275,6 +276,10 @@ impl Compiler {
275276
self.emit(Instruction::Jump{
276277
target: start_label,
277278
});
279+
self.set_label(else_label);
280+
ifletSome(orelse) = orelse{
281+
self.compile_statements(orelse)?;
282+
}
278283
self.set_label(end_label);
279284
self.emit(Instruction::PopBlock);
280285
}
@@ -1174,7 +1179,7 @@ impl Compiler {
11741179
end: end_label,
11751180
});
11761181
self.set_label(start_label);
1177-
self.emit(Instruction::ForIter);
1182+
self.emit(Instruction::ForIter{target: end_label});
11781183

11791184
self.compile_store(&generator.target)?;
11801185

‎vm/src/frame.rs‎

Lines changed: 16 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ impl Frame {
408408
self.push_value(iter_obj);
409409
Ok(None)
410410
}
411-
bytecode::Instruction::ForIter =>{
411+
bytecode::Instruction::ForIter{ target}=>{
412412
// The top of stack contains the iterator, lets push it forward:
413413
let top_of_stack =self.last_value();
414414
let next_obj = objiter::get_next_object(vm,&top_of_stack);
@@ -424,12 +424,7 @@ impl Frame {
424424
self.pop_value();
425425

426426
// End of for loop
427-
let end_label =ifletBlock::Loop{start: _, end} =self.last_block(){
428-
*end
429-
}else{
430-
panic!("Wrong block type")
431-
};
432-
self.jump(end_label);
427+
self.jump(*target);
433428
Ok(None)
434429
}
435430
Err(next_error) =>{
@@ -927,49 +922,18 @@ impl Frame {
927922
) ->FrameResult{
928923
let a =self.pop_value();
929924
let value =match op{
930-
&bytecode::UnaryOperator::Minus =>{
931-
// TODO:
932-
// self.invoke('__neg__'
933-
match a.borrow().kind{
934-
PyObjectKind::Integer{value:ref value1} => vm.ctx.new_int(-value1),
935-
PyObjectKind::Float{value:ref value1} => vm.ctx.new_float(-*value1),
936-
_ =>panic!("Not impl {:?}", a),
937-
}
938-
}
925+
&bytecode::UnaryOperator::Minus => vm.call_method(&a,"__neg__",vec![])?,
926+
&bytecode::UnaryOperator::Plus => vm.call_method(&a,"__pos__",vec![])?,
927+
&bytecode::UnaryOperator::Invert => vm.call_method(&a,"__invert__",vec![])?,
939928
&bytecode::UnaryOperator::Not =>{
940929
let value = objbool::boolval(vm, a)?;
941930
vm.ctx.new_bool(!value)
942931
}
943-
_ =>panic!("Not impl {:?}", op),
944932
};
945933
self.push_value(value);
946934
Ok(None)
947935
}
948936

949-
fn_eq(&mutself,vm:&mutVirtualMachine,a:PyObjectRef,b:PyObjectRef) ->PyResult{
950-
vm.call_method(&a,"__eq__",vec![b])
951-
}
952-
953-
fn_ne(&mutself,vm:&mutVirtualMachine,a:PyObjectRef,b:PyObjectRef) ->PyResult{
954-
vm.call_method(&a,"__ne__",vec![b])
955-
}
956-
957-
fn_lt(&mutself,vm:&mutVirtualMachine,a:PyObjectRef,b:PyObjectRef) ->PyResult{
958-
vm.call_method(&a,"__lt__",vec![b])
959-
}
960-
961-
fn_le(&mutself,vm:&mutVirtualMachine,a:PyObjectRef,b:PyObjectRef) ->PyResult{
962-
vm.call_method(&a,"__le__",vec![b])
963-
}
964-
965-
fn_gt(&mutself,vm:&mutVirtualMachine,a:PyObjectRef,b:PyObjectRef) ->PyResult{
966-
vm.call_method(&a,"__gt__",vec![b])
967-
}
968-
969-
fn_ge(&mutself,vm:&mutVirtualMachine,a:PyObjectRef,b:PyObjectRef) ->PyResult{
970-
vm.call_method(&a,"__ge__",vec![b])
971-
}
972-
973937
fn_id(&self,a:PyObjectRef) ->usize{
974938
a.get_id()
975939
}
@@ -1035,17 +999,17 @@ impl Frame {
1035999
let b =self.pop_value();
10361000
let a =self.pop_value();
10371001
let value =match op{
1038-
&bytecode::ComparisonOperator::Equal =>self._eq(vm,a, b),
1039-
&bytecode::ComparisonOperator::NotEqual =>self._ne(vm,a, b),
1040-
&bytecode::ComparisonOperator::Less =>self._lt(vm,a, b),
1041-
&bytecode::ComparisonOperator::LessOrEqual =>self._le(vm,a, b),
1042-
&bytecode::ComparisonOperator::Greater =>self._gt(vm,a, b),
1043-
&bytecode::ComparisonOperator::GreaterOrEqual =>self._ge(vm,a, b),
1044-
&bytecode::ComparisonOperator::Is =>Ok(vm.ctx.new_bool(self._is(a, b))),
1045-
&bytecode::ComparisonOperator::IsNot =>self._is_not(vm, a, b),
1046-
&bytecode::ComparisonOperator::In =>self._in(vm, a, b),
1047-
&bytecode::ComparisonOperator::NotIn =>self._not_in(vm, a, b),
1048-
}?;
1002+
&bytecode::ComparisonOperator::Equal =>vm._eq(&a, b)?,
1003+
&bytecode::ComparisonOperator::NotEqual =>vm._ne(&a, b)?,
1004+
&bytecode::ComparisonOperator::Less =>vm._lt(&a, b)?,
1005+
&bytecode::ComparisonOperator::LessOrEqual =>vm._le(&a, b)?,
1006+
&bytecode::ComparisonOperator::Greater =>vm._gt(&a, b)?,
1007+
&bytecode::ComparisonOperator::GreaterOrEqual =>vm._ge(&a, b)?,
1008+
&bytecode::ComparisonOperator::Is => vm.ctx.new_bool(self._is(a, b)),
1009+
&bytecode::ComparisonOperator::IsNot =>self._is_not(vm, a, b)?,
1010+
&bytecode::ComparisonOperator::In =>self._in(vm, a, b)?,
1011+
&bytecode::ComparisonOperator::NotIn =>self._not_in(vm, a, b)?,
1012+
};
10491013

10501014
self.push_value(value);
10511015
Ok(None)
@@ -1105,10 +1069,6 @@ impl Frame {
11051069
self.blocks.pop()
11061070
}
11071071

1108-
fnlast_block(&self) ->&Block{
1109-
self.blocks.last().unwrap()
1110-
}
1111-
11121072
pubfnpush_value(&mutself,obj:PyObjectRef){
11131073
self.stack.push(obj);
11141074
}

‎vm/src/obj/objfloat.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,13 @@ fn float_mod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
225225
}
226226
}
227227

228+
fnfloat_neg(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
229+
arg_check!(vm, args, required =[(i,Some(vm.ctx.float_type()))]);
230+
231+
let v1 =get_value(i);
232+
Ok(vm.ctx.new_float(-v1))
233+
}
234+
228235
fnfloat_pow(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
229236
arg_check!(
230237
vm,
@@ -257,6 +264,7 @@ pub fn init(context: &PyContext) {
257264
float_type.set_attr("__floordiv__", context.new_rustfunc(float_floordiv));
258265
float_type.set_attr("__init__", context.new_rustfunc(float_init));
259266
float_type.set_attr("__mod__", context.new_rustfunc(float_mod));
267+
float_type.set_attr("__neg__", context.new_rustfunc(float_neg));
260268
float_type.set_attr("__pow__", context.new_rustfunc(float_pow));
261269
float_type.set_attr("__sub__", context.new_rustfunc(float_sub));
262270
float_type.set_attr("__repr__", context.new_rustfunc(float_repr));

‎vm/src/obj/objint.rs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,12 @@ fn int_mod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
281281
}
282282
}
283283

284+
fnint_neg(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
285+
arg_check!(vm, args, required =[(i,Some(vm.ctx.int_type()))]);
286+
let i =BigInt::from_pyobj(i);
287+
Ok(vm.ctx.new_int(-i))
288+
}
289+
284290
fnint_pow(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
285291
arg_check!(
286292
vm,
@@ -386,6 +392,7 @@ pub fn init(context: &PyContext) {
386392
int_type.set_attr("__new__", context.new_rustfunc(int_new));
387393
int_type.set_attr("__mod__", context.new_rustfunc(int_mod));
388394
int_type.set_attr("__mul__", context.new_rustfunc(int_mul));
395+
int_type.set_attr("__neg__", context.new_rustfunc(int_neg));
389396
int_type.set_attr("__or__", context.new_rustfunc(int_or));
390397
int_type.set_attr("__pow__", context.new_rustfunc(int_pow));
391398
int_type.set_attr("__repr__", context.new_rustfunc(int_repr));

‎vm/src/vm.rs‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,30 @@ impl VirtualMachine {
409409
pubfn_and(&mutself,a:PyObjectRef,b:PyObjectRef) ->PyResult{
410410
self.call_method(&a,"__and__",vec![b])
411411
}
412+
413+
pubfn_eq(&mutself,a:&PyObjectRef,b:PyObjectRef) ->PyResult{
414+
self.call_method(a,"__eq__",vec![b])
415+
}
416+
417+
pubfn_ne(&mutself,a:&PyObjectRef,b:PyObjectRef) ->PyResult{
418+
self.call_method(a,"__ne__",vec![b])
419+
}
420+
421+
pubfn_lt(&mutself,a:&PyObjectRef,b:PyObjectRef) ->PyResult{
422+
self.call_method(a,"__lt__",vec![b])
423+
}
424+
425+
pubfn_le(&mutself,a:&PyObjectRef,b:PyObjectRef) ->PyResult{
426+
self.call_method(a,"__le__",vec![b])
427+
}
428+
429+
pubfn_gt(&mutself,a:&PyObjectRef,b:PyObjectRef) ->PyResult{
430+
self.call_method(a,"__gt__",vec![b])
431+
}
432+
433+
pubfn_ge(&mutself,a:&PyObjectRef,b:PyObjectRef) ->PyResult{
434+
self.call_method(a,"__ge__",vec![b])
435+
}
412436
}
413437

414438
#[cfg(test)]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp