DIRECTORY
Basics,
Atom USING [MakeAtom--, GetPName--],
ISMessage,
ISBinding,
ISNode,
ISScan,
ISToken,
ISTiogaIntern,
Rope USING [ROPE--, Fetch, Length, Concat, Substr--],
IO USING [STREAM, RIS, ROS,  EndOfStream, RopeFromROS, CR, GetChar, PeekChar, PutChar, GetIndex, SetIndex--, atom--];

ISScanImpl: CEDAR PROGRAM
IMPORTS Atom, ISBinding, ISNode, IO, --Rope, --ISTiogaIntern
EXPORTS ISBinding, ISScan  
= BEGIN OPEN ISToken, ISScan;

ParseFailure: PUBLIC SIGNAL [s: ISScan.ScanHandle, r: ISScan.ParseFailureReason] = CODE;
BindingFailure: PUBLIC SIGNAL [r: ISBinding.BindingFailureReason] = CODE;

currentEnvironment: ISBinding.EnvironmentHandle _ NIL;
environmentAnchor: ISBinding.Handle _ NIL;

notACharacter: CARDINAL = LAST[CARDINAL];

bufferWords: CARDINAL = ISScan.bufferBytes / 2; -- all must be power of two --

CreateScan: PUBLIC PROCEDURE [
base: Rope.ROPE,
index: INT,
bindingStack: ISBinding.StackHandle _ NIL,
family: ATOM _ NIL ] 
RETURNS [ScanHandle] = BEGIN

newScanner: CharactersScanner _ NEW[ScanStream.characters];
new: ScanHandle _ NEW[ScanObject];

newScanner^ _ [name: NIL, body: characters [cstream: IO.RIS[base]]];
IO.SetIndex[newScanner.cstream, index];

new^ _ [
stream: newScanner,
family: family--,--
--allocateWith: allocateWith--];
IF bindingStack#NIL THEN {new.bindingStack _ bindingStack; new.stackIsScans _ FALSE}
ELSE {new.bindingStack _ ISBinding.CreateStack[]; new.stackIsScans _ TRUE};
RETURN [new];
END;

InitializeScan: PUBLIC PROCEDURE [s: ScanHandle] = BEGIN
WITH s.stream SELECT FROM
ss: CharactersScanner => IF ss.cstream=NIL THEN ERROR;
ENDCASE => ERROR;
RETURN;
END;

InitializeScanThroughCurly: PUBLIC PROCEDURE [s: ScanHandle] = BEGIN
InitializeScan [s];
WITH s.stream SELECT FROM
ss: CharactersScanner =>
BEGIN
THROUGH [0..100) DO 
IF IO.PeekChar[ss.cstream]='{ THEN {[] _ AdvanceScan[s]; RETURN}; 
[] _ IO.GetChar[ss.cstream]; 
ENDLOOP;
END;
ENDCASE => ERROR;
SIGNAL ParseFailure [s, spare];
RETURN;
END;



UseUpPeek: PROC [s: IO.STREAM] ~ { [] _ IO.GetChar[s]; };

PeelInteger: PROCEDURE [stream: IO.STREAM, startCharacter: CHAR _ '0] RETURNS [LONG INTEGER] = BEGIN

li: LONG INTEGER _ startCharacter - '0;
a: ARRAY [0..10] OF NAT;
count: NAT _ 0;
radix: NAT _ 10;
peek: CHAR;

WHILE (peek_IO.PeekChar[stream]) IN ['0..'9] DO 
a[count] _ IO.GetChar[stream] - '0;
count _ MIN[count+1,10];
ENDLOOP;
IF peek='B OR  peek='b THEN { radix _ 8; UseUpPeek[stream] };
FOR z: NAT IN [0..count) DO li _ li*radix + a[z]; ENDLOOP;
RETURN [li];
END;

AdvanceScan: PUBLIC PROCEDURE [s: ScanHandle] = BEGIN
DO -- so we can repeatedly pop --
WITH s.stream SELECT FROM
ss: TokensScanner => s.stream.token _ TokenFromTokensScanner [ss];
ss: CharactersScanner => s.stream.token _ TokenFromCharactersScanner [ss];
ENDCASE => ERROR; -- not tokens or characters --
BEGIN
type: TVType _ s.stream.token.type;
IF (type = endOfString OR type = endOfStream)
AND s.stream.pushed#NIL THEN BEGIN -- pop the scan --
old: REF ScanStream _ s.stream.pushed;
s.stream _ old;
type _ s.stream.token.type;
IF type#endOfStream AND type#endOfString AND type3null THEN RETURN;
END
ELSE RETURN;
END;
ENDLOOP;
END;

TokenFromTokensScanner: PROCEDURE [ts: TokensSca~ner] RETURNS [obj: TVHandle] = BEGIN
IF ts.tokenList=NIL THEN obj _ NEW[TVObject.endOfStream]
ELSE {obj _ ts.tokenList; 43.tokenList _ ts.tokenList.next};
obj.streamName _ ts.name; --<<used to hurt tests 22may85 rma>>--
RETURN;
END;

TokenFromCharactersScanner: PROCEDURE [cs: CharactersScanner] RETURNS [tr: TVHandle] = BEGIN
byte: CHAR; 
inComment: BOOLEAN _ FALSE;
ios: IO.STREAM _ cs.cstream;

DO -- skip noise bytes and comments --
byte _ IO.GetChar[ios !
IO.EndOfStream => GOTO PopInputScanner];
IF inComment THEN
SELECT byte FROM
'- => IF IO.PeekChar[ios]='- THEN {UseUpPeek[ios]; inComment _ FALSE};
IO.CR => inComment _ FALSE; -- comment ended by cr or eos --
ENDCASE => NULL
ELSE 
SELECT VAL[byte] FROM
IN [1B..40B] => LOOP;
VAL['-] => IF IO.PeekChar[ios]='- THEN -- comment -- 
{UseUpPeek[ios]; inComment _ TRUE} ELSE EXIT;
ENDCASE => EXIT;
REPEAT
PopInputScanner => RETURN[NEW[TVObject.endOfStream]];
ENDLOOP;

SELECT byte FROM --<<trying to get a jump table from the compiler .. rma 13feb84>>--
IN ['A..'Z],
IN ['a..'z] => BEGIN -- atom or dollar --
--<<This code assumes that everything is in characterset zero>>--
rope: IO.STREAM _ IO.ROS[];
peek: CHAR;
IO.PutChar[rope, byte];
WHILE (peek_IO.PeekChar[ios]) IN ['A..'Z] OR peek IN ['a..'z]
OR peek IN ['0..'9] -- Allow non-leading digits --
OR peek='. DO  -- current (feb85) separator, e.g. 'FONT.Points' --
IO.PutChar[rope, IO.GetChar[ios]];
ENDLOOP;
IF peek='$ OR VAL[peek]=244B THEN BEGIN
-- the dollar used to be in the atom .. but no more .. rma feb85 --
UseUpPeek[ios];
tr _ NEW[TVObject _  [body: dollar[value: Atom.MakeAtom[IO.RopeFromROS[rope, TRUE]]]] ]; 
END
ELSE tr _ NEW[TVObject _  [body: atom[value: Atom.MakeAtom[IO.RopeFromROS[rope, TRUE]]]] ];
END;
'< => BEGIN -- characters --
startIndex: INT = IO.GetIndex[ios];
cs0: BOOLEAN _ TRUE;
DO --<< See comment above 'Get' >>--
char: CHAR _ IO.GetChar[ios];
IF cs0 AND char='> THEN
IF IO.PeekChar[ios]#'> THEN EXIT ELSE [] _ IO.GetChar[ios];
IF VAL[char]=377B THEN cs0 _ VAL[IO.GetChar[ios]]=0;
ENDLOOP;
tr _ NEW[TVObject _  [body: characters [stream: ios, startIndex: startIndex, length: IO.GetIndex[ios]-startIndex-1]] ];
END;
IN ['0..'9] => BEGIN -- number --
t: integer TVObject _ [body: integer[value: 0]];
t.value _ PeelInteger [stream: ios, startCharacter: byte];
tr _ NEW[TVObject _  t ];
END;
'_ => {tr _ NEW[TVObject _  [body: gets[]] ]};
VAL[254B] => {tr _ NEW[TVObject _  [body: gets[]] ]};
'= => {tr _ NEW[TVObject _  [body: gets[]] ]};
'{ => {tr _ NEW[TVObject _  [body: leftCurly[]] ]};
'} => {tr _ NEW[TVObject _  [body: rightCurly[]] ]};
'+ => {tr _ NEW[TVObject _  [body: plus[]] ]};
'- => {tr _ NEW[TVObject _  [body: minus[]] ]};
'* => {tr _ NEW[TVObject _  [body: times[]] ]};
'^ => {tr _ NEW[TVObject _  [body: open[]] ]};
VAL[255B] => {tr _ NEW[TVObject _  [body: open[]] ]};
'! => {tr _ NEW[TVObject _  [body: open[]] ]};
'| => {tr _ NEW[TVObject _  [body: open[]] ]};
'" => -- string .. Interscript string-constant --
BEGIN
IF cs.inString THEN {tr _ NEW[TVObject _  [body: endOfString[]] ]; cs.inString _ FALSE}
ELSE
BEGIN
stringToken: StringTVHandle _ NEW[string TVObject _ [body: string[]]];
stringToken.tail _ stringToken;
cs.inString _ TRUE;
DO
to: TVHandle _ TokenFromCharactersScanner [cs];
IF to.type=endOfString THEN 
{tr _ NEW[TVObject _  stringToken^ ]; GOTO FoundEndOfString}
ELSE
BEGIN
new: TVHandle _ CopyOneTV [to];
new.next _ NIL; stringToken.tail.next _ new; stringToken.tail _ new; 
END;
ENDLOOP;
END; -- of else --
EXITS FoundEndOfString => NULL;
END; -- of Interscript string-constant --
'/ => {tr _ NEW[TVObject _  [body: divide[]] ]};
'[ => {tr _ NEW[TVObject _  [body: push[]] ]};
'] => {tr _ NEW[TVObject _  [body: pop[]] ]};
ENDCASE => SIGNAL ParseFailure [NIL, unsupportedConstruct];
tr.streamName _ cs.name;
RETURN;
END;

CreateStack: PUBLIC PROCEDURE [useEnvironment: BOOLEAN _ TRUE]
RETURNS [ISBinding.StackHandle] = BEGIN 
sh: ISBinding.StackHandle _ NEW [ISBinding.StackObject];
sh^ _ [top: IF useEnvironment THEN environmentAnchor ELSE NIL];
RETURN [sh];
END;

DestroyStack: PUBLIC PROCEDURE [atStack: REF ISBinding.StackHandle] = BEGIN 
atStack^ _ NIL;
END;

AnchorBindings: PUBLIC PROCEDURE [stack: ISBinding.StackHandle]
RETURNS [ISBinding.Anchor] = {RETURN [stack^]};

CreateEnvironment: PUBLIC PROCEDURE [stack: ISBinding.StackHandle]
RETURNS [ISBinding.EnvironmentHandle] = BEGIN 
eh: ISBinding.EnvironmentHandle _ NEW[ISBinding.EnvironmentObject];
eh^ _ [stack: stack];
environmentAnchor _ stack.top;
RETURN [eh];
END;

UseEnvironment: PUBLIC PROCEDURE [environment: ISBinding.EnvironmentHandle] = BEGIN
currentEnvironment _ environment;
environmentAnchor _ environment.stack.top; --<<compatibility>>--
END;

UnuseEnvironment: PUBLIC PROCEDURE RETURNS [ISBinding.EnvironmentHandle] = BEGIN
eh: ISBinding.EnvironmentHandle _ currentEnvironment;
currentEnvironment _ NIL;
environmentAnchor _ NIL; --<<compatibility>>--
RETURN [eh];
END;

PruneBindings: PUBLIC PROCEDURE [
stack: ISBinding.StackHandle,
anchor: ISBinding.Anchor] = BEGIN
stack^ _ anchor; --<<no garbage collecting for now>>--
RETURN;
END;

AugmentBindings: PUBLIC PROCEDURE [
name: ATOM,
value: TVHandle,
stack: ISBinding.StackHandle] = BEGIN
temp: ISBinding.Handle _ NEW[ISBinding.Object];
temp^ _ [ previous: stack.top, name: name, value: value ];
stack.top _ temp;
RETURN;
END;

ObtainBinding: PUBLIC PROCEDURE [name: ATOM, stack: ISBinding.StackHandle]  RETURNS [TVHandle] = BEGIN
FOR temp: ISBinding.Handle _ stack.top, temp.previous UNTIL temp=NIL DO
IF temp.name=name THEN RETURN [temp.value];
ENDLOOP;
RETURN [NIL];
END;

CopyScanStream: PROCEDURE [old: REF ScanStream] RETURNS [new: REF ScanStream] = BEGIN
WITH old SELECT FROM
s: CharactersScanner => new _ NEW[characters ScanStream _ s^];
s: TokensScanner => new _ NEW[tokens ScanStream _ s^];
ENDCASE => NULL;
RETURN;
END;

CopyOneTV: PROCEDURE [tv: TVHandle] RETURNS [r: TVHandle] = BEGIN
WITH tv^ SELECT FROM
o: null TVObject => r _ NEW[null TVObject _ o];
o: endOfString TVObject => r _ NEW[endOfString TVObject _ o]; 
o: endOfStream TVObject => r _ NEW[endOfStream TVObject _ o]; 
o: endOfScript TVObject => r _ NEW[endOfScript TVObject _ o];
o: integer TVObject => r _ NEW[integer TVObject _ o];
o: atom TVObject => r _ NEW[atom TVObject _ o];
o: string TVObject => r _ NEW[string TVObject _ o];
o: dollar TVObject => r _ NEW[dollar TVObject _ o];
o: characters TVObject => r _ NEW[characters TVObject _ o];
o: plus TVObject => r _ NEW[plus TVObject _ o];
o: minus TVObject => r _ NEW[minus TVObject _ o];
o: times TVObject => r _ NEW[times TVObject _ o];
o: divide TVObject => r _ NEW[divide TVObject _ o];
o: gets TVObject => r _ NEW[gets TVObject _ o];
o: open TVObject => r _ NEW[open TVObject _ o];
o: leftCurly TVObject => r _ NEW[leftCurly TVObject _ o];
o: rightCurly TVObject => r _ NEW[rightCurly TVObject _ o];
o: push TVObject => r _ NEW[push TVObject _ o];
o: pop TVObject => r _ NEW[pop TVObject _ o];
o: node TVObject => r _ NEW[node TVObject _ o];
o: specialChars TVObject => r _ NEW[specialChars TVObject _ o];
o: styleOpen TVObject => r _ NEW[styleOpen TVObject _ o];
o: styleDefinition TVObject => r _ NEW[styleDefinition TVObject _ o];
ENDCASE;
RETURN;
END;

CollectRHS: PROCEDURE [scan: ScanHandle] RETURNS [TVObject] = BEGIN
uniaryMinus: BOOLEAN _ FALSE;    

SELECT scan.stream.token.type FROM 
gets => AdvanceScan [scan];
ENDCASE => NULL; 
SELECT scan.stream.token.type FROM 
plus => AdvanceScan [scan];  -- kill leading uniary plus -- 
minus => {uniaryMinus _ TRUE; AdvanceScan [scan]}; 
ENDCASE => NULL;
WITH scan.stream.token SELECT FROM
t: LeftCurlyTVHandle => BEGIN
child: NodeTVHandle;
return: NodeTVHandle _ NEW[node TVObject];
AdvanceScan [scan]; 
child _ CollectNode [scan: scan, bound: TRUE];
DO
WITH scan.stream.token SELECT FROM
n: NullTVHandle => AdvanceScan[scan];
o: OpenTVHandle => --Remove outer {} and splice innerds into input stream (macro expansion)--
BEGIN 
AdvanceScan[scan]; --Get rid of open--
scan.stream _ NEW[characters ScanStream _ [
name: NIL,
pushed: CopyScanStream[scan.stream],
body: characters [cstream: IO.RIS[ISTiogaIntern.PrintNodeContents[NARROW[child.isnode], FALSE]]]]];
AdvanceScan [scan]; -- prime the pump --
EXIT;
END;
ENDCASE => {
return^ _ [body: node[isnode: child.isnode]];
EXIT;
};
ENDLOOP;
RETURN [return^];
END; 
t: AtomTVHandle => BEGIN
rhsAtom: atom TVObject _ t^;
AdvanceScan [scan]; 
SELECT scan.stream.token.type FROM
open => BEGIN
b: TVHandle _ ObtainBinding [RemoveDot[rhsAtom.value], scan.bindingStack];
AdvanceScan [scan]; 
WITH b SELECT FROM
n: NodeTVHandle => { --Do "macro expansion" of node--
scan.stream _ NEW[characters ScanStream _ [
name: t.value,
pushed: CopyScanStream[scan.stream],
body: characters [cstream: IO.RIS[ISTiogaIntern.PrintNodeContents[NARROW[n.isnode]]]]]];
AdvanceScan [scan]; -- prime the pump --
RETURN[CollectRHS[scan]];
};
ENDCASE => RETURN [IF b=NIL THEN rhsAtom ELSE b^];
END;
ENDCASE => RETURN [rhsAtom]; 
END; 
t: IntegerTVHandle => BEGIN
int: integer TVObject _ t^;
operator: TVType;
IF uniaryMinus THEN int.value _ -int.value;
AdvanceScan [scan];
operator _ scan.stream.token.type; 
SELECT operator FROM
times, minus, plus => NULL;
ENDCASE => RETURN [int];
AdvanceScan [scan]; 
BEGIN
right: TVObject _ CollectRHS [scan];
WITH right SELECT FROM
far: integer TVObject => BEGIN
SELECT operator FROM
times => int.value _ int.value * far.value;
minus => int.value _ int.value - far.value;
plus => int.value _ int.value + far.value;
ENDCASE => ERROR;
RETURN [int];
END; 
ENDCASE => ERROR ParseFailure [scan, unexpectedDelimiter];
END;
END; 
ENDCASE => {rhs: TVObject _ scan.stream.token^; AdvanceScan [scan]; RETURN [rhs]};
END;

RemoveDot: PROC [a: ATOM] RETURNS [ATOM] ~ {
RETURN[a];
};

CollectNode: PUBLIC PROCEDURE [
scan: ScanHandle, 
parent: ISNode.Handle _ NIL,
bound: BOOL _ FALSE ] 
RETURNS [NodeTVHandle] = BEGIN
node: NodeTVHandle _ NEW[node TVObject];
primaryImpl: ISNode.Implementation _ NIL;
primaryTag: ATOM _ NIL;
oldLocalLimit: ISBinding.Anchor;
anchor: ISBinding.Anchor;
square: ISBinding.Anchor; -- bad usage: no nesting and little syntactic checking of '[]' --
contentBuffer: TVHandle _ NIL;
lastBufferedContent: TVHandle _ NIL;

BufferOrCall: --LOCAL-- PROCEDURE [con: TVHandle] = BEGIN
IF primaryImpl#NIL THEN BEGIN
WITH con SELECT FROM
cc: NodeTVHandle => 
BEGIN
ie: ISToken.InterscriptContext _ NEW[ISToken.InterscriptContextObject _ [ body: embedded[content: cc] ] ];
[] _ primaryImpl.internalize [ NARROW[node.isnode], ie ];
END;
cc: StyleOpenTVHandle => 
BEGIN
ie: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: styleOpen[identifier: cc] ] ];
[] _ primaryImpl.internalize [ NARROW[node.isnode], ie ];
END;
cc: StyleDefinitionTVHandle => 
BEGIN
ie: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: styleDefinition[definition: cc] ] ];
[] _ primaryImpl.internalize [ NARROW[node.isnode], ie ];
END;
ENDCASE => 
BEGIN
ic: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: content[content: con] ] ];
[] _ primaryImpl.internalize [ NARROW[node.isnode], ic ];
END;
END
ELSE
BEGIN
copy: TVHandle _ CopyOneTV[con];
IF lastBufferedContent#NIL THEN
{lastBufferedContent.next _ copy; lastBufferedContent _ copy}
ELSE contentBuffer _ lastBufferedContent _ copy;
END;
END;

