public void compileArgumentList(CompilableFunction function, Node[] parameters, int contextindex)
{
Code code = getCode();
ConstantPool pool = getPool();
int max = (parameters != null) ? parameters.length : 0;
int c = 0;
int n = function.getParameterCount();
for(int i=0; i<n; i++) {
Any defaultValue = function.getParameterDefault(i);
switch(function.getParameterType(i)) {
case CompilableFunction.PARAMETER_ANY:
if (c<max) {
parameters[c++].compile(this, Node.GET);
} else {
if (defaultValue != null) {
constant(defaultValue, true);
} else {
code.aconst_null();
}
}
break;
case CompilableFunction.PARAMETER_OBJECT:
if (c<max) {
parameters[c++].compile(this, Node.GET);
code.invokevirtual(pool.addMethodRef(TYPE_ANY,
"toObject", "()Ljava/lang/Object;"));
} else {
if (defaultValue != null) {
constant(defaultValue, true);
code.invokevirtual(pool.addMethodRef(TYPE_ANY,
"toObject", "()Ljava/lang/Object;"));
} else {
code.aconst_null();
}
}
break;
case CompilableFunction.PARAMETER_BOOLEAN:
if (c<max) {
Node node = parameters[c++];
if (node.isConstant()) {
code.iconst(node.eval().toBoolean());
} else {
node.compile(this, Node.GET_BOOLEAN);
}
} else {
if (defaultValue != null) {
code.iconst(defaultValue.toBoolean());
} else {
code.iconst(false);
}
}
break;
case CompilableFunction.PARAMETER_INT:
if (c<max) {
Node node = parameters[c++];
if (node.isConstant()) {
code.iconst(node.eval().toInt());
} else {
node.compile(this, Node.GET);
code.invokevirtual(pool.addMethodRef(TYPE_ANY,
"toInt", "()I"));
}
} else {
if (defaultValue != null) {
code.iconst(defaultValue.toInt());
} else {
code.iconst(0);
}
}
break;
case CompilableFunction.PARAMETER_LONG:
if (c<max) {
Node node = parameters[c++];
if (node.isConstant()) {
code.lconst(node.eval().toLong());
} else {
node.compile(this, Node.GET);
code.invokevirtual(pool.addMethodRef(TYPE_ANY,
"toLong", "()J"));
}
} else {
if (defaultValue != null) {
code.lconst(defaultValue.toLong());
} else {
code.lconst(0);
}
}
break;
case CompilableFunction.PARAMETER_DOUBLE:
if (c<max) {
Node node = parameters[c++];
if (node.isConstant()) {
code.dconst(node.eval().toDouble());
} else {
node.compile(this, Node.GET);
code.invokevirtual(pool.addMethodRef(TYPE_ANY,
"toDouble", "()D"));
}
} else {
if (defaultValue != null) {
code.dconst(defaultValue.toDouble());
} else {
code.dconst(0.0);
}
}
break;
case CompilableFunction.PARAMETER_STRING:
if (c<max) {
Node node = parameters[c++];
if (node.isConstant()) {
code.astring(node.eval().toString());
} else {
node.compile(this, Node.GET);
code.invokevirtual(pool.addMethodRef(TYPE_OBJECT,
"toString", "()Ljava/lang/String;"));
}
} else {
if (defaultValue != null) {
code.astring(defaultValue.toString());
} else {
code.aconst_null();
}
}
break;
case CompilableFunction.PARAMETER_ARRAY:
{
int arrayclazz = pool.addClass("anvil/core/Array");
int appendmethod = pool.addMethodRef(arrayclazz, "append",
"(Lanvil/core/Any;)Lanvil/core/Array;");
code.anew(arrayclazz);
code.dup();
code.invokespecial(pool.addMethodRef(arrayclazz, "<init>", "()V"));
for(; c < max; c++) {
code.dup();
parameters[c].compile(this, Node.GET);
code.invokevirtual(appendmethod);
}
}
break;
case CompilableFunction.PARAMETER_ANYLIST:
case CompilableFunction.PARAMETER_REST:
if (c >= max) {
code.getstatic(pool.addFieldRef(TYPE_ANY, "EMPTY_TUPLE",
"Lanvil/core/AnyTuple;"));
} else {
int tupleclazz = pool.addClass("anvil/core/AnyTuple");
int appendmethod = pool.addMethodRef(tupleclazz, "append",
"(Lanvil/core/Any;)Lanvil/core/Array;");
code.anew(tupleclazz);
code.dup();
code.iconst(max - c);
code.anewarray(TYPE_ANY);
int index = 0;
for(; c < max; c++) {
code.dup();
code.iconst(index++);
parameters[c].compile(this, Node.GET);
code.aastore();
}
code.invokespecial(pool.addMethodRef(tupleclazz, "<init>",
"([Lanvil/core/Any;)V"));
}
break;
case CompilableFunction.PARAMETER_LIST:
int len = max - c;
if (len <= 0) {
code.getstatic(pool.addFieldRef(TYPE_ANY, "ARRAY0",
"[Lanvil/core/Any;"));
} else {
code.iconst(len);
code.anewarray(TYPE_ANY);
int index = 0;