home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d512 / m2pascal.lha / M2Pascal / src / FunctionProcessing.mod < prev    next >
Text File  |  1991-07-20  |  6KB  |  209 lines

  1. IMPLEMENTATION MODULE FunctionProcessing;
  2.  
  3.      (*
  4.       * This module handles the processing for functions. The names
  5.       * are stored in a stack so nested functions can be used. Actually,
  6.       * nested functions aren't allowed so this module could be 
  7.       * re-written to be much smaller.
  8.       *
  9.       *)
  10.  
  11. FROM  scan       IMPORT STRING,           ReadAheadLine,
  12.                         ReadAheadSymbol,  TooFar,           SymbolType,
  13.                         IndentArray,      EolnAhead;
  14. FROM  errors     IMPORT FatalError,       ErrorMessage,     ErrorType,
  15.                         internal;
  16. FROM  InOut      IMPORT WriteString;
  17.  
  18. FROM  OutModule  IMPORT identical;
  19.  
  20. FROM  strings    IMPORT ConcatString;
  21.  
  22. FROM  Heap       IMPORT ALLOCATE,         DEALLOCATE ;
  23.  
  24. CONST
  25.       DEBUG               = FALSE;
  26. TYPE
  27.       ProcedureStatusType = ( colon, SemiColon, NotFound );
  28.       StackPtrType        = POINTER TO StackType;
  29.       StackType           = RECORD
  30.                              name  : STRING;
  31.                              next  : StackPtrType;
  32.                             END;
  33. VAR
  34.       indent          : IndentArray;
  35.       symbol          : STRING; 
  36.       SymbolClass     : SymbolType;
  37.  
  38.       top             : StackPtrType;
  39.  
  40.  
  41. PROCEDURE push ( FunctionName : STRING );
  42.  VAR node : StackPtrType;
  43. BEGIN
  44.  ALLOCATE ( node , SIZE ( StackType ) );
  45.  IF ( node = NIL ) THEN
  46.      FatalError ( OutOfMemory );
  47.  END;
  48.  
  49.  node^ .   name   := FunctionName;
  50.  node^ .   next   := top;
  51.  top              := node;
  52. END push;
  53.  
  54.  
  55. PROCEDURE BufferFull () : BOOLEAN;
  56. BEGIN
  57.  RETURN TooFar ();
  58. END BufferFull;
  59.  
  60.  
  61.  
  62.  (* Determine whether a colon is found after passed variables are
  63.     declared. This indicates that that a keyword follows and the 
  64.     procedure is a pascal function.
  65.  *)
  66. PROCEDURE GetStatus () : ProcedureStatusType;
  67.  VAR good : BOOLEAN;   ReturnVal : ProcedureStatusType;
  68. BEGIN
  69.   ReturnVal  :=  NotFound;
  70.   symbol     :=  "\0";
  71.  
  72.   WHILE (  ( NOT EolnAhead ()           ) AND 
  73.            ( NOT identical ( ")" , symbol ))     ) DO
  74.        ReadAheadSymbol ( symbol, SymbolClass );
  75.   END;
  76.  
  77.   IF ( identical ( ")" , symbol ) ) THEN
  78.        ReadAheadSymbol ( symbol, SymbolClass );
  79.        IF ( SymbolClass = blanks ) THEN
  80.             ReadAheadSymbol ( symbol, SymbolClass );
  81.        END;
  82.        IF ( identical ( ":" , symbol ) ) THEN
  83.             ReturnVal := colon;
  84.        END;
  85.        IF ( identical ( ";" , symbol ) ) THEN
  86.             ReturnVal := SemiColon;
  87.        END;
  88.   END;
  89.  
  90.   RETURN ReturnVal;
  91. END GetStatus;
  92.  
  93.  
  94.  
  95.  (* Determine whether a colon is found after passed variables are
  96.     declared. This indicates that that a keyword follows and the 
  97.     procedure is a pascal function. No parenthesis are necessary
  98.     in the declaration.
  99.  *)
  100. PROCEDURE GetInitStatus () : ProcedureStatusType;
  101.  VAR good : BOOLEAN;   ReturnVal : ProcedureStatusType;
  102. BEGIN
  103.   ReturnVal  :=  NotFound;
  104.   symbol     :=  "\0";
  105.  
  106.    (* Blanks after "procedure" *)
  107.   ReadAheadSymbol ( symbol, SymbolClass );
  108.  
  109.    (* First non-blank symbol after keyword "procedure" *)
  110.   IF ( SymbolClass = blanks ) THEN
  111.        ReadAheadSymbol ( symbol, SymbolClass );
  112.   END;
  113.  
  114.   IF ( identical ( ":" , symbol ) ) THEN
  115.        ReturnVal := colon;
  116.   END;
  117.   IF ( identical ( ";" , symbol ) ) THEN
  118.        ReturnVal := SemiColon;
  119.   END;
  120.  
  121.   IF ( ReturnVal = NotFound ) THEN       (* search rest of line *)
  122.        ReturnVal := GetStatus ();
  123.   END;
  124.  
  125.   RETURN ReturnVal;
  126. END GetInitStatus;
  127.  
  128.  
  129.  
  130.  
  131.  (* If the modula-2 procedure we're checking returns a value then it is a 
  132.     "function" in pascal.
  133.   *)
  134. PROCEDURE  IsAFunction () : BOOLEAN;
  135.  VAR good            : BOOLEAN;           
  136.      FunctionName    : STRING;            
  137.      ProcedureStatus : ProcedureStatusType;
  138.      ReturnVal       : BOOLEAN;
  139. BEGIN
  140.      FunctionName := "\0";
  141.      good         := TRUE;
  142.  
  143.           (* blanks between "PROCEDURE" and it's name *)
  144.      ReadAheadSymbol ( symbol, SymbolClass );
  145.  
  146.           (* procedure name *)
  147.      ReadAheadSymbol ( symbol, SymbolClass );
  148.      ConcatString    ( FunctionName, symbol );
  149.      IF DEBUG THEN
  150.          WriteString (" -Procedure name : " );
  151.              WriteString ( FunctionName ); WriteString("\n");
  152.      END;
  153.  
  154.      ProcedureStatus := GetInitStatus ();
  155.      WHILE ( ( ProcedureStatus = NotFound ) AND 
  156.              ( NOT BufferFull() )           AND 
  157.                good                            ) DO
  158.                           good            := ReadAheadLine ( indent );
  159.                           ProcedureStatus := GetStatus ();
  160.      END;
  161.  
  162.  
  163.       IF ( ( NOT good )  OR ( BufferFull() ) ) THEN
  164.          ErrorMessage ( UndeterminedProcedure );
  165.       ELSE
  166.            IF ( ProcedureStatus = colon ) THEN
  167.                 ReturnVal  := TRUE;
  168.                 push ( FunctionName );
  169.            ELSE
  170.                 ReturnVal  :=  FALSE;
  171.            END;
  172.       END;
  173.  
  174.       RETURN ReturnVal;
  175. END IsAFunction;
  176.  
  177.  
  178. (* 
  179.   We're through with reading in this function if "name" matches the
  180.   name on the top of the stack. If they match then pop the name off.
  181. *)
  182. PROCEDURE  PopFunctionName ( name  : STRING    );
  183.  VAR temp : StackPtrType;
  184. BEGIN
  185.    IF  ( top <> NIL ) THEN
  186.         IF ( identical ( name , top^.name ) ) THEN
  187.              temp   :=  top;
  188.              top    :=  top^.next;
  189.              DEALLOCATE ( temp , SIZE ( StackType ) );
  190.         END;
  191.    END;
  192. END PopFunctionName;
  193.  
  194.  
  195. PROCEDURE  FunctionName  ( VAR TheName : STRING );
  196. BEGIN
  197.     IF ( top <> NIL ) THEN
  198.         TheName  := top^.name;
  199.     ELSE
  200.         internal ( "FunctionName-> bottom of stack reached" );
  201.     END;
  202. END FunctionName;
  203.  
  204.  
  205.  
  206. BEGIN
  207.  top := NIL;
  208. END FunctionProcessing.
  209.