node^ _ [body: node[]];
node.isnode _ ISNode.Create [--scan.allocateWith--]; 

anchor _ AnchorBindings [scan.bindingStack];
oldLocalLimit _ ISTiogaIntern.localBindingLimit;
ISTiogaIntern.localBindingLimit _ anchor; --hack hack--
DO
WITH scan.stream.token SELECT FROM
t: NullTVHandle => AdvanceScan [scan];
-- lets us not AdvanceScan .. see at rightCurly --
t: EOScTVHandle => SIGNAL ParseFailure [scan,hitEndOfScript];
t: IntegerTVHandle =>
BEGIN
tvo: TVHandle _ NEW[TVObject _ CollectRHS [scan]]; -- to pick up integer expressions as content --
BufferOrCall [tvo]; 
END;
t: MinusTVHandle =>
BEGIN
tvo: TVHandle _ NEW[TVObject _ CollectRHS [scan]]; -- to pick up integer expressions as content --
BufferOrCall [tvo]; 
END;
t: PlusTVHandle => 
BEGIN
tvo: TVHandle _ NEW[TVObject _ CollectRHS [scan]]; -- to pick up integer expressions as content --
BufferOrCall [tvo]; 
END;
t: AtomTVHandle => 
BEGIN
theAtomicTV: TVObject _ scan.stream.token^;
theAtom: ATOM _ t.value;
AdvanceScan [scan];
WITH scan.stream.token SELECT FROM
x: GetsTVHandle => BEGIN
rhs: TVHandle _ NEW[TVObject _ CollectRHS [scan]];
AugmentBindings [RemoveDot[theAtom], CopyOneTV[rhs], scan.bindingStack]; 
END;
x: OpenTVHandle => BEGIN
original: ATOM;
tvo: TVHandle _ NEW[TVObject _ theAtomicTV]; -- may be altered below --
WITH tvo SELECT FROM t0: AtomTVHandle => original _ t0.value; ENDCASE; 
DO -- handling multiple opens ala Atom^^ --
WITH tvo SELECT FROM -- will surely be atom the first time --
t2: AtomTVHandle =>
WITH scan.stream.token SELECT FROM
t3: OpenTVHandle => BEGIN
b: TVHandle _ ObtainBinding [RemoveDot[t2.value], scan.bindingStack];
AdvanceScan [scan]; -- past the open -- 
IF b#NIL THEN tvo _ b ELSE GOTO EndOfOpenings;
END; -- and loop to handle atom bound to atom bound to ... --
ENDCASE => GOTO EndOfOpenings; 
ENDCASE => GOTO EndOfOpenings; 
REPEAT
EndOfOpenings => NULL;
ENDLOOP; 
WITH tvo SELECT FROM 
tt: NodeTVHandle => --Splice external node rep into input stream--
BEGIN
scan.stream _ NEW[characters ScanStream _ [
name: theAtom,
pushed: CopyScanStream[scan.stream],
body: characters [cstream: IO.RIS[ISTiogaIntern.PrintNodeContents[NARROW[tt.isnode]]]]]];
AdvanceScan [scan]; -- prime the pump --
END;
tt: StringTVHandle =>
BEGIN
scan.stream _ NEW[tokens ScanStream _ [
name: theAtom,
pushed: CopyScanStream[scan.stream],
body: tokens [tokenList: tt.list] ]];
BEGIN -- warn node impl about the styleOpen --
zz: TVHandle _ NEW[styleOpen TVObject _ [body: styleOpen[name: original]]];
BufferOrCall [zz];
END;
AdvanceScan [scan]; -- prime the pump --
END; 
tt: AtomTVHandle => BufferOrCall [tvo]; -- opens finally got just another atom --
ENDCASE => ERROR;
END; -- of open --
ENDCASE => -- just the atom was there --
{a: AtomTVHandle _ NEW[atom TVObject _ [body: atom[value: theAtom]]];
BufferOrCall [a]};
END; -- of atom --
t: CharactersTVHandle => BEGIN
BufferOrCall [scan.stream.token];
AdvanceScan [scan];
END;
t: StringTVHandle => {BufferOrCall [scan.stream.token]; AdvanceScan [scan]};
t: DollarTVHandle => 
BEGIN
IF primaryImpl=NIL THEN
BEGIN -- test this tag for being the primary impl --
im: ISNode.Implementation _ ISNode.GetImplementation [t.value, scan.family];
IF im#NIL AND im.implementationClass=primary THEN BEGIN
-- have the primary impl --
ii: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: initial [parent] ] ];
primaryImpl _ im; primaryTag _ t.value;
NARROW[node.isnode, ISNode.Handle].tag _ primaryTag;
NARROW[node.isnode, ISNode.Handle].printProc _ primaryImpl.printTioga;
primaryImpl.internalize [ NARROW[node.isnode], ii ];
WHILE contentBuffer#NIL DO 
temp: TVHandle;
WITH contentBuffer SELECT FROM
cb: NodeTVHandle => BEGIN
ie: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: embedded[content: cb] ] ];
[] _ primaryImpl.internalize [ NARROW[node.isnode], ie ];
END;
cb: StyleOpenTVHandle => BEGIN
ie: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: styleOpen[identifier: cb] ] ];
[] _ primaryImpl.internalize [ NARROW[NARROW[node.isnode]], ie ];
END;
ENDCASE => BEGIN
ic: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: content[content: contentBuffer] ] ];
[] _ primaryImpl.internalize [ NARROW[NARROW[node.isnode]], ic ];
END;
temp _ contentBuffer; contentBuffer _ contentBuffer.next;
ENDLOOP;
END;
END;
ISNode.SetTag [NARROW[node.isnode], t.value]; AdvanceScan [scan];
END;
t: PushTVHandle => {square _ AnchorBindings[scan.bindingStack]; AdvanceScan [scan]}; 
t: PopTVHandle => {PruneBindings[scan.bindingStack, square]; AdvanceScan [scan]}; 
t: LeftCurlyTVHandle => BEGIN
child: NodeTVHandle;
AdvanceScan [scan]; 
child _ CollectNode [scan, NARROW[node.isnode]];
DO
WITH scan.stream.token SELECT FROM
n: NullTVHandle => AdvanceScan[scan];
o: OpenTVHandle => --Remove outer {} and splice innerds into input stream (macro expansion)--
BEGIN 
AdvanceScan[scan]; --Get rid of open--
scan.stream _ NEW[characters ScanStream _ [
name: NIL,
pushed: CopyScanStream[scan.stream],
body: characters [cstream: IO.RIS[ISTiogaIntern.PrintNodeContents[NARROW[child.isnode], FALSE]]]]];
AdvanceScan [scan]; -- prime the pump --
EXIT;
END;
ENDCASE => {
BufferOrCall [child];
EXIT;
};
ENDLOOP;
END; 
t: RightCurlyTVHandle => BEGIN
IF primaryImpl=NIL OR primaryImpl.internalize=NIL THEN BEGIN
-- was no dollar that was a primary impl --
ii: ISToken.InterscriptContext _ NEW[InterscriptContextObject _ [body: initial [parent] ] ];
primaryImpl _ ISNode.GetImplementation [( primaryTag_NIL), scan.family];
IF primaryImpl=NIL OR primaryImpl.internalize=NIL THEN ERROR;
--<<defaults not set>>--
NARROW[node.isnode, ISNode.Handle].printProc _ primaryImpl.printTioga;
primaryImpl.internalize [NARROW[node.isnode], ii];
WHILE contentBuffer#NIL DO 
temp: TVHandle;
WITH contentBuffer SELECT FROM
cb: NodeTVHandle => BEGIN
ie: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: embedded[content: cb] ] ];
[] _ primaryImpl.internalize [ NARROW[node.isnode], ie ];
END;
cb: StyleOpenTVHandle => BEGIN
ie: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: styleOpen[identifier: cb] ] ];
[] _ primaryImpl.internalize [ NARROW[node.isnode], ie ];
END;
ENDCASE => BEGIN
ic: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: content[content: contentBuffer] ] ];
[] _ primaryImpl.internalize [ NARROW[node.isnode], ic ];
END;
temp _ contentBuffer; contentBuffer _ contentBuffer.next;
ENDLOOP;
END;
IF contentBuffer#NIL THEN ERROR; --<<cleared just above or at dollar>>--
FOR c: ISNode.TagHandle _ NARROW[node.isnode, ISNode.Handle].tagThread, c.next UNTIL c=NIL DO 
ib: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: bindings[scan.bindingStack] ] ];
dimpl: ISNode.Implementation _ ISNode.GetImplementation [c.tag, scan.family];
NARROW[node.isnode, ISNode.Handle].tag _ c.tag;
IF dimpl#NIL AND dimpl.internalize#NIL THEN dimpl.internalize [ NARROW[node.isnode], ib ];
ENDLOOP;
BEGIN
ie: ISToken.InterscriptContext _ NEW[ ISToken.InterscriptContextObject _ [ body: end[] ] ];
[] _ primaryImpl.internalize [ NARROW[node.isnode], ie ];
END;
PruneBindings [scan.bindingStack, anchor];
ISTiogaIntern.localBindingLimit _ oldLocalLimit;
scan.stream.token _ NEW[null TVObject _ [body: null[]]];
-- not AdvanceScan [scan]: might be last node --
RETURN [node];
END;
ENDCASE => ERROR ParseFailure [scan, outOfPlaceConstruct];
ENDLOOP;
END;

SHORTINTEGER: PROC [p: LONG INTEGER] RETURNS [INTEGER] ~ INLINE {
IF p < FIRST[INTEGER] OR p > LAST[INTEGER] THEN ERROR;
RETURN[INTEGER[p]];
};

ObtainBindingIntegerOrZero: PUBLIC PROCEDURE [
name: ATOM,
stack: ISBinding.StackHandle]
RETURNS [INTEGER] = BEGIN
tv: TVHandle _ ObtainBinding [name, stack];
IF tv=NIL THEN RETURN [0];
WITH tv SELECT FROM 
tt: IntegerTVHandle => RETURN [SHORTINTEGER [tt.value]]; 
ENDCASE => RETURN [0];
END;

END.    


��ò��ISScanImpl.mesa
Copyright c 1985 by Xerox Corporation.  All rights reserved.
edit by Ayers  17-Jun-85 14:14:31  
Rick Beach, August 1, 1985 2:13:30 pm PDT
MKaplan, September 13, 1985 3:14:03 pm PDT
allocateWith: ISNode.Handle,

The publication encoding is ISO-646, which is eight bit characters. --
Although we extend this to allow for sixteen bit characters, via 377B --
shifts, within "<>" strings, the regular scanner does not have to deal with --
this, since the bytes inside the "<>" are gobbled up by special routines. --
Get: PROCEDURE [s: CharactersScanner] RETURNS [e: Basics.Byte] = INLINE 
{e _ Peek[s]; s.nextCharacter _ notACharacter};

