Support chained assignment statements, e.g. a = b = c.

We know when we have begun a chained assignment when we process a DUP_TOP with non-null on the stack. Push a NODE_CHAINSTORE onto the stack when this happens, and keep it 'floating' on top of the stack for all STORE_X operations until the stack is empty.
To support versions of Python <= 2.5 which use DUP_TOP in more places, I modified ROT_TWO, ROT_THREE and ROT_FOUR to get rid of NODE_CHAINSTORE on the stack if it is present.
This commit is contained in:
Aralox
2020-10-23 21:19:01 +11:00
parent 1db8d28729
commit 7a89b72260
7 changed files with 200 additions and 14 deletions

View File

@@ -16,7 +16,7 @@ public:
NODE_CONVERT, NODE_KEYWORD, NODE_RAISE, NODE_EXEC, NODE_BLOCK,
NODE_COMPREHENSION, NODE_LOADBUILDCLASS, NODE_AWAITABLE,
NODE_FORMATTEDVALUE, NODE_JOINEDSTR, NODE_CONST_MAP,
NODE_ANNOTATED_VAR,
NODE_ANNOTATED_VAR, NODE_CHAINSTORE,
// Empty node types
NODE_LOCALS,
@@ -71,11 +71,27 @@ public:
void removeLast();
void append(PycRef<ASTNode> node) { m_nodes.emplace_back(std::move(node)); }
protected:
ASTNodeList(list_t nodes, ASTNode::Type type)
: ASTNode(type), m_nodes(std::move(nodes)) { }
private:
list_t m_nodes;
};
class ASTChainStore : public ASTNodeList {
public:
ASTChainStore(list_t nodes, PycRef<ASTNode> src)
: ASTNodeList(nodes, NODE_CHAINSTORE), m_src(std::move(src)) { }
PycRef<ASTNode> src() const { return m_src; }
private:
PycRef<ASTNode> m_src;
};
class ASTObject : public ASTNode {
public:
ASTObject(PycRef<PycObject> obj)