[Oberon] Nested blocks colouring tool.

Chris Glur easlab at absamail.co.za
Sun Jan 20 14:21:10 MET 2008


When trying to read/modify some of the N-O source code, I often think
that what I'm given is just a final distillation of a creation which used 
more tools than an editor  -- which tools are now hidden. 
Like seeing at the ones & zeroes may hide the fact that they were distilled
from other inputs by a compiler/assembler ?

As an example, ET.Mod PROC Handle seems to have blocks nested 8 deep.
And with the nested blocks colouring tool which I've proto-typed,

    [See ver-1, less than 2 screens of source code at:  
http://www.edgar-schwarz.de/mm/ProblemsPendingSolutions
     for contributor refining]
< since the mm-wiki has its *OWN* syntax which clashes with
Oberon's syntax, what I tried to post has corrupted formatting,
extra knowledge is needed to post Oberon code
to mm-wiki.  I had a mail-bounce from:
 EdgarSchwarz at T9725.t.pppool.de
when asking how to do it !>
 
I've used red, blue, mauve, brown, green: 
   CodeUtils.TraceBloks   1 ,
   ...
   CodeUtils.TraceBloks   8 ;
to colour the nested blocks.

And afterwards, by sighting-down the code-text, while entering the 
next-colour-initial I got:
r,b,m,n,g,r,b,r,b,r,n,g,r,b,g,b,g,b,r,b,r,g,n,m,b,g,r !!

You really need 2 people: one to look-and-talk and one to write.
That's why N-O's heads-up-operation [like a fighter pilot] is so superior ?

Interestingly, adjacent red & brown gives poor colour contrast.
Which can be avoided for opening-brackets, which are 
manually chosen 'on sight'. But closing-brackets 'arrive
without foresight'. And related to this concept: I've just tested the
same structure using only 2 alternating colour; and I get;
1= 	BEGIN
..
n-2 = 		END;
n-1=		IF ~ handled THEN TextFrames.Handle(F, M) END
n=	END Handle;
   where line 1 was chosen to be red, and consequently its matching
   closing-line n is red too.
And closing-line n-2 had to be green, because it's head [line  2]
followed a red block.
Therefore line n-1 had to be red.
Which means that adjacent lines n-1 and n are both red, although 
they are at different block-levels. 
What's the algorithm to avoid this ?

This reminds me of the classical map-colouring-problem in maths ?

Because of the simplicity of oberon's syntax the basic block-colouring
algorithms is trivial:
* GetCaretPosn or error
* Get/ScanOpenBrkt following caret or error
* 0 -> BlokLevel
* Repeat 
     ScanTokens;
     If OpenBrkt then INC(BlokLevel);
     If ClosingBrkt then DEC(BlokLevel);
* Until (BlokLevel = 0)
* ColourTheBlockFrom(CaretPosn to FinalTokenPosition).

And the data is:
OpenBrkt = {"IF","CASE","WHILE","REPEAT","FOR","LOOP","WITH","BEGIN"}
ClosingBrkt = {"UNTIL", "END"} .

Only for "UNTIL <bool-expression>" does the the closing-bracket-token
"UNTIL" not close the block, and correspondingly colour the block up
to the end.  A refinement to handle this might be more complex than
the whole basic algorithm ?
Another refinement might be to auto-select the colours of the inner blocks.
Perhaps by modulo-cycling through a set of 3,4 or 5 colours ?

This little exercise raised 2 queries for me:
1. why does Oberon report not list
   "BEGIN" <statement> "END"
as a valid statement ?  Like Pascal does ? 
The compiler recognises it.

2. What is my theoretical justification for using the function
  'Texts.Pos(TheScanner)' to get the current position in the 'Texts'
of the *SCANNER*,  when this function is only defined for the
*READER*, even if the 'Scanner = RECORD  ( Reader )' is a 
descendant/extension of the 'Reader = RECORD'.

BTW   Watson.ShowDef  Texts       shows:-
"   (* Return reader's position within the text. *)
	PROCEDURE Pos (VAR R: Reader): LONGINT;    "

Oberon doesn't automatically inherit the procedures when the
corresponding record-data-fields are inherited, as if 'Scanner'
was a java-like-descendant class of 'Reader' ?

Obviously the scanner would be a major part of the compiler's parser,
and the 'latest position of the scanner' would need to be returned,
eg. to mark error-position[s].  So 'Texts.Pos(TheScanner)' which is 
defined as telling  the *READER* current position, tells the *SCANNER* 
current position too  -- perhaps because the scanner uses the reader ?
But what is the theoretical justification for this undocumented fact ?
Ie. how would you KNOW that 'Texts.Pos(TheScanner)' gives you the 
scanner's [not just reader's] current position ?
BTW I hope not to have to analyse the Texts.Mod code myself !

== Chris Glur.




More information about the Oberon mailing list