GetGoodPeek: PROCEDURE [s: CharactersScanner] RETURNS [e: Basics.Byte] = INLINE 
{e _ s.nextCharacter; s.nextCharacter _ notACharacter};

UseUpPeek: PROCEDURE [s: CharactersScanner] = INLINE {s.nextCharacter _ notACharacter};

Peek: PROCEDURE [s: CharactersScanner] RETURNS [e: Basics.Byte] = INLINE BEGIN 
IF s.nextCharacter#notACharacter THEN RETURN [s.nextCharacter];
e _ s.nextCharacter _ GetByteAtOffset[s];
BumpStreamOffset[s];
RETURN;
END;

BumpStreamOffset: PROCEDURE [s: CharactersScanner] = INLINE BEGIN
s.byteInBuffer _ s.byteInBuffer + 1;
END;
GetByteAtOffset: PROCEDURE [s: CharactersScanner] RETURNS [Basics.Byte] = INLINE BEGIN
IF s.byteInBuffer>=ISScan.bufferBytes THEN
BEGIN
IF (s.runningAddress _ s.runningAddress + ISScan.bufferBytes/2) 
>= s.lastAddressPlusOne THEN SIGNAL ParseFailure [NIL, hitEndOfScript];
s.buffer _  s.runningAddress^;
s.byteInBuffer _ 0;
END;
RETURN [s.buffer[s.byteInBuffer] ];
END;
If the token in the stream that was just popped is not 'null' or eos then we assert that it has not been processed and return it.
t: characters TVObject _ [
body: characters [ value: [
offset: cs.byteInBuffer, 
limit: cs.byteInBuffer, 
bytes: LOOPHOLE[cs.runningAddress], 
context: XString.vanillaContext ] ] -- font supplied later -- ];
<<vanillaContext is correct because '< is in characterset zero>>--
always get here .. no RETURNs above --
DestroyEnvironment: PUBLIC PROCEDURE [at: REF ISBinding.EnvironmentHandle] = BEGIN
at.stack.zone.FREE[at];
garbage collect the other stuff when clinet destroys bindings --
END;

