Function varargs and keywordargs.

This commit is contained in:
Darryl Pogue
2011-10-09 22:38:18 -07:00
parent e372deb43b
commit 7701f221e8
2 changed files with 130 additions and 2 deletions

View File

@@ -238,16 +238,27 @@ public:
typedef std::list<std::pair<PycRef<ASTNode>, PycRef<ASTNode> > > kwparam_t;
ASTCall(PycRef<ASTNode> func, pparam_t pparams, kwparam_t kwparams)
: ASTNode(NODE_CALL), m_func(func), m_pparams(pparams), m_kwparams(kwparams) { }
: ASTNode(NODE_CALL), m_func(func), m_pparams(pparams), m_kwparams(kwparams),
m_var(Node_NULL), m_kw(Node_NULL) { }
PycRef<ASTNode> func() const { return m_func; }
const pparam_t& pparams() const { return m_pparams; }
const kwparam_t& kwparams() const { return m_kwparams; }
PycRef<ASTNode> var() const { return m_var; }
PycRef<ASTNode> kw() const { return m_kw; }
bool hasVar() const { return m_var != Node_NULL; }
bool hasKW() const { return m_kw != Node_NULL; }
void setVar(PycRef<ASTNode> var) { m_var = var; }
void setKW(PycRef<ASTNode> kw) { m_kw = kw; }
private:
PycRef<ASTNode> m_func;
pparam_t m_pparams;
kwparam_t m_kwparams;
PycRef<ASTNode> m_var;
PycRef<ASTNode> m_kw;
};

View File

@@ -349,6 +349,90 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
stack.push(new ASTCall(func, pparamList, kwparamList));
}
break;
case Pyc::CALL_FUNCTION_VAR_A:
{
PycRef<ASTNode> var = stack.top();
stack.pop();
int kwparams = (operand & 0xFF00) >> 8;
int pparams = (operand & 0xFF);
ASTCall::kwparam_t kwparamList;
ASTCall::pparam_t pparamList;
for (int i=0; i<kwparams; i++) {
PycRef<ASTNode> val = stack.top();
stack.pop();
PycRef<ASTNode> key = stack.top();
stack.pop();
kwparamList.push_front(std::make_pair(key, val));
}
for (int i=0; i<pparams; i++) {
pparamList.push_front(stack.top());
stack.pop();
}
PycRef<ASTNode> func = stack.top();
stack.pop();
PycRef<ASTNode> call = new ASTCall(func, pparamList, kwparamList);
call.cast<ASTCall>()->setVar(var);
stack.push(call);
}
break;
case Pyc::CALL_FUNCTION_KW_A:
{
PycRef<ASTNode> kw = stack.top();
stack.pop();
int kwparams = (operand & 0xFF00) >> 8;
int pparams = (operand & 0xFF);
ASTCall::kwparam_t kwparamList;
ASTCall::pparam_t pparamList;
for (int i=0; i<kwparams; i++) {
PycRef<ASTNode> val = stack.top();
stack.pop();
PycRef<ASTNode> key = stack.top();
stack.pop();
kwparamList.push_front(std::make_pair(key, val));
}
for (int i=0; i<pparams; i++) {
pparamList.push_front(stack.top());
stack.pop();
}
PycRef<ASTNode> func = stack.top();
stack.pop();
PycRef<ASTNode> call = new ASTCall(func, pparamList, kwparamList);
call.cast<ASTCall>()->setKW(kw);
stack.push(call);
}
break;
case Pyc::CALL_FUNCTION_VAR_KW_A:
{
PycRef<ASTNode> kw = stack.top();
stack.pop();
PycRef<ASTNode> var = stack.top();
stack.pop();
int kwparams = (operand & 0xFF00) >> 8;
int pparams = (operand & 0xFF);
ASTCall::kwparam_t kwparamList;
ASTCall::pparam_t pparamList;
for (int i=0; i<kwparams; i++) {
PycRef<ASTNode> val = stack.top();
stack.pop();
PycRef<ASTNode> key = stack.top();
stack.pop();
kwparamList.push_front(std::make_pair(key, val));
}
for (int i=0; i<pparams; i++) {
pparamList.push_front(stack.top());
stack.pop();
}
PycRef<ASTNode> func = stack.top();
stack.pop();
PycRef<ASTNode> call = new ASTCall(func, pparamList, kwparamList);
call.cast<ASTCall>()->setKW(kw);
call.cast<ASTCall>()->setVar(var);
stack.push(call);
}
break;
case Pyc::CONTINUE_LOOP_A:
curblock->append(new ASTKeyword(ASTKeyword::KW_CONTINUE));
break;
@@ -1694,6 +1778,20 @@ void print_src(PycRef<ASTNode> node, PycModule* mod)
print_src(p->second, mod);
first = false;
}
if (call->hasVar()) {
if (!first)
printf(", ");
printf("*");
print_src(call->var(), mod);
first = false;
}
if (call->hasKW()) {
if (!first)
printf(", ");
printf("**");
print_src(call->var(), mod);
first = false;
}
printf(")");
}
break;
@@ -1959,14 +2057,33 @@ void print_src(PycRef<ASTNode> node, PycModule* mod)
PycRef<PycCode> code_src = code.cast<ASTObject>()->object().cast<PycCode>();
ASTFunction::defarg_t defargs = src.cast<ASTFunction>()->defargs();
ASTFunction::defarg_t::iterator da = defargs.begin();
bool first = true;
for (int i=0; i<code_src->argCount(); i++) {
if (i > 0)
if (!first)
printf(", ");
printf("%s", code_src->getVarName(i)->value());
if ((code_src->argCount() - i) <= (int)defargs.size()) {
printf(" = ");
print_src(*da++, mod);
}
first = false;
}
if (code_src->flags() & PycCode::CO_VARARGS) {
if (!first)
printf(", ");
printf("*%s", code_src->getVarName(code_src->argCount())->value());
first = false;
}
if (code_src->flags() & PycCode::CO_VARKEYWORDS) {
if (!first)
printf(", ");
int idx = code_src->argCount();
if (code_src->flags() & PycCode::CO_VARARGS) {
idx++;
}
printf("**%s", code_src->getVarName(idx)->value());
first = false;
}
printf("):\n");
print_src(code, mod);