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

Commit99af466

Browse files
committed
Move max function test cases to snippet dir. Implement key and default argument on max function.
1 parent4acea45 commit99af466

File tree

13 files changed

+191
-41
lines changed

13 files changed

+191
-41
lines changed

‎parser/src/lexer.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ where
197197
// Skip backslash and newline
198198
self.shift();
199199
self.shift();
200+
// Idea: insert trailing newline here:
201+
// } else if self.chr0 != Some('\n') && self.chr1.is_none() {
202+
// self.chr1 = Some('\n');
200203
}else{
201204
break;
202205
}
File renamed without changes.

‎tests/snippets/builtins.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@
1717

1818
assertlist(filter(lambdax: ((x%2)==0), [0,1,2]))== [0,2]
1919

20+
assert3==eval('1+2')
21+
22+
code=compile('5+3','x.py','eval')
23+
asserteval(code)==8

‎vm/src/builtins.rs‎

Lines changed: 87 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ fn builtin_compile(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
132132
]
133133
);
134134
let source = objstr::get_value(source);
135+
// TODO: fix this newline bug:
136+
let source =format!("{}\n", source);
135137

136138
let mode ={
137139
let mode = objstr::get_value(mode);
@@ -206,19 +208,36 @@ fn builtin_eval(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
206208
arg_check!(
207209
vm,
208210
args,
209-
required =[
210-
(source,None),// TODO: Use more specific type
211+
required =[(source,None)],
212+
optional =[
211213
(_globals,Some(vm.ctx.dict_type())),
212214
(locals,Some(vm.ctx.dict_type()))
213215
]
214216
);
215-
// TODO: handle optional global and locals
216217

217-
let code_obj = source;// if source.borrow().kind
218+
// Determine code object:
219+
let code_obj =if objtype::isinstance(source,&vm.ctx.code_type()){
220+
source.clone()
221+
}elseif objtype::isinstance(source,&vm.ctx.str_type()){
222+
let mode = compile::Mode::Eval;
223+
let source = objstr::get_value(source);
224+
// TODO: fix this newline bug:
225+
let source =format!("{}\n", source);
226+
compile::compile(vm,&source, mode,None)?
227+
}else{
228+
returnErr(vm.new_type_error("code argument must be str or code object".to_string()));
229+
};
230+
231+
let locals =ifletSome(locals) = locals{
232+
locals.clone()
233+
}else{
234+
vm.new_dict()
235+
};
218236

237+
// TODO: handle optional globals
219238
// Construct new scope:
220239
let scope_inner =Scope{
221-
locals: locals.clone(),
240+
locals: locals,
222241
parent:None,
223242
};
224243
let scope =PyObject{
@@ -235,26 +254,38 @@ fn builtin_exec(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
235254
arg_check!(
236255
vm,
237256
args,
238-
required =[
239-
(source,None),
257+
required =[(source,None)],
258+
optional =[
240259
(_globals,Some(vm.ctx.dict_type())),
241260
(locals,Some(vm.ctx.dict_type()))
242261
]
243262
);
244-
// TODO: handle optional global and locals
245263

246264
// Determine code object:
247265
let code_obj =if objtype::isinstance(source,&vm.ctx.str_type()){
248266
let mode = compile::Mode::Exec;
249267
let source = objstr::get_value(source);
268+
// TODO: fix this newline bug:
269+
let source =format!("{}\n", source);
250270
compile::compile(vm,&source, mode,None)?
251-
}else{
271+
}elseif objtype::isinstance(source,&vm.ctx.code_type()){
252272
source.clone()
273+
}else{
274+
returnErr(vm.new_type_error("source argument must be str or code object".to_string()));
253275
};
254276

277+
// handle optional global and locals
278+
let locals =ifletSome(locals) = locals{
279+
locals.clone()
280+
}else{
281+
vm.new_dict()
282+
};
283+
284+
// TODO: use globals
285+
255286
// Construct new scope:
256287
let scope_inner =Scope{
257-
locals: locals.clone(),
288+
locals: locals,
258289
parent:None,
259290
};
260291
let scope =PyObject{
@@ -416,15 +447,56 @@ fn builtin_map(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
416447
}
417448

418449
fnbuiltin_max(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
419-
arg_check!(vm, args, required =[(x,None),(y,None)]);
450+
//arg_check!(vm, args, required = [(x, None), (y, None)]);
420451

421-
let order = vm.call_method(x,"__gt__",vec![y.clone()])?;
452+
let candidates =if args.args.len() >1{
453+
args.args.clone()
454+
}elseif args.args.len() ==1{
455+
vm.extract_elements(&args.args[0])?
456+
}else{
457+
// zero arguments means type error:
458+
returnErr(vm.new_type_error("Expected 1 or more arguments".to_string()));
459+
};
422460

423-
if objbool::get_value(&order){
424-
Ok(x.clone())
461+
if candidates.len() ==0{
462+
let default = args.get_optional_kwarg("default");
463+
if default.is_none(){
464+
returnErr(vm.new_value_error("max() arg is an empty sequence".to_string()));
465+
}else{
466+
returnOk(default.unwrap());
467+
}
468+
}
469+
470+
let key_func = args.get_optional_kwarg("key");
471+
472+
// Start with first assumption:
473+
letmut candidates_iter = candidates.into_iter();
474+
letmut x = candidates_iter.next().unwrap();
475+
// TODO: this key function looks pretty duplicate. Maybe we can create
476+
// a local function?
477+
letmut x_key =ifletSome(f) =&key_func{
478+
let args =PyFuncArgs::new(vec![x.clone()],vec![]);
479+
vm.invoke(f.clone(), args)?
425480
}else{
426-
Ok(y.clone())
481+
x.clone()
482+
};
483+
484+
for yin candidates_iter{
485+
let y_key =ifletSome(f) =&key_func{
486+
let args =PyFuncArgs::new(vec![y.clone()],vec![]);
487+
vm.invoke(f.clone(), args)?
488+
}else{
489+
y.clone()
490+
};
491+
let order = vm.call_method(&x_key,"__gt__",vec![y_key.clone()])?;
492+
493+
if !objbool::get_value(&order){
494+
x = y.clone();
495+
x_key = y_key;
496+
}
427497
}
498+
499+
Ok(x)
428500
}
429501

430502
// builtin_memoryview

‎vm/src/obj/objcode.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use super::objtype;
1111

1212
pubfninit(context:&PyContext){
1313
letref code_type = context.code_type;
14+
code_type.set_attr("__new__", context.new_rustfunc(code_new));
1415
code_type.set_attr("__repr__", context.new_rustfunc(code_repr));
1516
}
1617

@@ -24,6 +25,11 @@ pub fn copy_code(code_obj: &PyObjectRef) -> bytecode::CodeObject {
2425
}
2526
}
2627

28+
fncode_new(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
29+
arg_check!(vm, args, required =[(_cls,None)]);
30+
Err(vm.new_type_error(format!("Cannot directly create code object")))
31+
}
32+
2733
fncode_repr(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
2834
arg_check!(vm, args, required =[(o,Some(vm.ctx.code_type()))]);
2935

‎vm/src/obj/objdict.rs‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,27 @@ fn dict_delitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
109109
}
110110
}
111111

112+
/// When iterating over a dictionary, we iterate over the keys of it.
113+
fndict_iter(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
114+
arg_check!(vm, args, required =[(dict,Some(vm.ctx.dict_type()))]);
115+
116+
let keys =get_elements(dict)
117+
.keys()
118+
.map(|k| vm.ctx.new_str(k.to_string()))
119+
.collect();
120+
let key_list = vm.ctx.new_list(keys);
121+
122+
let iter_obj =PyObject::new(
123+
PyObjectKind::Iterator{
124+
position:0,
125+
iterated_obj: key_list,
126+
},
127+
vm.ctx.iter_type(),
128+
);
129+
130+
Ok(iter_obj)
131+
}
132+
112133
fndict_setitem(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
113134
arg_check!(
114135
vm,
@@ -165,6 +186,7 @@ pub fn init(context: &PyContext) {
165186
dict_type.set_attr("__contains__", context.new_rustfunc(dict_contains));
166187
dict_type.set_attr("__delitem__", context.new_rustfunc(dict_delitem));
167188
dict_type.set_attr("__getitem__", context.new_rustfunc(dict_getitem));
189+
dict_type.set_attr("__iter__", context.new_rustfunc(dict_iter));
168190
dict_type.set_attr("__new__", context.new_rustfunc(dict_new));
169191
dict_type.set_attr("__repr__", context.new_rustfunc(dict_repr));
170192
dict_type.set_attr("__setitem__", context.new_rustfunc(dict_setitem));

‎vm/src/obj/objframe.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,15 @@ use super::objtype;
1010

1111
pubfninit(context:&PyContext){
1212
letref frame_type = context.frame_type;
13+
frame_type.set_attr("__new__", context.new_rustfunc(frame_new));
1314
frame_type.set_attr("__repr__", context.new_rustfunc(frame_repr));
1415
}
1516

17+
fnframe_new(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
18+
arg_check!(vm, args, required =[(_cls,None)]);
19+
Err(vm.new_type_error(format!("Cannot directly create frame object")))
20+
}
21+
1622
fnframe_repr(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
1723
arg_check!(vm, args, required =[(_frame,Some(vm.ctx.frame_type()))]);
1824
let repr =format!("<frame object at .. >");

‎vm/src/obj/objiter.rs‎

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
*/
44

55
usesuper::super::pyobject::{
6-
AttributeProtocol,PyContext,PyFuncArgs,PyObject,PyObjectKind,PyObjectRef,PyResult,
7-
TypeProtocol,
6+
AttributeProtocol,PyContext,PyFuncArgs,PyObjectKind,PyObjectRef,PyResult,TypeProtocol,
87
};
98
usesuper::super::vm::VirtualMachine;
109
usesuper::objbool;
@@ -17,30 +16,10 @@ use super::objtype; // Required for arg_check! to use isinstance
1716
* function 'iter' is called.
1817
*/
1918
pubfnget_iter(vm:&mutVirtualMachine,iter_target:&PyObjectRef) ->PyResult{
20-
// Check what we are going to iterate over:
21-
let iterated_obj =if objtype::isinstance(iter_target,&vm.ctx.iter_type()){
22-
// If object is already an iterator, return that one.
23-
returnOk(iter_target.clone());
24-
}elseif objtype::isinstance(iter_target,&vm.ctx.list_type()){
25-
iter_target.clone()
26-
// } else if hasattr(iter_target, "__iter__") {
27-
}else{
28-
return vm.call_method(iter_target,"__iter__",vec![]);
29-
// let type_str = objstr::get_value(&vm.to_str(iter_target.typ()).unwrap());
30-
// let type_error = vm.new_type_error(format!("Cannot iterate over {}", type_str));
31-
// return Err(type_error);
32-
};
33-
34-
let iter_obj =PyObject::new(
35-
PyObjectKind::Iterator{
36-
position:0,
37-
iterated_obj: iterated_obj,
38-
},
39-
vm.ctx.iter_type(),
40-
);
41-
42-
// We are all good here:
43-
Ok(iter_obj)
19+
vm.call_method(iter_target,"__iter__",vec![])
20+
// let type_str = objstr::get_value(&vm.to_str(iter_target.typ()).unwrap());
21+
// let type_error = vm.new_type_error(format!("Cannot iterate over {}", type_str));
22+
// return Err(type_error);
4423
}
4524

4625
/*

‎vm/src/obj/objlist.rs‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,21 @@ fn list_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
183183
get_item(vm, list,&get_elements(list), needle.clone())
184184
}
185185

186+
fnlist_iter(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
187+
arg_check!(vm, args, required =[(list,Some(vm.ctx.list_type()))]);
188+
189+
let iter_obj =PyObject::new(
190+
PyObjectKind::Iterator{
191+
position:0,
192+
iterated_obj: list.clone(),
193+
},
194+
vm.ctx.iter_type(),
195+
);
196+
197+
// We are all good here:
198+
Ok(iter_obj)
199+
}
200+
186201
fnlist_setitem(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
187202
arg_check!(
188203
vm,
@@ -199,6 +214,7 @@ pub fn init(context: &PyContext) {
199214
list_type.set_attr("__contains__", context.new_rustfunc(list_contains));
200215
list_type.set_attr("__eq__", context.new_rustfunc(list_eq));
201216
list_type.set_attr("__getitem__", context.new_rustfunc(list_getitem));
217+
list_type.set_attr("__iter__", context.new_rustfunc(list_iter));
202218
list_type.set_attr("__setitem__", context.new_rustfunc(list_setitem));
203219
list_type.set_attr("__len__", context.new_rustfunc(list_len));
204220
list_type.set_attr("__new__", context.new_rustfunc(list_new));

‎vm/src/obj/objstr.rs‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub fn init(context: &PyContext) {
1414
str_type.set_attr("__eq__", context.new_rustfunc(str_eq));
1515
str_type.set_attr("__contains__", context.new_rustfunc(str_contains));
1616
str_type.set_attr("__getitem__", context.new_rustfunc(str_getitem));
17+
str_type.set_attr("__gt__", context.new_rustfunc(str_gt));
1718
str_type.set_attr("__len__", context.new_rustfunc(str_len));
1819
str_type.set_attr("__mul__", context.new_rustfunc(str_mul));
1920
str_type.set_attr("__new__", context.new_rustfunc(str_new));
@@ -53,6 +54,21 @@ fn str_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5354
Ok(vm.ctx.new_bool(result))
5455
}
5556

57+
fnstr_gt(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
58+
arg_check!(
59+
vm,
60+
args,
61+
required =[
62+
(zelf,Some(vm.ctx.str_type())),
63+
(other,Some(vm.ctx.str_type()))
64+
]
65+
);
66+
let zelf =get_value(zelf);
67+
let other =get_value(other);
68+
let result = zelf > other;
69+
Ok(vm.ctx.new_bool(result))
70+
}
71+
5672
fnstr_str(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
5773
arg_check!(vm, args, required =[(s,Some(vm.ctx.str_type()))]);
5874
Ok(s.clone())

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp