abaplint / transpiler

ABAP to JS transpiler & runtime
https://transpiler.abaplint.org
MIT License
82 stars 23 forks source link

cx_sy_itab_line_not_found #569

Open gregorwolf opened 2 years ago

gregorwolf commented 2 years ago

I'm trying to implement Advent of Code in ABAP and use also the transpiler to run it in Node.JS. But already with part 2 of day 1 I run into an issue. My implementation zcl_advent2020_day01_gw.clas.abap#L69 runs fine on a ABAP AS but results in the following error when using npm test:

ZCL_ADVENT2020_DAY01_GW: running ltcl_test->part2

<ref *1> cx_sy_itab_line_not_found [Error]
    at zcl_advent2020_day01_gw.part2 (file:///Users/gwolf/Documents/projects/abap/abap-advent-2021/output/zcl_advent2020_day01_gw.clas.mjs:107:22)
    at async ltcl_test.part2 (file:///Users/gwolf/Documents/projects/abap/abap-advent-2021/output/zcl_advent2020_day01_gw.clas.testclasses.mjs:22:19)
    at async run (file:///Users/gwolf/Documents/projects/abap/abap-advent-2021/output/index.mjs:36:3) {
  me: ABAPObject { value: [Circular *1] },
  previous: ABAPObject { value: undefined },
  textid: Character { value: '', length: 32, qualifiedName: 'undefined' },
  get_longtext: [AsyncFunction: if_message$get_longtext],
  get_text: [AsyncFunction: if_message$get_text]
}

when debugging the generated JavaScript code i see the value of abap.builtin.sy.get().tabix changing during the for loop. I think the error is somewhere there.

larshp commented 2 years ago

probably the read table, ints[ sy-tabix + 1 ] which changes tabix

workaround: try moving sy-tabix to a temporary variable

gregorwolf commented 2 years ago

That helped: https://github.com/gregorwolf/abap-advent-2021/runs/4423582159?check_suite_focus=true

larshp commented 2 years ago

also, there is a folder with the downported ABAP code, can you paste it here?

gregorwolf commented 2 years ago

Before the change:

CLASS zcl_advent2020_day01_gw DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES zif_advent2020_gw.
    METHODS:
      part1
        IMPORTING
          !input        TYPE string
        RETURNING
          VALUE(output) TYPE string,
      part2
        IMPORTING
          !input        TYPE string
        RETURNING
          VALUE(output) TYPE string.
  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      input_to_ints
        IMPORTING
          !input      TYPE string
        RETURNING
          VALUE(ints) TYPE ty_ints.
ENDCLASS.

CLASS zcl_advent2020_day01_gw IMPLEMENTATION.

  METHOD zif_advent2020_gw~solve.

    output = part2( input ).

  ENDMETHOD.

  METHOD input_to_ints.
    DATA lt_strings TYPE STANDARD TABLE OF string WITH DEFAULT KEY.
    FIELD-SYMBOLS <string> LIKE LINE OF lt_strings.
    FIELD-SYMBOLS <int> TYPE int4.
    SPLIT input AT |\n| INTO TABLE lt_strings.

    LOOP AT lt_strings ASSIGNING <string>.

      APPEND INITIAL LINE TO ints ASSIGNING <int>.
      <int> = <string>.
    ENDLOOP.

  ENDMETHOD.

  METHOD part1.
    DATA out_int TYPE int4.

    DATA ints TYPE ty_ints.
    FIELD-SYMBOLS <int> LIKE LINE OF ints.
    DATA temp1 LIKE LINE OF ints.
    ints = input_to_ints( input ).

    LOOP AT ints ASSIGNING <int>.
      IF sy-tabix > 1.

        READ TABLE ints INDEX sy-tabix - 1 INTO temp1.
        IF sy-subrc <> 0.
          RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
        ENDIF.
        IF <int> > temp1.
          out_int = out_int + 1.
        ENDIF.
      ENDIF.
    ENDLOOP.

    output = out_int.
    CONDENSE output.

  ENDMETHOD.

  METHOD part2.
    DATA: out_int            TYPE int4.

    DATA ints TYPE ty_ints.
    DATA number_of_ints TYPE i.
    FIELD-SYMBOLS <int> LIKE LINE OF ints.
    DATA sum_first_window TYPE int4.
    DATA temp1 LIKE LINE OF ints.
    DATA temp3 LIKE LINE OF ints.
    DATA sum_second_window TYPE int4.
    DATA temp2 LIKE LINE OF ints.
    DATA temp4 LIKE LINE OF ints.
    DATA temp5 LIKE LINE OF ints.
    ints = input_to_ints( input ).

    number_of_ints = lines( ints ).
    IF number_of_ints < 4.
      WRITE / 'input does contain less than 4 lines so there is nothing to compare'.
      RETURN.
    ENDIF.

    LOOP AT ints ASSIGNING <int>.
      IF sy-tabix + 3 > number_of_ints.
        EXIT.
      ENDIF.

      READ TABLE ints INDEX sy-tabix + 1 INTO temp1.
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      ENDIF.

      READ TABLE ints INDEX sy-tabix + 2 INTO temp3.
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      ENDIF.
      sum_first_window = <int> + temp1 + temp3.

      READ TABLE ints INDEX sy-tabix + 1 INTO temp2.
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      ENDIF.

      READ TABLE ints INDEX sy-tabix + 2 INTO temp4.
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      ENDIF.

      READ TABLE ints INDEX sy-tabix + 3 INTO temp5.
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      ENDIF.
      sum_second_window = temp2 + temp4 + temp5.
      IF sum_first_window < sum_second_window.
        out_int = out_int + 1.
      ENDIF.
    ENDLOOP.

    output = out_int.
    CONDENSE output.

  ENDMETHOD.

ENDCLASS.

After:

CLASS zcl_advent2020_day01_gw DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES zif_advent2020_gw.
    METHODS:
      part1
        IMPORTING
          !input        TYPE string
        RETURNING
          VALUE(output) TYPE string,
      part2
        IMPORTING
          !input        TYPE string
        RETURNING
          VALUE(output) TYPE string.
  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      input_to_ints
        IMPORTING
          !input      TYPE string
        RETURNING
          VALUE(ints) TYPE ty_ints.
ENDCLASS.

CLASS zcl_advent2020_day01_gw IMPLEMENTATION.

  METHOD zif_advent2020_gw~solve.

    output = part2( input ).

  ENDMETHOD.

  METHOD input_to_ints.
    DATA lt_strings TYPE STANDARD TABLE OF string WITH DEFAULT KEY.
    FIELD-SYMBOLS <string> LIKE LINE OF lt_strings.
    FIELD-SYMBOLS <int> TYPE int4.
    SPLIT input AT |\n| INTO TABLE lt_strings.

    LOOP AT lt_strings ASSIGNING <string>.

      APPEND INITIAL LINE TO ints ASSIGNING <int>.
      <int> = <string>.
    ENDLOOP.

  ENDMETHOD.

  METHOD part1.
    DATA out_int TYPE int4.

    DATA ints TYPE ty_ints.
    FIELD-SYMBOLS <int> LIKE LINE OF ints.
    DATA temp1 LIKE LINE OF ints.
    ints = input_to_ints( input ).

    LOOP AT ints ASSIGNING <int>.
      IF sy-tabix > 1.

        READ TABLE ints INDEX sy-tabix - 1 INTO temp1.
        IF sy-subrc <> 0.
          RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
        ENDIF.
        IF <int> > temp1.
          out_int = out_int + 1.
        ENDIF.
      ENDIF.
    ENDLOOP.

    output = out_int.
    CONDENSE output.

  ENDMETHOD.

  METHOD part2.
    DATA: out_int            TYPE int4.

    DATA ints TYPE ty_ints.
    DATA number_of_ints TYPE i.
    FIELD-SYMBOLS <int> LIKE LINE OF ints.
    DATA tabix LIKE sy-tabix.
    DATA sum_first_window TYPE int4.
    DATA temp1 LIKE LINE OF ints.
    DATA temp3 LIKE LINE OF ints.
    DATA sum_second_window TYPE int4.
    DATA temp2 LIKE LINE OF ints.
    DATA temp4 LIKE LINE OF ints.
    DATA temp5 LIKE LINE OF ints.
    ints = input_to_ints( input ).

    number_of_ints = lines( ints ).
    IF number_of_ints < 4.
      WRITE / 'input does contain less than 4 lines so there is nothing to compare'.
      RETURN.
    ENDIF.

    LOOP AT ints ASSIGNING <int>.

      tabix = sy-tabix.
      IF sy-tabix + 3 > number_of_ints.
        EXIT.
      ENDIF.

      READ TABLE ints INDEX tabix + 1 INTO temp1.
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      ENDIF.

      READ TABLE ints INDEX tabix + 2 INTO temp3.
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      ENDIF.
      sum_first_window = <int> + temp1 + temp3.

      READ TABLE ints INDEX tabix + 1 INTO temp2.
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      ENDIF.

      READ TABLE ints INDEX tabix + 2 INTO temp4.
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      ENDIF.

      READ TABLE ints INDEX tabix + 3 INTO temp5.
      IF sy-subrc <> 0.
        RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
      ENDIF.
      sum_second_window = temp2 + temp4 + temp5.
      IF sum_first_window < sum_second_window.
        out_int = out_int + 1.
      ENDIF.
    ENDLOOP.

    output = out_int.
    CONDENSE output.

  ENDMETHOD.

ENDCLASS.