[Oberon] Re: N-O Scanner structure confusing ?
easlab at absamail.co.za
Thu Feb 15 12:35:10 MET 2007
On 10 Feb 2007, Chris Glur <easlab at absamail.co.za> wrote:
> > [...]
> > Q- is it true that the Scanner is a descendant of the Reader ?
> > Q- and that the Scanner 'uses' its parent to step&read as part
> > of its scanning task ?
> > Q - and that if the reader's char-position was publicly
> > available, this would relate to the scanner's token position,
> > since the scanner uses the reader ?
> > Q - but the reader explicitly makes the read-postn-variable
> > unavailable; isolating it via a function [procedure] ?
> > [...]
> All "Q"s need a "yes" except the last one,
> cause the "scanner-reader" position is returned by Texts.Pos:
> Texts.Scanner record is an extension of a Texts.Reader record.
> A Texts.Scanner record variable therefore has the two fields org and off.
> The two fields describe the position of the scanner and are changed by a read.
> Every scan normally makes at least one read.
> After a scan, Texts.Pos(S) returns S.org+S.off, the sum of the two field values
> changed by the read operation that forced that scan to terminate.
> That's what Oberon code may tell,
> I wonder how execution of your code may telling you something else.
While I try to make a utility which will help expose the block
structure and nested statements, I'm trying to investigate
some meta-queries which have bothered me for a long time.
One such query: 'why do they keep repeating eg. Hex2Ascii procs
for several module', got the explanation that students need exercise.
My present query is:
why don't they write in a higher-level style eg.
IF CaretPostn = NIL THEN Error('Caret not set');
Scan1stTkn(S); // which also inits Scanner;
WHILE condition DO GetToken(S); DoStuff END;
instead of eg.
C.id := Oberon.get; C.F := NIL; C.car := NIL; C.text := NIL;
Display.Broadcast(C); (* get caret position *)
IF C.text = NIL THEN FAIL;
ELSE Texts.OpenScanner(S, C.text, C.pos); Texts.Scan(S);
WHILE condition DO Texts.Scan(S); DoStuff END
I want to investigate a formal procedure/method of
managing the high coupling of routines like Texts.Scan(S).
Instead of just spreading all the part on the table, to be
used as required. Ie. try some information hiding ?
But I don't think my method of using the Scanner's inherited
function value Texts.Pos(S) is 'sound'; beause Watson doesn't
show Texts.Pos(S) for the Scanner, and you are not supposed
to know that the scanner uses the reader and that therefore
the Reader's Pos relates to the Scanner's Pos.
Ie. it relies on undocumented, and hence potentially changeble
Before I spend time to derive a 'pattern' for a cookbook method
of knowing what arguments can be hidden, when executing
a sequence of strongly coupled procs, perhaps some one else
Eg. you are going to execute procs. P,Q,R in that sequence.
And P has var-pars: a,b,c,d,e.
And Q has var-pars: f,b,g,h.
And R has var-pars: i,j,f,b.
What N-O code seems to do is the most intuitive and natural,
and perhaps unconsidered: expose all vars: a....j; creating
code-clutter. And then just take what's needed when calling
the next proc.
So to use the TextScanner, the coder can't just look in a library
description or use Watson. S/he must be concerned with too
much of the internal workings of TextScanner - IMO.
I recently spent some time on a spreadsheet, after a year[s]
break, and was reminded that 'constrained coding';
ie. fill in the fields is much better that 'arty free flight'.
Our creativety should be freed up for proper problems.
Not for routine tasks which should be formally constrained,
or even better, automated.
== Chris Glur.
More information about the Oberon