1
1
extern crate itertools;
2
2
use std:: collections:: HashMap ;
3
+ use std:: collections:: HashSet ;
3
4
use std:: sync:: atomic:: { AtomicUsize , Ordering , ATOMIC_USIZE_INIT } ;
4
5
use std:: fmt;
5
6
use self :: itertools:: Itertools ;
@@ -12,7 +13,7 @@ use super::sandbox::EnvProxy;
12
13
#[ derive( Eq ) ]
13
14
pub struct Code {
14
15
pub argcount : usize ,
15
- pub kwonlyargcount : u32 ,
16
+ pub kwonlyargcount : usize ,
16
17
pub nlocals : u32 ,
17
18
pub stacksize : u32 ,
18
19
pub flags : u32 ,
@@ -32,6 +33,36 @@ impl Code {
32
33
pub fn co_varargs ( & self ) -> bool {
33
34
self . flags & 0x4 != 0
34
35
}
36
+ pub fn co_varkwargs ( & self ) -> bool {
37
+ self . flags & 0x8 != 0
38
+ }
39
+ pub fn get_varargs_name ( & self ) -> Option < & String > {
40
+ if self . co_varargs ( ) {
41
+ Some ( self . varnames . get ( self . argcount +self . kwonlyargcount ) . unwrap ( ) )
42
+ }
43
+ else {
44
+ None
45
+ }
46
+ }
47
+ pub fn get_varkwargs_name ( & self ) -> Option < & String > {
48
+ if self . co_varkwargs ( ) {
49
+ let mut index = self . argcount +self . kwonlyargcount ;
50
+ if self . co_varkwargs ( ) {
51
+ index += 1 ;
52
+ }
53
+ Some ( self . varnames . get ( index) . unwrap ( ) )
54
+ }
55
+ else {
56
+ None
57
+ }
58
+ }
59
+ pub fn keywords ( & self ) -> HashSet < & String > {
60
+ let mut res = HashSet :: new ( ) ;
61
+ for name in self . varnames [ self . argcount ..( self . argcount +self . kwonlyargcount ) ] . iter ( ) {
62
+ res. insert ( name) ;
63
+ }
64
+ res
65
+ }
35
66
}
36
67
37
68
#[ derive( Debug ) ]
@@ -48,9 +79,10 @@ pub enum ObjectContent {
48
79
List ( Vec < ObjectRef > ) ,
49
80
Code ( Box < Code > ) ,
50
81
Set ( Vec < ObjectRef > ) ,
82
+ Dict ( Vec < ( ObjectRef , ObjectRef ) > ) ,
51
83
FrozenSet ( Vec < ObjectRef > ) ,
52
84
Bytes ( Vec < u8 > ) ,
53
- Function ( String , ObjectRef ) , // module, code
85
+ Function ( String , ObjectRef , HashMap < String , ObjectRef > ) , // module, code, default arguments
54
86
Module ( ObjectRef ) ,
55
87
PrimitiveNamespace , // __primitives__
56
88
PrimitiveFunction ( String ) ,
@@ -131,12 +163,13 @@ impl ObjectRef {
131
163
ObjectContent :: Int ( ref i) => i. to_string ( ) ,
132
164
ObjectContent :: Bytes ( ref s) => "<bytes>" . to_string ( ) , // TODO
133
165
ObjectContent :: String ( ref s) => format ! ( "'{}'" , s) , // TODO: escape
166
+ ObjectContent :: Dict ( ref l) => format ! ( "{{{}}}" , l. iter( ) . map( |arg| { let ( ref k, ref v) = * arg; format!( "{}: {}" , k. repr( store) , v. repr( store) ) } ) . join( ", " ) ) ,
134
167
ObjectContent :: Tuple ( ref l) => format ! ( "tuple({})" , ObjectRef :: repr_vec( l, store) ) ,
135
168
ObjectContent :: List ( ref l) => format ! ( "[{}]" , ObjectRef :: repr_vec( l, store) ) ,
136
169
ObjectContent :: Code ( _) => "<code object>" . to_string ( ) ,
137
170
ObjectContent :: Set ( ref l) => format ! ( "set({})" , ObjectRef :: repr_vec( l, store) ) ,
138
171
ObjectContent :: FrozenSet ( ref l) => format ! ( "frozenset({})" , ObjectRef :: repr_vec( l, store) ) ,
139
- ObjectContent :: Function ( ref module, ref _code) => {
172
+ ObjectContent :: Function ( ref module, ref _code, ref _defaults ) => {
140
173
match obj. name {
141
174
None => format ! ( "<anonymous function in module {}>" , module) ,
142
175
Some ( ref s) => format ! ( "<function {} in module {}>" , s, module) ,
@@ -167,7 +200,7 @@ impl ObjectRef {
167
200
let func = store. deref ( self ) ;
168
201
let ref name = func. name ;
169
202
match func. content {
170
- ObjectContent :: Function ( ref module_name, ref _code) => module_name. clone ( ) ,
203
+ ObjectContent :: Function ( ref module_name, ref _code, ref _defaults ) => module_name. clone ( ) ,
171
204
ObjectContent :: Module ( ref _code) => name. clone ( ) . unwrap ( ) ,
172
205
_ => panic ! ( format!( "Not a function/module: {:?}" , func) ) ,
173
206
}
@@ -241,6 +274,7 @@ pub struct PrimitiveObjects {
241
274
242
275
pub set_type : ObjectRef ,
243
276
pub frozenset_type : ObjectRef ,
277
+ pub dict_type : ObjectRef ,
244
278
245
279
pub bytes_type : ObjectRef ,
246
280
pub str_type : ObjectRef ,
@@ -300,6 +334,7 @@ impl PrimitiveObjects {
300
334
let list_type = store. allocate ( Object :: new_class ( "list" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
301
335
let set_type = store. allocate ( Object :: new_class ( "set" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
302
336
let frozenset_type = store. allocate ( Object :: new_class ( "frozenset" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
337
+ let dict_type = store. allocate ( Object :: new_class ( "dict" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
303
338
let bytes_type = store. allocate ( Object :: new_class ( "bytes" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
304
339
let str_type = store. allocate ( Object :: new_class ( "str" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
305
340
let iterator_type = store. allocate ( Object :: new_class ( "iterator" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
@@ -335,6 +370,7 @@ impl PrimitiveObjects {
335
370
map. insert ( "list" . to_string ( ) , list_type. clone ( ) ) ;
336
371
map. insert ( "set" . to_string ( ) , set_type. clone ( ) ) ;
337
372
map. insert ( "frozenset" . to_string ( ) , frozenset_type. clone ( ) ) ;
373
+ map. insert ( "dict" . to_string ( ) , dict_type. clone ( ) ) ;
338
374
map. insert ( "bytes" . to_string ( ) , bytes_type. clone ( ) ) ;
339
375
map. insert ( "str" . to_string ( ) , str_type. clone ( ) ) ;
340
376
map. insert ( "function" . to_string ( ) , function_type. clone ( ) ) ;
@@ -359,7 +395,7 @@ impl PrimitiveObjects {
359
395
none_type : none_type, none : none,
360
396
int_type : int_type, bool_type : bool_type, true_obj : true_obj, false_obj : false_obj,
361
397
tuple_type : tuple_type, list_type : list_type,
362
- set_type : set_type, frozenset_type : frozenset_type,
398
+ set_type : set_type, frozenset_type : frozenset_type, dict_type : dict_type ,
363
399
bytes_type : bytes_type, str_type : str_type,
364
400
iterator_type : iterator_type,
365
401
function_type : function_type, code_type : code_type,
@@ -389,14 +425,17 @@ impl PrimitiveObjects {
389
425
pub fn new_set ( & self , v : Vec < ObjectRef > ) -> Object {
390
426
Object :: new_instance ( None , self . set_type . clone ( ) , ObjectContent :: Set ( v) )
391
427
}
428
+ pub fn new_dict ( & self , v : Vec < ( ObjectRef , ObjectRef ) > ) -> Object {
429
+ Object :: new_instance ( None , self . dict_type . clone ( ) , ObjectContent :: Dict ( v) )
430
+ }
392
431
pub fn new_frozenset ( & self , v : Vec < ObjectRef > ) -> Object {
393
432
Object :: new_instance ( None , self . frozenset_type . clone ( ) , ObjectContent :: FrozenSet ( v) )
394
433
}
395
434
pub fn new_code ( & self , c : Code ) -> Object {
396
435
Object :: new_instance ( None , self . code_type . clone ( ) , ObjectContent :: Code ( Box :: new ( c) ) )
397
436
}
398
- pub fn new_function ( & self , name : String , module_name : String , code : ObjectRef ) -> Object {
399
- Object :: new_instance ( Some ( name) , self . function_type . clone ( ) , ObjectContent :: Function ( module_name, code) )
437
+ pub fn new_function ( & self , name : String , module_name : String , code : ObjectRef , defaults : HashMap < String , ObjectRef > ) -> Object {
438
+ Object :: new_instance ( Some ( name) , self . function_type . clone ( ) , ObjectContent :: Function ( module_name, code, defaults ) )
400
439
}
401
440
pub fn new_module ( & self , name : String , code : ObjectRef ) -> Object {
402
441
Object :: new_instance ( Some ( name) , self . module . clone ( ) , ObjectContent :: Module ( code) )
0 commit comments