Commit 551d925d authored by Travis Hance's avatar Travis Hance

support arg unpacking

parent 6ab26e7f
......@@ -577,8 +577,15 @@ public:
bool visit_functiondef(AST_FunctionDef* node) override {
if (node == orig_node) {
for (AST_expr* e : node->args->args)
int counter = 0;
for (AST_expr* e : node->args->args) {
if (e->type == AST_TYPE::Tuple) {
doWrite(scoping->getInternedStrings().get("." + std::to_string(counter)));
}
counter++;
e->accept(this);
}
if (node->args->vararg.str().size()) {
mangleNameInPlace(node->args->vararg, cur->private_name, scoping->getInternedStrings());
doWrite(node->args->vararg);
......
......@@ -45,7 +45,7 @@
namespace pyston {
// TODO terrible place for these!
ParamNames::ParamNames(AST* ast) : takes_param_names(true) {
ParamNames::ParamNames(AST* ast, InternedStringPool& pool) : takes_param_names(true) {
if (ast->type == AST_TYPE::Module || ast->type == AST_TYPE::ClassDef || ast->type == AST_TYPE::Expression
|| ast->type == AST_TYPE::Suite) {
kwarg = "";
......@@ -58,7 +58,8 @@ ParamNames::ParamNames(AST* ast) : takes_param_names(true) {
if (arg->type == AST_TYPE::Name) {
args.push_back(ast_cast<AST_Name>(arg)->id.str());
} else {
args.push_back("." + std::to_string(i + 1));
InternedString dot_arg_name = pool.get("." + std::to_string(i));
args.push_back(dot_arg_name.str());
}
}
......
......@@ -2502,6 +2502,27 @@ CFG* computeCFG(SourceInfo* source, std::vector<AST_stmt*> body) {
}
}
if (source->ast->type == AST_TYPE::FunctionDef) {
// Unpack tuple arguments
// Tuple arguments get assigned names ".0", ".1" etc. So this
// def f(a, (b,c), (d,e)):
// would expand to:
// def f(a, .1, .2):
// (b, c) = .1
// (d, e) = .2
AST_arguments* args = ast_cast<AST_FunctionDef>(source->ast)->args;
int counter = 0;
for (AST_expr* arg_expr : args->args) {
if (arg_expr->type == AST_TYPE::Tuple) {
InternedString arg_name = source->getInternedStrings().get("." + std::to_string(counter));
AST_Name* arg_name_expr
= new AST_Name(arg_name, AST_TYPE::Load, arg_expr->lineno, arg_expr->col_offset);
visitor.pushAssign(arg_expr, arg_name_expr);
}
counter++;
}
}
for (int i = (skip_first ? 1 : 0); i < body.size(); i++) {
if (!visitor.curblock)
break;
......
......@@ -230,7 +230,7 @@ struct ParamNames {
std::vector<llvm::StringRef> args;
llvm::StringRef vararg, kwarg;
explicit ParamNames(AST* ast);
explicit ParamNames(AST* ast, InternedStringPool& pool);
ParamNames(const std::vector<llvm::StringRef>& args, llvm::StringRef vararg, llvm::StringRef kwarg);
static ParamNames empty() { return ParamNames(); }
......@@ -305,7 +305,7 @@ public:
takes_varargs(takes_varargs),
takes_kwargs(takes_kwargs),
source(std::move(source)),
param_names(this->source->ast),
param_names(this->source->ast, this->source->getInternedStrings()),
always_use_version(NULL),
code_obj(NULL) {
assert(num_args >= num_defaults);
......
# expected: fail
def f((a,b)):
print a,b
print sorted(list(locals().iteritems()))
f(range(2))
f((1, 2))
def g(a, (b,c), d, (e,f), (g, (h, i), j)):
print a
print b
print c
print d
print e
print f
print g
print h
print i
print j
print sorted(list(locals().iteritems()))
g(1, (2, 3), 4, (5, 6), (7, (8, 9), 10))
......@@ -49,7 +49,7 @@ TEST_F(AnalysisTest, augassign) {
ASSERT_TRUE(liveness->isLiveAtEnd(module->interned_strings->get("a"), block));
}
std::unique_ptr<PhiAnalysis> phis = computeRequiredPhis(ParamNames(func), cfg, liveness.get(), scope_info);
std::unique_ptr<PhiAnalysis> phis = computeRequiredPhis(ParamNames(func, si->getInternedStrings()), cfg, liveness.get(), scope_info);
}
void doOsrTest(bool is_osr, bool i_maybe_undefined) {
......@@ -93,7 +93,7 @@ void doOsrTest(bool is_osr, bool i_maybe_undefined) {
entry_descriptor->args[iter_str] = NULL;
phis = computeRequiredPhis(entry_descriptor, liveness.get(), scope_info);
} else {
phis = computeRequiredPhis(ParamNames(func), cfg, liveness.get(), scope_info);
phis = computeRequiredPhis(ParamNames(func, si->getInternedStrings()), cfg, liveness.get(), scope_info);
}
// First, verify that we require phi nodes for the block we enter into.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment