-- File: WiskXD.mesa 
-- last edit by Sandman on July 21, 1980  3:46 PM
-- last edit by Bruce on Oct 10, 1980 8:20 PM
-- last edit by Sweet on April 17, 1980  5:00 PM
-- last edit by Mark on July 11, 1980  11:04 PM

DIRECTORY
  AltoFileDefs USING [FA],
  Ascii USING [ControlZ, CR, SP],
  Copier USING [Outer],
  DebugOps USING [FileName],
  DSyms USING [GFrameMdi],
  HeapString USING [AppendChar],
  Inline USING [LongNumber],
  MachineDefs USING [GFHandle],
  Source USING [Handle, LoadWindow, Open],
  StreamDefs USING [GetFA, JumpToFA, StreamError, StreamHandle],
  String USING [AppendChar, AppendString, EqualString],
  SymbolTable USING [Base],
  TextSW USING [GetPosition],
  ToolWindow USING [GetName, Handle, SetName, WindowForSubwindow],
  Window USING [Handle];
  
WiskXD: PROGRAM
  IMPORTS
    Copier, DebugOps, DSyms, HeapString, Source, StreamDefs, String, TextSW, ToolWindow
  EXPORTS Source =
  BEGIN OPEN MachineDefs;
  
  SourceTooLong: ERROR = CODE;
  
  CheckForBravo8: PUBLIC PROC [sh: Source.Handle, gf: GFHandle, w: Window.Handle] = {
    IF CheckIt[sh] THEN Reload[gf,w]};
    
  CheckIt: PROC [sh: Source.Handle] RETURNS [BOOLEAN] =
    BEGIN
    name: STRING ← [40];
    WITH LOOPHOLE[sh, StreamDefs.StreamHandle] SELECT FROM
      Disk => DebugOps.FileName[name, file];
      ENDCASE => RETURN[FALSE];
    FOR i: CARDINAL DECREASING IN [0..name.length) DO 
      IF name[i] = '$ THEN RETURN[TRUE];
      ENDLOOP;
    RETURN[FALSE];
    END;
    
  Reload: PROC [gf: GFHandle, w: Window.Handle] = {
    fileId: STRING ← [40];
    file: Source.Handle;
    Inner: PROC [base: SymbolTable.Base] = {String.AppendString[fileId,base.sourceFile]};
    AddDollar[ToolWindow.WindowForSubwindow[w]];
    Copier.Outer[DSyms.GFrameMdi[gf],Inner];
    file ← Source.Open[fileId];
    IF file = NIL THEN RETURN;
    Source.LoadWindow[fileId, gf, file, TextSW.GetPosition[w,0]]};
    
  AddDollar: PROC [w: Window.Handle] = {
    s: STRING ← ToolWindow.GetName[w];
    IF s[s.length-1] = '. THEN s[s.length-1] ← '$ ELSE HeapString.AppendChar[@s,'$];
    ToolWindow.SetName[w,s]};
    
  LittleParser: PUBLIC PROCEDURE [sh: Source.Handle, module: STRING] =
    BEGIN OPEN Ascii;
    char: CHARACTER;
    testId: STRING ← [40];
    fa: AltoFileDefs.FA;
    found: BOOLEAN ← FALSE;
    StreamDefs.GetFA[sh, @fa];
    sh.reset[sh];
    WHILE ~found DO
      ENABLE StreamDefs.StreamError, NotFound =>
	BEGIN module.length ← 0; EXIT END;
      GetId[sh,testId];
      SELECT TRUE FROM
	String.EqualString[testId, "DIRECTORY"L] =>
	  DO
	    SELECT (char ← sh.get[sh]) FROM
	      '- =>
		IF (char ← sh.get[sh]) = '- THEN
		  DO
		    SELECT sh.get[sh] FROM
		      CR => BEGIN char ← CR; EXIT END;
		      '- => IF sh.get[sh] = '- THEN
			BEGIN char ← sh.get[sh]; EXIT END;
		      ENDCASE;
		    ENDLOOP;
	      ENDCASE;
	    IF char = '; THEN EXIT;
	    ENDLOOP;
	ENDCASE =>
	  BEGIN OPEN String;
	  module.length ← 0;
	  AppendString[module,testId];
	  GetId[sh,testId];
	  IF EqualString[testId, "PROGRAM"L] OR
	    EqualString[testId, "MONITOR"L] THEN found ← TRUE;
	  EXIT;
	  END;
      ENDLOOP;
    StreamDefs.JumpToFA[sh, @fa];
    IF ~found THEN module.length ← 0;
    END;
    
  NotFound: SIGNAL = CODE;
  
  GetId: PROCEDURE [s: StreamDefs.StreamHandle, token: STRING] =
    BEGIN OPEN Ascii;
    c: CHARACTER ← s.get[s];
    token.length ← 0;
    DO 
      SELECT c FROM
	'- =>
	  IF (c ← s.get[s]) = '- THEN
	    DO
	      SELECT s.get[s] FROM
		CR => BEGIN c ← CR; EXIT END;
		'- => IF s.get[s] = '- THEN
		  BEGIN c ← s.get[s]; EXIT END;
		ENDCASE;
	      ENDLOOP
	  ELSE SIGNAL NotFound;
	ControlZ => UNTIL s.get[s] = CR DO
	  NULL REPEAT FINISHED => c ← CR ENDLOOP;
	<= SP, ': => IF token.length # 0 THEN RETURN ELSE c ← s.get[s];
	'=, '[ => SIGNAL NotFound;
	ENDCASE =>
	  BEGIN String.AppendChar[token, c]; c ← s.get[s]; END;
      ENDLOOP;
    END;
    
Shorten: PUBLIC PROC [lc: LONG CARDINAL] RETURNS [CARDINAL] =
  BEGIN OPEN ln: LOOPHOLE[lc,Inline.LongNumber];
  IF ln.highbits # 0 THEN ERROR SourceTooLong;
  RETURN [ln.lowbits]
  END;
  
END.