home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / ME494-3.ZIP / SRC / MODULA_2.SRC < prev    next >
Encoding:
Text File  |  1990-04-17  |  14.4 KB  |  652 lines

  1. $MACRO_FILE MODULA_2;
  2. {******************************************************************************
  3.                                                         MULTI-EDIT MACRO FILE
  4.  
  5. Name: MODULA_2
  6.  
  7. Description:    Language support for Modula-2
  8.  
  9. MOD_IND - Smart indent
  10. MODTEMP - Template editing
  11. MODMTCH - Construct matching
  12.  
  13.                              (C) Copyright 1989 by American Cybernetics, Inc.
  14. ******************************************************************************}
  15.  
  16. $MACRO MOD_IND;
  17. {******************************************************************************
  18.                                                                 MULTI-EDIT MACRO
  19.  
  20. Name: MOD_IND
  21.  
  22. Description:  This macro will perform a smart indent when the <ENTER> key is
  23.     pressed.  This macro is called by the macro CR.
  24.  
  25.                              (C) Copyright 1989 by American Cybernetics, Inc.
  26. ******************************************************************************}
  27.  
  28.     DEF_STR(C_STR);          {Word to check for indent}
  29.     DEF_INT(T_COL,T_COL2);   {Temp column positions}
  30.     DEF_INT(sig_char_found,ind_count,jx);
  31.     DEF_CHAR(found_char);
  32.  
  33.     MARK_POS;
  34.     Reg_Exp_Stat := True;
  35.     Refresh := False;
  36.     LEFT;
  37.     {Check to see if we are inside a comment}
  38.     {Don't go back farther than 20 lines in order to improve speed}
  39.     IF Search_Bwd('{(@*}||{@*)}',20) THEN
  40.         IF (Cur_Char = '(') THEN
  41.             RIGHT;
  42.             RIGHT;
  43.             Set_Indent_Level; { this stuff below needed to be moved inside this loop }
  44.             GOTO_MARK;        { you might check the PAS_IND because I think it has the same problem }
  45.             Refresh := True;
  46.             CR;
  47.             GOTO MAC_EXIT;
  48.         END;
  49.     END;
  50.  
  51.     GOTO_MARK;
  52.     MARK_POS;
  53.  
  54.     CALL skip_mod_noise1;
  55.     FOUND_CHAR := CUR_CHAR;
  56.     GOTO_MARK;
  57.     REFRESH := TRUE;
  58.  
  59.     T_COL2 := C_COL;         {Store current position}
  60.     FIRST_WORD;              {Go to the first word on the line}
  61.     T_COL := C_COL;          {Store this position}
  62.  
  63.     IF T_COL2 < T_COL THEN   {If this position is greater than the original}
  64.         T_COL := T_COL2;       {  then store the original}
  65.         GOTO_COL(T_COL);       {  and go there}
  66.     END;
  67.     IF NOT (At_Eol) THEN     {If we are not beyond the end of the line then}
  68.         SET_INDENT_LEVEL;      {  set the indent level}
  69.     END;
  70.  
  71.     T_COL := C_COL;          {Store the current position}
  72.                                                      {Get the current word, removing any extra space}
  73.     C_STR := ' ' + REMOVE_SPACE(CAPS( GET_WORD('; (,{') )) + ' ';
  74.  
  75.     GOTO_COL(T_COL2);        {Put cursor on original position}
  76.     CR;                      {Perform a carriage return}
  77.  
  78.                                                      {If the word is in this list, and the original
  79.                                                             position was not on the first word then
  80.                                                             indent}
  81.     IF (T_COL <> T_COL2) AND (LENGTH(C_STR) <> 0) AND
  82.         (POS(C_STR,
  83.      ' PROCEDURE BEGIN CASE '
  84.      ) <> 0) THEN
  85.             INDENT;
  86.     ELSE
  87.         IF (Found_Char <> ';') and (T_COL <> T_COL2) and (LENGTH(C_STR) <> 0)
  88.             AND (POS(C_STR,
  89.         ' VAR TYPE CONST PROCEDURE BEGIN IF WHILE REPEAT LOOP WITH FOR ELSE ELSIF '
  90.         ) <> 0) THEN
  91.             INDENT;
  92.         ELSE
  93.     {*********************************************************************}
  94.     {***>>> IF YOU DON'T WANT AN UNDENT AFTER 'END' THEN COMMENT OUT THE  }
  95.     {***>>> FOLLOWING THREE LINES                                         }
  96. {      IF (C_STR = ' END ') THEN
  97.                 UNDENT;
  98.             END; }
  99.         END;
  100.     END;
  101.     GOTO MAC_EXIT;
  102.  
  103. skip_mod_noise1:
  104.  
  105. { Here we look for the nearest preceding nonblank character.  If it is a
  106.     closing comment then we find the nearest opening comment.
  107.     }
  108.  
  109.     IF (SEARCH_BWD('[~ ]', 1)) THEN
  110.         IF (CUR_CHAR = ')') THEN
  111.             LEFT;
  112.             IF (CUR_CHAR = '*') THEN
  113.                 JX := SEARCH_BWD('(@*', 0);
  114.                 LEFT;
  115.                 GOTO skip_mod_noise1;
  116.             END;
  117.             RIGHT;
  118.             SIG_CHAR_FOUND := TRUE;
  119.             GOTO EXIT_skip_mod;
  120.         END;
  121.  
  122.         SIG_CHAR_FOUND := TRUE;
  123.         GOTO EXIT_skip_mod;
  124.     END;
  125.  
  126. { If we failed to find a nonblank character on the current line, and the
  127.     cursor is on line 1, we failed to find a significant character; otherwise,
  128.     we back up a line and try again. }
  129.  
  130.     IF (C_LINE = 1) THEN
  131.         SIG_CHAR_FOUND := FALSE;
  132.         GOTO EXIT_skip_mod;
  133.     END;
  134.     UP;
  135.     EOL;
  136.     GOTO skip_mod_noise1;
  137.  
  138. EXIT_skip_mod:
  139.     REFRESH := TRUE;
  140.     RET;
  141.  
  142. MAC_EXIT:
  143.  
  144. END_MACRO;
  145.  
  146. $MACRO MODTEMP;
  147. {******************************************************************************
  148.                                                                 MULTI-EDIT MACRO
  149.  
  150. Name: MODTEMP
  151.  
  152. Description: Creates modula 2 language constructs based on a single character
  153.     to the left of the current cursor position.
  154.  
  155.                              (C) Copyright 1989 by American Cybernetics, Inc.
  156. ******************************************************************************}
  157.  
  158.     DEF_INT(Temp_Col,Temp_Insert,Temp_Indent_Col);
  159.     DEF_STR(Key_Chars, Tstr );
  160.     DEF_CHAR(Temp_Char);
  161.     Key_Chars := 'BIWFPMCRLE';
  162.     Temp_Insert := Insert_Mode;
  163.     If NOT (At_Eol) Then { if we ain't at the eol of the line }
  164.         RM('MEERROR^Beeps /C=1'); { let the user know he's got stuff to the right on the line }
  165.         Make_Message('Not at the end of the line.'); { you can take this out if you would like }
  166.         GOTO END_OF_MAC;
  167.     End;
  168.     Insert_Mode := True;
  169.     Temp_Col := C_COL;
  170.     If (C_Col > 1) Then
  171.         Left;
  172.         If (Pos(Caps(Cur_Char),Key_Chars) = 0) Then
  173.             Goto_Col(Temp_Col);
  174.             Goto END_OF_MAC;
  175.         End;
  176.     ELSE
  177.         Goto END_OF_MAC;
  178.     End;
  179.     Temp_Col := C_COL;
  180.  
  181.     If (Caps(Cur_Char) = 'B') Then
  182.         Insert_Mode := False;
  183.         Indent;
  184.         Temp_Indent_Col := C_Col; { save current indent column position away as to be }
  185.         Goto_Col(Temp_Col);       { indent level sensitive }
  186.         Text('BEGIN');
  187.         Insert_Mode := True;
  188.         Cr;
  189.         Cr;
  190.         Goto_Col(Temp_Col);
  191.         Text('END ;');
  192.         Up;
  193.         Goto_Col(Temp_Indent_Col);
  194.         Goto END_OF_MAC;
  195.     End;
  196.  
  197.     If (Caps(Cur_Char) = 'I') Then
  198.         Insert_Mode := False;
  199.         Indent;
  200.         Goto_Col(Temp_Col);
  201.         Text('IF () THEN');
  202.         Insert_Mode := True;
  203.         Cr;
  204.         Cr;
  205.         Goto_Col(Temp_Col);
  206.         Text('END;');
  207.         Up;
  208.         Up;
  209.         Goto_Col(Temp_Col + 4);
  210.         Goto END_OF_MAC;
  211.     End;
  212.  
  213.     If (Caps(Cur_Char) = 'E') Then
  214.         Insert_Mode := False;
  215.         Indent;
  216.         Temp_Indent_Col := C_Col;
  217.         Goto_Col(Temp_Col);
  218.         Text('ELSE');
  219.         Insert_Mode := True;
  220.         Cr;
  221.         Cr;
  222.         Up;
  223.         Goto_Col(Temp_Indent_Col);
  224.         Goto END_OF_MAC;
  225.     End;
  226.  
  227.     If (Caps(Cur_Char) = 'W') Then
  228.         Insert_Mode := False;
  229.         Indent;
  230.         Goto_Col(Temp_Col);
  231.         Text('WHILE () DO');
  232.         Insert_Mode := True;
  233.         Cr;
  234.         Cr;
  235.         Goto_Col(Temp_Col);
  236.         Text('END;');
  237.         Up;
  238.         Up;
  239.         Goto_Col(Temp_Col + 7);
  240.         Goto END_OF_MAC;
  241.     End;
  242.  
  243.     If (Caps(Cur_Char) = 'F') Then
  244.         Insert_Mode := False;
  245.         Indent;
  246.         Goto_Col(Temp_Col);
  247.         Text('FOR  :=  TO  DO');
  248.         Insert_Mode := True;
  249.         Cr;
  250.         Cr;
  251.         Goto_Col(Temp_Col);
  252.         Text('END;');
  253.         Up;
  254.         Up;
  255.         Goto_Col(Temp_Col + 4);
  256.         Goto END_OF_MAC;
  257.     End;
  258.  
  259.     If (Caps(Cur_Char) = 'P') Then
  260.         Return_Str := '';
  261.         RM('USERIN^QUERYBOX /T=PROCEDURE NAME?/W=40/C=' + str(wherex) +
  262.                 '/L=' + Str(wherey - 2));
  263.         If return_int < 1 THEN
  264.             goto END_OF_MAC;
  265.         end;
  266.         Insert_Mode := False;
  267.         Indent;
  268.         Temp_Indent_Col := C_Col;
  269.         Goto_Col(Temp_Col);
  270.         Text('PROCEDURE ' + return_str + '(  );');
  271.         Insert_Mode := True;
  272.         Cr;
  273.         Goto_Col(Temp_Indent_Col);
  274.         Text('BEGIN');
  275.         Cr;
  276.         Cr;
  277.         Goto_Col(Temp_Indent_Col);
  278.         Text('END ' + return_str + ';');
  279.         Up;
  280.         Up;
  281.         Up;
  282.         Goto_Col(Temp_Col + 12 + length(return_str));
  283.         Goto END_OF_MAC;
  284.     End;
  285.  
  286.     If (Caps(Cur_Char) = 'M') Then
  287.         Return_Str := '';
  288.         RM('USERIN^QUERYBOX /T=MODULE NAME?/W=40');
  289.         If return_int < 1 THEN
  290.             goto END_OF_MAC;
  291.         end;
  292.         RM('USERIN^XMENU /T=1/B=1/M=Implementation module()Definition module()Module()');
  293.         tstr := '';
  294.         If return_int < 1 THEN
  295.             goto END_OF_MAC;
  296.         end;
  297.         If return_int = 1 then
  298.             tstr := 'IMPLEMENTATION ';
  299.         end;
  300.         If return_int = 2 then
  301.             tstr := 'DEFINITION ';
  302.         end;
  303.  
  304.         Insert_Mode := False;
  305.         Indent;
  306.         Goto_Col(Temp_Col);
  307.         Text(tstr + 'MODULE ' + return_str + ';');
  308.         Insert_Mode := True;
  309.         Cr;
  310.         Cr;
  311.         Goto_Col(Temp_Col);
  312.  
  313.         If return_int <> 2 then
  314.             Text('BEGIN');
  315.             Cr;
  316.             Cr;
  317.             Goto_Col(Temp_Col);
  318.         end;
  319.         Text('END ' + return_str + '.');
  320.         Up;
  321.         Goto_Col(1);
  322.         Goto END_OF_MAC;
  323.     End;
  324.  
  325.     If (Caps(Cur_Char) = 'C') Then
  326.         Insert_Mode := False;
  327.         Indent;
  328.         Goto_Col(Temp_Col);
  329.         Text('CASE  OF');
  330.         Insert_Mode := True;
  331.         Cr;
  332.         Cr;
  333.         Goto_Col(Temp_Col);
  334.         Text('END;');
  335.         Up;
  336.         Up;
  337.         Goto_Col(Temp_Col + 5);
  338.         Goto END_OF_MAC;
  339.     End;
  340.  
  341.     If (Caps(Cur_Char) = 'R') Then
  342.         Insert_Mode := False;
  343.         Indent;
  344.         Goto_Col(Temp_Col);
  345.         Text('REPEAT');
  346.         Insert_Mode := True;
  347.         Cr;
  348.         Cr;
  349.         Goto_Col(Temp_Col);
  350.         Text('UNTIL ();');
  351.         Goto_Col(Temp_Col + 7);
  352.         Goto END_OF_MAC;
  353.     End;
  354.  
  355.     If (Caps(Cur_Char) = 'L') Then
  356.         Insert_Mode := False;
  357.         Indent;
  358.         Temp_Indent_Col := C_Col;
  359.         Goto_Col(Temp_Col);
  360.         If C_Col <> 1 THEN
  361.             Left;
  362.         END;
  363.         If Caps(Cur_Char) = 'E' THEN
  364.             Text('ELSIF');
  365.             Insert_Mode := True;
  366.             Cr;
  367.             Goto_Col(Temp_Indent_Col);
  368.         ELSE
  369.             Goto_Col(Temp_Col);
  370.             Text('LOOP');
  371.             Insert_Mode := True;
  372.             Cr;
  373.             Goto_Col(Temp_Indent_Col);
  374.             Text('IF () THEN');
  375.             Cr;
  376.             Indent;
  377.             Text('EXIT;');
  378.             Cr;
  379.             Undent;
  380.             Goto_Col(Temp_Indent_Col);
  381.             Text('END;');
  382.             Cr;
  383.             Goto_Col(Temp_Col);
  384.             Text('END;');
  385.             Up;
  386.             Up;
  387.             Up;
  388.             Goto_Col(Temp_Col + 6);
  389.         END;
  390.         Goto END_OF_MAC;
  391.     End;
  392.  
  393. END_OF_MAC:
  394.     Insert_Mode := Temp_Insert;
  395. END_MACRO;
  396.  
  397. $MACRO MODMTCH TRANS;
  398. {******************************************************************************
  399.                                                                 MULTI-EDIT MACRO
  400.  
  401. Name: MODMTCH
  402.  
  403. Description: Construct matching for Modula-2
  404.  
  405.                              (C) Copyright 1989 by American Cybernetics, Inc.
  406. ******************************************************************************}
  407.  
  408.     DEF_STR( Str1,     {Match strings}
  409.                      EStr1,
  410.                      T_Str, S_Str, FStr );
  411.  
  412.     DEF_INT( Direction,   {1 = search forward, 0 = backward}
  413.                      B_Count,     {Match count.  0 = match found}
  414.                      S_Res,       {Search results}
  415.                      Second_Time );
  416.  
  417.  
  418.     Second_Time := False;
  419.     Refresh := False;     {Turn screen refresh off}
  420.     Str1 := '';
  421.     EStr1 := '';
  422.  
  423. Find_Match_Str:
  424.  
  425.     IF (Cur_Char = '(') THEN   {Setup match for '('}
  426.         Right;
  427.         If cur_char = '*' then
  428.             Str1 := '(*';
  429.             EStr1 := '*)';
  430.             S_Str := '{(@*}||{@*)}';
  431.         else
  432.             Left;
  433.             Str1 := '(';
  434.             EStr1 := ')';
  435.             S_Str := '[()'']';
  436.         end;
  437.         Direction := 1;
  438.         GOTO Start_Match;
  439.     END;
  440.  
  441.     IF (Cur_Char = ')') THEN   {Setup match for ')'}
  442.         If (C_Col <> 1) then
  443.             Left;
  444.         end;
  445.         If cur_char = '*' then
  446.             Str1 := '*)';
  447.             EStr1 := '(*';
  448.             S_Str := '{(@*}||{@*)}';
  449.         else
  450.             Right;
  451.             Str1 := ')';
  452.             EStr1 := '(';
  453.             S_Str := '[()'']';
  454.         end;
  455.         Direction := 0;
  456.         GOTO Start_Match;
  457.     END;
  458.  
  459.     IF At_EOL THEN     {If we are at the end of a line the go to the first word}
  460.         First_Word;
  461.     END;
  462.  
  463.     IF (Cur_Char = ' ') or
  464.          (Cur_Char = '|9') or
  465.          (Cur_Char = '|255') THEN      {If we are on a blank space then find a word}
  466.         Word_Right;
  467.     END;
  468.  
  469.     S_Str := '['']||{%||[|9 ;)]{END}||{IF}||{WHILE}||{FOR}||{CASE}||{LOOP}||{WITH}||{BEGIN}$||[|9 ;.(]}||{(@*}||{@*)}';
  470.  
  471.     T_Str := Caps( Get_Word(';. |9|255') );  {Get the current word}
  472.  
  473.     IF (T_Str = 'IF') OR (T_Str = 'WHILE') OR (T_Str = 'FOR') or (T_Str = 'CASE') or
  474.          (T_STR = 'LOOP') or (T_Str = 'WITH') or (T_Str = 'BEGIN') or
  475.          (T_Str = 'ELSE') OR (T_Str = 'ELSIF') THEN
  476.         Str1 := 'IF WHILE FOR CASE LOOP WITH BEGIN';
  477.         EStr1 := 'END';
  478.         Direction := 1;
  479.         GOTO Start_Match;
  480.     END;
  481.  
  482.     IF T_Str = 'END' THEN
  483.         Str1 := 'END';
  484.         Estr1 := 'IF WHILE FOR CASE LOOP WITH BEGIN';
  485.         Direction := 0;
  486.         Word_Left;
  487.         Left;
  488.         GOTO Start_Match;
  489.     END;
  490.  
  491.     S_Str := '['']||{%||[|9 ;)]{REPEAT}||{UNTIL}$||[|9 ;.(]}||{(@*}||{@*)}';
  492.  
  493.     IF T_Str = 'REPEAT' THEN
  494.         Str1 := 'REPEAT';
  495.         Estr1 := 'UNTIL';
  496.         Direction := 1;
  497.         GOTO Start_Match;
  498.     END;
  499.  
  500.     IF T_Str = 'UNTIL' THEN
  501.         Str1 := 'UNTIL';
  502.         Estr1 := 'REPEAT';
  503.         Direction := 0;
  504.         Word_Left;
  505.         Left;
  506.         GOTO Start_Match;
  507.     END;
  508.  
  509.  
  510.     {If we didn't find a word to match the first time then try again}
  511.     If NOT( Second_Time ) THEN
  512.         Second_Time := True;
  513.         First_Word;
  514.         GOTO Find_Match_Str;
  515.     END;
  516.  
  517.     Make_Message('NOTHING to Match');
  518.     GOTO Macro_Exit;
  519.  
  520. Start_Match:
  521.     Reg_Exp_Stat := True;
  522.     Ignore_Case := false;
  523.     B_Count := 1;
  524.     S_Res := 1;
  525.     Make_Message('Matching...  Press <ESC> to Stop.');
  526.     Working;
  527.  
  528. MATCH_LOOP:   {Main loop}
  529.                     {If the <ESC> key is pressed while matching then abort the search}
  530.     if check_key then
  531.         if key1 = 27 then
  532.             Make_Message('Match Aborted.');
  533.             goto macro_exit;
  534.         end;
  535.     end;
  536.  
  537.     If S_Res = 0 THEN   {If last search result was false then exit}
  538.         GOTO Error_Exit;
  539.     END;
  540.  
  541.     If B_Count = 0 THEN {If match count is 0 then success}
  542.         GOTO Found_Exit;
  543.     END;
  544.  
  545.     If Direction = 1 THEN {Perform search based on direction}
  546.         Right;
  547.         While NOT( At_EOL) and (Cur_CHar = '|255') DO
  548.             Right;
  549.         END;
  550.         S_Res := Search_Fwd(S_Str,0);
  551.     ELSE
  552.         Left;
  553.         While (Cur_CHar = '|255') or
  554.                     (Cur_Char = '|9') DO
  555.             Left;
  556.         END;
  557.         S_Res := Search_Bwd(S_Str,0);
  558.     END;
  559.  
  560.     If S_Res = 0 THEN   {If search failed then exit}
  561.         GOTO Macro_Exit;
  562.     END;
  563.  
  564.     FStr := Found_Str;
  565.  
  566.     IF Length(FStr) > 2 THEN
  567.         IF XPOS(Copy(FStr,1,1),'|9 ;()',1)  THEN  {If the first char is a space or a ;}
  568.             FStr := Copy(FStr,2,20);         {  then eliminate it}
  569.         END;
  570.                                                                             {If it ended in a space, ; or . then}
  571.         IF XPOS(Copy(FStr,Length(FStr),1),'|9 ;.()',1) THEN
  572.             FStr := Copy(FStr,1,Length(FStr) - 1);  {eliminate that char}
  573.         END;
  574.     END;
  575.  
  576.                                                             {If we found the first match string then}
  577.     IF XPOS(FStr,STR1,1) THEN
  578.         ++B_Count;   {Inc the match count}
  579.         GOTO Match_Loop;
  580.     END;
  581.  
  582.     IF XPOS(FStr,ESTR1,1) THEN          {If we found the second match string then}
  583.         --B_Count;    {  decrement the match count}
  584.         GOTO Match_Loop;
  585.     END;
  586.  
  587.     If Fstr = '(*' THEN
  588.         IF Direction = 1 then
  589.             S_Res := Search_Fwd('@*)',0);
  590.             RIGHT;
  591.         END;
  592.         Goto Match_Loop;
  593.     END;
  594.  
  595.     If Fstr = '*)' THEN
  596.         IF Direction = 0 then
  597.             S_Res := Search_Bwd('(@*',0);
  598.         ELSE
  599.             RIGHT;
  600.         END;
  601.         Goto Match_Loop;
  602.     END;
  603.  
  604.     If FStr = '''''' THEN        {If we found two single quotes the skip it}
  605.         If Direction = 1 THEN
  606.             RIGHT;
  607.         ELSE
  608.             LEFT;
  609.         END;
  610.         GOTO Match_Loop;
  611.     END;
  612.  
  613.                                                             {If we found a single quote then match it}
  614.     IF FStr = '''' THEN
  615.  
  616.         Quote_Loop:
  617.  
  618.             If Direction = 1 THEN
  619.                 RIGHT;
  620.             ELSE
  621.                 LEFT;
  622.             END;
  623.             IF Direction = 1 THEN
  624.                 S_Res := Search_Fwd('''',0);
  625.             ELSE
  626.                 S_Res := Search_Bwd('''',0);
  627.             END;
  628.             If S_Res = 0 THEN
  629.                 GOTO Macro_Exit;
  630.             END;
  631.             FStr := Found_Str;
  632.             If FStr = '''''' THEN
  633.                 GOTO Quote_Loop;
  634.             END;
  635.             GOTO Match_Loop;
  636.  
  637.     END;
  638.  
  639. Error_Exit:     {Go here for unsucessfull match}
  640.     Make_Message('Match NOT Found');
  641.     GOTO Macro_Exit;
  642.  
  643. Found_Exit:     {Go here for successfull match}
  644.     If EStr1 = '*)' then
  645.         right;
  646.     end;
  647.     Make_Message('Match Found');
  648. Macro_Exit:
  649.     Refresh := True;
  650.     Redraw;
  651. END_MACRO;
  652.