|
1 |
| -// count number of tokens given as arguments. |
2 |
| -// see: https://danielkeep.github.io/tlborm/book/blk-counting.html |
3 |
| -#[macro_export] |
4 |
| -macro_rules! replace_expr { |
5 |
| - ($_t:tt $sub:expr) => { |
6 |
| - $sub |
7 |
| - }; |
8 |
| -} |
9 |
| - |
10 |
| -#[macro_export] |
11 |
| -macro_rules! count_tts { |
12 |
| - ($($tts:tt)*) => {0usize $(+ $crate::replace_expr!($tts 1usize))*}; |
13 |
| -} |
14 |
| - |
15 |
| -#[macro_export] |
16 |
| -macro_rules! type_check { |
17 |
| - ($vm:ident, $args:ident, $arg_count:ident, $arg_name:ident, $arg_type:expr) => { |
18 |
| - // None indicates that we have no type requirement (i.e. we accept any type) |
19 |
| - if let Some(expected_type) = $arg_type { |
20 |
| - let arg = &$args.args[$arg_count]; |
21 |
| - |
22 |
| - if !$crate::obj::objtype::isinstance(arg, &expected_type) { |
23 |
| - use $crate::pyobject::TypeProtocol; |
24 |
| - |
25 |
| - let arg_typ = arg.class(); |
26 |
| - let expected_type_name = $vm.to_pystr(&expected_type)?; |
27 |
| - let actual_type = $vm.to_pystr(&arg_typ)?; |
28 |
| - return Err($vm.new_type_error(format!( |
29 |
| - "argument of type {} is required for parameter {} ({}) (got: {})", |
30 |
| - expected_type_name, |
31 |
| - $arg_count + 1, |
32 |
| - stringify!($arg_name), |
33 |
| - actual_type |
34 |
| - ))); |
35 |
| - } |
36 |
| - } |
37 |
| - }; |
38 |
| -} |
39 |
| - |
40 |
| -#[macro_export] |
41 |
| -macro_rules! arg_check { |
42 |
| - ( $vm: ident, $args:ident ) => { |
43 |
| - // Zero-arg case |
44 |
| - if $args.args.len() != 0 { |
45 |
| - return Err($vm.new_type_error(format!( |
46 |
| - "Expected no arguments (got: {})", $args.args.len()))); |
47 |
| - } |
48 |
| - }; |
49 |
| - ( $vm: ident, $args:ident, required=[$( ($arg_name:ident, $arg_type:expr) ),*] ) => { |
50 |
| - $crate::arg_check!($vm, $args, required=[$( ($arg_name, $arg_type) ),*], optional=[]); |
51 |
| - }; |
52 |
| - ( $vm: ident, $args:ident, required=[$( ($arg_name:ident, $arg_type:expr) ),*], optional=[$( ($optional_arg_name:ident, $optional_arg_type:expr) ),*] ) => { |
53 |
| - let mut arg_count = 0; |
54 |
| - |
55 |
| - // use macro magic to compile-time count number of required and optional arguments |
56 |
| - let minimum_arg_count = $crate::count_tts!($($arg_name)*); |
57 |
| - let maximum_arg_count = minimum_arg_count + $crate::count_tts!($($optional_arg_name)*); |
58 |
| - |
59 |
| - // verify that the number of given arguments is right |
60 |
| - if $args.args.len() < minimum_arg_count || $args.args.len() > maximum_arg_count { |
61 |
| - let expected_str = if minimum_arg_count == maximum_arg_count { |
62 |
| - format!("{}", minimum_arg_count) |
63 |
| - } else { |
64 |
| - format!("{}-{}", minimum_arg_count, maximum_arg_count) |
65 |
| - }; |
66 |
| - return Err($vm.new_type_error(format!( |
67 |
| - "Expected {} arguments (got: {})", |
68 |
| - expected_str, |
69 |
| - $args.args.len() |
70 |
| - ))); |
71 |
| - }; |
72 |
| - |
73 |
| - // for each required parameter: |
74 |
| - // check if the type matches. If not, return with error |
75 |
| - // assign the arg to a variable |
76 |
| - $( |
77 |
| - $crate::type_check!($vm, $args, arg_count, $arg_name, $arg_type); |
78 |
| - let $arg_name = &$args.args[arg_count]; |
79 |
| - #[allow(unused_assignments)] |
80 |
| - { |
81 |
| - arg_count += 1; |
82 |
| - } |
83 |
| - )* |
84 |
| - |
85 |
| - // for each optional parameter, if there are enough positional arguments: |
86 |
| - // check if the type matches. If not, return with error |
87 |
| - // assign the arg to a variable |
88 |
| - $( |
89 |
| - let $optional_arg_name = if arg_count < $args.args.len() { |
90 |
| - $crate::type_check!($vm, $args, arg_count, $optional_arg_name, $optional_arg_type); |
91 |
| - let ret = Some(&$args.args[arg_count]); |
92 |
| - #[allow(unused_assignments)] |
93 |
| - { |
94 |
| - arg_count += 1; |
95 |
| - } |
96 |
| - ret |
97 |
| - } else { |
98 |
| - None |
99 |
| - }; |
100 |
| - )* |
101 |
| - }; |
102 |
| -} |
103 |
| - |
104 | 1 | #[macro_export]
|
105 | 2 | macro_rules! no_kwargs {
|
106 | 3 | ( $vm: ident, $args:ident ) => {
|
|
0 commit comments