#include <perms.h>

//          Edinburgh IMP77 Compiler - Version 8.4
//
//     1  !* Program Name : JUMP
//     2
//     3  !*   Title      :  X  The IMP Control Transfer Statements.
//     4  !*   Version    :  II
//     5  !*   Date       :  24 August 1985
//     6  !*   Description:  Testing of the  ->,  %SWITCH and %LABEL Statements.
//     7
//     8  %Begin

int main(int argc, char **argv) { /*%begin*/
  _imp_initialise(argc, argv);

  //     9
  //    10      %string(255) param    { Used to get input from CLI}

  _imp_string255 PARAM;

  //    11
  //    12      %Integer  J

  int J;

  //    13      %Integer  K

  int K;

  //    14
  //    15      %Integer  Error

  int ERROR;

  //    16      %Integer  Up

  int UP;

  //    17      %Integer  Down

  int DOWN;

  //    18
  //    19
  //    20      %Switch  SW (100 : 355)    { Non-zero base switch with lot of switches.

  int SW_index;
  int SW_line;
  char *SW_file;
  static const void *SW[256] = {
      &&case_SW_default, &&case_SW_101,     &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_105,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_109,     &&case_SW_default, &&case_SW_111,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_121,     &&case_SW_122,     &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_140,     &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_145,     &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_160,     &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_165,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_182,     &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_193,     &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_200,     &&case_SW_201,
      &&case_SW_202,     &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_255,
      &&case_SW_256,     &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_296,     &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_301,     &&case_SW_default, &&case_SW_default,
      &&case_SW_304,     &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_324,     &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default, &&case_SW_default,
      &&case_SW_default, &&case_SW_default, &&case_SW_354,     &&case_SW_355};

  //    21
  //    22      %Label   Alpha

  // __label__ /* block-scoped label (GCC) */ ALPHA;

  //    23      %Label   Beta

  // __label__ /* block-scoped label (GCC) */ BETA;

  //    24      %Label   Gamma

  // __label__ /* block-scoped label (GCC) */ GAMMA;

  //    25      %Label   Delta

  // __label__ /* block-scoped label (GCC) */ DELTA;

  //    26      %Label   Out

  // __label__ /* block-scoped label (GCC) */ OUT;

  //    27      %Label   Cont

  // __label__ /* block-scoped label (GCC) */ CONT;

  //    28
  //    29
  //    30  %owninteger failures=0

  static int FAILURES = 0;

  //    31
  //    32  %routine pass

  void PASS(void) {
    //    33    printstring("Pass")

    _imp_PRINTSTRING(_imp_str_literal("Pass"));

    //    34    New Line

    _imp_NEWLINE();

    //    35  %end

    return;
  } /* end of PASS */

  //    36  %routine fail

  void FAIL(void) {
    //    37    printstring("FAIL")

    _imp_PRINTSTRING(_imp_str_literal("FAIL"));

    //    38    New Line

    _imp_NEWLINE();

    //    39    failures = failures+1

    FAILURES = FAILURES + 1;

    //    40  %end

    return;
  } /* end of FAIL */

  //    41
  //    42
  //    43
  //    44     ! Code to find out where the output is to be sent
  //    45     ! -----------------------------------------------
  //    46     ! Where the output goes to depends on the parameter after the
  //    47     ! name used to run the program.
  //    48     !                       Parameter   |   Result
  //    49     !                       ------------|-------------
  //    50     !                     No parameter  |  No output
  //    51     !                          "s"      |  The screen
  //    52     !                          "j"      |  "journal"
  //    53     !                     anything else |  file name entered
  //    54
  //    55     ! NOTE THAT THIS CODE USES STRING COMPARISONS, WHICH MAY NOT HAVE BEEN
  //    56     ! TESTED YET. IF THE PROGRAM FAILS CHECK IT WAS NOT IN THIS PART.
  //    57
  //    58     param=cliparam

  _imp_strncpy(/*?*/ &PARAM, ({
                 __typeof__(_imp_string255) tmp; /*B*/
                 tmp = _imp_CLIPARAM();
                 (void *)&tmp;
               }),
               /*max:*/ 255);

  //    59     %if param = "" %then select output (2) %c

  if (_imp_strcmp((_imp_string *)/*?*/ &PARAM, (_imp_string *)/*?*/ _imp_str_literal_ptr("")) != 0) goto L_0001;

  _imp_SELECTOUTPUT(2);
  goto L_0002;
L_0001:;

  if (_imp_strcmp((_imp_string *)/*?*/ &PARAM, (_imp_string *)/*?*/ _imp_str_literal_ptr("s")) == 0) goto L_0003;

  if (_imp_strcmp((_imp_string *)/*?*/ &PARAM, (_imp_string *)/*?*/ _imp_str_literal_ptr("S")) != 0) goto L_0004;

L_0003:;
  _imp_SELECTOUTPUT(0);
  goto L_0002;
L_0004:;

  if (_imp_strcmp((_imp_string *)/*?*/ &PARAM, (_imp_string *)/*?*/ _imp_str_literal_ptr("j")) == 0) goto L_0005;

  if (_imp_strcmp((_imp_string *)/*?*/ &PARAM, (_imp_string *)/*?*/ _imp_str_literal_ptr("J")) != 0) goto L_0006;

L_0005:;
  _imp_OPENOUTPUT(2, _imp_str_literal("journal"));
  _imp_SELECTOUTPUT(2);
  goto L_0002;
L_0006:;
  _imp_OPENOUTPUT(2,
                  *({
                    __typeof__(_imp_string255) tmp = PARAM /*q*/;
                    (_imp_string255 *)&tmp;
                  })
  );
  _imp_SELECTOUTPUT(2);
L_0002:;

//    60+    %else %if param="s" %or param="S" %then select output (0) %c
//    61+    %else %if param="j" %or param="J" %then  %c
//    62+       open output(2,"journal") %and select output (2) %c
//    63+    %else open output(2,param) %and select output (2)
//    64
//    65
//    66
//    67     New Lines(2)

  _imp_NEWLINES(2);

  //    68     Print String ("Control Transfer Statements");   New Line

  _imp_PRINTSTRING(_imp_str_literal("Control Transfer Statements"));
  _imp_NEWLINE();

  //    69     Print String ("===========================");   New Lines (3)

  _imp_PRINTSTRING(_imp_str_literal("==========================="));
  _imp_NEWLINES(3);

  //    70
  //    71
  //    72      Print String ("Test the -> Statement and %Switch");   New Line

  _imp_PRINTSTRING(_imp_str_literal("Test the -> Statement and %Switch"));
  _imp_NEWLINE();

  //    73      Print String ("---------------------------------");   New Line

  _imp_PRINTSTRING(_imp_str_literal("---------------------------------"));
  _imp_NEWLINE();

  //    74
  //    75      Up = 0

  UP = 0;

  //    76      Down = 0

  DOWN = 0;

  //    77
  //    78      -> Delta

  goto U_1003;

  //    79
  //    80      Alpha:  Up   = Up   + 1;  -> Gamma

U_1000:;
  UP = UP + 1;
  goto U_1002;

  //    81      Beta:   Down = Down + 1;  -> Out

U_1001:;
  DOWN = DOWN + 1;
  goto U_1004;

  //    82      Gamma:  Up   = Up   + 1;  -> Beta

U_1002:;
  UP = UP + 1;
  goto U_1001;

  //    83      Delta:  Down = Down + 1;  -> Alpha

U_1003:;
  DOWN = DOWN + 1;
  goto U_1000;

  //    84      Out:

U_1004:;

//    85           %If Up = Down = 2 %then pass %else fail

  {
// Double-sided test on DOWN (Part I)
    int tmp;
    if (UP != (tmp = DOWN)) goto L_0007;
// Double-sided test on DOWN (Part II)
    if (tmp != 2) goto L_0007;
  }
  PASS();
  goto L_0008;
L_0007:;
  FAIL();
L_0008:;

//    86  !            Forward and Backward simple jumps.
//    87
//    88
//    89
//    90      Up    = 100

  UP = 100;

  //    91      Error = 0

  ERROR = 0;

  //    92
  //    93      %For J = 990, 10, 3540 %cycle

  // %for J = 990, 10, 3540 %cycle
  {
    J = 980;
  L_0009:
    if (J == 3540) goto L_000A;
    J += 10;

    //    94
    //    95          -> SW (J // 10 + 1)   { Introduces an integer expression in the switch

    SW_line = __LINE__;
    SW_file = __FILE__;
    SW_index = ((long)J / (long)10) + 1;
    goto case_SW_dispatch;

    //    96
    //    97
    //    98          SW(140):   Error = Error + 1 %unless Up = 140

  case_SW_140:;
    if (UP == 140) goto L_000D;
    ERROR = ERROR + 1;
  L_000D:;

  //    99                     -> Cont

    goto U_1005;

    //   100
    //   101          SW(255):   Error = Error + 1 %unless Up = 255

  case_SW_255:;
    if (UP == 255) goto L_000E;
    ERROR = ERROR + 1;
  L_000E:;

  //   102                     -> Cont

    goto U_1005;

    //   103
    //   104          SW(105):   Error = Error + 1 %unless Up = 105

  case_SW_105:;
    if (UP == 105) goto L_000F;
    ERROR = ERROR + 1;
  L_000F:;

  //   105                     -> Cont

    goto U_1005;

    //   106
    //   107          SW(304):   Error = Error + 1 %unless Up = 304

  case_SW_304:;
    if (UP == 304) goto L_0010;
    ERROR = ERROR + 1;
  L_0010:;

  //   108                     -> Cont

    goto U_1005;

    //   109
    //   110          SW(182):   Error = Error + 1 %unless Up = 182

  case_SW_182:;
    if (UP == 182) goto L_0011;
    ERROR = ERROR + 1;
  L_0011:;

  //   111                     -> Cont

    goto U_1005;

    //   112
    //   113          SW(354):   Error = Error + 1 %unless Up = 354

  case_SW_354:;
    if (UP == 354) goto L_0012;
    ERROR = ERROR + 1;
  L_0012:;

  //   114                     -> Cont

    goto U_1005;

    //   115
    //   116          SW(111):   Error = Error + 1 %unless Up = 111

  case_SW_111:;
    if (UP == 111) goto L_0013;
    ERROR = ERROR + 1;
  L_0013:;

  //   117                     -> Cont

    goto U_1005;

    //   118
    //   119          SW(193):   Error = Error + 1 %unless Up = 193

  case_SW_193:;
    if (UP == 193) goto L_0014;
    ERROR = ERROR + 1;
  L_0014:;

  //   120                     -> Cont

    goto U_1005;

    //   121
    //   122          SW(121):   Error = Error + 1 %unless Up = 121

  case_SW_121:;
    if (UP == 121) goto L_0015;
    ERROR = ERROR + 1;
  L_0015:;

  //   123                     -> Cont

    goto U_1005;

    //   124
    //   125          SW(201):   Error = Error + 1 %unless Up = 201

  case_SW_201:;
    if (UP == 201) goto L_0016;
    ERROR = ERROR + 1;
  L_0016:;

  //   126                     -> Cont

    goto U_1005;

    //   127
    //   128          SW(296):   Error = Error + 1 %unless Up = 296

  case_SW_296:;
    if (UP == 296) goto L_0017;
    ERROR = ERROR + 1;
  L_0017:;

  //   129                     -> Cont

    goto U_1005;

    //   130
    //   131          SW(160):   Error = Error + 1 %unless Up = 160

  case_SW_160:;
    if (UP == 160) goto L_0018;
    ERROR = ERROR + 1;
  L_0018:;

  //   132                     -> Cont

    goto U_1005;

    //   133
    //   134          SW(122):   Error = Error + 1 %unless Up = 122

  case_SW_122:;
    if (UP == 122) goto L_0019;
    ERROR = ERROR + 1;
  L_0019:;

  //   135                     -> Cont

    goto U_1005;

    //   136
    //   137          SW(101):   Error = Error + 1 %unless Up = 101

  case_SW_101:;
    if (UP == 101) goto L_001A;
    ERROR = ERROR + 1;
  L_001A:;

  //   138                     -> Cont

    goto U_1005;

    //   139
    //   140          SW(202):   Error = Error + 1 %unless Up = 202

  case_SW_202:;
    if (UP == 202) goto L_001B;
    ERROR = ERROR + 1;
  L_001B:;

  //   141                     -> Cont

    goto U_1005;

    //   142
    //   143          SW(301):   Error = Error + 1 %unless Up = 301

  case_SW_301:;
    if (UP == 301) goto L_001C;
    ERROR = ERROR + 1;
  L_001C:;

  //   144                     -> Cont

    goto U_1005;

    //   145
    //   146          SW(355):   Error = Error + 1 %unless Up = 355

  case_SW_355:;
    if (UP == 355) goto L_001D;
    ERROR = ERROR + 1;
  L_001D:;

  //   147                     -> Cont

    goto U_1005;

    //   148
    //   149          SW(200):   Error = Error + 1 %unless Up = 200

  case_SW_200:;
    if (UP == 200) goto L_001E;
    ERROR = ERROR + 1;
  L_001E:;

  //   150                     -> Cont

    goto U_1005;

    //   151
    //   152          SW(324):   Error = Error + 1 %unless Up = 324

  case_SW_324:;
    if (UP == 324) goto L_001F;
    ERROR = ERROR + 1;
  L_001F:;

  //   153                     -> Cont

    goto U_1005;

    //   154
    //   155          SW(*):     -> Cont

  case_SW_default:;
    goto U_1005;

    //   156
    //   157          SW(109):   Error = Error + 1 %unless Up = 109

  case_SW_109:;
    if (UP == 109) goto L_0020;
    ERROR = ERROR + 1;
  L_0020:;

  //   158                     -> Cont

    goto U_1005;

    //   159
    //   160          SW(256):   Error = Error + 1 %unless Up = 256

  case_SW_256:;
    if (UP == 256) goto L_0021;
    ERROR = ERROR + 1;
  L_0021:;

  //   161                     -> Cont

    goto U_1005;

    //   162
    //   163          SW(145):   Error = Error + 1 %unless Up = 145

  case_SW_145:;
    if (UP == 145) goto L_0022;
    ERROR = ERROR + 1;
  L_0022:;

  //   164                     -> Cont

    goto U_1005;

    //   165
    //   166          SW(165):   Error = Error + 1 %unless Up = 165

  case_SW_165:;
    if (UP == 165) goto L_0023;
    ERROR = ERROR + 1;
  L_0023:;

  //   167
  //   168
  //   169          Cont:      Up = Up + 1

  U_1005:;
    UP = UP + 1;

    //   170
    //   171      %Repeat

    goto L_0009;
  }

L_000A:;

//   172      %If Error = 0 %and Up = 356 %then pass %else fail

  if (ERROR != 0) goto L_0024;
  if (UP != 356) goto L_0024;
  PASS();
  goto L_0025;
L_0024:;
  FAIL();
L_0025:;

//   173  !       %Switch operation.
//   174
//   175
//   176
//   177  select output(0)

  _imp_SELECTOUTPUT(0);

  //   178  write(failures,1);  printstring(" failure(s)");  newline

  _imp_WRITE(FAILURES, 1);
  _imp_PRINTSTRING(_imp_str_literal(" failure(s)"));
  _imp_NEWLINE();

  //   179
  //   180  %End %of %Program

  _imp_stop(0);
  return 0;

case_SW_dispatch:
  if (SW_index < 100 || SW_index > 355)
    _imp_signalf(6, 3, SW_index, "->SW(%d) out of bounds at %s line %d", SW_index, SW_file, SW_line);
  goto *SW[SW_index - 100];
end_0:;
}