in case caller didn't
This can be uncommented if you want to look at properties with the EditTool (warning:  a couple of other places have to be changed... look for Rope.Concat's or Cat's having "." as an argument).
n: Rope.ROPE = Atom.GetPName[a];
FOR k: INT IN [0..Rope.Length[n]-1] DO
IF Rope.Fetch[n, k]='. THEN RETURN[Atom.MakeAtom[Rope.Concat[Rope.Substr[n, 0, k], Rope.Substr[n, k+1]]]];
ENDLOOP;
^^ knowing that the only difference between ISNode.Create[x] and -- 
ISNode.Create[y] is the atom stored into the type field --
scan advanced by CollectRHS: AdvanceScan [scan];
scan advanced by CollectRHS: AdvanceScan [scan];
scan advanced by CollectRHS: AdvanceScan [scan];
Look to see if the lhs is non-qualified (no '.').  If so, assume that this is a style definition and pass it to the node-impl.
BEGIN
dotTest: Rope.ROPE _ Atom.GetPName[theAtom];
FOR k: INT IN [0..Rope.Length[dotTest]-1] DO
IF Rope.Fetch[dotTest, k]='. THEN EXIT
REPEAT
FINISHED => GOTO Dotless;
ENDLOOP;
EXITS Dotless => BEGIN
sd: TVHandle _ NEW[styleDefinition TVObject _ [body: styleDefinition [
name: theAtom,
value: CopyOneTV[rhs]]]];
BufferOrCall [sd];
END;
END;
fall through having done opens until 'tvo' not an atom or no more opens --
^^ not NARROW[node.isnode] _ ISNode.Create [aa]; --
we know that the only difference between ISNode.Create[x] and -- 
ISNode.Create[y] is the atom stored into the type field --
feed to node-impl the content we had to remember while --
we didn't know what the impl was --
ISMessage.PutF["CollectNode: %g\n", IO.atom[t.value]];
--<<Make PourImpl do this: child.isnode.parent _ NARROW[node.isnode];>>--
Êí��˜�codešœ™Kšœ
Ïmœ1™<Kšœ#™#K™)K™*—K˜�šÏk	˜	Kšœ˜Kšœžœ˜$K˜
Kšœ
˜
Kšœ˜Kšœ˜Kšœ˜Kšœ˜KšœžœžÏc#œ˜5Kšžœžœžœžœžœžœ0Ÿœ˜u—K˜�KšÐln
œž
˜KšžœžœŸ
œ
˜<Kšžœ˜šœžœžœ˜K˜�Kšœžœžœ8žœ˜Xšœžœžœ'žœ˜IK˜�—Kšœ2žœ˜6Kšœ&žœ˜*K˜�Kšœžœžœžœ˜)K˜�Kšœ
žœŸ˜NK˜�šÏn
œžœž	œ˜Kšœžœ˜Kšœžœ˜K™Kšœ&žœ˜*Kšœžœžœ˜Kšžœž˜Kšœ žœ˜;Kšœžœ
˜"K˜�Kšœžœžœžœ	˜Dšžœ%˜'K˜�—Kšœ+ŸœŸœ˜Qšžœžœžœ6žœ˜TKšžœAžœ˜K—Kšžœ˜
Kšžœ˜—K˜�š¡œžœž	œž˜8šžœ
žœž˜Kš	œžœžœžœžœ˜6Kšžœžœ˜—Kšžœ˜Kšžœ˜——˜�š¡œžœž	œž˜DK˜šžœ
žœž˜˜Kšž˜šžœ
žœ˜Kšžœžœžœžœ˜BKšœžœ˜Kšžœ˜—Kšžœ˜—Kšžœžœ˜—Kšžœ˜Kšžœ˜Kšžœ˜—K™�KšœF™FKšœH™HKšœN™NKšœL™LK˜�š¡œž	œžœžœ™H™/K™�——š¡œž	œžœžœ™P™7K™�——Kš¡	œž	œžœ#™WK™�š
¡œž	œžœžœžœ™OKšžœžœžœ™?K™)K™Kšžœ™Kšžœ™K™�—š¡œž	œžœž™AK™$Kšžœ™——˜�š	¡œž	œžœžœž™Všžœ$ž™*Kšž™šžœ>™@Kšœžœžœžœ™G—K™K™Kšžœ™—Kšžœ™#Kšžœ™——˜�Kš
¡	œžœžœžœžœ˜9K˜�š¡œž	œ
žœžœžœžœžœžœž˜dK˜�Kšœžœžœ˜'Kšœžœ	žœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜K˜�šžœžœžœ
žœ˜0Kšœžœ˜#Kšœžœ
˜Kšžœ˜—Kšžœ	žœ
žœ"˜=Kš
žœžœžœžœžœ˜:Kšžœ˜šžœ˜K˜�——š¡œžœž˜5šžœŸ˜!šžœ
žœž˜K˜BKšœJ˜JKšžœžœŸ˜0—šž˜Kšœ#˜#šžœžœ˜-š	žœžœžœžœŸ˜5Kšœžœ˜&K˜Kšœ™Kšœ˜Kš
žœžœžœžœžœ˜CKšž˜——Kšžœžœ˜Kšžœ˜—Kšžœ˜—Kšžœ˜K˜�—š¡œž	œžœž˜Ušžœžœžœžœ˜8Kšžœ8˜<—KšœŸ&˜@Kšžœ˜šžœ˜K˜�——š¡œž	œžœž˜\Kšœžœ˜Kšœžœžœ˜Kšœžœžœ˜K˜�šžœŸ#˜&šœžœ˜Kšžœžœ˜(—šžœž˜šžœž˜Kš	œžœžœžœžœ˜FKšžœžœŸ ˜<Kšžœž˜——šžœ˜šžœžœž˜Kšžœžœ˜šžœžœžœžœžœŸ
œ˜5Kšœžœžœžœ˜-—Kšžœžœ˜——šž˜Kšœžœžœ˜5—šžœ˜K˜�—šžœžœŸC˜TKšžœ
˜šžœ
žœŸœŸA˜kKš	œžœžœžœžœ˜Kšœžœ˜Kšžœ˜š
žœžœžœ
žœžœ	˜=Kšžœžœ
Ÿ˜2šžœ	žœŸ3˜BKšžœžœ˜"—Kšžœ˜—š	žœ	žœžœžœž˜'KšŸC˜CK˜Kšœžœ0žœžœ˜YKšž˜—Kšžœžœ.žœžœ˜[Kšžœ˜—šœžœŸ˜™™K™K™Kšœžœ™$Kšœ$Ÿœ™@——KšœB™BKšœžœžœ˜#Kšœžœžœ˜šžœŸ!˜$Kšœžœžœ˜šžœžœ	ž˜Kšžœžœžœžœžœžœ˜;—Kš
žœžœžœžœžœ˜4Kšžœ˜—KšœžœLžœ ˜wKšžœ˜—šžœžœŸ˜!K˜0Kšœ:˜:Kšœžœ˜Kšžœ˜—Kšœžœ˜.Kšžœžœ˜5Kšœžœ˜.Kšœžœ$˜3Kšœžœ%˜4Kšœžœ˜.Kšœžœ ˜/Kšœžœ ˜/Kšœžœ˜.Kšžœžœ˜5Kšœžœ˜.Kšœžœ˜.šžœŸ+˜1Kšž˜Kšžœ
žœžœ4žœ˜Wšž˜Kšž˜Kšœžœ%˜FKšœ˜Kšœžœ˜šž˜Kšœ/˜/šžœžœ˜Kšœžœžœ˜<—šž˜Kšž˜Kšœ˜Kšœžœ7˜EKšžœ˜—Kšžœ˜—KšžœŸ
˜—Kšžœžœ˜KšžœŸ$˜)—Kšœžœ!˜0Kšœžœ˜.Kšœžœ˜-Kšžœžœžœ˜;—Kšœ&™&K˜Kšžœ˜Kšžœ˜——K˜�š
¡œžœž	œžœžœ˜>šžœžœ˜(Kšœžœ˜8Kš	œžœžœžœžœ˜?Kšžœ˜Kšžœ˜——K˜�š
¡œžœž	œžœžœ˜LKšœžœ˜Kšžœ˜—K˜�š¡œžœž	œ˜?Kšžœžœ˜/—K˜�š¡œžœž	œ˜Bšžœ!žœ˜.Kšœ"žœ˜CK˜K˜Kšžœ˜Kšžœ˜K˜�——š¡œžœž	œ.ž˜SK˜!Kšœ+Ÿ˜@Kšžœ˜K˜�—š	¡œžœž	œžœ!ž˜PK˜5Kšœžœ˜KšœžœŸ˜.Kšžœ˜Kšžœ˜—K˜�š	¡œžœž	œžœ ž™RKšœžœ™Kšœ@™@Kšžœ™K™�—š¡
œžœž	œ=ž˜aKšœŸ%˜6Kšžœ˜šžœ˜K˜�——š	¡œžœž	œ	žœ3ž˜fKšœžœ˜/Kšœ:˜:Kšœ˜Kšžœ˜šžœ˜K˜�——š¡
œžœž	œžœ žœž˜fšžœ3žœžœž˜GKšžœžœžœ˜+Kšžœ˜—Kšžœžœ˜
Kšžœ˜—˜�š¡œž	œžœ
žœžœž˜Ušžœžœž˜Kšœžœ˜>Kšœžœ˜6Kšžœžœ˜—Kšž˜Kšžœ˜K˜�—Kš¡	œž	œžœž˜Ašžœžœž˜Kšœžœ˜/Kšœžœ˜>Kšœžœ˜>Kšœžœ˜=Kšœžœ˜5Kšœžœ˜/Kšœžœ˜3Kšœžœ˜3Kšœžœ˜;Kšœžœ˜/Kšœžœ˜1Kšœžœ˜1Kšœžœ˜3Kšœžœ˜/Kšœžœ˜/Kšœžœ˜9Kšœžœ˜;Kšœžœ˜/Kšœžœ˜-Kšœžœ˜/Kšœ žœ˜?Kšœžœ˜9Kšœ#žœ˜E—Kšžœ˜Kšžœ˜Kšžœ˜—K˜�š¡
œž	œžœž˜CKšœ
žœžœ˜!K˜�šžœžœ˜#Kšœ˜Kšžœžœ˜Kšœ™—šžœžœ˜#KšœŸœ˜<Kšœžœ˜3Kšžœžœ˜—šžœž˜"šœž˜Kšœ˜Kšœžœ˜*K˜Kšœ(žœ˜.šž˜šžœž˜"K˜%šœŸJ˜]Kšžœ˜KšœŸ˜&šœžœ˜+Kšœžœ˜
K˜$Kš	œžœžœ!žœžœ˜cKšœŸ˜(Kšžœ˜—Kšžœ˜—šžœ˜Kšœ-˜-Kšžœ˜K˜——Kšžœ˜—Kšžœ˜Kšžœ˜—šœž˜Kšœ˜K˜šžœž˜"šœž˜
K˜JK˜šžœžœž˜šœŸ ˜5šœžœ˜+K˜K˜$Kšœžœžœ!žœ˜XKšœŸ˜(Kšžœ˜—K˜—Kšžœžœžœžœžœ	žœ˜2—Kšžœ˜—Kšžœžœ˜—Kšžœ˜—šœž˜Kšœ˜K˜Kšžœ
žœ˜+K˜K˜#šžœ
ž˜Kšœžœ˜Kšžœžœ˜—˜Kšž˜K˜$šžœž˜šœž˜šžœ
ž˜K˜+K˜+K˜*Kšžœžœ˜Kšžœ˜
Kšžœ˜——Kšžœžœ*˜:—Kšž˜—Kšžœ˜—Kšžœ=žœ˜R——Kšžœ˜K˜�K™Áš
¡	œžœžœžœžœ˜,Kšœžœ™ šžœžœžœž™&KšžœžœžœH™jKšžœ™—Kšžœ˜
Kšœ˜K˜�—š¡œžœž	œ.žœ	žœžœžœž˜…Kšœžœ˜(Kšœ%žœ˜)Kšœžœžœ˜K˜ K˜KšœŸA˜[Kšœžœ˜Kšœ žœ˜$K˜�š¡œŸ	œž	œž˜9šžœ
žœž
˜šžœžœž˜šœ˜Kšž˜Kšœ!žœF˜jKšœžœ˜9Kšžœ˜—šœ˜Kšž˜Kšœ!žœK˜oKšœžœ˜9Kšžœ˜—šœ˜Kšž˜Kšœ!žœQ˜uKšœžœ˜9Kšžœ˜—šžœ˜Kšž˜Kšœ!žœG˜kKšœžœ˜9Kšžœ˜——Kšž˜—šž˜Kšž˜Kšœ ˜ šžœžœž˜K˜=—Kšžœ,˜0Kšžœ˜—Kšžœ˜—K˜�K˜KšœŸœ˜5KšœD™DKšœ:™:K˜�K˜,Kšœ0˜0Kšœ*Ÿ
˜7šž˜šžœžœž˜"Kšœ&Ÿ3˜YKšœžœ$˜=šœ˜Kšž˜Kšœžœ Ÿ/˜bK˜Kšœ0™0Kšžœ˜—šœ˜Kšž˜Kšœžœ Ÿ/˜bK˜Kšœ0™0Kšžœ˜—šœ˜Kšž˜Kšœžœ Ÿ/˜bK˜Kšœ0™0Kšžœ˜—šœ˜Kšž˜K˜+Kšœ	žœ˜K˜šžœžœž˜"šœž˜Kšœžœ˜2KšœI˜IKšœ~™~šž™Kšœžœ™,šžœžœžœž™,Kšžœžœž™&Kšž™Kšžœžœ	™Kšžœ™—šžœž™Kšœžœ]™oK™Kšžœ™—Kšžœ™—Kšžœ˜—šœž˜Kšœ
žœ˜KšœžœŸ˜GKšžœžœžœ*žœ˜GšžœŸ(˜+šžœžœžœŸ(˜=šœ˜šžœžœž˜"šœž˜K˜EKšœŸœ˜(Kš
žœžœžœ	žœžœ˜.KšžœŸ8˜=—Kšžœžœ˜——Kšžœžœ˜—šž˜Kšœžœ˜—Kšžœ˜	—KšœJ™Jšžœžœžœ˜šœŸ.˜Bšž˜šœžœ˜+K˜K˜$Kšœžœžœ!žœ˜YKšœŸ˜(—Kšžœ˜——šœ˜Kšž˜šœžœ˜'K˜K˜$K˜%—šžœŸ(˜.Kšœžœ9˜KK˜Kšžœ˜—KšœŸ˜(Kšžœ˜—Kšœ(Ÿ)˜QKšžœžœ˜—KšžœŸ
˜—šžœŸ˜(Kšœžœ/˜EKšœ˜——KšžœŸ
˜—šœž˜K˜!K˜Kšžœ˜—KšœL˜Lšœ˜Kšž˜šžœ
žœž˜KšžœŸ.˜4K˜Lšžœžœžœ ž
˜7KšŸ˜Kšœ!žœB˜fK˜'Kšžœ.˜4Kšœžœ&™3KšœA™AKšœ:™:Kšžœ@˜FKšœžœ˜4Kšœ9™9Kšœ#™#šžœžœžœ˜K˜šžœžœž˜šœž˜Kšœ!žœG˜kKšœžœ˜9Kšžœ˜—šœž˜Kšœ!žœK˜oKšœžœžœ˜AKšžœ˜—šžœž˜Kšœ!žœQ˜uKšœžœžœ˜AKšžœ˜——K˜9Kšžœ˜—Kšžœ˜—Kšžœ˜—Kšœžœ,˜AKšœ$žœ™6Kšžœ˜—KšœU˜UKšœR˜Ršœž˜Kšœ˜K˜Kšœžœ˜0KšŸ1žœŸœŸ™Išž˜šžœž˜"K˜%šœŸJ˜]Kšžœ˜KšœŸ˜&šœžœ˜+Kšœžœ˜
K˜$Kš	œžœžœ!žœžœ˜cKšœŸ˜(Kšžœ˜—Kšžœ˜—šžœ˜Kšœ˜Kšžœ˜K˜——Kšžœ˜—Kšžœ˜—šœž˜š	žœ
žœžœžœž
˜<KšŸ+˜+Kšœ!žœ8˜\Kšœ5žœ˜HKš
žœ
žœžœžœžœžœŸ˜VKšžœ@˜FKšœžœ˜2šžœžœžœ˜K˜šžœžœž˜šœž˜Kšœ!žœG˜kKšœžœ˜9Kšžœ˜—šœž˜Kšœ!žœK˜oKšœžœ˜9Kšžœ˜—šžœž˜Kšœ!žœQ˜uKšœžœ˜9Kšžœ˜——K˜9Kšžœ˜—Kšžœ˜—Kš	žœžœžœžœŸ'˜Hš
žœžœ/žœžœžœ˜^Kšœ!žœM˜qK˜MKšžœ)˜/Kšžœžœžœžœžœžœ˜ZKšžœ˜—šž˜Kšœ!žœ7˜[Kšœžœ˜9Kšžœ˜—K˜*Kšœ0˜0Kšœžœ"Ÿ0˜iKšžœ˜Kšžœ˜—Kšžœžœ*˜:—Kšžœ˜—Kšžœ˜K˜�—šžœžœžœžœžœžœžœ˜AKšžœžœžœžœžœžœžœžœ˜6Kšžœžœ˜K˜K˜�—š
¡œžœž	œ	žœžœžœž˜r˜+Kšžœžœžœžœ˜šžœžœžœ˜Kšœžœžœ˜9Kšžœžœ˜—Kšžœ˜K˜�——Kšžœ˜—K˜�K˜�—�…—����Wj��„I��