[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