Implement BUILD_SET and SET_UPDATE

This commit is contained in:
Akash Munagala
2023-02-12 15:56:18 -08:00
parent a6de2209fc
commit aaad868445
2 changed files with 68 additions and 1 deletions

View File

@@ -12,7 +12,7 @@ public:
NODE_INVALID, NODE_NODELIST, NODE_OBJECT, NODE_UNARY, NODE_BINARY,
NODE_COMPARE, NODE_SLICE, NODE_STORE, NODE_RETURN, NODE_NAME,
NODE_DELETE, NODE_FUNCTION, NODE_CLASS, NODE_CALL, NODE_IMPORT,
NODE_TUPLE, NODE_LIST, NODE_MAP, NODE_SUBSCR, NODE_PRINT,
NODE_TUPLE, NODE_LIST, NODE_SET, NODE_MAP, NODE_SUBSCR, NODE_PRINT,
NODE_CONVERT, NODE_KEYWORD, NODE_RAISE, NODE_EXEC, NODE_BLOCK,
NODE_COMPREHENSION, NODE_LOADBUILDCLASS, NODE_AWAITABLE,
NODE_FORMATTEDVALUE, NODE_JOINEDSTR, NODE_CONST_MAP,
@@ -358,6 +358,18 @@ private:
value_t m_values;
};
class ASTSet : public ASTNode {
public:
typedef std::set<PycRef<ASTNode>> value_t;
ASTSet(value_t values)
: ASTNode(NODE_SET), m_values(std::move(values)) { }
const value_t& values() const { return m_values; }
private:
value_t m_values;
};
class ASTMap : public ASTNode {
public:

View File

@@ -322,6 +322,16 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
stack.push(new ASTList(values));
}
break;
case Pyc::BUILD_SET_A:
{
ASTSet::value_t values;
for (int i=0; i<operand; i++) {
values.insert(stack.top());
stack.pop();
}
stack.push(new ASTSet(values));
}
break;
case Pyc::BUILD_MAP_A:
if (mod->verCompare(3, 5) >= 0) {
auto map = new ASTMap;
@@ -1547,6 +1557,33 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
}
}
break;
case Pyc::SET_UPDATE_A:
{
PycRef<ASTNode> rhs = stack.top();
stack.pop();
PycRef<ASTSet> lhs = stack.top().cast<ASTSet>();
stack.pop();
if (rhs.type() != ASTNode::NODE_OBJECT) {
fprintf(stderr, "Unsupported argument found for SET_UPDATE\n");
break;
}
// I've only ever seen this be a TYPE_FROZENSET, but let's be careful...
PycRef<PycObject> obj = rhs.cast<ASTObject>()->object();
if (obj->type() != PycObject::TYPE_FROZENSET) {
fprintf(stderr, "Unsupported argument type found for SET_UPDATE\n");
break;
}
ASTSet::value_t result = lhs->values();
for (const auto& it : obj.cast<PycSet>()->values()) {
result.insert(new ASTObject(it));
}
stack.push(new ASTSet(result));
}
break;
case Pyc::LIST_EXTEND_A:
{
PycRef<ASTNode> rhs = stack.top();
@@ -2838,6 +2875,24 @@ void print_src(PycRef<ASTNode> node, PycModule* mod)
fputs("]", pyc_output);
}
break;
case ASTNode::NODE_SET:
{
fputs("{", pyc_output);
bool first = true;
cur_indent++;
for (const auto& val : node.cast<ASTSet>()->values()) {
if (first)
fputs("\n", pyc_output);
else
fputs(",\n", pyc_output);
start_line(cur_indent);
print_src(val, mod);
first = false;
}
cur_indent--;
fputs("}", pyc_output);
}
break;
case ASTNode::NODE_COMPREHENSION:
{
PycRef<ASTComprehension> comp = node.cast<ASTComprehension>();