public void handleDebugFunctionEntry(FunctionCallCPInstruction funCallInst)
     throws DMLRuntimeException {
   // push caller frame into call stack
   _dbState.pushFrame(getVariables(), _dbState.getPC());
   // initialize pc for callee's frame
   _dbState.pc =
       new DMLProgramCounter(funCallInst.getNamespace(), funCallInst.getFunctionName(), 0, 0);
 }
 /**
  * This function should be called only if user has specified -debug option. In this function, if
  * the user has issued one of the step instructions or has enabled suspend flag in previous
  * instruction (through breakpoint), then it will wait until user issues a new debugger command.
  *
  * @param currInst current instruction
  * @throws DMLRuntimeException if DMLRuntimeException occurs
  */
 @SuppressWarnings("deprecation")
 private void suspendIfAskedInDebugMode(Instruction currInst) throws DMLRuntimeException {
   if (!DMLScript.ENABLE_DEBUG_MODE) {
     System.err.println(
         "ERROR: The function suspendIfAskedInDebugMode should not be called in non-debug mode.");
   }
   // check for stepping options
   if (!_dbState.suspend && _dbState.dbCommand != null) {
     if (_dbState.dbCommand.equalsIgnoreCase("step_instruction")) {
       System.out.format("Step instruction reached at %s.\n", _dbState.getPC().toString());
       _dbState.suspend = true;
     } else if (_dbState.dbCommand.equalsIgnoreCase("step_line")
         && _dbState.prevPC.getLineNumber() != currInst.getLineNum()
         && _dbState.prevPC.getLineNumber() != 0) {
       // Don't step into first instruction of first line
       // System.out.format("Step reached at %s.\n", this._prog.getPC().toString());
       System.out.format("Step reached at %s.\n", _dbState.getPC().toStringWithoutInstructionID());
       _dbState.suspend = true;
     } else if (_dbState.dbCommand.equalsIgnoreCase("step return")
         && currInst instanceof FunctionCallCPInstruction) {
       FunctionCallCPInstruction funCallInst = (FunctionCallCPInstruction) currInst;
       if (_dbState.dbCommandArg == null
           || funCallInst.getFunctionName().equalsIgnoreCase(_dbState.dbCommandArg)) {
         System.out.format(
             "Step return reached at %s.\n", _dbState.getPC().toStringWithoutInstructionID());
         _dbState.suspend = true;
       }
     }
   }
   // check if runtime suspend signal is set
   if (_dbState.suspend) {
     // flush old commands and arguments
     _dbState.dbCommand = null;
     _dbState.dbCommandArg = null;
     // print current DML script source line
     if (currInst.getLineNum() != 0) _dbState.printDMLSourceLine(currInst.getLineNum());
     // save current symbol table
     _dbState.setVariables(this.getVariables());
     // send next command signal to debugger control module
     _dbState.nextCommand = true;
     // suspend runtime execution thread
     Thread.currentThread().suspend();
     // reset next command signal
     _dbState.nextCommand = false;
   }
   // reset runtime suspend signal
   _dbState.suspend = false;
   // update previous pc
   _dbState.prevPC.setFunctionName(_dbState.getPC().getFunctionName());
   _dbState.prevPC.setProgramBlockNumber(_dbState.getPC().getProgramBlockNumber());
   _dbState.prevPC.setLineNumber(currInst.getLineNum());
 }
  public static CPInstruction parseSingleInstruction(CPINSTRUCTION_TYPE cptype, String str)
      throws DMLUnsupportedOperationException, DMLRuntimeException {
    ExecType execType = null;

    if (str == null || str.isEmpty()) return null;

    switch (cptype) {
      case AggregateUnary:
        return AggregateUnaryCPInstruction.parseInstruction(str);

      case AggregateBinary:
        return AggregateBinaryCPInstruction.parseInstruction(str);

      case AggregateTernary:
        return AggregateTernaryCPInstruction.parseInstruction(str);

      case ArithmeticBinary:
        return ArithmeticBinaryCPInstruction.parseInstruction(str);

      case Ternary:
        return TernaryCPInstruction.parseInstruction(str);

      case Quaternary:
        return QuaternaryCPInstruction.parseInstruction(str);

      case BooleanBinary:
        return BooleanBinaryCPInstruction.parseInstruction(str);

      case BooleanUnary:
        return BooleanUnaryCPInstruction.parseInstruction(str);

      case BuiltinBinary:
        return BuiltinBinaryCPInstruction.parseInstruction(str);

      case BuiltinUnary:
        return BuiltinUnaryCPInstruction.parseInstruction(str);

      case Reorg:
        return ReorgCPInstruction.parseInstruction(str);

      case UaggOuterChain:
        return UaggOuterChainCPInstruction.parseInstruction(str);

      case MatrixReshape:
        return MatrixReshapeCPInstruction.parseInstruction(str);

      case Append:
        return AppendCPInstruction.parseInstruction(str);

      case RelationalBinary:
        return RelationalBinaryCPInstruction.parseInstruction(str);

      case File:
        return FileCPInstruction.parseInstruction(str);

      case Variable:
        return VariableCPInstruction.parseInstruction(str);

      case Rand:
        return DataGenCPInstruction.parseInstruction(str);

      case StringInit:
        return StringInitCPInstruction.parseInstruction(str);

      case External:
        return FunctionCallCPInstruction.parseInstruction(str);

      case ParameterizedBuiltin:
        execType = ExecType.valueOf(str.split(Instruction.OPERAND_DELIM)[0]);
        if (execType == ExecType.CP) return ParameterizedBuiltinCPInstruction.parseInstruction(str);
        else // exectype CP_FILE
        return ParameterizedBuiltinCPFileInstruction.parseInstruction(str);

      case MultiReturnBuiltin:
        return MultiReturnBuiltinCPInstruction.parseInstruction(str);

      case QSort:
        return QuantileSortCPInstruction.parseInstruction(str);

      case QPick:
        return QuantilePickCPInstruction.parseInstruction(str);

      case MatrixIndexing:
        execType = ExecType.valueOf(str.split(Instruction.OPERAND_DELIM)[0]);
        if (execType == ExecType.CP) return MatrixIndexingCPInstruction.parseInstruction(str);
        else // exectype CP_FILE
        return MatrixIndexingCPFileInstruction.parseInstruction(str);

      case Builtin:
        String[] parts = InstructionUtils.getInstructionPartsWithValueType(str);
        if (parts[0].equals("log") || parts[0].equals("log_nz")) {
          if (parts.length == 3) {
            // B=log(A), y=log(x)
            return BuiltinUnaryCPInstruction.parseInstruction(str);
          } else if (parts.length == 4) {
            // B=log(A,10), y=log(x,10)
            return BuiltinBinaryCPInstruction.parseInstruction(str);
          }
        } else {
          throw new DMLRuntimeException("Invalid Builtin Instruction: " + str);
        }
      case MMTSJ:
        return MMTSJCPInstruction.parseInstruction(str);

      case PMMJ:
        return PMMJCPInstruction.parseInstruction(str);

      case MMChain:
        return MMChainCPInstruction.parseInstruction(str);

      case Partition:
        return DataPartitionCPInstruction.parseInstruction(str);

      case CentralMoment:
        return CentralMomentCPInstruction.parseInstruction(str);

      case Covariance:
        return CovarianceCPInstruction.parseInstruction(str);

      case INVALID:

      default:
        throw new DMLRuntimeException("Invalid CP Instruction Type: " + cptype);
    }
  }