private Code readNaryAssign(int opcode, boolean wideBase, boolean wideRest) throws IOException { int target = readBase(wideBase); int nOperands = readBase(wideBase); int[] operands = new int[nOperands]; for (int i = 0; i != nOperands; ++i) { operands[i] = readBase(wideBase); } int typeIdx = readRest(wideRest); Type type = typePool[typeIdx]; switch (opcode) { case Code.OPCODE_indirectinvokefn: case Code.OPCODE_indirectinvokemd: { if (!(type instanceof Type.FunctionOrMethod)) { throw new RuntimeException("expected function or method type"); } int operand = operands[0]; operands = Arrays.copyOfRange(operands, 1, operands.length); return Code.IndirectInvoke((Type.FunctionOrMethod) type, target, operand, operands); } case Code.OPCODE_invokefn: case Code.OPCODE_invokemd: { if (!(type instanceof Type.FunctionOrMethod)) { throw new RuntimeException("expected function or method type"); } int nameIdx = readRest(wideRest); NameID nid = namePool[nameIdx]; return Code.Invoke((Type.FunctionOrMethod) type, target, operands, nid); } case Code.OPCODE_lambdafn: case Code.OPCODE_lambdamd: { if (!(type instanceof Type.FunctionOrMethod)) { throw new RuntimeException("expected function or method type"); } // Lambda's are the only instances of NULLABLENARYASSIGN's for (int i = 0; i != operands.length; ++i) { operands[i] -= 1; } int nameIdx = readRest(wideRest); NameID nid = namePool[nameIdx]; return Code.Lambda((Type.FunctionOrMethod) type, target, operands, nid); } case Code.OPCODE_newmap: { if (!(type instanceof Type.Map)) { throw new RuntimeException("expected map type"); } return Code.NewMap((Type.Map) type, target, operands); } case Code.OPCODE_newrecord: { if (!(type instanceof Type.Record)) { throw new RuntimeException("expected record type"); } return Code.NewRecord((Type.Record) type, target, operands); } case Code.OPCODE_newlist: { if (!(type instanceof Type.List)) { throw new RuntimeException("expected list type"); } return Code.NewList((Type.List) type, target, operands); } case Code.OPCODE_newset: { if (!(type instanceof Type.Set)) { throw new RuntimeException("expected set type"); } return Code.NewSet((Type.Set) type, target, operands); } case Code.OPCODE_newtuple: { if (!(type instanceof Type.Tuple)) { throw new RuntimeException("expected tuple type"); } return Code.NewTuple((Type.Tuple) type, target, operands); } case Code.OPCODE_sublist: { if (!(type instanceof Type.EffectiveList)) { throw new RuntimeException("expected list type"); } return Code.SubList( (Type.EffectiveList) type, target, operands[0], operands[1], operands[2]); } case Code.OPCODE_substring: { if (!(type instanceof Type.Strung)) { throw new RuntimeException("expected string type"); } return Code.SubString(target, operands[0], operands[1], operands[2]); } } throw new RuntimeException("unknown opcode encountered (" + opcode + ")"); }