mirror of
https://github.com/zrax/pycdc.git
synced 2026-06-23 11:34:07 +00:00
Merge 5d79f6c90d into b428976097
This commit is contained in:
commit
e968b2fb48
6 changed files with 100 additions and 11 deletions
68
ASTree.cpp
68
ASTree.cpp
|
|
@ -1664,13 +1664,67 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
|
|||
ASTFunction::defarg_t defArgs, kwDefArgs;
|
||||
const int defCount = operand & 0xFF;
|
||||
const int kwDefCount = (operand >> 8) & 0xFF;
|
||||
for (int i = 0; i < defCount; ++i) {
|
||||
defArgs.push_front(stack.top());
|
||||
stack.pop();
|
||||
}
|
||||
for (int i = 0; i < kwDefCount; ++i) {
|
||||
kwDefArgs.push_front(stack.top());
|
||||
stack.pop();
|
||||
const int annotationCount = (operand >> 16) & 0x7FFF;
|
||||
|
||||
/* Docs for 3.3 say KW Pairs come first, but reality disagrees */
|
||||
if (mod->verCompare(3, 3) <= 0) {
|
||||
for (int i = 0; i < defCount; ++i) {
|
||||
defArgs.push_front(stack.top());
|
||||
stack.pop();
|
||||
}
|
||||
/* KW Defaults not mentioned in docs, but they come after the positional args */
|
||||
for (int i = 0; i < kwDefCount; ++i) {
|
||||
kwDefArgs.push_front(stack.top());
|
||||
stack.pop(); // KW Pair object
|
||||
stack.pop(); // KW Pair name
|
||||
}
|
||||
} else if (mod->verCompare(3, 5) <= 0) {
|
||||
/* From Py 3.4 there can now be annotation params
|
||||
The order has also switched so Kwargs come before Pos Args */
|
||||
if(annotationCount) {
|
||||
stack.pop(); // Tuple of param names for annotations
|
||||
for (int i = 0; i < annotationCount; ++i) {
|
||||
stack.pop(); // Pop annotation objects and ignore
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < kwDefCount; ++i) {
|
||||
kwDefArgs.push_front(stack.top());
|
||||
stack.pop(); // KW Pair object
|
||||
stack.pop(); // KW Pair name
|
||||
}
|
||||
for (int i = 0; i < defCount; ++i) {
|
||||
defArgs.push_front(stack.top());
|
||||
stack.pop();
|
||||
}
|
||||
} else {
|
||||
/* From Py 3.6 the operand stopped being an argument count
|
||||
and changed to a flag that indicates what is represented by
|
||||
preceding tuples on the stack. Docs for 3.7 are clearer,
|
||||
docs for 3.6 may have not been correctly updated */
|
||||
if(operand & 0x08) { // Cells for free vars to create a closure
|
||||
stack.pop(); // Ignore these for syntax generation
|
||||
}
|
||||
if(operand & 0x04) { // Annotation dict (3.6-9) or string (3.10+)
|
||||
stack.pop(); // Ignore annotations
|
||||
}
|
||||
if(operand & 0x02) { // Kwarg Defaults
|
||||
PycRef<ASTNode> kw_tuple = stack.top();
|
||||
stack.pop();
|
||||
std::vector<PycRef<ASTNode>> kw_values = kw_tuple.cast<ASTConstMap>()->values();
|
||||
|
||||
for(const PycRef<ASTNode>& kw : kw_values) {
|
||||
kwDefArgs.push_front(kw);
|
||||
}
|
||||
}
|
||||
if(operand & 0x01) { // Positional Defaults (including positional-or-KW args)
|
||||
PycRef<ASTNode> pos_tuple = stack.top();
|
||||
stack.pop();
|
||||
std::vector<PycRef<PycObject>> pos_values = pos_tuple.cast<ASTObject>()->object().cast<PycTuple>()->values();
|
||||
|
||||
for(const PycRef<PycObject>& pos : pos_values) {
|
||||
defArgs.push_back(new ASTObject(pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
stack.push(new ASTFunction(fun_code, defArgs, kwDefArgs));
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -57,3 +57,6 @@ def x7c(foo = 1, *, bar, **kwargs):
|
|||
|
||||
def x7d(foo = 1, *, bar = 2, **kwargs):
|
||||
pass
|
||||
|
||||
def x7e(foo = 1, *, bar = 2, baz = 3, **kwargs):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -34,18 +34,50 @@ def x4c ( foo , bar = 1 , bla = 2 , * args , ** kwargs ) : <EOL>
|
|||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x5a ( * , bar = 1 ) : <EOL>
|
||||
def x5a ( * , bar ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x5b ( * , bar = 1 , ** kwargs ) : <EOL>
|
||||
def x5b ( * , bar = 1 ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x6a ( foo , * , bar = 1 ) : <EOL>
|
||||
def x5c ( * , bar = 1 , ** kwargs ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x7a ( foo , * , bar = 1 , ** kwargs ) : <EOL>
|
||||
def x6a ( foo , * , bar ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x6b ( foo , * , bar = 1 ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x6c ( foo = 1 , * , bar ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x6d ( foo = 1 , * , bar = 2 ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x7a ( foo , * , bar , ** kwargs ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x7b ( foo , * , bar = 1 , ** kwargs ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x7c ( foo = 1 , * , bar , ** kwargs ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x7d ( foo = 1 , * , bar = 2 , ** kwargs ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def x7e ( foo = 1 , * , bar = 2 , baz = 3 , ** kwargs ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue