home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / interpre / pl / simulato.pas < prev    next >
Pascal/Delphi Source File  |  1979-12-31  |  10KB  |  503 lines

  1. PROGRAM SIMULATOR;
  2. {$C-,K-,V-,D-}
  3. CONST
  4.      MIN = 1;
  5.      MAX = 5000;
  6. TYPE
  7.     WORKSTRING = STRING[80];
  8.     OPERATION_PART =
  9.              (ADD5,AND5,ARROW5,ASSIGN5,BAR5,CALL5,CONSTANT5,DIVIDE5,END_PROC5,
  10.               END_PROG5,EQUAL5,FI5,GREATER5,INDEX5,LESS5,MINUS5,MODULO5,
  11.               MULTIPLY5,NOT5,OR5,PROC5,PROG5,READ5,SUBTRACT5,VALUE5,VARIABLE5,
  12.               WRITE5);
  13.     STORE = ARRAY[MIN..MAX] OF INTEGER;
  14.     ERRORS = (DIVISION_BY_ZERO6,IF_STATEMENT_FAILS6,RANGE_ERROR6,
  15.               STACK_OVERFLOW6);
  16. VAR
  17.     ST: STORE;
  18.     P,B,S: INTEGER;
  19.     STACK_BOTTOM: INTEGER;
  20.     RUNNING: BOOLEAN;
  21.     TEMP2: TEXT[$2000];
  22.     OK: BOOLEAN;
  23.  
  24.  
  25. FUNCTION EXIST(FILENAME: WORKSTRING): BOOLEAN;
  26. VAR
  27.    FIL: FILE;
  28.    RESULT: INTEGER;
  29. BEGIN
  30.      ASSIGN(FIL,FILENAME);
  31.      {$I-}
  32.      RESET(FIL);
  33.      {$I+}
  34.      RESULT:= IORESULT;
  35.      IF RESULT = 0
  36.         THEN
  37.           BEGIN
  38.             CLOSE(FIL);
  39.             EXIST:= TRUE
  40.           END
  41.         ELSE EXIST:= FALSE
  42. END;
  43.  
  44. PROCEDURE ERROR(ERR_TYPE: ERRORS; NUM: INTEGER);
  45. BEGIN
  46.      WRITELN;
  47.      IF ERR_TYPE <> STACK_OVERFLOW6
  48.         THEN WRITE('LINE ',NUM:5,' - INTERPRETER ERROR ')
  49.         ELSE WRITE('PC = ',NUM:5,' - INTERPRETER ERROR ');
  50.      CASE ERR_TYPE OF
  51.           DIVISION_BY_ZERO6: WRITELN(' -- DIVISION BY ZERO');
  52.           IF_STATEMENT_FAILS6: WRITELN(' -- IF STATEMENT FAILS');
  53.           RANGE_ERROR6: WRITELN(' -- RANGE ERROR');
  54.           STACK_OVERFLOW6: WRITELN(' -- STACK OVERFLOW')
  55.      END;
  56.      RUNNING:= FALSE
  57. END;
  58.  
  59. PROCEDURE ALLOCATE(WORDS: INTEGER);
  60. BEGIN
  61.      S:= S + WORDS;
  62.      IF S > MAX
  63.         THEN ERROR(STACK_OVERFLOW6,P)
  64. END;
  65.  
  66. PROCEDURE VARIABLE(LEVEL,DISPLACEMENT: INTEGER);
  67. VAR
  68.    X: INTEGER;
  69. BEGIN
  70.      ALLOCATE(1);
  71.      X:= B;
  72.      WHILE LEVEL > 0 DO
  73.        BEGIN
  74.             X:= ST[X];
  75.             LEVEL:= LEVEL - 1
  76.        END;
  77.      ST[S]:= X + DISPLACEMENT;
  78.      P:= P + 3
  79. END;
  80.  
  81. PROCEDURE INDEX(BOUND,LINENUM: INTEGER);
  82. VAR
  83.    I: INTEGER;
  84. BEGIN
  85.      I:= ST[S];
  86.      S:= S - 1;
  87.      IF (I < 1) OR (I > BOUND)
  88.         THEN ERROR(RANGE_ERROR6,LINENUM)
  89.         ELSE ST[S]:= ST[S] + I - 1;
  90.      P:= P + 3
  91. END;
  92.  
  93.  
  94.  
  95. PROCEDURE CONSTANT(VALUE: INTEGER);
  96. BEGIN
  97.      ALLOCATE(1);
  98.      ST[S]:= VALUE;
  99.      P:= P + 2
  100. END;
  101.  
  102. PROCEDURE VALUE;
  103. BEGIN
  104.      ST[S]:= ST[ST[S]];
  105.      P:= P + 1
  106. END;
  107.  
  108. PROCEDURE NOTX;
  109. BEGIN
  110.      ST[S]:= 1 - ST[S];
  111.      P:= P + 1
  112. END;
  113.  
  114. PROCEDURE MULTIPLY;
  115. BEGIN
  116.      P:= P + 1;
  117.      S:= S - 1;
  118.      ST[S]:= ST[S] * ST[S+1]
  119. END;
  120.  
  121. PROCEDURE DIVIDE(LINENUM: INTEGER);
  122. BEGIN
  123.      IF ST[S+1] = 0
  124.         THEN ERROR(DIVISION_BY_ZERO6,LINENUM)
  125.         ELSE
  126.           BEGIN
  127.             P:= P + 2;
  128.             S:= S - 1;
  129.             ST[S]:= ST[S] DIV ST[S+1]
  130.           END
  131. END;
  132.  
  133. PROCEDURE MODULO(LINENUM: INTEGER);
  134. BEGIN
  135.      IF ST[S+1] = 0
  136.         THEN ERROR(DIVISION_BY_ZERO6,LINENUM)
  137.         ELSE
  138.             BEGIN
  139.               P:= P + 2;
  140.               S:= S - 1;
  141.               ST[S]:= ST[S] MOD ST[S+1]
  142.             END
  143. END;
  144.  
  145. PROCEDURE MINUS;
  146. BEGIN
  147.      ST[S]:= -ST[S];
  148.      P:= P + 1
  149. END;
  150.  
  151. PROCEDURE ADD;
  152. BEGIN
  153.      P:= P + 1;
  154.      S:= S - 1;
  155.      ST[S]:= ST[S] + ST[S+1]
  156. END;
  157.  
  158. PROCEDURE SUBTRACT;
  159. BEGIN
  160.      P:= P + 1;
  161.      S:= S - 1;
  162.      ST[S]:= ST[S] - ST[S+1]
  163. END;
  164.  
  165. PROCEDURE LESS;
  166. BEGIN
  167.      P:= P + 1;
  168.      S:= S - 1;
  169.      ST[S]:= ORD(ST[S] < ST[S+1])
  170. END;
  171.  
  172. PROCEDURE EQUAL;
  173. BEGIN
  174.      P:= P + 1;
  175.      S:= S - 1;
  176.      ST[S]:= ORD(ST[S] = ST[S+1])
  177. END;
  178.  
  179. PROCEDURE GREATER;
  180. BEGIN
  181.      P:= P + 1;
  182.      S:= S - 1;
  183.      ST[S]:= ORD(ST[S] > ST[S+1])
  184. END;
  185.  
  186. PROCEDURE ANDX;
  187. BEGIN
  188.      P:= P + 1;
  189.      S:= S - 1;
  190.      IF ST[S] = ORD(TRUE)
  191.         THEN ST[S]:= ST[S+1]
  192. END;
  193.  
  194. PROCEDURE ORX;
  195. BEGIN
  196.      P:= P + 1;
  197.      S:= S - 1;
  198.      IF ST[S] = ORD(FALSE)
  199.         THEN ST[S]:= ST[S+1]
  200. END;
  201.  
  202.  
  203. PROCEDURE READINT(VAR VALUE: INTEGER);
  204. VAR
  205.    X,Y: INTEGER;
  206.    RESULT: INTEGER;
  207. BEGIN
  208.      X:= WHEREX;
  209.      Y:= WHEREY;
  210.      REPEAT
  211.            {$I-}
  212.            READ(VALUE);
  213.            {$I+}
  214.            RESULT:= IORESULT;
  215.            IF RESULT <> 0
  216.               THEN
  217.                 BEGIN
  218.                   GOTOXY(X,Y);
  219.                   CLREOL;
  220.                   WRITE(^G)
  221.                 END
  222.      UNTIL RESULT = 0;
  223.      WRITELN
  224. END;
  225.  
  226.  
  227. PROCEDURE READX(NUMBER: INTEGER);
  228. VAR
  229.    X: INTEGER;
  230. BEGIN
  231.      P:= P + 2;
  232.      S:= S - NUMBER;
  233.      X:= S;
  234.      WHILE X < S + NUMBER DO
  235.        BEGIN
  236.          X:= X + 1;
  237.          LOWVIDEO;
  238.          WRITE('? ');
  239.          NORMVIDEO;
  240.          READINT(ST[ST[X]])
  241.        END
  242. END;
  243.  
  244. PROCEDURE WRITEX(NUMBER: INTEGER);
  245. VAR
  246.    X: INTEGER;
  247. BEGIN
  248.      P:= P + 2;
  249.      S:= S - NUMBER;
  250.      X:= S;
  251.      WHILE X < S + NUMBER DO
  252.        BEGIN
  253.          X:= X + 1;
  254.          WRITE(ST[X]:6)
  255.        END;
  256.      WRITELN;
  257. END;
  258.  
  259. PROCEDURE ASSIGNX(NUMBER: INTEGER);
  260. VAR
  261.    X: INTEGER;
  262. BEGIN
  263.      P:= P + 2;
  264.      S:= S - 2*NUMBER;
  265.      X:= S;
  266.      WHILE X < S + NUMBER DO
  267.        BEGIN
  268.          X:= X + 1;
  269.          ST[ST[X]]:= ST[X + NUMBER]
  270.        END
  271. END;
  272.  
  273. PROCEDURE CALLX(LEVEL,ADDR: INTEGER);
  274. VAR
  275.    X: INTEGER;
  276. BEGIN
  277.      ALLOCATE(3);
  278.      X:= B;
  279.      WHILE LEVEL > 0 DO
  280.        BEGIN
  281.          X:= ST[X];
  282.          LEVEL:= LEVEL - 1
  283.        END;
  284.      ST[S-2]:= X;
  285.      ST[S-1]:= B;
  286.      ST[S]:= P + 3;
  287.      B:= S - 2;
  288.      P:= ADDR
  289. END;
  290.  
  291. PROCEDURE ARROW(ADDR: INTEGER);
  292. BEGIN
  293.      IF ST[S] = ORD(TRUE)
  294.         THEN P:= P + 2
  295.         ELSE P:= ADDR;
  296.      S:= S - 1
  297. END;
  298.  
  299. PROCEDURE BAR(ADDR: INTEGER);
  300. BEGIN
  301.      P:= ADDR
  302. END;
  303.  
  304. PROCEDURE FI(LINENUM: INTEGER);
  305. BEGIN
  306.      ERROR(IF_STATEMENT_FAILS6,LINENUM)
  307. END;
  308.  
  309. PROCEDURE PROC(VAR_LENGTH, ADDR: INTEGER);
  310. BEGIN
  311.      ALLOCATE(VAR_LENGTH);
  312.      P:= ADDR
  313. END;
  314.  
  315. PROCEDURE END_PROC;
  316. BEGIN
  317.      S:= B - 1;
  318.      P:= ST[B + 2];
  319.      B:= ST[B + 1]
  320. END;
  321.  
  322. PROCEDURE PROG(VAR_LENGTH, ADDR: INTEGER);
  323. BEGIN
  324.      B:= STACK_BOTTOM;
  325.      S:= B;
  326.      ALLOCATE(VAR_LENGTH + 2);
  327.      P:= ADDR
  328. END;
  329.  
  330. PROCEDURE END_PROG;
  331. BEGIN
  332.      RUNNING:= FALSE
  333. END;
  334.  
  335.  
  336.  
  337.  
  338. PROCEDURE LOAD_PROGRAM;
  339. VAR
  340.    N: INTEGER;
  341. BEGIN
  342.      N:= MIN;
  343.      {$I-}
  344.      REPEAT
  345.            READ(TEMP2,ST[N]);
  346.            N:= N + 1
  347.      UNTIL EOF(TEMP2);
  348.      {$I+}
  349.      STACK_BOTTOM:= N
  350. END;
  351.  
  352. PROCEDURE RUN_PROGRAM;
  353. VAR
  354.    OPERATION: OPERATION_PART;
  355. BEGIN
  356.      RUNNING:= TRUE;
  357.      P:= MIN;
  358.      WHILE RUNNING DO
  359.        BEGIN
  360.          OPERATION:= OPERATION_PART(ST[P]);
  361.          CASE OPERATION OF
  362.               ADD5: ADD;
  363.               AND5: ANDX;
  364.               ARROW5: ARROW(ST[P+1]);
  365.               ASSIGN5: ASSIGNX(ST[P+1]);
  366.               BAR5: BAR(ST[P+1]);
  367.               CALL5: CALLX(ST[P+1],ST[P+2]);
  368.               CONSTANT5: CONSTANT(ST[P+1]);
  369.               DIVIDE5: DIVIDE(ST[P+1]);
  370.               END_PROC5: END_PROC;
  371.               END_PROG5: END_PROG;
  372.               EQUAL5: EQUAL;
  373.               FI5: FI(ST[P+1]);
  374.               GREATER5: GREATER;
  375.               INDEX5: INDEX(ST[P+1],ST[P+2]);
  376.               LESS5: LESS;
  377.               MINUS5: MINUS;
  378.               MODULO5: MODULO(ST[P+1]);
  379.               MULTIPLY5: MULTIPLY;
  380.               NOT5: NOTX;
  381.               OR5: ORX;
  382.               PROC5: PROC(ST[P+1],ST[P+2]);
  383.               PROG5: PROG(ST[P+1],ST[P+2]);
  384.               READ5: READX(ST[P+1]);
  385.               SUBTRACT5: SUBTRACT;
  386.               VALUE5: VALUE;
  387.               VARIABLE5: VARIABLE(ST[P+1],ST[P+2]);
  388.               WRITE5: WRITEX(ST[P+1])
  389.          END { CASE }
  390.        END { WHILE }
  391. END;
  392.  
  393. PROCEDURE SCROLLDOWN(LINES: INTEGER);
  394. TYPE
  395.     REGISTERS = RECORD CASE INTEGER OF
  396.                   1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,FLAGS: INTEGER);
  397.                   2: (AL,AH,BL,BH,CL,CH,DL,DH: BYTE);
  398.                 END;
  399. VAR
  400.    REGS: REGISTERS;
  401. BEGIN
  402.      REGS.AH:= 7;
  403.      REGS.AL:= LINES;
  404.      REGS.BH:= 7;
  405.      REGS.CH:= 0;
  406.      REGS.CL:= 0;
  407.      REGS.DH:= 24;
  408.      REGS.DL:= 79;
  409.      INTR($10,REGS)
  410. END;
  411.  
  412. PROCEDURE INITIALIZE;
  413. VAR
  414.    I: INTEGER;
  415.    FIL: FILE;
  416. BEGIN
  417.      CLRSCR;
  418.      LOWVIDEO;
  419.      GOTOXY(1,1);
  420.      WRITE(#186' PROGRAM: ');
  421.      NORMVIDEO;
  422.      WRITE('PL SIMULATOR - RUNS PL CODE FROM THE PARSER ');
  423.      LOWVIDEO;
  424.      GOTOXY(80,1);
  425.      WRITE(#186);
  426.      GOTOXY(1,2);
  427.      WRITE(#186' AUTHOR: ');
  428.      NORMVIDEO;
  429.      WRITE('JAY MONFORT                        ');
  430.      LOWVIDEO;
  431.      WRITE('FOR: ');
  432.      NORMVIDEO;
  433.      WRITE('MATH 434 - COMPILER DESIGN');
  434.      LOWVIDEO;
  435.      GOTOXY(80,2);
  436.      WRITE(#186);
  437.      GOTOXY(1,3);
  438.      WRITE(#186' DATE: ');
  439.      NORMVIDEO;
  440.      WRITE('NOVEMBER 27, 1986');
  441.      LOWVIDEO;
  442.      GOTOXY(80,3);
  443.      WRITE(#186);
  444.      GOTOXY(1,4);
  445.      WRITE(#204);
  446.      FOR I:= 2 TO 79 DO WRITE(#205);
  447.      WRITELN(#185);
  448.      FOR I:= 5 TO 23 DO
  449.        BEGIN
  450.             GOTOXY(1,I);
  451.             WRITE(#186);
  452.             GOTOXY(80,I);
  453.             WRITE(#186)
  454.        END;
  455.      GOTOXY(1,24);
  456.      WRITE(#200);
  457.      FOR I:= 2 TO 79 DO WRITE(#205);
  458.      WRITE(#188);
  459.      SCROLLDOWN(1);
  460.      GOTOXY(1,1);
  461.      WRITE(#201);
  462.      FOR I:= 2 TO 79 DO WRITE(#205);
  463.      WRITE(#187);
  464.      WINDOW(2,6,79,24);
  465.      GOTOXY(1,1);
  466.      IF NOT EXIST('TEMP2')
  467.         THEN OK:= FALSE
  468.         ELSE
  469.           BEGIN
  470.             OK:= TRUE;
  471.             ASSIGN(TEMP2,'TEMP2.');
  472.             RESET(TEMP2)
  473.           END
  474. END;
  475.  
  476. PROCEDURE FINALIZE;
  477. BEGIN
  478.      WRITELN; WRITELN;
  479.      IF OK
  480.         THEN CLOSE(TEMP2);
  481.      WINDOW(1,1,80,25);
  482.      GOTOXY(1,25);
  483.      CLREOL;
  484.      GOTOXY(1,24);
  485.      NORMVIDEO
  486. END;
  487.  
  488. BEGIN
  489.      INITIALIZE;
  490.      IF OK
  491.        THEN
  492.          BEGIN
  493.            LOAD_PROGRAM;
  494.            RUN_PROGRAM
  495.          END
  496.        ELSE
  497.            BEGIN
  498.                 GOTOXY(20,6);
  499.                 WRITE('TEMP2 NOT FOUND'^G^G)
  500.            END;
  501.      FINALIZE
  502. END.
  503.