"St80Sources.V00 (16 December 1980 4:31:56 pm )"
"82" Association$'As yet unclassified'
[key: t1 value: t2 | |
	key ← t1.
	value ← t2].
"66" Association$'As yet unclassified'
[value← val | |
	↑value ← val].
"51" Association$'As yet unclassified'
[key | |
	↑key].
"112" Association$'As yet unclassified'
[printon: strm | |
	strm print: key.
	strm append: '->'.
	strm print: value].
"55" Association$'As yet unclassified'
[value | |
	↑value].
"66" SymbolTable$'Insertion'
[ name ← x | |
	↑super  name value← x].
"74" SymbolTable$'Access to parts'
[ref: name ← val | |
	↑super  name ← val].
"61" SymbolTable$'Searching'
[ name | |
	↑(super  name) value].
"245" SymbolTable$'Growing and shrinking'
[growto: size | name copy |
	copy ← self class new init: size "create a copy of the new size".
	self do: [:name | copy insert: name withref: (self ref: name)].
	self copyfrom: copy "hash each entry into it"].
"204" SymbolTable$'Insertion'
[declare: name as: x | a s |
	(name is: Vector)
	  ifTrue:
		[s ← x asStream.
		name do: [:a | self declare: a as: s next]]
	  ifFalse:
		[self declare: name.
		self  name ← x]].
"84" UserView$'As yet unclassified'
[primEIANext← char | |<primitive: 75>
	↑self croak].
"135" Bitmap$'As yet unclassified'
[ x ← val | |<primitive: 18>
	NoteTaker
	  ifTrue: [user croak]
	  ifFalse: [↑self instfield: x ← val]].
"162" Bitmap$'As yet unclassified'
[fromStream: strm | i hi lo |
	(1 to: self length) do:
		[:i | hi ← strm next.
		lo ← strm next.
		self  i ← (hi lshift: 8) + lo]].
"123" Bitmap$'As yet unclassified'
[ x | |<primitive: 17>
	NoteTaker
	  ifTrue: [user croak]
	  ifFalse: [↑self instfield: x]].
"151" Bitmap$'As yet unclassified'
[toStream: strm | i |
	(1 to: self length) do:
		[:i | strm next← self  i lshift: 8.
		strm next← self  i land: 255]].
"111" Bitmap$'As yet unclassified'
[printon: strm | |
	strm append: 'a Bitmap of length '.
	strm print self length].
"137" Bitmap$'As yet unclassified'
[fromString: s | i |
	(1 to: self length) do: [:i | self  i ← s  (i + i) + (s  (i + i - 1) lshift: 8)]].
"512" ClassOrganizer$'Conversion to text'
[fromParagraph: para | t i j g |
	user displayoffwhile [
		(t ← para asVector.
		self globalComment← t  1.
		commentVector ← Vector new: t length - 1.
		groupVector ← Vector new: t length - 1.
		(1 to: t length - 1) do:
			[:i | g ← t  (i + 1).
			commentVector  i ← g  1.
			[0 = (j ← g find: #←)] whileFalseDo:  [ "reconstitute ← suffixes"
				g ← g replace: j - 1 to: j by: (g  (j - 1) + '←') unique inVector].
			groupVector  i ← (g copy: 2 to: g length) sort])]].
"344" ClassOrganizer$'Access to parts'
[delete: selector | i |
	 "delete this from all categories"
	(1 to: groupVector length) do:
		[:i | (groupVector  i has: selector)
		  ifTrue:
			[groupVector  i ← groupVector  i delete: selector.
			((groupVector  i) length = 0 and: [commentVector  i = default])
			  ifTrue: [self deleteCategory: i]]]].
"151" ClassOrganizer$'Access to parts'
[asStream | v t |
	v ← Stream new of: (Vector new: 200).
	groupVector do: [:t | v append: t].
	↑v contents asStream].
"251" ClassOrganizer$'Conversion to text'
[asParagraph | s i |
	s ← Stream default.
	s print: self globalComment.
	(1 to: commentVector length) do:
		[:i | s cr.
		s print: ((commentVector  i) inVector concat: groupVector  i)].
	↑s contents asParagraph].
"685" ClassOrganizer$'Access to parts'
[classify: selector under: heading | s h n |
	(selector is: Vector)
	  ifTrue: [selector do: [:s | self classify: s under: heading]]
	  ifFalse:
		[s ← commentVector find: heading.
		(s > 0 and: [(groupVector  s has: selector)])
		  ifTrue: [↑self].
		(h ← self invert: selector)
		  ifTrue:
			[heading = default
			  ifTrue: [↑self].
			n ← commentVector find: h.
			groupVector  n ← groupVector  n delete: selector].
		s = 0
		  ifTrue: [s ← self insert: heading].
		groupVector  s ← groupVector  s insertSorted: selector.
		n ← commentVector find: default.
		(n > 0 and: [(groupVector  n) length = 0])
		  ifTrue: [self deleteCategory: n]]].
"120" ClassOrganizer$'Access to parts'
[globalCommentItself | |
	↑globalComment "used only by Class archiveOn:changesOnly:"].
"82" ClassOrganizer$'Initialization'
[classInit | |
	default ← 'As yet unclassified'].
"174" ClassOrganizer$'Access to parts'
[invert: selector | i |
	(1 to: groupVector length) do:
		[:i | (groupVector  i has: selector)
		  ifTrue: [↑commentVector  i]].
	↑false].
"119" ClassOrganizer$'Access to parts'
[has: sel | t |
	groupVector do:
		[:t | (t has: sel)
		  ifTrue: [↑true]].
	↑false].
"200" ClassOrganizer$'Initialization'
[init: sortedVec | |
	self globalComment← 'This class has not yet been commented'.
	commentVector ← 'As yet unclassified' inVector.
	groupVector ← sortedVec inVector].
"177" ClassOrganizer$'Access to parts'
[category: str | i |
	i ← commentVector find: str.
	i = 0
	  ifTrue: [user notify: 'No such category: ' + str]
	  ifFalse: [↑groupVector  i]].
"87" ClassOrganizer$'Access to parts'
[globalComment | |
	↑globalComment asParagraph text].
"67" ClassOrganizer$'Access to parts'
[categories | |
	↑commentVector].
"488" ClassOrganizer$'Access to parts'
[insert: heading | di dgroup hi |
	 "force default category to end, delete if empty"
	(di ← commentVector find: default) > 0
	  ifTrue: [dgroup ← groupVector  di].
	commentVector ← {(commentVector without: di) , heading}.
	groupVector ← {(groupVector without: di) , (Vector new: 0)}.
	hi ← commentVector length.
	(di = 0 or: [dgroup length = 0])
	  ifTrue: [↑hi].
	commentVector ← {commentVector , default}.
	groupVector ← {groupVector , dgroup}.
	↑hi].
"151" ClassOrganizer$'Access to parts'
[deleteCategory: index | |
	groupVector ← groupVector without: index.
	commentVector ← commentVector without: index].
"108" ClassOrganizer$'Access to parts'
[globalComment← t1 | |
	 "String or RemoteParagraph"
	globalComment ← t1].
"142" RemoteParagraph$'As yet unclassified'
[fromParagraph: p | |
	self position← file position "write me (only once!) on file".
	p storeOn: file].
"94" RemoteParagraph$'As yet unclassified'
[position | |
	↑hipos + 1000 * 2000 + (lowpos + 1000)].
"148" RemoteParagraph$'As yet unclassified'
[position← p | |
	p ← p intdiv: 2000.
	hipos ← (p  1) asInteger - 1000.
	lowpos ← (p  2) asInteger - 1000].
"94" RemoteParagraph$'As yet unclassified'
[fromString: s | |
	self fromParagraph: s asParagraph].
"60" Paragraph$'Text alignment'
[flushright | |
	alignment ← 4].
"336" Paragraph$'Manipulation of format runs'
[makerun: len val: val | str i |
	 "Make up a solid run of value val"
	len = 0
	  ifTrue: [↑nullString].
	str ← String new: len - 1 / 255 + 1 * 2.
	(1 to: str length by: 2) do:
		[:i | str  i ← (len > 255
		  ifTrue: [255]
		  ifFalse: [len]).
		str  (i + 1) ← val.
		len ← len - 255].
	↑str].
"48" Paragraph$'Normal access'
[ x | |
	↑text  x].
"99" Paragraph$'Manipulation of format runs'
[runcat: x to: y | |
	↑self runcat: x and: [y] and: ['']].
"446" Paragraph$'Manipulation of format runs'
[run: a to: b | c |
	 "subrange of run"
	a > b
	  ifTrue: [↑nullString].
	runs  nil
	  ifTrue: [↑self makerun: 1 + b - a val: 0].
	a ← self runfind: a.
	b ← self runfind: b.
	c ← runs copy: a  1 to: b  1 + 1 "copy the sub-run".
	a  1 = (b  1)
	  ifTrue: [c  1 ← 1 + (b  2) - (a  2)]
	  ifFalse:
		[c  1 ← 1 + (runs  (a  1)) - (a  2) "trim the end lengths".
		c  (c length - 1) ← b  2].
	↑c].
"57" Paragraph$'Text alignment'
[justify | |
	alignment ← 1].
"504" Paragraph$'Normal access'
[replace: a to: b by: c | |
	 "alters self - doesnt copy"
	(runs  nil and: [(c isnt: self class)])
	  ifFalse: [runs ← self runcat: (self run: 1 to: a - 1) and: [((c is: self class)
				  ifTrue: [c runs]
				  ifFalse: [self makerun: c length val: (runs empty
					  ifTrue: [0]
					  ifFalse: [runs  ((self runfind: b)  1 + 1)])])] and: [(self run: b + 1 to: text length)]].
	text ← text replace: a to: b by: ((c is: self class)
			  ifTrue: [c text]
			  ifFalse: [c])].
"52" Paragraph$'Normal access'
[asParagraph | |
	↑self].
"185" Paragraph$'Normal access'
[copy: a to: b | |
	 "Return a copied subrange of this paragraph"
	↑self class new text: (text copy: a to: b) runs: (self run: a to: b) alignment: alignment].
"84" Paragraph$'Manipulation of format runs'
[allBold | |
	self maskrunsunder: 1 to: 1].
"86" Paragraph$'Manipulation of format runs'
[allItalic | |
	self maskrunsunder: 2 to: 2].
"161" Paragraph$'Filing'
[storeOn: file | |
	file nextString← text.
	runs  nil
	  ifTrue: [file next← 0]
	  ifFalse: [file nextString← runs].
	file next← alignment].
"45" Paragraph$'Normal access'
[text | |
	↑text].
"58" Paragraph$'Normal access'
[asVector | |
	↑text asVector].
"154" Paragraph$'Manipulation of format runs'
[runs | |
	 "return runs or default if none"
	runs  nil
	  ifTrue: [↑self makerun: text length val: 0].
	↑runs].
"835" Paragraph$'Manipulation of format runs'
[runcat: r1 and: r2 and: r3 | i r olen len oc c nr |
	nr ← Stream new "concatenate and compact 3 runs" of: (String new: 30).
	oc ← false.
	(1 to: 3) do:
		[:i | r ← (i = 1
				  ifTrue: [r1]
				  ifFalse:
					[i = 2
					  ifTrue: [r2]
					  ifFalse: [r3]]).
		r length = 0
		  ifFalse:
			[r ← r asStream.
			[len ← r next] whileTrueDo:
				[c ← r next.
				len = 0
				  ifFalse:
					[ "ignore empty runs (shouldn't be any)"
					oc = c
					  ifTrue:
						[(olen ← olen + len)  255
						  ifFalse:
							[nr next← 255.
							nr next← oc.
							olen ← olen - 255]]
					  ifFalse:
						[oc
						  ifTrue:
							[nr next← olen.
							nr next← oc] "first time thru".
						olen ← len.
						oc ← c]]]]].
	oc
	  ifTrue:
		[nr next← olen "leftovers".
		nr next← oc].
	↑nr contents].
"919" Paragraph$'Bravo conversions'
[bravoRuns: s | i old len dif new bit bits |
	 "Encode the runs in a Bravo paragraph trailer onto a Stream"
	s append:  "assume Ctrl-Z is already there"
	(alignment = 1
	  ifTrue: ['j\g']
	  ifFalse:
		[alignment = 2
		  ifTrue: ['c\g']
		  ifFalse: ['\g']]).
	runs  nil
	  ifFalse:
		[len ← 0.
		old ← 256.
		bits ← #(1 2 4 ).
		(1 to: runs length by: 2) do:
			[:i | dif ← old lxor: (new ← runs  (i + 1)).
			(dif land: 247) = 0
			  ifTrue: [ "No changes"
				len ← len + (runs  i)]
			  ifFalse:
				[i = 1
				  ifFalse: [len printon: s].
				(1 to: 3) do:
					[:bit | (dif land: bits  bit) = 0
					  ifFalse: [s next← ((new land: bits  bit)  0
						  ifTrue: ['biu']
						  ifFalse: ['BIU'])  bit]].
				(dif land: 240)  0
				  ifTrue:
					[ "Font change"
					s append: 'f'.
					s print: (new lshift: 4).
					s space].
				old ← new.
				len ← runs  i]]].
	s cr].
"94" Paragraph$'Initialization of parts'
[text: t1 alignment: t2 | |
	text ← t1.
	alignment ← t2].
"303" Paragraph$'Press printing'
[hideData: complete | s |
	s ← Stream new of: (String new: 150).
	s next← complete.
	complete = 0
	  ifTrue: [s nextword← text length]
	  ifFalse: [s nextString← text].
	s nextString← (runs  nil
	  ifTrue: [nullString]
	  ifFalse: [runs]).
	s next← alignment.
	↑s contents].
"49" Paragraph$'Press printing'
[pressCode | |
	↑99].
"59" Paragraph$'Text alignment'
[flushleft | |
	alignment ← 0].
"54" Paragraph$'Normal access'
[length | |
	↑text length].
"108" Paragraph$'Normal access'
[findString: str startingAt: start | |
	↑text findString: str startingAt: start].
"108" Paragraph$'Initialization of parts'
[copy | |
	↑self class new text: text runs: runs alignment: alignment].
"184" Paragraph$'Press printing'
[hidePress: press complete: c | |
	press skipcode: self pressCode "not called by Form-Path-Image, but probably by Class printout" data: (self hideData: c)].
"58" Paragraph$'Normal access'
[asStream | |
	↑text asStream].
"372" Paragraph$'Manipulation of format runs'
[maskrun: i to: j under: m to: val | r k |
	 "Alter my runs so that the bits selected by m become val." "Maybe merge this with mergestyle"
	r ← self run: i to: j.
	(2 to: r length by: 2) do: [:k | r  k ← (r  k land: 255 - m) + val].
	runs ← self runcat: (self run: 1 to: i - 1) and: [r] and: [(self run: j + 1 to: text length)]].
"79" StyleSheet$'As yet unclassified'
[NoteTakerize | x |
	(fontset  0) NTformat].
"74" StyleSheet$'Access to Parts'
[font: fontindex | |
	↑fontset  fontindex].
"54" StyleSheet$'Access to Parts'
[tabsize | |
	↑tabsize].
"56" StyleSheet$'Access to Parts'
[linelead | |
	↑linelead].
"52" StyleSheet$'Access to Parts'
[effect | |
	↑effect].
"235" StyleSheet$'Initialization'
[fontset: t1 lineheight: t2 linelead: t3 baseline: t4 tabsize: t5 spacesize: t6 effect: t7 | |
	fontset ← t1.
	lineheight ← t2.
	linelead ← t3.
	baseline ← t4.
	tabsize ← t5.
	spacesize ← t6.
	effect ← t7].
"86" StyleSheet$'Access to Parts'
[fontfamily: fontindex | |
	↑fontset family: fontindex].
"82" StyleSheet$'Access to Parts'
[fontsize: fontindex | |
	↑fontset size: fontindex].
"60" StyleSheet$'Access to Parts'
[lineheight | |
	↑lineheight].
"56" StyleSheet$'Access to Parts'
[baseline | |
	↑baseline].
"192" StyleSheet$'Initialization'
[fontset: t1 | |
	fontset ← t1.
	self fontset: fontset lineheight: fontset height linelead: 0 baseline: fontset baseline tabsize: 32 spacesize: 4 effect: storing].
"58" StyleSheet$'Access to Parts'
[spacesize | |
	↑spacesize].
"159" Object$'System Primitives'
[performDangerously: selector with: arg1 with: arg2 with: arg3 | |<primitive: 36>
	 "selector had better take 3 args"
	user croak].
"162" Object$'System Primitives'
[messageNotUnderstood: op withArgs: args from: sender | |
	thisContext sender← sender.
	user notify: 'Message not understood: ' + op].
"322" Object$'Printing'
[printon: strm | t |
	strm append: (self  nil
	  ifTrue: ['nil']
	  ifFalse:
		[self  false
		  ifTrue: ['false']
		  ifFalse:
			[self  true
			  ifTrue: ['true']
			  ifFalse:
				[t ← self class title.
				strm append: (('AEIO' has: t  1)
				  ifTrue: ['an ']
				  ifFalse: ['a ']).
				t]]])].
"120" Object$'Construction'
[asVector | v |
	self  nil
	  ifTrue: [↑Vector new: 0].
	v ← Vector new: 1.
	v  1 ← self.
	↑v].
"81" Object$'Compiler Defaults'
[argsOff: stack | |
	self
	  ifTrue: [stack pop: 1]].
"124" Object$'System Primitives'
[nail | |
	NoteTaker
	  ifFalse: [↑self Altonail] "Nail me in core and return my core address"].
"54" Object$'Compiler Defaults'
[remote: generator | |
	].
"113" Object$'Compiler Defaults'
[printon: strm indent: level precedence: p forValue: v decompiler: decompiler | |
	].
"132" Object$'System Primitives'
[nextInstance | |<primitive: 82>
	 "return next in enumeration of my class, false if done"
	user croak].
"56" Object$'Aspects'
[hash | |<primitive: 39>
	user croak].
"74" Object$'Aspects'
[title | |
	↑self class title + '.' + self asOop base8].
"125" Object$'Construction'
[copy | |
	 "create new copy of self"
	(self is: Object)
	  ifTrue: [↑self].
	↑self class copy: self].
"64" Object$'Aspects'
[instfield: n | |<primitive: 37>
	user croak].
"85" Object$'Aspects'
[canunderstand: selector | |
	↑self class canunderstand: selector].
"145" Object$'Compiler Defaults'
[notify: errorString at: position in: stream | |
	↑self notify: errorString at: position in: stream for: self class].
"52" Object$'Classification'
[species | |
	↑self class].
"57" Object$'Printing'
[print | |
	user show: self asString].
"83" Object$'Aspects'
[ref: index | |
	↑FieldReference new object: self offset: index].
"64" Object$'Classification'
[class | |<primitive: 24>
	user croak].
"64" Object$'Classification'
[isnt: x | |
	↑self class  x  false].
"63" Object$'Construction'
[asStream | |
	↑self asVector asStream].
"57" Object$'Aspects'
[asOop | |<primitive: 39>
	user croak].
"47" Object$'Classification'
[isArray | |
	↑false].
"48" Rectangle$'Aspects'
[rightside | |
	↑corner x].
"110" Rectangle$'Conversion'
[printon: strm | |
	strm print: origin.
	strm append: ' rect: '.
	strm print: corner].
"61" Rectangle$'Altering'
[growby: pt | |
	corner ← corner + pt].
"45" Rectangle$'Aspects'
[hash | |
	↑super hash].
"71" Rectangle$'Arithmetic'
[has: pt | |
	↑origin  pt and: [pt < corner]].
"87" Rectangle$'Initialization'
[copy | |
	↑origin copy "new rectangle" rect: corner copy].
"50" Rectangle$'Aspects'
[size | |
	↑corner - origin].
"52" Rectangle$'Altering'
[growto: t1 | |
	corner ← t1].
"111" Rectangle$'Conversion'
[bitmapLength | extent |
	extent ← corner - origin.
	↑extent y * (extent x + 15 / 16)].
"124" Rectangle$'Arithmetic'
[max: rect | |
	↑Rectangle new origin: (origin min: rect origin) corner: (corner max: rect corner)].
"62" Rectangle$'Arithmetic'
[empty | |
	↑origin < corner  false].
"62" Rectangle$'Image'
[comp | |
	self color: black mode: xoring].
"43" Rectangle$'Aspects'
[minX | |
	↑origin x].
"43" Rectangle$'Aspects'
[minY | |
	↑origin y].
"43" Rectangle$'Aspects'
[maxY | |
	↑corner y].
"43" Rectangle$'Aspects'
[maxX | |
	↑corner x].
"342" Rectangle$'Altering'
[maxstretch: bound | bx by boundr selfr |
	bx ← (bound corner - origin) x.
	by ← (bound corner - origin) y.
	boundr ← bx asFloat / by.
	selfr ← self width asFloat / self height.
	selfr > boundr
	  ifTrue: [self extent← bx  (bx asFloat / selfr) asInteger]
	  ifFalse: [self extent← (by asFloat * selfr) asInteger  by]].
"45" Rectangle$'Aspects'
[bottom | |
	↑corner y].
"130" Rectangle$'Conversion'
[hardcopy: pf thickness: th | r |
	((self inset: 0 - th) minus: self) do: [:r | pf showrect: r color: 0]].
"145" Rectangle$'Arithmetic'
[include: r | |
	 "Returns the merge with an adjacent rectangle."
	↑(origin min: r origin) rect: (corner max: r corner)].
"120" Rectangle$'Arithmetic'
[nearest: pt | |
	↑((origin x max: pt x) min: corner x)  ((origin y max: pt y) min: corner y)].
"115" Rectangle$'Border'
[outline: thick | t |
	t ← 1  1 * thick.
	(self inset: t) clear: black.
	self clear: white].
"83" Rectangle$'Border'
[outline | |
	 "default border is two thick"
	self outline: 2].
"155" Rectangle$'Aspects'
[corners | v |
	v ← Vector new: 4.
	v  1 ← origin.
	v  2 ← corner x  origin y.
	v  3 ← corner.
	v  4 ← origin x  corner y.
	↑v].
"104" Rectangle$'Aspects'
[height← h | |
	 "change my bottom y to make my height h"
	corner y← origin y + h].
"51" Rectangle$'Aspects'
[origin← t1 | |
	origin ← t1].
"51" Rectangle$'Aspects'
[corner← t1 | |
	corner ← t1].
"78" Rectangle$'Aspects'
[extent← extent | |
	corner ← origin + extent.
	↑extent].
"184" Rectangle$'Altering'
[dragto: dest | v i |
	self blt: dest mode: storing.
	v ← dest rect: dest + self extent.
	(self minus: v) do: [:i | i clear].
	origin ← dest.
	corner ← v corner].
"84" Rectangle$'Altering'
[moveto: pt | |
	corner ← corner + pt - origin.
	origin ← pt].
"389" Rectangle$'Border'
[boxcomp | t1 |
	 "paints a border withoud disturbing interior"
	(t1 ← Rectangle new origin: origin - (2  2) corner: corner x + 2  origin y) color: black mode: xoring.
	t1 moveto: origin x - 2  corner y.
	t1 color: black mode: xoring.
	t1 origin← corner x  (origin y - 2).
	t1 color: black mode: xoring.
	t1 moveto: origin - (2  2).
	t1 color: black mode: xoring].
"84" Rectangle$'Altering'
[moveby: pt | |
	origin ← origin + pt.
	corner ← corner + pt].
"485" Rectangle$'Initialization'
[fromuser | t |
	origin ← OriginCursor showwhile [ "Show the origin cursor until the user presses a mouse button,
		then get my origin"
				(user waitbug)] "Show the corner cursor and complement me until the user presses
		a button again.  The loop is arranged so 
		that complementing stays on for a little while.".
	t ← origin.
	CornerCursor showwhile [([corner ← t.
		t ← user mpnext] whileTrueDo:
			[self comp.
			t ← t max: origin.
			self comp])]].
"55" Rectangle$'Aspects'
[width | |
	↑corner x - origin x].
"94" Rectangle$'Image'
[clear | |
	 "default is backround"
	self color: background mode: storing].
"69" Rectangle$'Image'
[comp: color | |
	self color: color mode: xoring].
"450" Rectangle$'Aspects'
[side: side | |
	 "Returns one side as a rectangle." "Sides are numbered 0-3.  +1 goes counterclockwise.  Xor: 2 gets opposite side."
	side = 0
	  ifTrue: [↑origin rect: corner x "top"  origin y].
	side = 1
	  ifTrue: [↑origin rect: origin x "left"  corner y].
	side = 2
	  ifTrue: [↑origin x "bottom"  corner y rect: corner].
	side = 3
	  ifTrue: [↑corner x "right"  origin y rect: corner].
	.
	user notify: 'Invalid side'].
"54" Rectangle$'Image'
[flash | |
	self comp.
	self comp].
"352" Rectangle$'Aspects'
[edge: side | |
	 "Returns one side as a number." "Sides are numbered 0-3.  +1 goes counterclockwise.  lxor: 2 gets opposite side."
	side = 0
	  ifTrue: [↑origin y "top"].
	side = 1
	  ifTrue: [↑origin x "left"].
	side = 2
	  ifTrue: [↑corner y "bottom"].
	side = 3
	  ifTrue: [↑corner x "right"].
	.
	user notify: 'Invalid side'].
"65" Rectangle$'Image'
[reverse | |
	self color: black mode: xoring].
"390" Rectangle$'Altering'
[usermove: bound | m lim |
	lim ← bound corner - self extent.
	self bordercomp.
	m ← user mp.
	[true] whileTrueDo:
		[user redbug
		  ifTrue:
			[self bordercomp.
			self moveto: (bound origin max: ((m ← user mp) min: lim)).
			self bordercomp].
		[user anybug and: [m = user mp]] whileTrueDo: [].
		user bluebug
		  ifTrue:
			[user waitnobug.
			↑self bordercomp]]].
"590" Rectangle$'Altering'
[usersize: bound | m lim |
	self origin  nil
	  ifTrue:
		[origin ← user mp.
		self extent← 16].
	self bordercomp.
	m ← user mp.
	[true] whileTrueDo:
		[lim ← bound corner - self extent.
		user redbug
		  ifTrue:
			[self bordercomp.
			self moveto: (bound origin max: ((m ← user mp) min: lim)).
			self bordercomp].
		user yellowbug
		  ifTrue:
			[self bordercomp.
			corner ← m ← (user mp min: bound corner) max: origin.
			self bordercomp].
		[user anybug and: [m = user mp]] whileTrueDo: [].
		user bluebug
		  ifTrue:
			[user waitnobug.
			↑self bordercomp]]].
"1382" Rectangle$'Image'
[rotate | size maskr spt mpt tpt data temp atab btab i unit |
	 "(00 rect: 128128) rotate."
	size ← self extent x.
	spt ← size  size "size must be a power of 2".
	data ← Rectangle new origin: origin extent: spt.
	maskr ← Rectangle new origin: (mpt ← origin + (0  size)) extent: spt.
	temp ← Rectangle new origin: (tpt ← mpt + (size  0)) extent: spt.
	atab ← {0  0 , (1  0) , (0  0) , (0  1) , (1  1) , (0  1) , (1  0) , (1  0) , (1  0)}.
	btab ← {0  0 , (1  1) , (0  0) , (1  1) , (1  1) , (1  1)}.
	unit ← size / 2.
	maskr clear: white.
	(Rectangle new origin: mpt extent: unit  unit) clear: black.
	[unit < 1] whileFalseDo: 
		[(1 to: 3) do:
			[:i |  "flip left and right halves"
			temp clear: white.
			maskr blt: atab  i * unit + tpt mode: storing.
			maskr blt: atab  (3 + i) * unit + tpt mode: oring.
			data bltcomp: tpt mode: erasing.
			temp blt: atab  (6 + i) * unit + origin mode: xoring].
		(1 to: 3) do:
			[:i |  "flip diagonals"
			temp clear: white.
			maskr blt: btab  i * unit + tpt mode: storing.
			data bltcomp: tpt mode: erasing.
			temp blt: btab  (3 + i) * unit + origin mode: xoring].
		(unit ← unit / 2) < 1
		  ifFalse:
			[maskr blt: 0  unit + mpt mode: erasing.
			maskr blt: unit  0 + mpt mode: erasing.
			maskr blt: unit * 2  0 + mpt mode: oring.
			maskr blt: 0  (2 * unit) + mpt mode: oring]]].
"86" Rectangle$'ST76'
[ALTObitsFromString: str mode: mode | |<primitive: 75>
	user croak].
"86" Rectangle$'ST76'
[ALTObitsIntoString: str mode: mode | |<primitive: 75>
	user croak].
"80" Rectangle$'ST76'
[ALTObltcomp: dest mode: mode | |<primitive: 75>
	user croak].
"91" Rectangle$'ST76'
[ALTObrush: dest mode: mode color: color | |<primitive: 75>
	user croak].
"75" Rectangle$'Conversion'
[hardcopy: pf | |
	self hardcopy: pf thickness: 2].
"76" Rectangle$'ST76'
[ALTOblt: dest mode: mode | |<primitive: 75>
	user croak].
"79" Rectangle$'ST76'
[ALTOcolor: color mode: mode | |<primitive: 75>
	user croak].
"69" Rectangle$'Altering'
[usermove | |
	self usermove: user screenrect].
"69" Rectangle$'Altering'
[usersize | |
	self usersize: user screenrect].
"511" Rectangle$'Initialization'
[fromuserevenword | t |
	origin ← OriginCursor showwhile [ "Show the origin cursor until the user presses a mouse button,
		then get my origin"
				(user waitbug)] "Show the corner cursor and complement me until the user presses
		a button again.  The loop is arranged so 
		that complementing stays on for a little while.".
	t ← origin.
	CornerCursor showwhile [([corner ← t.
		t ← user mpnext] whileTrueDo:
			[self comp.
			t ← t x + 15 | 16  t y max: origin.
			self comp])]].
"221" Rectangle$'Arithmetic'
[+ delta | |
	↑Rectangle new "Return a Rectangle which is the sum of me and delta (which is a Rectangle, Point, or Number)" origin: origin + delta asRectOrigin corner: corner + delta asRectCorner].
"228" Rectangle$'Arithmetic'
[- delta | |
	↑Rectangle new "Return a Rectangle which is the difference of me and delta (which is a Rectangle, Point, or Number)" origin: origin - delta asRectOrigin corner: corner - delta asRectCorner].
"79" Rectangle$'Arithmetic'
[= r | |
	↑origin = r origin and: [corner = r corner]].
"225" Rectangle$'Arithmetic'
[* scale | |
	↑Rectangle new "Return a Rectangle which is the product of me and scale (which is a Rectangle, Point, or Number)" origin: origin * scale asRectOrigin corner: corner * scale asRectCorner].
"226" Rectangle$'Arithmetic'
[/ scale | |
	↑Rectangle new "Return a Rectangle which is the quotient of me and scale (which is a Rectangle, Point, or Number)" origin: origin / scale asRectOrigin corner: corner / scale asRectCorner].
"383" Rectangle$'Conversion'
[bitsFromStream: strm | rec s |
	rec ← origin rect: origin + (self width  (16 min: self height)).
	s ← rec bitmap.
	[rec maxY  corner y] whileTrueDo:
		[s fromStream: strm.
		rec bitsFromString: s.
		rec moveby: 0  16].
	rec minY < corner y
	  ifTrue:
		[rec corner y← corner y.
		s ← nil.
		s ← rec bitmap.
		s fromStream: strm.
		rec bitsFromString: s]].
"117" Rectangle$'Conversion'
[bitmap | extent |
	extent ← corner - origin.
	↑Bitmap new: extent y * (extent x + 15 / 16)].
"59" Rectangle$'Aspects'
[area | |
	↑self width * self height].
"59" Rectangle$'Conversion'
[asRectangle | |
	 "Return self."].
"52" Rectangle$'Conversion'
[asRectCorner | |
	↑corner].
"52" Rectangle$'Conversion'
[asRectOrigin | |
	↑origin].
"87" Rectangle$'Altering'
[translate: pt | |
	origin ← origin + pt.
	corner ← corner + pt].
"100" Rectangle$'Initialization'
[origin: t1 extent: extent | |
	origin ← t1.
	corner ← origin + extent].
"118" Rectangle$'Conversion'
[bitStringLength | extent |
	extent ← corner - origin.
	↑2 * extent y * (extent x + 15 / 16)].
"384" Rectangle$'Border'
[border: thick color: color | t3 |
	 "paints a border withoud disturbing interior"
	(t3 ← Rectangle new origin: origin - (thick  thick) corner: corner x + thick  origin y) clear: color.
	t3 moveto: origin x - thick  corner y.
	t3 clear: color.
	t3 origin← corner x  (origin y - thick).
	t3 clear: color.
	t3 moveto: origin - (thick  thick).
	t3 clear: color].
"121" Rectangle$'Arithmetic'
[intersect: r | |
	↑Rectangle new origin: (origin max: r origin) corner: (corner min: r corner)].
"227" Rectangle$'Image'
[brush: dest mode: mode color: color | |
	NoteTaker
	  ifTrue: [DisplayBLTer copyRect: self toPoint: dest effect: 8 + (mode land: 3) screen: color]
	  ifFalse: [self ALTObrush: dest mode: mode color: color]].
"337" Rectangle$'Image'
[blowup: at by: scale | z dest |
	dest ← Rectangle new origin: at extent: self extent * scale.
	((dest has: origin) or: [(dest has: corner)])
	  ifTrue:
		[z ← self bitsIntoString.
		dest outline.
		self moveto: dest origin.
		self bitsFromString: z]
	  ifFalse: [dest outline].
	self blowup: at by: scale spacing: 1].
"252" Rectangle$'Arithmetic'
[side: side distanceTo: pt | |
	side = 0
	  ifTrue: [↑pt y - origin y].
	side = 1
	  ifTrue: [↑pt x - origin x].
	side = 2
	  ifTrue: [↑corner y - pt y].
	side = 3
	  ifTrue: [↑corner x - pt x].
	.
	user notify: 'Invalid side'].
"191" Rectangle$'Arithmetic'
[sideNearest: pt | d dmin i imin |
	dmin ← 32767.
	(0 to: 3) do:
		[:i | dmin > (d ← self side: i distanceTo: pt) abs
		  ifTrue:
			[dmin ← d.
			imin ← i]].
	↑imin].
"342" Rectangle$'Aspects'
[withSide: side at: pt | |
	 "Returns a rectangle with one side moved."
	side = 0
	  ifTrue: [↑origin x  pt y rect: corner].
	side = 1
	  ifTrue: [↑pt x  origin y rect: corner].
	side = 2
	  ifTrue: [↑origin rect: corner x  pt y].
	side = 3
	  ifTrue: [↑origin rect: pt x  corner y].
	.
	user notify: 'Invalid side'].
"370" Rectangle$'Conversion'
[bitsOntoStream: strm | rec s |
	rec ← origin rect: origin + (self width  (16 min: self height)).
	(s ← self bitmap) all← 0.
	[rec maxY  corner y] whileTrueDo:
		[rec bitsIntoString: s.
		rec moveby: 0  16.
		s toStream: strm].
	rec minY < corner y
	  ifTrue:
		[rec height← corner y - rec miny.
		s ← rec bitsIntoString.
		s toStream: strm]].
"83" Rectangle$'Initialization'
[origin: t1 corner: t2 | |
	origin ← t1.
	corner ← t2].
"189" Rectangle$'Image'
[blt: dest mode: mode | |
	NoteTaker
	  ifTrue: [DisplayBLTer copyRect: self toPoint: dest effect: (mode land: 3) screen: 0]
	  ifFalse: [self ALTOblt: dest mode: mode]].
"201" Rectangle$'Image'
[bltcomp: dest mode: mode | |
	NoteTaker
	  ifTrue: [DisplayBLTer copyRect: self toPoint: dest effect: 4 + (mode land: 3) screen: 0]
	  ifFalse: [self ALTObltcomp: dest mode: mode]].
"206" Rectangle$'Image'
[color: color mode: mode | |
	NoteTaker
	  ifTrue: [DisplayBLTer copyRect: self toPoint: origin effect: 12 + (mode land: 3) screen: color]
	  ifFalse: [self ALTOcolor: color mode: mode]].
"80" Rectangle$'Arithmetic'
[inset: p1 and: p2 | |
	↑origin + p1 rect: corner - p2].
"116" Rectangle$'Conversion'
[bitsIntoString | str |
	str ← self bitmap.
	self bitsIntoString: str mode: storing.
	↑str].
"128" Rectangle$'Conversion'
[bitsIntoString: str | |
	self bitsIntoString: str mode: storing "default stores bits into the string"].
"125" Rectangle$'Conversion'
[bitsFromString: str | |
	self bitsFromString: str mode: storing "default stores bits onto display"].
"349" Rectangle$'Aspects'
[withEdge: side at: coord | |
	 "Returns a rectangle with one side moved."
	side = 0
	  ifTrue: [↑origin x  coord rect: corner].
	side = 1
	  ifTrue: [↑coord  origin y rect: corner].
	side = 2
	  ifTrue: [↑origin rect: corner x  coord].
	side = 3
	  ifTrue: [↑origin rect: coord  corner y].
	.
	user notify: 'Invalid side'].
"71" Rectangle$'Image'
[clear: color | |
	self color: color mode: storing].
"72" Rectangle$'Arithmetic'
[inset: p1 | |
	↑origin + p1 rect: corner - p1].
"101" Rectangle$'Aspects'
[width← w | |
	 "change my right x to make my width w"
	corner x← origin x + w].
"43" Rectangle$'Aspects'
[origin | |
	↑origin].
"52" Rectangle$'Aspects'
[extent | |
	↑corner - origin].
"59" Rectangle$'Arithmetic'
[center | |
	↑origin + corner / 2].
"705" Rectangle$'Arithmetic'
[minus: r | s yorg ycor |
	 "return Vector of Rectangles comprising
				the part of me not intersecting r "
	 "Make sure the intersection is non-empty"
	(origin  r corner and: [r origin  corner])
	  ifFalse: [↑self inVector].
	s ← (Vector new: 4) asStream.
	r origin y > origin y
	  ifTrue: [s next← origin rect: corner x  (yorg ← r origin y)]
	  ifFalse: [yorg ← origin y].
	r corner y < corner y
	  ifTrue: [s next← origin x  (ycor ← r corner y) rect: corner]
	  ifFalse: [ycor ← corner y].
	r origin x > origin x
	  ifTrue: [s next← origin x  yorg rect: r origin x  ycor].
	r corner x < corner x
	  ifTrue: [s next← r corner x  yorg rect: corner x  ycor].
	↑s contents].
"43" Rectangle$'Aspects'
[corner | |
	↑corner].
"56" Rectangle$'Aspects'
[height | |
	↑corner y - origin y].
"94" Rectangle$'Arithmetic'
[intersects: r | |
	↑(origin max: r origin) < (corner min: r corner)].
"139" Rectangle$'Arithmetic'
[isWithin: rect | |
	 "am I equal to or contained within rect"
	↑origin  rect origin and: [corner  rect corner]].
"118" BitBlt$'Access to Parts'
[sourceRaster: t1 | |
	 "length of a 'scanline' source in 16-bit words"
	sourceRaster ← t1].
"128" BitBlt$'Setup'
[clipRect: rect | |
	clipX ← rect minX.
	clipY ← rect minY.
	clipWidth ← rect width.
	clipHeight ← rect height].
"222" BitBlt$'Setup'
[destForm: t1 | |
	destForm ← t1.
	self clipRect: (0  0 rect: destForm extent).
	destRaster ← destForm width + 15 / 16.
	dest ← (NoteTaker
			  ifTrue: [destForm bits]
			  ifFalse: [destForm bits lock])].
"90" BitBlt$'Setup'
[destOrigin: destOrigin | |
	destX ← destOrigin x.
	destY ← destOrigin y].
"189" BitBlt$'Setup'
[sourceForm: t1 | |
	sourceForm ← t1.
	sourceRaster ← sourceForm width + 15 / 16.
	source ← (NoteTaker
			  ifTrue: [sourceForm bits]
			  ifFalse: [sourceForm bits lock])].
"126" BitBlt$'Setup'
[sourceRect: rect | |
	sourceX ← rect minX.
	sourceY ← rect minY.
	width ← rect width.
	height ← rect height].
"106" BitBlt$'Operations'
[installDisplay | |<primitive: 67>
	user croak "set up source=cursor, dest=display"].
"336" Form$'EDITING'
[blinkbrush: parentimage | pt |
	pt ← parentimage mp "to show current position of brush in the form.".
	brush displayat: parentimage rectangle origin + pt effect: 2 clippedBy: user screenrect.
	brush displayat: parentimage rectangle origin + pt effect: 2 clippedBy: user screenrect.
	↑parentimage rectangle origin + pt].
"396" Form$'EDITING'
[newbrush: superimage | pt rect |
	OriginCursor topage1.
	user waitbug.
	pt ← superimage mp + superimage rectangle origin.
	rect ← pt rect: pt.
	CornerCursor topage1.
	[user nobug] whileFalseDo: 
		[rect reverse.
		rect reverse.
		pt ← superimage mp + superimage rectangle origin.
		rect corner← rect origin max: pt].
	brush ← Form new fromrectangle: rect.
	NormalCursor topage1].
"108" Form$'MODULE ACCESS'
[figure | |
	↑figure "return the figure( color assiciated with black) for the form "].
"148" Path$'MODIFYING PATHS'
[deleteindex: i | r |
	r ← array  (i + 1 to: position).
	position ← i - 1.
	self append: r.
	array  (position + 1) ← nil].
"108" Path$'TRANSFORMATIONS'
[+ delta | i |
	↑self copy "add delta to every point in the path" translate: delta].
"314" Path$'ACCESSING PATHS'
[pointnearestto: p | distance i nearest d |
	distance ← p dist: self  1 "return the index of the point  in the path nearest (manhatten norm) to p.".
	nearest ← 1.
	(1 to: position) do:
		[:i | d ← p dist: self  i.
		d < distance
		  ifTrue:
			[nearest ← i.
			distance ← d]].
	↑nearest].
"345" Path$'MODIFYING PATHS'
[insert: pt atindex: index | r |
	index > position "insert pt at index in the path"
	  ifTrue: [self next← pt]
	  ifFalse:
		[r ← (position = limit
				  ifTrue: [self grow]
				  ifFalse: [self growby: 0]).
		position ← 0.
		self append: (r  1 to: index - 1).
		self next← pt.
		self append: r  (index to: r length)]].
"782" Path$'SPECIAL PATHS'
[addlinefrom: p1 to: p2 | x1 y1 dx dy yinc x0 y0 cdl i |
	dx ← p2 x "for now just add points to the space at alto resolution between p1 and p2
	inclusive" - p1 x.
	dy ← p2 y - p1 y.
	dx < 0
	  ifTrue:
		[dx ← 0 - dx.
		dy ← 0 - dy.
		x0 ← p2 x.
		y0 ← p2 y]
	  ifFalse:
		[x0 ← p1 x.
		y0 ← p1 y].
	dy  0
	  ifTrue: [yinc ← 1]
	  ifFalse:
		[yinc ← 0 - 1.
		dy ← 0 - dy].
	dx  dy
	  ifTrue:
		[cdl ← dx / 2.
		(0 to: dx) do:
			[:i | self add: x0  y0.
			cdl ← cdl + dy.
			x0 ← x0 + 1.
			cdl > dx
			  ifTrue:
				[cdl ← cdl - dx.
				y0 ← y0 + yinc]]]
	  ifFalse:
		[ "y is fastest mover"
		cdl ← dy / 2.
		(0 to: dy) do:
			[:i | self add: x0  y0.
			cdl ← cdl + dx.
			y0 ← y0 + yinc.
			cdl > dy
			  ifTrue:
				[cdl ← cdl - dy.
				x0 ← x0 + 1]]]].
"224" Path$'MEASURING'
[rectangle | r i |
	r ← Rectangle new "return the bounding rectangle that includes all the points in the path." origin: self  1 extent: 1  1.
	(1 to: self length) do: [:i | r ← r include: self  i].
	↑r].
"193" Path$'TRANSFORMATIONS'
[normalize | delta i |
	delta ← self origin "subtract the origin of the path from every point in the path".
	(1 to: self length) do: [:i | self  i ← self  i - delta]].
"131" Path$'MEASURING'
[width | |
	↑self size "return the width of the bounding rectangle that includes all the points in the path." x].
"170" Path$'SYSTEM'
[printon: strm | t |
	strm append: 'a Path: '.
	(array is: String)
	  ifTrue: [strm space append: self]
	  ifFalse: [self do: [:t | strm space print: t]]].
"465" Path$'SPECIAL PATHS'
[addarcfrom: p1 via: p2 to: p3 | pa pb i k s |
	s ← Path new "Kaehler method for Flegal curve" init.
	s add: p1.
	pa ← p2 - p1.
	pb ← p3 - p2.
	k ← 5 max: pa x abs + pa y abs + pb x abs + pb y abs / 20.
	(1 to: k) do: [:i |  "k is a guess how many segments are appropriate"
		s add: pa * i / k + p1 * (k - i) + (pb * (i - 1) / k + p2 * (i - 1)) / (k - 1)].
	s add: p3.
	(1 to: s length - 1) do: [:i | self addlinefrom: s  i to: s  (i + 1)]].
"148" Path$'TRANSFORMATIONS'
[translate: delta | i |
	(1 to: self length "add delta to every point in the path") do: [:i | self  i ← self  i + delta]].
"103" Path$'BUILDING PATHS'
[comment | |
	 "see Set for these ... add:, append:, and ← are the main ones"].
"80" Path$'INIT'
[init | |
	self default "must be executed for each new instance."].
"143" Path$'MEASURING'
[extent | |
	↑self rectangle "return the extent of the bounding rectangle that includes all the points in the path." extent].
"143" Path$'MEASURING'
[corner | |
	↑self rectangle "return the corner of the bounding rectangle that includes all the points in the path." corner].
"133" Path$'MEASURING'
[height | |
	↑self size "return the height of the bounding rectangle that includes all the points in the path." y].
"143" Path$'MEASURING'
[origin | |
	↑self rectangle "return the origin of the bounding rectangle that includes all the points in the path." origin].
"35" Path$'SYSTEM'
[pressCode | |
	↑6].
"145" Path$'SYSTEM'
[copy | t |
	t ← Path new "returns a new instance of Path that is a copy " init.
	t append: (array  (1 to: position)) copy.
	↑t].
"141" Path$'MEASURING'
[size | |
	↑self rectangle "return the extent of the bounding rectangle that includes all the points in the path." extent].
"149" Path$'TRANSFORMATIONS'
[scale: factor | i |
	(1 to: self length "scale every point in the path by factor") do: [:i | self  i ← self  i * factor]].
"136" Set$'Index operations'
[ i ← val | |
	position + 1 = i
	  ifTrue: [self next← val]
	  ifFalse: [↑array  i ← val "self checkIndex:"]].
"65" Set$'Index operations'
[ i | |
	↑array  i "self checkIndex:"].
"51" Set$'Value operations'
[add: x | |
	self next← x].
"93" Set$'Initialization'
[of: t1 to: t2 | |
	array ← t1.
	position ← t2.
	limit ← array length].
"316" Set$'Arithmetic operations'
[product: s | product i |
	product ← Set new "product of two sets ... sets must be of equal length" default.
	self length = s length
	  ifTrue:
		[(1 to: position) do: [:i | product add: s  i * (self  i)].
		↑product].
	user notify: 'product undefined...sets are not of equal length'].
"177" Set$'Index operations'
[deleteI: i | v j |
	v ← self  i.
	(i to: position - 1) do: [:j | array  j ← array  (j + 1)].
	array  position ← nil.
	position ← position - 1.
	↑v].
"175" Set$'Viewing'
[printon: strm | t |
	strm append: 'a Set: '.
	(array is: String)
	  ifTrue: [strm append: self]
	  ifFalse: [self do:
			[:t | strm space.
			strm print: t]]].
"52" Set$'Initialization'
[default | |
	self vector: 8].
"82" Set$'Initialization'
[vector: t1 | |
	limit ← t1.
	self of: (Vector new: limit)].
"178" Set$'Private'
[growby: n | old |
	old ← Set new "grow and reset self. return old Set for copying" of: array to: position.
	self of: (array species new: limit + n) to: 0.
	↑old].
"67" Set$'Value operations'
[append: x | |
	x do: [:x | self next← x]].
"93" Set$'Viewing'
[viewer: v | |
	views  nil
	  ifTrue: [views ← Set default].
	views next← v].
"82" Set$'Initialization'
[string: t1 | |
	limit ← t1.
	self of: (String new: limit)].
"29" Set$'Viewing'
[asSet | |
	].
"39" Set$'Viewing'
[length | |
	↑position].
"58" Set$'Value operations'
[has: x | |
	↑(self find: x) > 0].
"45" Set$'Viewing'
[copy | |
	↑self viewer copy].
"86" Set$'Value operations'
[insert: x | |
	(self find: x) = 0
	  ifTrue: [self next← x]].
"107" Set$'Value operations'
[find: v | i |
	(1 to: position) do:
		[:i | array  i = v
		  ifTrue: [↑i]].
	↑0].
"45" Set$'Viewing'
[species | |
	↑array species].
"69" Set$'Private'
[next | |
	user notify: 'no direct reading of a Set'].
"112" Set$'Private'
[checkIndex: i | |
	(i  1 and: [i  position])
	  ifTrue: [↑i].
	↑user notify: 'illegal index'].
"127" Set$'Value operations'
[delete: x | i |
	(1 to: position) do:
		[:i | array  i  x
		  ifTrue: [↑self deleteI: i]].
	↑false].
"44" Set$'Viewing'
[asStream | |
	↑self viewer].
"45" SetReader$'Reading'
[asSet | |
	↑self copy].
"69" SetReader$'Reading'
[length | |
	↑limit - position "how much left"].
"152" SetReader$'Reading'
[copy | t1 |
	 "yield contents all at once as a Set"
	↑(t1 ← Set new) of: (array species new: limit - position).
	t1 append: self].
"134" SetReader$'Initialization'
[of: t1 from: t2 for: n | |
	array ← t1.
	position ← t2.
	position ← position - 1.
	limit ← position + n].
"120" Set$'Viewing'
[viewRange: i to: j | |
	↑SetReader new "self viewer:" of: array from: i to: j "max: 1" "min: position"].
"391" Set$'Index operations'
[insertI: i value: v | old j |
	i > position
	  ifTrue: [self next← v]
	  ifFalse:
		[old ← array.
		position = limit
		  ifTrue:
			[limit ← limit + (10 max: limit / 4).
			array ← array species new: limit.
			(1 to: i - 1) do: [:j | array  j ← old  j]].
		(position to: i by: 1) do: [:j | array  (j + 1) ← old  j].
		array  i ← v.
		position ← position + 1]].
"60" Set$'Viewing'
[initView: v | |
	↑v of: array to: position].
"90" Set$'Viewing'
[notViewed: v | |
	views delete: v.
	views empty
	  ifTrue: [views ← nil]].
"215" Set$'Index operations'
[deleteI: i to: j | n k |
	n ← j - i + 1.
	(i to: position - n) do: [:k | array  k ← array  (k + n)].
	(position - n + 1 to: position) do: [:k | array  k ← nil].
	position ← position - n].
"108" Set$'Viewing'
[viewer | |
	↑SetReader new of: array from: 1 to: position "self viewRange: 1 to: position"].
"72" Set$'Private'
[pastend← x | |
	↑self append: self grow.
	self next← x].
"339" Set$'Arithmetic operations'
[dotproduct: s | i dotproduct |
	dotproduct ← 0.0 "dot product of two sets ... sets must be of equal length".
	self length = s length
	  ifTrue:
		[(1 to: position) do: [:i | dotproduct ← dotproduct + (s  i * (self  i))].
		↑dotproduct].
	user notify: 'dot product undefined...sets are not of equal length'].
"183" Set$'Arithmetic operations'
[summation | i summation |
	summation ← 0.0 "sum of the values in the set".
	(1 to: position) do: [:i | summation ← summation + (self  i)].
	↑summation].
"123" Set$'Private'
[grow | |
	↑self growby: (10 max: limit / 4 "self grown and reset. returns another Set with old contents")].
"521" Form$'EDITING'
[line: parentimage | pt1 pt2 path pt |
	BlankCursor topage1 "line tool for forms.".
	[user redbug] whileFalseDo:  [pt1 ← self blinkbrush: parentimage].
	brush displayat: pt1 effect: color clippedBy: user screenrect.
	[user nobug] whileFalseDo:  [pt2 ← self blinkbrush: parentimage].
	brush displayat: pt2 effect: color clippedBy: user screenrect.
	path ← Path new init.
	path addlinefrom: pt1 to: pt2.
	path do: [:pt | brush displayat: pt effect: color clippedBy: user screenrect].
	NormalCursor topage1].
"134" Form$'PATTERN ACCESS'
[black | i |
	(1 to: bits length "sets all bits in the form to black ( to ones)") do: [:i | bits  i ← 0 - 1]].
"131" Form$'PATTERN ACCESS'
[white | i |
	(1 to: bits length "sets all bits in the form to white ( to zeros)") do: [:i | bits  i ← 0]].
"132" Form$'PATTERN ACCESS'
[gray | i |
	(1 to: bits length "sets all bits in the form to gray ( to gray)") do: [:i | bits  i ← 10922]].
"76" Form$'MODULE ACCESS'
[width | |
	↑extent x "return the width of the Form"].
"722" Form$'DISPLAY'
[displayat: path effect: effect clippedBy: cliprect | r i clippedrect |
	(path is: Point) "basic form display primitive"
	  ifTrue:
		[r ← Rectangle new origin: path extent: self extent.
		r bitsFromString: bits mode: effect clippedBy: cliprect.
		aurorarunning
		  ifTrue: [user displayoffwhile [
				(clippedrect ← r intersect: user screenrect.
				aurora destination: clippedrect.
				aurora source: clippedrect.
				aurora figure: figure.
				aurora ground: ground.
				aurora function: 1103 "AoverB".
				aurora doit.
				aurora function: 0.
				aurora doit)]]]
	  ifFalse:
		[(path is: Path)
		  ifTrue: [(1 to: path length) do: [:i | self displayat: path  i effect: effect clippedBy: cliprect]]]].
"663" Form$'EDITING'
[arc: parentimage | pt1 pt2 pt3 path pt |
	BlankCursor topage1 "arc tool for forms.".
	[user redbug] whileFalseDo:  [pt1 ← self blinkbrush: parentimage].
	brush displayat: pt1 effect: color clippedBy: user screenrect.
	[user nobug] whileFalseDo:  [pt2 ← self blinkbrush: parentimage].
	brush displayat: pt2 effect: color clippedBy: user screenrect.
	[user redbug] whileFalseDo:  [pt3 ← self blinkbrush: parentimage].
	brush displayat: pt3 effect: color clippedBy: user screenrect.
	path ← Path new init.
	path addarcfrom: pt1 via: pt2 to: pt3.
	path do: [:pt | brush displayat: pt effect: color clippedBy: user screenrect].
	NormalCursor topage1].
"521" Form$'EDITING'
[resize: superimage | pt f |
	superimage boxcomp.
	CornerCursor topage1.
	user waitbug.
	[user nobug] whileFalseDo: 
		[superimage reverse.
		superimage reverse.
		pt ← superimage superimage mp + superimage superimage rectangle origin.
		superimage corner← pt max: superimage origin + (16  16)].
	f ← Form new fromrectangle: superimage rectangle.
	bits ← f bits.
	extent ← f extent.
	offset ← 0  0.
	superimage white.
	superimage resize.
	superimage display.
	superimage boxcomp.
	NormalCursor topage1].
"268" Form$'INIT'
[extent: t1 figure: t2 ground: t3 offset: t4 | |
	extent ← t1.
	figure ← t2.
	ground ← t3.
	offset ← t4.
	bits ← Bitmap new: extent y "creates a virtual bit map with width = (extent x) and height = (extent y) with the bits all 1." * (extent x + 15 / 16)].
"109" Form$'MODULE ACCESS'
[ground | |
	↑ground "return the ground ( color assiciated with white) for the form "].
"104" Form$'As yet unclassified'
[extent: t1 bits: t2 offset: t3 | |
	extent ← t1.
	bits ← t2.
	offset ← t3].
"231" Form$'SYSTEM'
[hideData: complete | s t3 |
	(t3 ← Stream new "a Form does not split across page boundaries") of: (s ← String new: 12).
	t3 nextPoint← extent.
	t3 nextPoint← offset.
	t3 nextword← figure.
	t3 nextword← ground.
	↑s].
"35" Form$'SYSTEM'
[pressCode | |
	↑5].
"49" Form$'MODULE ACCESS'
[length | |
	↑bits length].
"108" Form$'SYSTEM'
[copy | t |
	t ← Form new "return a copy of myself" extent: extent.
	t bits: bits copy.
	↑t].
"121" Menu$'User interactions'
[fbug | index |
	index ← self bugit "for fixed menus" "get the index".
	↑index "return index"].
"75" Menu$'User interactions'
[show | |
	frame clear: black.
	text displayall].
"149" Menu$'Initialization'
[stringFromVector: v | s |
	s ← Stream default "DW classInit".
	v do:
		[:v | s append: v.
		s cr].
	self string: s contents].
"128" Menu$'User interactions'
[moveto: pt | |
	self clear.
	frame moveto: pt.
	text frame moveto: pt + 2.
	thisline moveto: pt + 2].
"156" Menu$'User interactions'
[zbug | index bits |
	bits ← self movingsetup.
	[(index ← self bugit) = 0] whileTrueDo: [].
	frame bitsFromString: bits.
	↑index].
"116" Menu$'User interactions'
[rebug | |
	user waitbug "wait for button down again".
	↑self bug "bugcursor showwhile"].
"729" Menu$'Internal'
[bugit | pt bits rect |
	user nobug
	  ifTrue: [↑0].
	 "accidental bug returns 0"
	thisline comp.
	[true] whileTrueDo:
		[(text frame has: (pt ← user mp))
		  ifTrue:
			[user anybug
			  ifTrue:
				[(thisline has: pt)
				  ifFalse:
					[text charofpoint: pt andrect [:rect | rect].
					pt ← rect origin.
					thisline comp "selection follows mouse".
					thisline moveto: text frame origin x  pt y.
					thisline comp]]
			  ifFalse: [↑1 + (thisline origin y - text frame origin y / text lineheight) "return index"]]
		  ifFalse:
			[thisline comp "he left the menu".
			[text frame has: user mp] whileFalseDo: 
				[user nobug
				  ifTrue: [↑0]].
			thisline comp "return 0 for abort"]] "he came back"].
"46" Menu$'User interactions'
[frame | |
	↑frame].
"51" Menu$'User interactions'
[clear | |
	frame clear].
"47" Textframe$'Access to Parts'
[para | |
	↑para].
"646" Textframe$'Testing'
[Testing | |
	 "

Stuff to do:
Fast type-in
Try out line buffer

TD measureall. TD enter.
TimesRoman10 fromStrike: 'TimesRoman10'.
user time [TD align; align; align; align.] 575
until user anybug do [TD align].
 | p. user print: (p←user waitbug); cr.
	user print: (p←TD charofpoint: p); cr.
	user print: (TD pointofchar: p1); cr.
TD pointofchar: 68 
TD displayall; nselect: user waitbug.
TD clearfrom: user mp y a TDTextImage
TD reversefrom: 1 to: 20.
 | i. spy every: 10; on [for i to: 100 do
[TD displayall ]]; report: 'show.spy'; close.
spy every: 10; on [TD select: user waitbug]; report: 'select.spy'; close.
"].
"86" Textframe$'Displaying'
[show: t1 | |
	para ← t1.
	self measureall.
	self displayall].
"160" Textframe$'Line management'
[lineofy: y | |
	 "Return line number for a given y (may be out of range!)"
	↑y - frame minY / style lineheight + 1 min: lastline].
"76" Textframe$'Initialization'
[classInit | |
	space ← 32.
	cr ← 13.
	tab ← 9].
"48" Textframe$'Displaying'
[comp | |
	window comp].
"59" TextScanner$'Access to parts'
[leftx | |
	↑destX - width].
"2944" TextScanner$'Scanning'
[scanline: line at: y stopx: t3 stopchar: stopchar | ascii runx reason emphasis newrun endrun padwidth relx tabsize spacepad t15 |
	stopx ← t3.
	chari ← line starti - 1.
	spacecount ← line spaces.
	padwidth ← line padwidth.
	destX ← spacex ← runx ← frame minX.
	emphasis ← charpad ← spacepad ← 0.
	tabsize ← style tabsize.
	spacei ← 1.
	(t15 ← para alignment) = 0
	  ifFalse:
		[ "LeftFlush"
		t15 = 1
		  ifTrue:
			[spacecount > 0
			  ifTrue:
				[ "Justified"
				charpad ← padwidth / (line stopi - chari + spacecount).
				charpad > 0
				  ifTrue:
					[padwidth ← padwidth - (charpad * (line stopi - chari - 2 - spacecount)).
					printing
					  ifTrue: [(frame minX  y rect: frame maxX  (y + style lineheight)) clear: white]].
				spacepad ← padwidth / spacecount.
				spacecount ← spacecount - (padwidth \ spacecount)]]
		  ifFalse:
			[t15 = 2
			  ifTrue: [destX ← destX + (padwidth / 2)]
			  ifFalse:
				[ "Centered"
				t15 = 4
				  ifTrue: [destX ← destX + padwidth]]]] "RightFlush".
	reason ← 10.
	[reason < 10] whileFalseDo: 
		[ "2=>stopx, 3=>stopchar, 4=>CR, 
			10=>end of run, 11=>ascii out of range, 12-254=>exception chars"
		reason = 10
		  ifTrue:
			[reason ← 255.
			chari  stopchar
			  ifTrue: [reason ← 3]
			  ifFalse:
				[ "new run"
				printing
				  ifTrue: [self emphasize: emphasis leftx: runx rightx: destX liney: y].
				runx ← destX.
				chari ← chari + 1.
				newrun ← para runAndVal: chari.
				emphasis ← newrun  2 land: 15.
				endrun ← newrun  1 + chari - 1 min: stopchar.
				self setfont: (newrun  2 lshift: 4) liney: y]]
		  ifFalse:
			[NoteTaker
			  ifFalse: [source ← glyphs lock].
			reason ← self scanword: endrun.
			NoteTaker
			  ifFalse: [glyphs unlock].
			reason > 10
			  ifTrue:
				[reason = 12
				  ifTrue:
					[spacecount ← spacecount - 1 "space".
					spacecount = 0
					  ifTrue: [spacepad ← spacepad + 1].
					spacei ← chari.
					spacex ← destX.
					width ← spacesize + spacepad.
					printing
					  ifTrue:
						[super effect: 28.
						self callBLT]]
				  ifFalse:
					[reason = 13
					  ifTrue:
						[relx ← destX - frame minX "tab".
						width ← (para alignment > 0
								  ifTrue: [tabsize + charpad]
								  ifFalse: [relx + tabsize | tabsize - relx]).
						printing
						  ifTrue:
							[super effect: 28.
							self callBLT]]
					  ifFalse:
						[reason = 11
						  ifTrue: [ascii ← maxascii + 1].
						sourceX ← xtable  (ascii + 1).
						width ← xtable  (ascii + 2) - sourceX.
						printing
						  ifTrue:
							[super effect: 16.
							self callBLT].
						width ← width + charpad]].
				(destX ← destX + width) > stopx
				  ifTrue: [reason ← 2]
				  ifFalse:
					[chari  endrun
					  ifTrue: [reason ← 10]
					  ifFalse: [chari ← chari + 1]]]
			  ifFalse:
				[reason = 4
				  ifTrue: [width ← 0] "CR"]]].
	printing
	  ifTrue: [self emphasize: emphasis leftx: runx rightx: destX liney: y]].
"1385" TextScanner$'Scanning'
[emphasize: emphasis leftx: leftx rightx: rightx liney: liney | y y2 |
	 "Should eventually use self callBLT, to get windowing and go faster"
	(font  nil or: [font height = style lineheight])
	  ifFalse:
		[font ascent < style baseline
		  ifTrue:
			[y ← liney + (style baseline - font ascent).
			(leftx  liney rect: rightx  y) clear: white].
		font descent < (style lineheight - style baseline)
		  ifTrue:
			[y ← liney + (style baseline + font descent).
			y2 ← y + (style lineheight - (style baseline + font descent)).
			(leftx  y rect: rightx  y2) clear: white]].
	emphasis = 0
	  ifFalse:
		[emphasis  8
		  ifTrue:
			[emphasis ← emphasis - 8 "Strike-out".
			y ← liney + (style baseline / 2).
			(leftx  y rect: rightx  (y + 1)) clear: black].
		emphasis  4
		  ifTrue:
			[emphasis ← emphasis - 4 "Underline".
			y ← liney + style baseline.
			(leftx  y rect: rightx  (y + 1)) clear: black].
		emphasis  2
		  ifTrue:
			[emphasis ← emphasis - 2 "Itallic".
			y ← liney + style lineheight - 4.
			[y  liney] whileFalseDo: 
				[(leftx  liney rect: rightx - 1  y) blt: leftx + 1  liney mode: storing.
				(leftx  liney rect: leftx + 1  y) clear: white.
				y ← y - 4]].
		emphasis  1
		  ifTrue:
			[emphasis ← emphasis - 1 "Bold".
			(leftx  liney rect: rightx  (liney + style lineheight)) blt: leftx + 1  liney mode: oring]]].
"98" TextScanner$'Access to parts'
[spacecount | |
	↑0 - spacecount "because counted down from zero"].
"263" TextScanner$'Initialization'
[classInit | |
	 "TextScanner classInit."
	space ← 32.
	tab ← 9.
	cr ← 13.
	(defaultExceptions ← Vector new: 256) all← 0.
	defaultExceptions  (space + 1) ← 12.
	defaultExceptions  (tab + 1) ← 13.
	defaultExceptions  (cr + 1) ← 4].
"536" TextScanner$'Initialization'
[setfont: newfont liney: liney | |
	newfont = fontno
	  ifTrue: [ "Just bump y if same font"
		destY ← liney + style baseline - font ascent]
	  ifFalse:
		[font ← style font: (fontno ← newfont).
		xtable ← font xtable.
		spacesize ← font spacewidth.
		minascii ← font minascii.
		maxascii ← font maxascii.
		glyphs ← font glyphs.
		printing
		  ifTrue:
			[sourceRaster ← font raster.
			destY ← liney + style baseline - font ascent.
			height ← font height.
			NoteTaker
			  ifTrue: [source ← glyphs]]]].
"72" TextScanner$'Initialization'
[exceptionTable: t1 | |
	exceptions ← t1].
"881" TextScanner$'Scanning'
[scanword: endrun | ascii |<primitive: 76>
	 "Scan or print text until terminated by x-value, special character or new format run.
	Returns an Integer as follows:
		2=>stopx, 10=>end of run, 11=>ascii out of range,
		else exceptionschari (4=CR, 12=space, 13=tab)"
	super effect: 16 "exceptions and xtable are Vectors of Integers, printing is Boolean, rest are Integers" "becomes: super effect: 3 in new encoding".
	[chari > endrun] whileFalseDo: 
		[ascii ← text  chari.
		exceptions  (ascii + 1)  0
		  ifTrue: [↑exceptions  (ascii + 1)].
		(ascii < minascii or: [ascii > maxascii])
		  ifTrue: [↑11].
		sourceX ← xtable  (ascii + 1).
		width ← xtable  (ascii + 2) - sourceX.
		printing
		  ifTrue: [self callBLT].
		width ← width + charpad.
		destX ← destX + width.
		destX > stopx
		  ifTrue: [↑2].
		chari ← chari + 1].
	chari ← chari - 1.
	↑10].
"52" TextScanner$'Access to parts'
[rightx | |
	↑destX].
"344" TextScanner$'Initialization'
[frame: t1 window: w para: t3 style: t4 printing: t5 | |
	frame ← t1.
	para ← t3.
	style ← t4.
	printing ← t5.
	super init.
	self screen: white.
	self toDisplay.
	exceptions ← defaultExceptions.
	fontno ← 1 "indicates font not set".
	text ← (para ← para asParagraph) text.
	NoteTaker
	  ifTrue: [self window: w]].
"53" TextScanner$'Access to parts'
[spacei | |
	↑spacei].
"53" TextScanner$'Access to parts'
[spacex | |
	↑spacex].
"914" TextScanner$'Scanning'
[type: ascii | |
	 "For incremental typing in a line"
	exceptions  (ascii + 1)  0
	  ifTrue: [↑exceptions  (ascii + 1)].
	(ascii < minascii or: [ascii > maxascii])
	  ifTrue: [ascii ← maxascii + 1].
	stopx ← frame maxX.
	sourceX ← xtable  (ascii + 1).
	(ascii  space and: [ascii  tab])
	  ifTrue: [width ← xtable  (ascii + 2) - sourceX]
	  ifFalse:
		[ascii = space
		  ifTrue: [width ← spacesize]
		  ifFalse: [width ← style tabsize]].
	(destX + width > stopx or: [ascii = cr])
	  ifTrue: [↑1].
	(destX  destY rect: stopx - width  (destY + height)) blt: destX + width  destY mode: storing "slide the rest of the line over".
	(ascii  space and: [ascii  tab])
	  ifTrue: [super effect: 16]
	  ifFalse: [super effect: 28].
	(NoteTaker or: [effect = 28])
	  ifTrue: [self callBLT]
	  ifFalse:
		[source ← glyphs lock.
		self callBLT.
		glyphs unlock].
	destX ← destX + width.
	↑0].
"80" TextScanner$'Access to parts'
[chari | |
	↑chari "index of last char scanned"].
"137" Textframe$'Displaying'
[printer: printing | |
	↑TextScanner new frame: frame window: window para: para style: style printing: printing].
"118" Textframe$'Line management'
[yofline: line | |
	 "top y of given line"
	↑frame minY + (line - 1 * style lineheight)].
"88" Textframe$'Displaying'
[outline | |
	 "from TextFrame"
	window border: 2 color: black].
"324" Textframe$'Initialization'
[frame: t1 window: t2 para: t3 style: t4 | |
	frame ← t1.
	window ← t2.
	para ← t3.
	style ← t4.
	(NoteTaker or: [frame  nil])
	  ifFalse: [frame ← window ← frame intersect: user screenrect].
	lines ← Vector new: 32.
	lastline ← 0.
	(para  nil or: [frame  nil])
	  ifFalse: [self measureall]].
"861" Textframe$'Measuring'
[charofpoint: point andrect rect | linei leftx rightx y chari P orig r |
	 "Return character index of character at point" "TD enter."
	linei ← 0 max: (self lineofy: point y).
	y ← self yofline: linei.
	linei = 0
	  ifTrue:
		[chari ← 1.
		orig ← frame minX  (y + style lineheight)]
	  ifFalse:
		[point y > (y + style lineheight)
		  ifTrue:
			[self pointofchar: para length + 1 andrect [:r | r].
			rect value← r.
			↑para length + 1].
		P ← self printer: false.
		P scanline: lines  linei at: y stopx: point x stopchar: (lines  linei) stopi.
		chari ← P chari.
		rightx ← P rightx.
		leftx ← P leftx.
		(point x  (leftx + rightx / 2) or: [para  chari = cr])
		  ifTrue: [orig ← leftx  y]
		  ifFalse:
			[chari ← chari + 1.
			orig ← rightx  y]].
	rect value← Rectangle new origin: orig extent: 0  style lineheight.
	↑chari].
"655" Textframe$'Measuring'
[pointofchar: index andrect rect | linei y P orig |
	 "Return origin of character index"
	linei ← self lineofchar: index.
	y ← self yofline: linei.
	index > para length
	  ifTrue:
		[(para length = 0 or: [para  para length = cr])
		  ifTrue: [orig ← frame minX  (y + style lineheight)]
		  ifFalse:
			[P ← self printer: false.
			P scanline: lines  linei at: y stopx: 9999 stopchar: index - 1.
			orig ← P rightx  y]]
	  ifFalse:
		[.
		P ← self printer: false.
		P scanline: lines  linei at: y stopx: 9999 stopchar: index.
		orig ← P leftx  y].
	rect value← Rectangle new origin: orig extent: 0  style lineheight.
	↑orig].
"70" Textframe$'Displaying'
[show | |
	self measureall.
	self displayall].
"69" Textframe$'Displaying'
[clear | |
	(frame intersect: window) clear].
"158" Textframe$'Initialization'
[para: t1 frame: t2 style: t3 | |
	para ← t1.
	frame ← t2.
	style ← t3.
	self frame: frame window: frame para: para style: style].
"90" Textframe$'Scheduling'
[aboutToFrame | |
	 "My frame is about to change.  I dont care."].
"374" Textframe$'Displaying'
[put: t1 at: pt centered: center | rect |
	para ← t1.
	window ← frame ← pt rect: 1000  1000.
	para ← para asParagraph.
	self measureall.
	self pointofchar: para length + 1 andrect [:rect | rect].
	window growto: rect corner.
	center
	  ifTrue: [window moveby: pt - window center].
	window ← window inset: 3  2.
	window clear: white.
	self show].
"101" Textframe$'Displaying'
[put: t1 centered: pt | |
	para ← t1.
	self put: para at: pt centered: true].
"118" Textframe$'Scheduling'
[takeCursor | |
	user cursorloc← window center "Move the cursor to the center of my window."].
"146" Textframe$'Initialization'
[para: t1 frame: t2 | |
	para ← t1.
	frame ← t2.
	self frame: frame window: frame para: para style: DefaultTextStyle].
"111" Textframe$'Measuring'
[lastshown | ignored |
	↑self charofpoint: window corner andrect [:ignored | ignored]].
"104" Textframe$'Access to Parts'
[frame← t1 | |
	frame ← t1.
	window ← frame "Change my frame and window."].
"51" Textframe$'Access to Parts'
[window | |
	↑window].
"157" Textframe$'Measuring'
[scrolln: n | ignored |
	↑self charofpoint: frame corner x  (frame origin y + (n * style lineheight)) andrect [:ignored | ignored]].
"83" AltoFileDirectory$'Alto'
[flush | |
	bitsFile  nil
	  ifFalse: [bitsFile flush]].
"689" AltoFileDirectory$'Dictionary'
[nextEntry: file | s elen |
	dirFile  nil
	  ifTrue:
		[(file name compare: dirname) = 2
		  ifTrue:
			[file serialNumber: {32768 , 100} "return system directory file. known serialNumber and leader".
			file leader: 4096.
			↑file].
		self error: 'directory not open']
	  ifFalse:
		[ "return the next file entry, ignore deleted entries,
	and leave dirFile positioned before next entry"
		[s ← dirFile nextword] whileTrueDo:
			[elen ← s land: dfmask - 1.
			(s allmask: dfmask)
			  ifTrue:
				[file readFrom: dirFile.
				dirFile skip: elen * 2 - (file fileSize + 2).
				↑file].
			 "deleted entry, again"
			dirFile skipwords: elen - 1].
		↑false]].
"495" AltoFileDirectory$'FileDirectory'
[virtualToReal: vadr | t2 d |
	 "inverse of realToVirtual:" "vadr < 0 or vadr  totalPages [
		self error: 'illegal virtual address']" "faster to do /\ for normal Integers" "t ← vadr intdiv: diskPages.
	sec ← t2 intdiv: nSectors"
	vadr < diskPages
	  ifTrue:
		[d ← 0.
		t2 ← vadr]
	  ifFalse:
		[d ← 2.
		t2 ← vadr \ diskPages].
	↑(t2 \ nSectors "sector" lshift: 12) + (t2 / nSectors "cylinder & head" lshift: 2) + d "disk" "(vadr / diskPages) lshift: 1"].
"336" AltoFileDirectory$'Alto'
[configure: s | nDisks nHeads nTracks |
	nDisks ← s nextword "read disk configuration from a Stream:
		either leader page of SysDir or beginning of DiskDescriptor".
	nTracks ← s nextword.
	nHeads ← s nextword.
	nSectors ← s nextword.
	diskPages ← nTracks * nHeads * nSectors.
	totalPages ← nDisks * diskPages].
"1429" AltoFileDirectory$'Dictionary'
[Position← entry | name elen s holepos holesize entrysize nlen sk |
	name ← entry name "entry format
		1	n (length in words, including this one) + undeleted bit (dfmask)
		2-3	serialNumber
		4	version
		5	0?
		6	virtual address of page 0
		7-n name as Bcpl string (extra 0 if length even)".
	(dirFile  nil and: [(name compare: dirname) = 2])
	  ifTrue: [↑true].
	self reset.
	holepos ← false.
	holesize ← dfmask.
	nlen ← name length.
	entrysize ← self entrySize: entry "desired entry size".
	[s ← dirFile nextword] whileTrueDo:
		[elen ← s land: dfmask - 1 "entry length in words".
		entrysize > elen
		  ifTrue: [sk ← 2 "entry too small"]
		  ifFalse:
			[s = elen
			  ifTrue:
				[sk ← 2 "deleted entry. check hole size for later inserting or renaming".
				elen < holesize
				  ifTrue:
					[holesize ← elen "hole is the smallest so far".
					holepos ← dirFile position]]
			  ifFalse:
				[ "normal entry, big enough"
				dirFile skip: 10.
				nlen  dirFile next
				  ifTrue: [sk ← 13 "name wrong size"]
				  ifFalse:
					[sk ← 13 - nlen.
					(name compare: (dirFile next: nlen)) = 2
					  ifTrue:
						[dirFile skip: sk "name match, position back to beginning of entry".
						↑entry]]]] "sk is the character offset from the entry header word to the next entry".
		dirFile skip: elen * 2 + sk].
	holepos
	  ifTrue: [dirFile position← holepos - 2] "at end of dirFile".
	↑false].
"224" AltoFileDirectory$'Alto'
[diskID | f u |
	(f ← self oldFile: 'sys.boot' "return user name and disk name installed in O.S.") readonly.
	f position← 512.
	u ← f nextString.
	f padNext.
	u ← {u , f nextString}.
	f close.
	↑u].
"183" AltoFile$'DictionaryEntry'
[storeOn: s | |
	s append: serialNumber.
	s nextword← 1.
	s nextword← 0.
	s nextword← directory realToVirtual: leader.
	s nextString← name.
	s padNext← 0].
"103" AltoFile$'DictionaryEntry'
[fileSize | |
	↑11 + (name length "sn, version, fn, leader, name" lor: 1)].
"116" AltoFilePage$'Alto'
[freePage | |
	page fill: 11 to: 16 with: 255 "label for a free page: version, sn1, sn2 = 1"].
"65" AltoFilePage$'FilePage'
[serialNumber | |
	↑page  (13 to: 16)].
"151" AltoFilePage$'FilePage'
[init | |
	page  nil
	  ifTrue: [super init]
	  ifFalse: [ "nextp, backp, lnused, numch, pn"
		page fill: 1 to: 10 with: 0]].
"49" AltoFilePage$'FilePage'
[address | |
	↑address].
"82" AltoFilePage$'FilePage'
[length: len | |
	page word: numch ← len "self header:"].
"49" AltoFilePage$'FilePage'
[headerLength | |
	↑16].
"72" AltoFilePage$'FilePage'
[length | |
	↑page word: numch "self header:"].
"80" AltoFilePage$'FilePage'
[lastPage | |
	↑(page word: nextp) "self header:" = 0].
"168" AltoFilePage$'FilePage'
[serialNumber: sn | |
	page copy: 13 to: 16 with: sn from: 1 to: 4 "page(13 to: 16) ← sn" "self header:".
	page word: vn ← 1 "fixed version"].
"76" AltoFilePage$'FilePage'
[pageNumber | |
	↑page word: pagen "self header:"].
"57" AltoFilePage$'FilePage'
[address: t1 | |
	address ← t1].
"84" AltoFilePage$'FilePage'
[pageNumber: pn | |
	page word: pagen ← pn "self header:"].
"71" FilePage$'Dictionary'
[ i ← v | |
	↑page  (self checkIndex: i) ← v].
"63" FilePage$'Dictionary'
[ i | |
	↑page  (self checkIndex: i)].
"83" FilePage$'Page'
[dataLength | |
	↑512 "physical length of data in page. default"].
"152" FilePage$'Page'
[asStream: s | offset |
	offset ← self headerLength.
	↑s of: self dataString from: offset + 1 to: offset + self length "self dataEnd"].
"85" FilePage$'Page'
[headerLength | |
	↑0 "length of stuff before data begins in page"].
"57" FilePage$'Page'
[dataBeginning | |
	↑self headerLength].
"103" FilePage$'Page'
[dataMaxEnd | |
	↑self headerLength "physical end of data in page" + self dataLength].
"35" FilePage$'Page'
[page | |
	↑page].
"117" FilePage$'Page'
[pageLength | |
	↑self headerLength "physical size of page" + self dataLength + self trailerLength].
"83" FilePage$'Page'
[trailerLength | |
	↑0 "length of stuff after data ends in page"].
"89" FilePage$'File'
[doCommand: com error: s | |
	↑file doCommand: com page: self error: s].
"41" FilePage$'Page'
[dataString | |
	↑page].
"52" FilePage$'DictionaryEntry'
[dictionary | |
	↑file].
"60" FilePage$'DictionaryEntry'
[dictionary: t1 | |
	file ← t1].
"108" FilePage$'DictionaryEntry'
[name: sp | |
	self init.
	self serialNumber: sp  1.
	self pageNumber: sp  2].
"90" FilePage$'Page'
[header: n ← v | |
	↑page word: n ← v "set and return n-th header word"].
"185" FilePage$'DictionaryEntry'
[init | |
	page  nil
	  ifTrue: [page ← String new: self pageLength "self page:"].
	self length: 0 "not sure who depends on this besides FileStream read:"].
"35" FilePage$'File'
[file | |
	↑file].
"78" FilePage$'Page'
[length | |
	self subError "logical length of data in page"].
"129" FilePage$'File'
[write | |
	↑file Write: self "some files, e.g. AltoFile, will return a last empty page instead of a full one"].
"102" FilePage$'File'
[get: pn | |
	self pageNumber: pn "recycle self".
	self length: 0.
	↑file Get: self].
"49" FilePage$'Initialize'
[page: t1 | |
	page ← t1].
"91" FilePage$'Page'
[word: i | |
	↑page word: self headerLength "no bounds checking" / 2 + i].
"60" FilePage$'Page'
[full | |
	↑self length = self dataLength].
"135" FilePage$'Page'
[checkIndex: i | |
	(i > 0 and: [i  self length])
	  ifTrue: [↑i + self headerLength].
	self error: 'illegal index'].
"95" FilePage$'Page'
[dataEnd | |
	↑self headerLength "logical end of data in page" + self length].
"66" FilePage$'Dictionary'
[asStream | |
	↑self asStream: Stream new].
"77" FilePage$'Page'
[address | |
	self subError "page address, e.g. on a disk"].
"50" FilePage$'Page'
[length: len | |
	self subError].
"52" FilePage$'File'
[endFile | |
	↑file endFile: self].
"95" FilePage$'Page'
[lastPage | |
	↑self pageNumber "is this last page in file?"  file lastPage].
"101" FilePage$'Page'
[word: i ← v | |
	↑page word: (self headerLength "no bounds checking" / 2 + i) ← v].
"49" FilePage$'Page'
[address: a | |
	self subError].
"74" FilePage$'Page'
[dataEnd: pos | |
	self length: pos - self headerLength].
"56" FilePage$'Page'
[serialNumber | |
	↑file serialNumber].
"55" FilePage$'Page'
[serialNumber: sn | |
	self subError].
"104" FilePage$'File'
[read: pn | |
	self pageNumber: pn "recycle self".
	self length: 0.
	↑file Read: self].
"49" FilePage$'Page'
[pageNumber | |
	self subError].
"102" FilePage$'Dictionary'
[reopen | |
	file reopen.
	file makeEntry: self "self may have been released"].
"74" FilePage$'Page'
[header: n | |
	↑page word: n "return n-th header word"].
"53" FilePage$'Page'
[pageNumber: pn | |
	self subError].
"49" FilePage$'Initialize'
[file: t1 | |
	file ← t1].
"121" Dict$'Name-Value Access'
[ name ← value | |
	↑self write: (self newEntry "replace or insert" name: name value: value)].
"71" Dict$'Entry Access'
[list: entries | |
	self match: entries to: user].
"114" Dict$'Name-Value Access'
[ name | entry |
	(entry ← self find: name "find")
	  ifTrue: [↑entry value].
	↑false].
"286" Dict$'Entry Creation'
[makeEntry: entry | cl |
	 "entry or name"
	cl ← self entryClass.
	(cl  false or: [(entry Is: cl)])
	  ifTrue: [↑entry].
	 "entry should not be converted or is the correct type" "convert entry from a name to an entry with that name"
	↑self newEntry name: entry].
"167" Dict$'Entry Creation'
[nextEntry: entry | |
	↑entry "return next name and value in entry, or false.
	if insert or delete occurs after previous next, may be problem"].
"81" Dict$'Stream Access'
[position← name | |
	↑self Position← self makeEntry: name].
"72" Dict$'Entry Access'
[retrieve: entry | |
	↑self find: entry "match:?"].
"249" Dict$'Stream Access'
[Position← entry | |
	↑self position← entry name "position to name, or position to insert place and return false if not found.
	subclass had better define position← or Position← (preferably)
	otherwise circularity results!!!"].
"87" Dict$'Entry Creation'
[entryClass | |
	self subError "a subclass of DictionaryEntry"].
"119" Dict$'Entry Operations'
[Rename: entry from: nentry | |
	self Delete: entry.
	self Insert: (entry name: nentry name)].
"322" Dict$'Entry Access'
[rename: entry newName: name | nentry |
	(self Find: (nentry ← self makeEntry: name "not tested"))
	  ifTrue: [↑self error: 'already exists' error: nentry].
	(self Find: (entry ← self makeEntry: entry))
	  ifTrue:
		[self Rename: entry from: nentry.
		↑entry].
	↑self error: 'not found' entry: entry].
"323" Dict$'Entry Operations'
[Match: entries to: strm | entry pat ents |
	self reset "default (unordered) is to compare entire dictionary with entries".
	self do:
		[:entry | ents ← entries asStream.
		[ents and: [(pat ← ents next)]] whileTrueDo:
			[(pat match: entry)
			  ifTrue:
				[ents ← false.
				strm next← entry]]]].
"86" Dict$'Stream Access'
[append: dict | entry |
	dict do: [:entry | self write: entry]].
"59" Dict$'Name-Value Access'
[lookup: name | |
	↑self  name].
"100" Dict$'Entry Access'
[found: entry | |
	↑self nextEntry: entry "found, fill it in from dictionary"].
"60" Dict$'Entry Access'
[store: entry | |
	↑self write: entry].
"66" Dict$'File-Based dictionary'
[file | |
	↑false "return my file"].
"403" Dict$'Entry Access'
[match: entries to: strm | entry nentries |
	 "return a Set of entries which match those in entries
	(can include exact values and patterns and ranges)"
	((entries is: Vector) or: [(entries Is: Set)])
	  ifFalse: [entries ← entries inVector].
	nentries ← Set new vector: entries length.
	entries do: [:entry | nentries next← self makeEntry: entry].
	↑self Match: nentries to: strm].
"68" Dict$'Initialize'
[init: initialSize | |
	 "default is to ignore"].
"163" Dict$'Entry Access'
[get: entry | |
	(self Find: (entry ← self makeEntry: entry "find or insert"))
	  ifTrue: [↑self found: entry].
	self Insert: entry.
	↑entry].
"187" Dict$'Entry Access'
[insert: entry | |
	(self Find: (entry ← self makeEntry: entry))
	  ifTrue: [↑self error: 'not inserted (already found)' entry: entry].
	self Insert: entry.
	↑entry].
"153" Dict$'File-Based dictionary'
[obsolete | |
	self file "is my information obsolete (should I regenerate it)?"
	  ifTrue: [↑self file obsolete].
	↑false].
"157" Dict$'Entry Access'
[find: entry | |
	(self Find: (entry ← self makeEntry: entry))
	  ifTrue: [↑self found: entry].
	↑self error: 'not found' entry: entry].
"181" Dict$'File-Based dictionary'
[release | |
	 "obsolete and deallocate storage, especially if connected to an external view,
	e.g. a File"
	self file
	  ifTrue: [self file release]].
"109" Dict$'Entry Operations'
[entrySize: entry | |
	self subError "storage size of entry, constant or variable"].
"94" Dict$'Stream Access'
[next | |
	↑self nextEntry: self newEntry "return next entry or false"].
"92" Dict$'Entry Operations'
[Find: entry | |
	↑self Position← entry "is entry in dictionary?"].
"185" Dict$'Entry Access'
[delete: entry | |
	(self Find: (entry ← self makeEntry: entry))
	  ifTrue:
		[self Delete: entry.
		↑entry].
	↑self error: 'not deleted (not found)' entry: entry].
"68" Dict$'Stream Access'
[asStream | |
	 "leave position where it is"].
"78" Dict$'Entry Operations'
[error: e entry: entry | |
	↑false "entry error: e"].
"188" Dict$'Entry Access'
[replace: entry | |
	(self Find: (entry ← self makeEntry: entry))
	  ifTrue:
		[self Replace: entry.
		↑entry].
	↑self error: 'not replaced (not found)' entry: entry].
"118" Dict$'Entry Access'
[match: entries | set |
	set ← Set new vector: 50.
	self match: entries to: set.
	↑set contents].
"183" Dict$'Entry Access'
[write: entry | |
	 "replace or insert"
	(self Find: (entry ← self makeEntry: entry))
	  ifTrue: [self Replace: entry]
	  ifFalse: [self Insert: entry].
	↑entry].
"43" Dict$'File-Based dictionary'
[open | |
	].
"112" Dict$'Name-Value Access'
[insert: name with: value | |
	↑self insert: (self newEntry name: name value: value)].
"114" Dict$'Name-Value Access'
[replace: name with: value | |
	↑self replace: (self newEntry name: name value: value)].
"54" Dict$'Entry Access'
[contents | |
	↑self match: '*'].
"62" Dict$'Entry Access'
[create: entry | |
	↑self insert: entry].
"73" Dict$'Stream Access'
[reset | |
	self subError "position to beginning"].
"92" Dict$'Entry Operations'
[Delete: entry | |
	self subError "entry found (next), delete it"].
"96" Dict$'Entry Operations'
[Insert: entry | |
	self subError "entry not found, insert it (next)"].
"78" Dict$'Stream Access'
[position | |
	self subError "current position (name)"].
"168" Dict$'File-Based dictionary'
[close | |
	self obsolete
	  ifFalse:
		[ "possible cleanup before a release"
		self file
		  ifTrue: [self file close].
		self release]].
"58" Dict$'Entry Access'
[read: entry | |
	↑self find: entry].
"108" Dict$'Entry Access'
[exists: entry | |
	↑self Find: (self makeEntry: entry) "doesn't initialize too much"].
"103" Dict$'File-Based dictionary'
[reopen | |
	self open "reinitialize, especially if a File is involved"].
"97" Dict$'Entry Creation'
[newEntry | t1 |
	↑(t1 ← self entryClass new) dictionary: self.
	t1 init].
"102" Dict$'Entry Operations'
[Replace: entry | |
	self subError "entry found (next), replace it's value"].
"48" Dict$'Entry Access'
[list | |
	self list: '*'].
"55" AltoFile$'Dictionary'
[entryClass | |
	↑AltoFilePage].
"332" AltoFileAddressTable$'Reading and writing'
[ i ← val | virt |
	virt ← dp0 realToVirtual: val.
	starts  nil
	  ifTrue:
		[super  i ← virt.
		↑val].
	super  i ← virt - i + starts last "superclass tries for constant runs".
	offset > 0
	  ifTrue: [↑val].
	 "OK if same run"
	values last← virt.
	↑val "else fix new run value base"].
"113" AltoFileAddressTable$'Reading and writing'
[ i | base |
	base ← super  i.
	↑dp0 virtualToReal: base + offset].
"304" AltoFileAddressTable$'Reading and writing'
[position← p | l |
	 "shortens (for file shorten)"
	p > max
	  ifTrue: [user notify: 'invalid extension']
	  ifFalse:
		[max ← p.
		(l ← starts findSorted: max) < starts length
		  ifTrue:
			[starts ← starts copy: 1 to: l.
			values ← values copy: 1 to: l]]].
"401" RunVector$'Reading and writing'
[ i ← val | |
	offset ← 0.
	min  nil
	  ifTrue:
		[min ← max ← i.
		starts ← i inVector.
		values ← val inVector]
	  ifFalse:
		[i - 1  max
		  ifTrue:
			[user notify: 'RunVectors must be loaded sequentially'.
			↑val].
		max ← i.
		val = values last
		  ifTrue:
			[offset ← i - starts last.
			↑val].
		starts ← {starts , i}.
		values ← {values , val}.
		↑val]].
"49" RunVector$'Reading and writing'
[max | |
	↑max].
"149" RunVector$'Reading and writing'
[ i | index |
	index ← starts findSorted: i.
	offset ← i - (starts  index) "distance into run".
	↑values  index].
"49" RunVector$'Reading and writing'
[min | |
	↑min].
"90" RunVector$'Reading and writing'
[length | |
	max  nil
	  ifTrue: [↑0].
	↑max - min + 1].
"72" Array$'Reading and Writing'
[ x ← val | |
	↑x subscripts: self ← val].
"60" Array$'Reading and Writing'
[ x | |
	↑x subscripts: self].
"61" Array$'Copying and Altering'
[+ arg | |
	↑self concat: arg].
"101" Array$'Reading and Writing'
[> v | |
	 "for sorting vectors by first element"
	↑self  1 > (v  1)].
"101" Array$'Reading and Writing'
[< v | |
	 "for sorting vectors by first element"
	↑self  1 < (v  1)].
"228" Array$'Reading and Writing'
[= arg | x |
	arg isArray
	  ifTrue:
		[self length  arg length
		  ifTrue: [↑false].
		(1 to: self length) do:
			[:x | self  x = (arg  x)
			  ifFalse: [↑false]].
		↑true]
	  ifFalse: [↑false]].
"77" Array$'Copying and Altering'
[growby: n | |
	↑self growto: self length + n].
"72" Array$'Reading and Writing'
[last← val | |
	↑self  self length ← val].
"82" Array$'Reading and Writing'
[length | |
	user notify: 'message not understood.'].
"146" Array$'Comparing'
[hash | |
	 "make sure = arrays hash =ly"
	self length = 0
	  ifTrue: [↑17171].
	↑(self  1) hash + (self  self length) hash].
"102" Array$'Mapping'
[cansubscript: a | i |
	self do:
		[:i | (i cansubscript: a)
		  ifFalse: [↑false]]].
"53" Array$'Searching'
[has: x | |
	↑(self find: x)  0].
"72" Array$'Copying and Altering'
[copy | |
	↑self copy: 1 to: self length].
"85" Array$'Mapping'
[subscripts: x | |
	 "subarrays"
	↑Substring new data: x map: self].
"217" Array$'Mapping'
[subscripts: x ← val | |
	 "subrange replacement"
	self length  val length
	  ifTrue: [user notify: 'lengths not commensurate']
	  ifFalse:
		[val copyto: (Substring new data: x map: self).
		↑val]].
"51" Array$'Compatibility'
[isIntervalBy1 | |
	↑false].
"104" Array$'Searching'
[find: x | i |
	(1 to: self length) do:
		[:i | self  i = x
		  ifTrue: [↑i]].
	↑0].
"46" Array$'Compatibility'
[species | |
	↑Vector].
"113" Array$'Copying and Altering'
[growto: n | |
	↑self copy: 1 to: self length "copyto:" to: (self species new: n)].
"177" Array$'Copying and Altering'
[delete: obj | s each |
	s ← (self species new: self length) asStream.
	self do:
		[:each | obj = each
		  ifFalse: [s next← each]].
	↑s contents].
"61" Array$'Reading and Writing'
[last | |
	↑self  self length].
"57" Array$'Conversion'
[asStream | |
	↑Stream new of: self].
"39" Array$'Compatibility'
[isArray | |
	].
"93" Array$'Reading and Writing'
[all← val | i |
	(1 to: self length) do: [:i | self  i ← val]].
"58" Array$'Conversion'
[viewer | |
	↑SetReader new of: self].
"52" Array$'Reading and Writing'
[first | |
	↑self  1].
"81" Array$'Copying and Altering'
[grow | |
	↑self growto: (4 max: self length * 2)].
"233" Array$'Permutation'
[sort | |
	self sort: 1 to: self length "Permute my elements so they are sorted nondescending.  Note: if I am a substring, only my map will be permuted.  In certain situations, this may not be what you expect."].
"94" Array$'Permutation'
[reverse | |
	↑Substring new data: self map: (self length to: 1 by: 1)].
"213" Array$'Permutation'
[permutationToSort | |
	↑(self  (1 to: self length "Return a Vector, permutation, such that selfpermutation is sorted nondescending.  Do not alter self.") copy sort: 1 to: self length) map].
"115" Array$'Copying and Altering'
[insertNonDescending: x | |
	 "self is assumed to be sorted"
	↑self insertSorted: x].
"83" Array$'Copying and Altering'
[copyto: t | |
	↑self copy: 1 to: self length to: t].
"124" Array$'Searching'
[count: x | i n |
	n ← 0.
	(1 to: self length) do:
		[:i | x = (self  i)
		  ifTrue: [n ← n + 1]].
	↑n].
"238" Array$'Copying and Altering'
[notNil | t i |
	 "copy self (which contains no falses) removing all nils"
	t ← (self species new: self length - (self count: nil)) asStream.
	self do:
		[:i | i  nil
		  ifFalse: [t next← i]].
	↑t asArray].
"253" Array$'Copying and Altering'
[replace: a to: b by: s | x xs |
	x ← self species new: self length + s length - (1 + b - a).
	xs ← x asStream.
	self copy: 1 to: a - 1 to: xs.
	s copy: 1 to: s length to: xs.
	self copy: b + 1 to: self length to: xs.
	↑x].
"1203" Array$'Permutation'
[sort: i to: j | di dij dj tt ij k l n |
	(n ← j + 1 "Sort elements i through j of self to be nondescending." "The prefix d means the data at." - i)  1
	  ifFalse:
		[ "Nothing to sort." "Sort di,dj."
		di ← self  i.
		dj ← self  j.
		di > dj
		  ifTrue:
			[self swap: i with: j.
			tt ← di.
			di ← dj.
			dj ← tt].
		n = 2
		  ifFalse:
			[ "They are the only two elements."
			ij ← i + j lshift: 1 "ij is the midpoint of i and j." "Sort di,dij,dj.  Make dij be their median.".
			dij ← self  ij.
			di > dij
			  ifTrue:
				[self swap: i with: ij.
				dij ← di]
			  ifFalse:
				[dj < dij
				  ifTrue:
					[self swap: j with: ij.
					dij ← dj]].
			n = 3
			  ifFalse:
				[ "They are the only three elements." "Find k>i and l<j such that dk,dij,dl are in reverse order.  Swap k and l.  Repeat this procedure until j and k pass each other."
				k ← i.
				l ← j.
				[[self  (l ← l - 1) > dij] whileTrueDo: [].
				[self  (k ← k + 1) < dij] whileTrueDo: [].
				k  l] whileTrueDo: [self swap: k with: l "Now l<k (either 1 or 2 less), and di through dl are all less than dk through dj.  Sort those two segments."].
				self sort: i to: l.
				self sort: k to: j]]]].
"107" Array$'Searching'
[findnon: x | i |
	(1 to: self length) do:
		[:i | self  i  x
		  ifTrue: [↑i]].
	↑0].
"152" Array$'Permutation'
[promote: t | n |
	n ← self find: t.
	n = 0
	  ifFalse:
		[self  (n to: 2 by: 1) ← self  (n - 1 to: 1 by: 1).
		self  1 ← t]].
"105" Array$'Copying and Altering'
[copy: a to: b | |
	↑self copy: a to: b to: (self species new: b - a + 1)].
"338" Array$'Copying and Altering'
[without: index | s me i |
	 "if index in range, return self without index"
	(index cansubscript: self)
	  ifTrue:
		[s ← (self species new: self length - 1) asStream.
		me ← self asStream.
		(1 to: self length) do:
			[:i | i = index
			  ifTrue: [me next]
			  ifFalse: [s next← me next]].
		↑s asArray]].
"96" Array$'Permutation'
[swap: i with: j | t |
	t ← self  i.
	self  i ← self  j.
	self  j ← t].
"46" Array$'Conversion'
[sum | |
	↑self sumTo: 0].
"153" Array$'Copying and Altering'
[concat: arg | x s |
	x ← self species new: self length + arg length.
	self copyto: (s ← x asStream).
	arg copyto: s.
	↑x].
"67" Array$'Conversion'
[asSet | |
	↑Set new of: self to: self length].
"201" Array$'Copying and Altering'
[copy: a to: b to: t | i s me |
	s ← t asStream.
	me ← Stream new of: self from: a to: b.
	(a to: b) do: [:i |  "general code wont stop at false"
		s next← me next].
	↑t].
"304" Array$'Searching'
[findSorted: x | lo mid hi |
	 " returns index of largest element  x "
	hi ← self length + 1.
	lo ← 1.
	[lo < hi] whileTrueDo:
		[ "binary search; self must be sorted"
		self  (mid ← lo + hi / 2) > x
		  ifTrue: [hi ← mid]
		  ifFalse: [lo ← mid + 1]].
	↑hi - 1 " 0resultlength "].
"85" Dictionary$'Searching'
[ name ← val | |
	↑values  (self findorerror: name) ← val].
"222" Dictionary$'Private'
[growto: size | name copy |
	copy ← self class new init: size "create a copy of the new size".
	self do: [:name | copy insert: name with: self  name].
	self copyfrom: copy "hash each entry into it"].
"73" Dictionary$'Searching'
[ name | |
	↑values  (self findorerror: name)].
"185" Dictionary$'Inserting and Deleting'
[delete: name | |
	(name is: Vector)
	  ifTrue: [super delete: name]
	  ifFalse:
		[values  (self findorerror: name) ← nil.
		super delete: name]].
"155" Dictionary$'Inserting and Deleting'
[tally: name | x |
	(x ← self find: name)
	  ifTrue: [↑values  x ← values  x + 1].
	self insert: name with: 1.
	↑1].
"44" Dictionary$'Private'
[values | |
	↑values].
"141" Dictionary$'Inserting and Deleting'
[with: names values: vals | i |
	(1 to: names length) do: [:i | self insert: names  i with: vals  i]].
"141" Dictionary$'Inserting and Deleting'
[insertall: names | |
	 "default value is nil"
	self insertall: names with: (Vector new: names length)].
"168" Dictionary$'Inserting and Deleting'
[insertall: names with: vals | i |
	 "insert many entries"
	(1 to: names length) do: [:i | self insert: names  i with: vals  i]].
"92" Dictionary$'Private'
[swap: i with: j | |
	values swap: i with: j.
	super swap: i with: j].
"111" Dictionary$'Initialization'
[copyfrom: dict | |
	self objects← dict objects copy.
	values ← dict values copy].
"298" Dictionary$'Inversion'
[asInvertedVector | s i v |
	 "in form ((value, object), ...)"
	s ← (Vector new: objects length) asStream.
	(1 to: objects length) do:
		[:i | objects  i  nil
		  ifFalse:
			[v ← Vector new: 2.
			v  1 ← values  i.
			v  2 ← objects  i.
			s next← v]].
	↑s contents].
"131" Dictionary$'Inserting and Deleting'
[insert: name with: value | |
	self insert: name.
	values  (self findorerror: name) ← value].
"167" Dictionary$'Inversion'
[invertto: dict | i |
	(1 to: objects length) do:
		[:i | objects  i  nil
		  ifFalse: [dict insert: values  i with: objects  i]].
	↑dict].
"258" Dictionary$'Private'
[rehash | i copy |
	copy ← Dictionary new init: self size "create a copy".
	(1 to: objects length) "hash each entry into it" do:
		[:i | objects  i  nil
		  ifFalse: [copy insert: objects  i with: values  i]].
	self copyfrom: copy].
"92" Dictionary$'Inversion'
[invert | |
	↑self invertto: (Dictionary new init: objects length)].
"102" Dictionary$'Searching'
[lookup: name | x |
	(x ← self find: name)
	  ifTrue: [↑values  x].
	↑false].
"133" Dictionary$'Inversion'
[invert: obj | i |
	(1 to: values length) do:
		[:i | values  i = obj
		  ifTrue: [↑objects  i]].
	↑false].
"181" Dictionary$'Inserting and Deleting'
[clean | name |
	 "release unreferenced entries"
	self do:
		[:name |  "slick, huh"
		(self  name) refct = 1
		  ifTrue: [self delete: name]]].
"92" Dictionary$'Initialization'
[init: size | |
	values ← Vector new: size.
	super init: size].
"239" HashSet$'Private'
[growto: t1 | t2 t3 |
	 "faster insert for growing"
	t2 ← self class new init: t1.
	t1 < objects length
	  ifTrue: [self do: [:t3 | t2 insert: t3]]
	  ifFalse: [self do: [:t3 | t2 rawinsert: t3]].
	objects ← t2 objects].
"375" HashSet$'Insertion and deletion'
[delete: obj | i j l |
	(obj is: Vector)
	  ifTrue: [obj do: [:i | self delete: i]]
	  ifFalse:
		[i ← self findorerror: obj.
		objects  i ← nil.
		l ← objects length.
		[objects  (i ← (i = l
				  ifTrue: [1]
				  ifFalse: [i + 1]))  nil] whileFalseDo: 
			[i = (j ← self findornil: objects  i)
			  ifFalse: [self swap: i with: j]]]].
"43" HashSet$'Private'
[objects | |
	↑objects].
"67" HashSet$'Access to parts'
[asStream | |
	↑self contents asStream].
"179" HashSet$'Access to parts'
[contents | obj strm |
	strm ← (Vector new: objects length) asStream.
	objects do:
		[:obj | obj  nil
		  ifFalse: [strm next← obj]].
	↑strm contents].
"51" HashSet$'Private'
[objects← t1 | |
	objects ← t1].
"238" HashSet$'Private'
[rehash | i copy |
	copy ← HashSet new init: self size "create a copy".
	(1 to: objects length) "hash each entry into it" do:
		[:i | objects  i  nil
		  ifFalse: [copy insert: objects  i]].
	objects ← copy objects].
"215" HashSet$'Private'
[sparse | i n |
	n ← objects length "true if (1 max: 1/4 of table) is nil".
	(1 to: objects length) do:
		[:i | objects  i  nil
		  ifTrue:
			[(n ← n - 4)  0
			  ifTrue: [↑true]]].
	↑false].
"90" HashSet$'Insertion and deletion'
[insertall: objs | x |
	objs do: [:x | self insert: x]].
"102" HashSet$'Initialization'
[copyfrom: hset | |
	 "take on state of hset"
	objects ← hset objects copy].
"66" HashSet$'Private'
[swap: i with: j | |
	objects swap: i with: j].
"214" HashSet$'Searching'
[findorerror: name | i |
	i ← self findornil: name.
	objects  i = name
	  ifTrue: [↑i].
	 "allow the user to put a correct value into i"
	user notify: name asString + ' cannot be found'.
	↑i].
"297" HashSet$'Private'
[findorinsert: obj | i |
	 "insert if not found, "
	i ← self findornil: obj.
	objects  i = obj
	  ifTrue: [↑i].
	 "found it"
	self sparse
	  ifTrue:
		[objects  i ← obj.
		↑i].
	 "insert if room"
	self growto: objects length * 2 "grow".
	↑self findorinsert: obj "and insert"].
"357" HashSet$'Private'
[findornil: obj | i loc |
	 "index if found or available slot"
	loc ← obj hash \ objects length.
	(1 to: objects length) do:
		[:i | loc ← (loc = objects length
				  ifTrue: [1]
				  ifFalse: [loc + 1]).
		objects  loc  nil
		  ifTrue: [↑loc].
		objects  loc = obj
		  ifTrue: [↑loc]].
	↑1 "table full - caller must check for hit"].
"418" HashSet$'Growing and shrinking'
[packprobes | tot n l i obj t |
	 "(fullness, avg #probes)"
	tot ← n ← 0.
	l ← objects length.
	(1 to: l) do:
		[:i | (obj ← objects  i)  nil
		  ifFalse:
			[t ← obj hash \ l.
			tot ← tot + (i < t
					  ifTrue: [l - t + i]
					  ifFalse: [i - t]).
			n ← n + 1]].
	n = 0
	  ifTrue: [↑{1 , 1}].
	↑{n asFloat / l , (tot asFloat / n)} "Class md packprobes(0.4921875 2.53968255 )"].
"51" HashSet$'Initialization'
[init | |
	self init: 4].
"194" HashSet$'As yet unclassified'
[lookup: obj | i |
	 "object if found, else false (object=obj but may not obj)"
	i ← self findornil: obj.
	objects  i = obj
	  ifTrue: [↑objects  i].
	↑false].
"76" HashSet$'Searching'
[has: obj | |
	↑objects  (self findornil: obj) = obj].
"80" HashSet$'Initialization'
[init: size | |
	objects ← Vector new: (size max: 2)].
"88" HashSet$'Initialization'
[copy | |
	 " a copy of me"
	↑self class new copyfrom: self].
"55" HashSet$'Access to parts'
[size | |
	↑objects length].
"85" HashSet$'Insertion and deletion'
[insert: obj | i |
	self findorinsert: obj.
	↑obj].
"319" HashSet$'Growing and shrinking'
[shrink | table oldtable |
	oldtable ← self.
	table ← oldtable growto: (2 max: oldtable size / 2).
	[table size = oldtable size] whileFalseDo: 
		[(oldtable size - table size) print.
		user show: ' '.
		oldtable ← table.
		table ← oldtable growto: (2 max: oldtable size / 2)].
	↑table].
"141" HashSet$'Searching'
[find: obj | i |
	 "index if found, else false"
	i ← self findornil: obj.
	objects  i = obj
	  ifTrue: [↑i].
	↑false].
"135" HashSet$'Private'
[rawinsert: t1 | t2 |
	 "assumes there is room for the new one"
	t2 ← self findornil: t1.
	objects  t2 ← t1.
	↑t2].
"184" Array$'Conversion'
[frequencies | d x |
	 "return a sorted vector ((freq item) (freq item) ...)"
	d ← Dictionary new init: 64.
	self do: [:x | d tally: x].
	↑d asInvertedVector sort].
"238" Array$'Conversion'
[transform each to expr | s i |
	 "a copy of me with each element transformed"
	s ← (self species new: self length) asStream.
	(1 to: self length) do:
		[:i | each value← self  i.
		s next← expr eval].
	↑s asArray].
"147" Array$'Searching'
[find x suchThat predicate | i |
	(1 to: self length) do:
		[:i | x value← self  i.
		predicate eval
		  ifTrue: [↑i]].
	↑0].
"259" Array$'Copying and Altering'
[insertSorted: x | a c i |
	 "self is assumed to be sorted"
	i ← self findSorted: x.
	c ← (a ← self species new: self length + 1) asStream.
	self  (1 to: i) copyto: c.
	c next← x.
	self  (i + 1 to: self length) copyto: c.
	↑a].
"251" Array$'Searching'
[all variable suchThat expr | s i x |
	 "a copy of some of me"
	s ← (self species new: self length) asStream.
	(1 to: self length) do:
		[:i | x ← self  i.
		variable value← x.
		expr eval
		  ifTrue: [s next← x]].
	↑s contents].
"159" Array$'Searching'
[first x suchThat predicate | i |
	(1 to: self length) do:
		[:i | x value← self  i.
		predicate eval
		  ifTrue: [↑self  i]].
	↑false].
"157" Array$'Conversion'
[sumTo: subTotal | x |
	 "add all my elements to this subTotal (usually 0 or 0.0)"
	self do: [:x | subTotal ← subTotal + x].
	↑subTotal].
"94" AltoFile$'DictionaryEntry'
[init | |
	super init.
	pageAddresses ← AltoFileAddressTable new].
"259" AltoFile$'File'
[doCommand: com page: page error: e | |
	error ← nullString.
	(self dskprim: directory diskNumber address: page address command: com page: page page)
	  ifTrue: [↑page].
	error ← self errorString: error "set by dskprim:...".
	↑self error: e].
"613" AltoFile$'Alto'
[errorString: status | t s |
	status = 1 "see Alto hardware manual for details on error word format"
	  ifTrue: [↑'primitive failure, bad args?'].
	s ← Stream default.
	s append: #('' 'hardware error or sector overflow' 'check error' 'disk command specified illegal sector' )  (1 + (status land: 3)).
	(1 to: 6) do:
		[:t | (status allmask: (128 lshift: 1 - t))
		  ifTrue:
			[s space.
			s append: #('seek failed, possible illegal track' 'seek in progress' 'disk unit not ready' 'hardware late' 'hardware not transferring' 'checksum' )  t]].
	s space.
	s append: status base8.
	↑s contents].
"39" AltoFile$'Alto'
[leader | |
	↑leader].
"61" AltoFile$'Alto'
[pageAddresses: t1 | |
	pageAddresses ← t1].
"897" AltoFile$'File'
[Write: page | nextPage labelDirty returnPage |
	((labelDirty ← page lastPage) and: [page full])
	  ifTrue:
		[returnPage ← nextPage ← self newPage "last page can't be full, so glue on another page".
		directory allocate: nextPage after: (directory realToVirtual: page address).
		nextPage init.
		nextPage header: backp ← page address.
		nextPage pageNumber: (lastpn ← page pageNumber + 1).
		nextPage serialNumber: serialNumber.
		nextPage doCommand: CWW error: 'writePage: (allocate)' "link to current page".
		page header: nextp ← nextPage address.
		pageAddresses
		  ifTrue: [pageAddresses  lastpn ← nextPage address] "growSmalltalkBy:"]
	  ifFalse: [returnPage ← page] "whenever a last (or second last) page is written, write label also".
	self doCommand: (labelDirty
	  ifTrue: [CWW]
	  ifFalse: [CCW]) page: page error: 'writePage:'.
	type ← read + write.
	↑returnPage].
"100" AltoFile$'Dictionary'
[open | |
	type ← read "don't find last page immediately.  for later close"].
"391" AltoFile$'File'
[sameFile | page s |
	(page ← self newPage: 0) address: leader "if any of following  tests fail, File will be reinitialized".
	↑((page doCommand: CCR error: false) "serial number match" and: [page pageNumber "correct page number" = 0]) and: [(s ← page asStream "last write was by us".
	type = (s next: 4) and: [(s skip: 8 "same name".
	(name compare: s nextString) = 2)])]].
"787" AltoFile$'File'
[endFile: page | nextPage pn |
	page  false
	  ifTrue: [pn ← 1 "free all of file"]
	  ifFalse:
		[page full
		  ifTrue:
			[nextPage ← self Write: page "if page was a full last page, next is an empty (and now last) page".
			nextPage lastPage
			  ifTrue: [↑nextPage].
			page ← self read: page pageNumber + 1.
			page empty
			  ifTrue: [↑page].
			page length: 0].
		page header: nextp ← 0.
		self Write: page "free rest of file".
		pn ← page pageNumber].
	lastpn ← false "reset by readPage:".
	[lastpn  false and: [(nextPage ← self read: (pn ← pn + 1))]] whileTrueDo:
		[nextPage init.
		nextPage freePage.
		nextPage doCommand: CWW error: 'endFile:'.
		directory deallocate: nextPage].
	page
	  ifTrue: [pageAddresses position← lastpn ← page pageNumber].
	↑page].
"47" AltoFile$'Alto'
[leader: t1 | |
	leader ← t1].
"838" AltoFile$'File'
[Read: page | pn p palen |
	pn ← page pageNumber.
	pageAddresses
	  ifTrue: [palen ← pageAddresses length]
	  ifFalse:
		[pn = 0
		  ifTrue: [palen ← 0]
		  ifFalse: [↑false]].
	((palen min: pn) to: pn) do:
		[:p | page pageNumber: p "set up page for checking" "zeroed by machine code
			header: nextp ← [p < palen [pageAddresses(p+1)] 0];
			header: backp ← [p=0 [0]; =1eader] pageAddresses(p-1)];
			length: [p < palen [page dataLength] 0];".
		page address: (p = 0
		  ifTrue: [leader]
		  ifFalse: [pageAddresses  p]).
		page doCommand: CCR error: 'readPage:'.
		page lastPage
		  ifTrue:
			[(lastpn ← p) < pn
			  ifTrue: [↑false]]
		  ifFalse:
			[(p  palen and: [pageAddresses])
			  ifTrue: [pageAddresses  (p + 1) ← page header: nextp] "no need to store if already known or no page table"]].
	↑page].
"239" AltoFile$'DictionaryEntry'
[readFrom: s | |
	serialNumber ← s next: 4 "read file description from SysDir".
	s skip: 4 "self version: s nextword. s skip: 2".
	leader ← directory virtualToReal: s nextword.
	name ← s nextString.
	s padNext].
"306" AltoFile$'File'
[Get: page | p pn |
	pn ← page pageNumber.
	(self Read: page)
	  ifTrue: [↑page].
	 "page now contains last page"
	(lastpn to: pn - 1) do:
		[:p | page pageNumber: p.
		page length: page dataLength "this writes current and allocates next (empty) page".
		page ← self Write: page].
	↑page].
"440" AltoFile$'File'
[classInit | |
	AltoFilePool declare: #(CRR CCR CCW CWW ) as: #(18496 18512 18520 18536 ) "before filing in:
		Smalltalk declare: AltoFilePool as: (SymbolTable new init: 32)" "disk commands".
	AltoFilePool declare: #(dfmask boffset dirname ) as: #(1024 32 'SysDir.' ) "bit means active directory entry" "byte offset of bit table in DiskDescriptor".
	AltoFilePool declare: #(nextp backp numch pagen vn ) as: #(1 2 4 5 6 )].
"100" AltoFile$'Dictionary'
[close | |
	type ← self updateLeader: (self read: 0) "to look at at reopen"].
"388" AltoFile$'Alto'
[dskprim: diskNumber address: a command: com page: string | |<primitive: 79>
	 "0/1" "starting Alto disk address" "disk command (usually CCR, CCW, CWW)" "string containing label and data"
	error ← 1 "if disk routine encounters an error,
	error ← (DCB status, to be interpreted by errorString:).
	false" "if other error occurs, e.g. nil instead of Integer...".
	↑false].
"64" AltoFile$'File'
[findLastPage | |
	self read: 20000.
	↑lastpn].
"540" AltoFile$'Alto'
[updateLeader: page | s time lastwrite |
	time ← user timewords "see <Alto>AltoFileSys.D, (p.3 leader page) for further info".
	s ← page asStream.
	(type anymask: write)
	  ifTrue:
		[directory flush "set creation/write/read date and file name".
		lastwrite ← time.
		s append: time.
		s append: time.
		s append: time.
		name empty
		  ifFalse: [s nextString← name]]
	  ifFalse:
		[ "remember creation, skip write, update read date"
		lastwrite ← s next: 4.
		s skip: 4.
		s append: time].
	self Write: page.
	↑lastwrite].
"63" File$'DictionaryEntry'
[printon: strm | |
	strm append: name].
"103" File$'DictionaryEntry'
[init | |
	lastpn ← false.
	error ← nullString.
	serialNumber ← String new: 4].
"170" File$'File Length'
[length | page |
	page ← self read: self lastPage "length in characters" "defeat ST76 optimization".
	.
	↑lastpn - 1 * page dataLength + page length].
"86" File$'FileDirectory'
[rename: newName | |
	↑directory rename: self newName: newName].
"64" File$'FilePage'
[get: pn | |
	↑self Get: (self makeEntry: pn)].
"37" File$'FilePage'
[error | |
	↑error].
"237" FileStream$'File'
[settopage: p char: c | |
	(self read: p asSmall "mainly for compatibility, since page sizes may vary.
	in general, use position←, wordposition←")
	  ifTrue: [self skip: c asSmall]
	  ifFalse: [self error: 'no page']].
"73" FileStream$'Stream'
[ i ← v | |
	self position← i - 1.
	↑self next← v].
"66" FileStream$'Stream'
[ i | |
	self position← i - 1.
	↑self next].
"93" FileStream$'File'
[flush | |
	self obsolete
	  ifTrue: [↑page].
	self fixEnd.
	↑page write].
"277" FileStream$'Filin/Filout'
[filin | p |
	user cr.
	self readonly.
	self end
	  ifTrue: [self file error: 'empty file']
	  ifFalse:
		[[p ← self nextParagraph] whileTrueDo:
			[FilinSource ← self.
			user print: nil  p text.
			user space].
		self close.
		FilinSource ← nil]].
"70" FileStream$'Stream'
[wordposition← w | |
	↑self position: w size: 2].
"132" FileStream$'Print'
[printout: source | t2 |
	(t2 ← self asPressPrinter) stamp.
	t2 printchanges: source.
	t2 close.
	t2 toPrinter].
"66" FileStream$'Stream'
[position← p | |
	↑self position: p size: 1].
"166" FileStream$'File'
[shorten | |
	self on:  "normally called by close and not directly by user"
	(page dataEnd: (limit ← position).
	page endFile).
	position ← limit].
"126" FileStream$'Filin/Filout'
[filout: source | t2 |
	(t2 ← self asParagraphPrinter) stamp.
	t2 printchanges: source.
	t2 close].
"110" FileStream$'Stream'
[printon: strm | |
	super printon: strm.
	strm append: ' on '.
	self file printon: strm].
"302" FileStream$'Print'
[toPrinter | pp p |
	user displayoffwhile [
		 "print an unformatted or Bravo file as a press file"
		(pp ← (self directory file: self name + 'Press') asPressPrinter.
		self readonly.
		[p ← self nextParagraph] whileTrueDo: [pp print: p].
		self close)].
	pp close.
	pp toPrinter].
"267" FileStream$'Access Modes'
[writeshorten | |
	self setMode: write + shorten "allow write and shorten File upon closing. in general, this would be faster for overwriting Files since pages might not have to be read first. at present, treated same as readwriteshorten"].
"170" FileStream$'Stream'
[end | |
	self reopen.
	position < limit
	  ifTrue: [↑false].
	(self read: page pageNumber + 1)
	  ifTrue: [↑position = limit "page empty"].
	↑true].
"501" FileStream$'Stream'
[append: s | |
	 "try to make some special cases go much faster"
	(s is: String)
	  ifTrue:
		[s length > 80
		  ifTrue:
			[self writeString: s from: 1 to: s length.
			↑s]]
	  ifFalse:
		[(s is: Stream)
		  ifTrue:
			[(s limit - s position > 80 and: [(s asArray is: String)])
			  ifTrue:
				[self writeString: s asArray from: s position + 1 to: s limit.
				↑s]]
		  ifFalse:
			[(s is: FileStream)
			  ifTrue:
				[self writeFile: s for: nil.
				↑s]]].
	↑super append: s].
"48" FileStream$'Dictionary'
[file | |
	↑page file].
"166" FileStream$'Stream'
[next: n from: strm | |
	(n > 80 and: [(strm is: FileStream)])
	  ifTrue: [self writeFile: strm for: n]
	  ifFalse: [↑super next: n from: strm]].
"135" FileStream$'Stream'
[length | |
	page lastPage
	  ifTrue: [↑page pageNumber - 1 * page dataLength + page length].
	↑self file length].
"48" FileStream$'Dictionary'
[obsolete | |
	↑dirty].
"78" FileStream$'Stream'
[word: i | |
	self wordposition← i - 1.
	↑self nextword].
"76" FileStream$'Filin/Filout'
[filout | |
	self filout: Changes contents sort].
"134" FileStream$'Stream'
[contents | s |
	self readonly "read all of a File".
	self reset.
	s ← self next: self length.
	self close.
	↑s].
"85" FileStream$'Stream'
[word: i ← v | |
	self wordposition← i - 1.
	↑self nextword← v].
"251" FileStream$'Initialize'
[on: t1 | |
	 "some page from a File, usually page 1, or another FileStream"
	page ← t1.
	(page is: FileStream)
	  ifTrue: [page ← page page].
	page asStream: self.
	externalViews insert: self "obsolete flag".
	dirty ← false].
"653" FileStream$'Stream'
[skip: n | p plen |
	n = 0
	  ifFalse:
		[self reopen.
		p ← position + n.
		(n > 0
		  ifTrue: [p  limit]
		  ifFalse:
			[self fixEnd "important on last page".
			p < page dataBeginning])
		  ifTrue:
			[plen ← page dataLength "simply: self position ← self position + n.
		however, since we are incurable optimizers..." "assume p is not Large, otherwise use intdiv:".
			p ← p - page dataBeginning.
			(self positionPage: page pageNumber + (n < 0
			  ifTrue: [p + 1 / plen - 1]
			  ifFalse: [p / plen]) character: p \ plen)
			  ifFalse: [self error: 'cannot skip ' + n asString]]
		  ifFalse: [ "same page"
			position ← p]]].
"313" FileStream$'Stream'
[settoend | |
	self reopen "self position ← self length" "make sure file is open so lastPage is correct" "when writing on the last page, lastPage may be too small".
	(self read: (self file lastPage max: page pageNumber))
	  ifTrue: [position ← limit]
	  ifFalse: [self error: 'settoend???']].
"504" FileStream$'Stream'
[into: s endError: err | charsRead len t |
	len ← s length.
	len > 80
	  ifTrue: [charsRead ← len - (self readString: s from: 1 to: len)]
	  ifFalse:
		[ "in line: super into: s endError: err"
		charsRead ← 0 "read until count or stream is exhausted".
		[charsRead < len and: [(t ← self next)]] whileTrueDo: [s  (charsRead ← charsRead + 1) ← t]].
	err
	  ifTrue:
		[charsRead = len
		  ifTrue: [↑s].
		user notify: 'only read first ' + charsRead asString]
	  ifFalse: [↑charsRead]].
"339" FileStream$'Stream'
[pastend← v | |
	self writing
	  ifTrue:
		[self reopen
		  ifTrue: [↑self next← v].
		(limit < page dataMaxEnd or: [(self nextPage
		  ifTrue: [position = limit]
		  ifFalse: [self error: 'could not get page'])])
		  ifTrue: [limit ← page dataMaxEnd].
		↑self next← v]
	  ifFalse: [self error: 'no writing allowed']].
"134" FileStream$'Stream'
[pastend | |
	(self reopen or: [(page lastPage  false and: [self nextPage])])
	  ifTrue: [↑self next].
	↑false].
"59" FileStream$'Stream'
[position | |
	↑self positionSize: 1].
"103" FileStream$'Stream'
[reset | |
	(self read: 1) "self position ← 0"
	  ifFalse: [self error: 'reset']].
"249" FileStream$'Dictionary'
[close | |
	self obsolete
	  ifFalse:
		[self writing
		  ifTrue:
			[(rwmode anymask: shorten)
			  ifTrue: [self shorten]
			  ifFalse: [self flush]].
		dirty ← limit ← 0.
		self file close.
		externalViews delete: self]].
"873" FileStream$'Fast Access'
[readString: s from: start to: stop | len charsLeft |
	self readonly "for reading a subrange of a large String from a file (quickly, if BitBlt is used);
	called by FileStream into:endError:".
	self reopen.
	start ← start - 1.
	charsLeft ← stop - start "keep going until all of the requested characters are copied or
	until end of file. if end of current page only, next page is read.".
	[charsLeft > 0 and: [self end  false]] whileTrueDo:
		[len ← limit - position "len = # characters of current page that will fit in String" min: charsLeft.
		charsLeft ← charsLeft - len "copy subrange of page into String".
		s copy: start + 1 to: start + len with: array from: position + 1 to: position + len "update source and destination pointers".
		position ← position + len.
		start ← start + len "return the number of characters not read"].
	↑charsLeft].
"1079" FileStream$'File'
[read: pn | p |
	pn < 1 "normally accessed by nextPage, position:size:, reopen, reset, settoend"
	  ifTrue: [↑false].
	self obsolete
	  ifTrue:
		[page reopen "reopen the file, (re)read the page".
		(p ← page read: pn)
		  ifTrue: [self on: p]
		  ifFalse: [↑false]]
	  ifFalse:
		[(pn = page pageNumber and: [(page length > 0 or: [position > page dataBeginning])])
		  ifTrue:
			[self fixEnd.
			page asStream: self]
		  ifFalse:
			[ "current page has wrong page number or is empty (possibly from error)"
			self writing
			  ifTrue:
				[((pn > page pageNumber and: [page full  false])
				  ifTrue: [position ← page dataMaxEnd "fill up last page when positioning past it"]
				  ifFalse: [ "otherwise, fixEnd"
					position > page dataEnd])
				  ifTrue: [page dataEnd: (limit ← position)].
				p ← page write.
				p pageNumber = pn
				  ifFalse: [ "already have next page, e.g. at end of AltoFile" "read it or create it"
					p ← page get: pn]]
			  ifFalse: [p ← page read: pn].
			p
			  ifTrue: [(page ← p) asStream: self]
			  ifFalse: [↑false]]]].
"58" FileStream$'Fast Access'
[streamPosition | |
	↑position].
"78" FileStream$'Fast Access'
[streamPosition← t1 | |
	position ← t1.
	↑position].
"1234" FileStream$'Fast Access'
[writeFile: fs for: charsLeft | start len maxLimit |
	 "for copying part or all of one file to another (quickly, if BitBlt is used);
	charsLeft  nil means copy until end, otherwise a number of characters.
	called by FileStream append:, next:from:"
	self writing
	  ifFalse: [self error: 'read only!'].
	self reopen.
	fs readonly.
	fs reopen.
	maxLimit ← page dataMaxEnd "keep going until all of the requested characters are copied or
	until end of file. if end of current page only, next page is read.".
	[(charsLeft  nil or: [charsLeft > 0]) and: [fs end  false]] whileTrueDo:
		[ "end of current destination page?"
		position = maxLimit
		  ifTrue: [self nextPage].
		start ← fs streamPosition.
		len ← maxLimit - position min: fs limit - start.
		charsLeft  nil
		  ifFalse:
			[len ← len min: charsLeft.
			charsLeft ← charsLeft - len] "copy subrange of source page into destination page".
		array copy: position + 1 to: position + len with: fs asArray from: start + 1 to: start + len "update source and destination pointers".
		fs streamPosition← start + len.
		position ← position + len.
		position > limit
		  ifTrue: [limit ← position]].
	↑charsLeft  nil
	  ifTrue: [0]
	  ifFalse: [charsLeft]].
"869" FileStream$'Fast Access'
[writeString: s from: start to: stop | len charsLeft maxLimit |
	 "for writing a subrange of a large String onto a file (quickly, if BitBlt is used);
	called by FileStream append:"
	self writing
	  ifFalse: [self error: 'read only!'].
	self reopen.
	start ← start - 1.
	charsLeft ← stop - start.
	maxLimit ← page dataMaxEnd "keep going until all of the requested characters are copied".
	[charsLeft > 0] whileTrueDo:
		[ "end of current page?"
		position = maxLimit
		  ifTrue: [self nextPage].
		len ← maxLimit - position min: charsLeft.
		charsLeft ← charsLeft - len "copy subrange of String into page".
		array copy: position + 1 to: position + len with: s from: start + 1 to: start + len "update source and destination pointers".
		start ← start + len.
		position ← position + len.
		position > limit
		  ifTrue: [limit ← position]].
	↑s].
"449" FileStream$'File'
[positionPage: pn character: c | |
	(self read: pn) "normally accessed by position:size:, skip:"
	  ifTrue:
		[position ← position + c "c assumed between 0 and page dataLength. position, limit were set in on:".
		(position  limit or: [self writing])
		  ifTrue: [↑true].
		position ← limit.
		↑false]
	  ifFalse:
		[c = 0
		  ifTrue: [↑self positionPage: pn - 1 "try end of previous page" character: page dataLength].
		↑false]].
"306" FileStream$'File'
[pad: size | rem |
	rem ← ( "skip to next boundary of size and return how many characters skipped"
			(page dataLength \ size = 0
			  ifTrue: [position - page dataBeginning]
			  ifFalse: [self position]) \ size) asSmall.
	rem = 0
	  ifTrue: [↑0].
	self skip: size - rem.
	↑size - rem].
"322" FileStream$'File'
[pad: size with: val | rem |
	rem ← ( "pad to next boundary of size and return how many characters padded"
			(page dataLength \ size = 0
			  ifTrue: [position - page dataBeginning]
			  ifFalse: [self position]) \ size) asSmall.
	rem = 0
	  ifTrue: [↑0].
	self next: (size - rem) ← val.
	↑size - rem].
"365" FileStream$'Fast Access'
[readPages: n | charsLeft len s |
	len ← n * page dataLength "read n pages of characters".
	s ← String new: len "charsRead ← self into: s endError: false.".
	charsLeft ← self readString: s from: 1 to: len.
	charsLeft = 0
	  ifTrue: [↑s].
	 "read len chars" "return characters read only before end of file"
	↑s copy: 1 to: len - charsLeft].
"231" FileStream$'Filin/Filout'
[nextParagraph | text |
	self end "Bravo format paragraph (or self contents if no trailer)"
	  ifTrue: [↑false].
	text ← self upto: 26 "ctrl-z".
	↑text asParagraph applyBravo: self at: 1 to: text length].
"37" FileStream$'File'
[page | |
	↑page].
"147" FileStream$'File'
[fixEnd | |
	(self writing and: [position > page dataEnd])
	  ifTrue: [page dataEnd: (limit ← position) "fix the end of page"]].
"133" FileStream$'Print'
[printoutclass: class | t2 |
	(t2 ← self asPressPrinter) stamp.
	t2 printclass: class.
	t2 close.
	t2 toPrinter].
"92" CodeWindow$'Initialization'
[classInit | |
	stdTemplates ← (0  0 rect: 36  36) inVector].
"90" CodeWindow$'Initialization'
[hardcopy: p | pane |
	panes do: [:pane | pane hardcopy: p]].
"67" CodePane$'Window protocol'
[show | |
	frame outline.
	pared show].
"127" CodePane$'Browse/Notify protocol'
[formerly: oldpara | |
	 "should not be called before 'showing:'"
	pared formerly: oldpara].
"157" CodePane$'Browse/Notify protocol'
[reflects: selection | |
	 "am I trying to show the code of selectorPane selection?"
	↑class  nil and: [selection > 0]].
"70" CodePane$'Browse/Notify protocol'
[oldContents | |
	↑pared formerly].
"236" CodePane$'Browse/Notify protocol'
[compile: parag in: defaultClass under: category | |
	↑(self compiler: defaultClass) new compile: parag in: (class  nil
	  ifTrue: [defaultClass]
	  ifFalse: [class]) under: category notifying: self].
"95" CodePane$'Initialization'
[class: t1 selector: t2 para: para | |
	class ← t1.
	selector ← t2].
"40" CodePane$'Initialization'
[init | |
	].
"56" CharLine$'Access to Parts'
[stopi← t1 | |
	stopi ← t1].
"134" CharLine$'Initialization'
[starti: t1 stopi: t2 spaces: t3 padwidth: t4 | |
	starti ← t1.
	stopi ← t2.
	spaces ← t3.
	padwidth ← t4].
"91" CharLine$'Operations'
[slide: delta | |
	starti ← starti + delta.
	stopi ← stopi + delta].
"149" CharLine$'Operations'
[= line | |
	↑(starti = line starti and: [stopi = line stopi]) and: [(spaces = line spaces and: [padwidth = line padwidth])]].
"54" CharLine$'Access to Parts'
[padwidth | |
	↑padwidth].
"48" CharLine$'Access to Parts'
[stopi | |
	↑stopi].
"50" CharLine$'Access to Parts'
[spaces | |
	↑spaces].
"50" CharLine$'Access to Parts'
[starti | |
	↑starti].
"954" CodePane$'Window protocol'
[yellowbug | t1 |
	(t1 ← editmenu bug) = 5
	  ifTrue: [self doit]
	  ifFalse:
		[t1 = 1
		  ifTrue: [scrollBar hidewhile [(pared again)]]
		  ifFalse:
			[t1 = 2
			  ifTrue: [pared copyselection]
			  ifFalse:
				[t1 = 3
				  ifTrue: [pared cut]
				  ifFalse:
					[t1 = 4
					  ifTrue: [pared paste]
					  ifFalse:
						[t1 = 6
						  ifTrue:
							[pared formerly
							  ifTrue: [scrollBar hidewhile [
									((selectorPane compile: pared contents)
									  ifTrue: [pared formerly: false])]]
							  ifFalse: [frame flash]]
						  ifFalse:
							[t1 = 7
							  ifTrue: [pared undo]
							  ifFalse:
								[t1 = 8
								  ifTrue:
									[pared formerly
									  ifTrue:
										[pared Deletion← pared contents.
										scrollBar hidewhile [(self showing: pared formerly)]]
									  ifFalse: [frame flash]]
								  ifFalse:
									[t1 = 9
									  ifTrue: [pared realign]]]]]]]]]].
"149" CodePane$'Browse/Notify protocol'
[execute: parseStream for: codePane | |
	 "as my own selectorPane"
	↑self execute: parseStream in: false to: nil].
"260" CodePane$'Browse/Notify protocol'
[execute: parseStream in: context to: receiver | cls |
	cls ← (context
			  ifTrue: [context mclass]
			  ifFalse: [receiver class]).
	↑(self compiler: cls) new evaluate: parseStream in: context to: receiver notifying: self].
"60" CodePane$'Browse/Notify protocol'
[interactive | |
	↑true].
"144" CodePane$'Browse/Notify protocol'
[compile: parag | |
	 "as my own selectorPane"
	↑self compile: parag in: class under: 'As yet unclassified'].
"234" CodePane$'Browse/Notify protocol'
[notify: errorString at: position in: stream | |
	pared fintype.
	pared selectRange: (position to: position).
	pared replace: ('' + errorString + '.') asParagraph.
	pared selectAndScroll.
	↑false].
"189" CodePane$'Window protocol'
[frame← t1 | |
	frame ← t1.
	pared  nil "Change my frame and that of my pared (if any)."
	  ifFalse:
		[pared frame← frame.
		scrollBar on: frame from: pared]].
"64" TextImage$'ACCESS TO PARTS'
[formerly: t1 | |
	oldEntity ← t1].
"247" TextImage$'EDITING'
[fixframe: f | dy |
	dy ← (frame  nil
			  ifTrue: [0]
			  ifFalse: [self frameoffset]).
	window ← f copy.
	frame ← Rectangle new origin: window origin + (2  dy) extent: window width - 4  9999.
	self measureall.
	↑window].
"1197" TextImage$'SELECTION'
[selecting | pt t h1 h2 c h drag2 selection |
	t ← self charofpoint: (pt ← user mp) andrect [:h1 | h1].
	self complement: off.
	self fintype.
	(t = c1 and: [c1 = c2])
	  ifTrue:
		[[ "bugged hairline - maybe double-bug"
		user redbug and: [t = (self charofpoint: user mp andrect [:h | h])]] whileTrueDo: [ "wait for unclick or drawing selection"
			].
		user redbug  false
		  ifTrue:
			[self selectword.
			self select.
			↑true]].
	sel ← on "draw out and record (c1 and c2) a selection".
	c1 ← c2 ← t.
	h2 ← h1 + (1  0).
	self complementfrom: h1 to: h2.
	selection ← true.
	[pt ← user mpnext] whileTrueDo:
		[c ← self charofpoint: pt andrect [:h | h].
		c1 = c2
		  ifTrue: [drag2 ← c  c2].
		drag2
		  ifTrue:
			[c < c1
			  ifTrue: [self pointofchar: (c ← c1) andrect [:h | h]].
			self complementfrom: h to: h2.
			c2 ← c.
			h2 ← h]
		  ifFalse:
			[c > c2
			  ifTrue: [self pointofchar: (c ← c2) andrect [:h | h]].
			self complementfrom: h1 to: h.
			c1 ← c.
			h1 ← h].
		h1 = h2
		  ifTrue: [self complementfrom: h1 to: (h2 ← h1 + (1  0))]].
	drag2
	  ifFalse: [ "get rid of extra line in backwards select"
		self complementfrom: h2 - (1  0) to: h2]].
"740" TextImage$'SCROLLING'
[scrollby: n | oldw topline |
	(n > 0 and: [n + (topline ← self lineofy: window minY) > lastline])
	  ifTrue: [n ← lastline - topline].
	n ← n * self lineheight max: self frameoffset.
	frame moveby: 0  (0 - n).
	n abs  window height
	  ifTrue:
		[self show.
		self select]
	  ifFalse:
		[ "need only to reshow part of window"
		oldw ← window.
		window ← (n < 0
				  ifTrue: [window inset: 0  0 and: [0  (0 - n)]]
				  ifFalse: [window inset: 0  n and: [0  0]]).
		window blt: window origin - (0  n) mode: storing.
		n < 0
		  ifTrue: [window corner y← window origin y - n]
		  ifFalse: [window origin y← self yofline: (self lineofy: window corner y - n)].
		self displayall.
		self select.
		window ← oldw]].
"1453" TextImage$'SELECTION'
[selectword | a b dir t level open close s slen t10 |
	a ← b ← dir ← 1 "Select bracketed or word range, as a result of double-bug.".
	s ← para text.
	slen ← s length.
	level ← 1.
	open ← '([{<''"
'.
	close ← ')]}>''"
'.
	c1  1
	  ifTrue:
		[dir ← 1.
		t ← c1]
	  ifFalse:
		[c1 > slen
		  ifTrue: [t ← c1 - 1]
		  ifFalse:
			[t ← open find: (a ← para  (c1 - 1)).
			t > 0
			  ifTrue:
				[ "delim on left"
				dir ← 1.
				b ← close  t.
				t ← c1 - 1]
			  ifFalse:
				[ "match to the right"
				t ← close find: (a ← para  c1).
				t > 0
				  ifTrue:
					[ "delim on right"
					dir ← 1.
					b ← open  t.
					t ← c1]
				  ifFalse:
					[ "match to the left"
					a ← 1.
					t ← c1]]]] "no delims - select a token".
	[level = 0 or: [(dir = 1
	  ifTrue: [t  slen]
	  ifFalse: [t  1])]] whileFalseDo: 
		[(t10 ← s  (t ← t + dir)) = b
		  ifTrue: [level ← level - 1]
		  ifFalse:
			[ "leaving nest"
			t10 = a
			  ifTrue: [level ← level + 1]
			  ifFalse:
				[ "entering nest"
				.
				a = 1
				  ifTrue:
					[(s  t) tokenish
					  ifTrue:
						[ "token check goes left "
						t = 1
						  ifTrue:
							[c1 ← dir ← 1.
							t ← c2]]
					  ifFalse:
						[dir = 1
						  ifTrue:
							[c1 ← t + 1.
							dir ← 1.
							t ← c2 - 1]
						  ifFalse: [ "then right"
							level ← 0]]]]]].
	level  0
	  ifTrue: [t ← t + dir].
	dir = 1
	  ifTrue: [c2 ← t min: slen + 1]
	  ifFalse: [c1 ← t + 1]].
"311" TextImage$'SELECTION'
[selectAndScroll | l dy c1y ignored |
	l ← self lineheight.
	self select.
	c1y ← (self pointofchar: c1 andrect [:ignored | ignored]) y.
	dy ← c1y - window minY.
	dy  0
	  ifTrue: [dy ← c1y + l - 1 - window maxY max: 0].
	dy  0
	  ifTrue: [self scrollby: dy abs + l - 1 / l * dy sign]].
"92" TextImage$'ACCESS TO PARTS'
[frameoffset | |
	↑frame minY "a useful number" - window minY].
"513" TextImage$'SELECTION'
[reversefrom: char1 to: char2 | h1 h2 rect |
	self pointofchar: char1 andrect [:rect | rect] "Complement the dots corresponding to the the lines and part-lines of the paragraph between the left edge of char1 and the left edge of char2.  If char1 = char2, this is sort of a no-op.  If char1 > char2, this is undefined.".
	h1 ← rect.
	char2 = char1
	  ifTrue: [h2 ← h1 + (1  0)]
	  ifFalse:
		[self pointofchar: char2 andrect [:rect | rect].
		h2 ← rect].
	self complementfrom: h1 to: h2].
"121" TextImage$'EDITING'
[copyselection | |
	Scrap ← self selection "copy the current selection and store it in the Scrap."].
"211" TextImage$'Editing'
[againOnce | t |
	t ← para findString: Deletion startingAt: c2.
	t = 0
	  ifTrue: [↑false].
	self unselect.
	c1 ← t.
	c2 ← c1 + Deletion length.
	self replace: Scrap.
	self selectAndScroll].
"69" TextImage$'ACCESS TO PARTS'
[begintypein← t1 | |
	begintypein ← t1].
"165" TextImage$'SYSTEM'
[copy | t |
	t ← TextImage new paragraph: para copy frame: frame copy style: style copy.
	t c1← c1.
	t c2← c2.
	t begintypein← begintypein.
	↑t].
"1341" TextImage$'Public Messages'
[kbd | more char |
	 "key struck on the keyboard"
	(c1 < c2 and: [self checklooks])
	  ifTrue: [↑self show complement].
	more ← Set new string: 16.
	begintypein
	  ifFalse:
		[Deletion ← self selection.
		begintypein ← c1].
	[char ← user kbdnext] whileTrueDo:
		[char = bs
		  ifTrue:
			[more empty "backspace"
			  ifTrue: [begintypein ← begintypein min: (c1 ← 1 max: c1 - 1)]
			  ifFalse: [more skip: 1]]
		  ifFalse:
			[char = cut
			  ifTrue:
				[self fintype.
				c1 = c2
				  ifTrue: [c2 ← c1 + 1 min: para length + 1].
				self replace: nullString.
				self complement.
				Scrap ← Deletion.
				↑self].
			char = paste
			  ifTrue: [↑self paste].
			char = ctlw
			  ifTrue:
				[ "ctl-w for backspace word"
				more empty
				  ifFalse:
					[self replace: more.
					more reset.
					c1 ← c2].
				c1 ← 1 max: c1 - 1.
				[c1 > 1 and: [(para  (c1 - 1)) tokenish]] whileTrueDo: [c1 ← c1 - 1].
				begintypein ← begintypein min: c1]
			  ifFalse:
				[char = esc
				  ifTrue:
					[ "select previous type-in"
					more empty
					  ifTrue: [self unselect]
					  ifFalse:
						[self replace: more.
						c1 ← c2].
					self fintype.
					c1 ← c2 - Scrap length.
					↑self complement].
				 "just a normal character"
				more next← char]]].
	self replace: more.
	c1 ← c2.
	self selectAndScroll].
"175" TextImage$'EDITING'
[cut | |
	self fintype "cut out the current selection and redisplay the paragraph.".
	self replace: nullString.
	self selectAndScroll.
	Scrap ← Deletion].
"51" TextImage$'ACCESS TO PARTS'
[contents | |
	↑para].
"224" TextImage$'SELECTION'
[complement: nsel | |
	nsel = sel
	  ifFalse:
		[ "already that way"
		(nsel = on and: [(user rawkbck or: [user redbug])])
		  ifFalse:
			[ "slippage"
			sel ← nsel.
			self reversefrom: c1 to: c2]]].
"1229" TextImage$'EDITING'
[checklooks | t val mask range |
	t ← #(166 150 137 151 230 214 201 215 135 159 144 143 128 127 129 131 180 149 199 223 208 207 192 191 240 226 ) find: user kbck.
	t = 0
	  ifTrue: [↑false].
	user kbd.
	oldEntity
	  ifFalse:
		[oldEntity ← para.
		para ← para copy].
	t = 25
	  ifTrue: [para ← para toBravo]
	  ifFalse:
		[ "ctl-T"
		t = 26
		  ifTrue: [para ← para fromBravo]
		  ifFalse:
			[ "ctl-F"
			.
			val ← #(1 2 4 256 1 2 4 256 0 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 )  t "ctl-b i - x   B I  X" "ctl-0 1 ... 9" "ctl-shift-0 1 ... 5".
			val = 256
			  ifTrue:
				[mask ← 255.
				val ← 0]
			  ifFalse:
				[ "reset all"
				val < 0
				  ifTrue:
					[mask ← 0 - val.
					val ← 0]
				  ifFalse:
					[ "reset emphasis"
					(val > 0 and: [val < 16])
					  ifTrue: [mask ← val]
					  ifFalse: [ "set emphasis"
						mask ← 240]]] "set font".
			para maskrun: c1 to: c2 - 1 under: mask to: val "fix paragraph".
			mask = 240
			  ifTrue: [self replace: c1 to: c2 - 1 "remeasure if changing fonts" with: (para copy: c1 to: c2 - 1)]
			  ifFalse: [ "otherwise just redisplay lines"
				self displaylines: (self lineofchar: c1) to: (self lineofchar: c2)].
			self select]]].
"108" TextImage$'SELECTION'
[selection | |
	para text empty
	  ifTrue: [↑para copy].
	↑para copy: c1 to: c2 - 1].
"61" TextImage$'SELECTION'
[complement | |
	self complement: on].
"57" TextImage$'SELECTION'
[selectRange | |
	↑c1 to: c2 - 1].
"117" TextImage$'SELECTION'
[selectRange: r | |
	self complement: off.
	c1 ← r start.
	c2 ← r stop.
	self complement: on].
"245" TextImage$'INIT'
[classInit | |
	bs ← 8.
	ctlw ← 145.
	esc ← 160.
	cut ← 173.
	paste ← 158.
	Scrap ← Deletion ← nullString.
	on ← 1.
	off ← 0.
	paragraphmenu ← Menu new string: 'again
copy
cut
paste
doit
compile
undo
cancel
align
fit
resize
'].
"48" TextImage$'INIT'
[close | |
	superimage ← nil].
"136" TextImage$'ACCESS TO PARTS'
[height | rect |
	self pointofchar: para length + 1 andrect [:rect | rect].
	↑rect corner y - frame minY].
"211" TextImage$'INIT'
[paragraph: t1 frame: t2 style: t3 | |
	para ← t1.
	frame ← t2.
	style ← t3.
	nil  para
	  ifTrue: [para ← nullString].
	c1 ← c2 ← begintypein ← 1.
	self para: para frame: frame style: style].
"61" TextImage$'ACCESS TO PARTS'
[Deletion← s | |
	Deletion ← s].
"1156" TextImage$'SELECTION'
[complementfrom: hair1 to: hair2 | temprect |
	hair1 minY "Complement the screen dots corresponding to the lines and part-lines of the paragraph between hair1 inclusive and hair2 exclusive.  If hair1 = hair2, this is a no-op.  If hair1 > hair2, they are reversed. This complementing happens in three parts, A, B, and C, between points 1 and 2, according to the following illustration:
					1AAA
					BBBB
					BBBB
					BBBB
					CCC2
unless there is just one line involved, as in:
					1DD2
" "one line case" = hair2 minY
	  ifTrue: [(((hair1 minX  hair2 minX
		  ifTrue: [hair1 origin rect: hair2 corner]
		  ifFalse: [hair2 origin rect: hair1 corner]) intersect: frame) intersect: window) comp]
	  ifFalse:
		[hair1 minY > hair2 minY
		  ifTrue:
			[temprect ← hair1.
			hair1 ← hair2.
			hair2 ← temprect].
		temprect ← frame minX  hair1 maxY rect: frame maxX  hair2 minY.
		(((hair1 origin rect: temprect maxX  temprect minY) intersect: frame) intersect: window) comp.
		((temprect intersect: frame) intersect: window) comp.
		(((temprect minX  temprect maxY rect: hair2 corner) intersect: frame) intersect: window) comp]].
"112" TextImage$'DISPLAY'
[show | |
	lastline = 0
	  ifTrue: [super show]
	  ifFalse: [self displayall].
	sel ← off].
"411" TextImage$'EDITING'
[fit | rect |
	(window intersect: frame) "make the bounding rectangle of the TextImage contain all the textwhile not changing the width of the TextImage." white.
	frame extent← frame width  1000.
	self pointofchar: para length + 1 andrect [:rect | rect].
	frame extent← frame width  (rect corner y - frame origin y).
	self show.
	frame border: 1 color: 1.
	self reversefrom: c1 to: c2].
"51" TextImage$'ACCESS TO PARTS'
[c1← t1 | |
	c1 ← t1].
"51" TextImage$'ACCESS TO PARTS'
[c2← t1 | |
	c2 ← t1].
"89" TextImage$'EDITING'
[undo | |
	self fintype.
	self replace: Deletion.
	self complement].
"135" TextImage$'EDITING'
[align | |
	para alignment← #(1 2 4 0 0 )  (1 + para alignment).
	self displayall.
	self reversefrom: c1 to: c2].
"94" TextImage$'SELECTION'
[selectionAsStream | |
	↑Stream new of: para text from: c1 to: c2 - 1].
"62" TextImage$'ACCESS TO PARTS'
[frame← f | |
	self fixframe: f].
"56" TextImage$'ACCESS TO PARTS'
[formerly | |
	↑oldEntity].
"55" TextImage$'DISPLAY'
[leave | |
	self complement: off].
"60" TextImage$'SELECTION'
[unselect | |
	self complement: off].
"215" TextImage$'EDITING'
[replace: t | |
	oldEntity
	  ifFalse:
		[oldEntity ← para.
		para ← para copy].
	begintypein
	  ifFalse: [Deletion ← self selection].
	self replace: c1 to: c2 - 1 with: t.
	c2 ← c1 + t length].
"105" TextImage$'SELECTION'
[select | |
	sel ← off.
	c1  nil
	  ifTrue: [c1 ← c2 ← 1].
	self complement: on].
"55" TextImage$'ACCESS TO PARTS'
[Scrap← s | |
	Scrap ← s].
"80" TextImage$'DISPLAY'
[enter | |
	begintypein ← false.
	self show.
	self select].
"75" TextImage$'SYSTEM'
[presson: press in: r | |
	↑para presson: press in: r].
"239" TextImage$'Editing'
[again | many |
	many ← user leftShiftKey.
	self fintype
	  ifTrue:
		[Scrap ← Scrap text.
		self select].
	many
	  ifTrue: [[self againOnce] whileTrueDo: []]
	  ifFalse:
		[self againOnce
		  ifFalse: [frame flash]]].
"182" TextImage$'EDITING'
[paste | |
	self fintype "paste the Scrap over the current selection and redisplay the paragraph.".
	self unselect.
	self replace: Scrap.
	self selectAndScroll].
"98" TextImage$'SELECTION'
[select: t | |
	self complement: off.
	c1 ← c2 ← t.
	self selectAndScroll].
"139" TextImage$'PARAGRAPH EDITOR'
[scrollPos | t |
	t ← self height - self lineheight.
	t = 0
	  ifTrue: [↑0.0].
	↑0.0 - self frameoffset / t].
"84" TextImage$'PARAGRAPH EDITOR'
[scrollUp: n | |
	self scrollby: n / self lineheight].
"58" TextImage$'EDITING'
[realign | |
	self align.
	sel ← on].
"204" TextImage$'EDITING'
[fintype | |
	begintypein
	  ifTrue:
		[begintypein < c1
		  ifTrue:
			[Scrap ← para copy: begintypein to: c1 - 1.
			c1 ← begintypein].
		begintypein ← false]
	  ifFalse: [↑false]].
"105" TextImage$'PARAGRAPH EDITOR'
[scrollTo: f | |
	self scrollUp: self frameoffset + (f * self height) - 4].
"921" ScrollBar$'Scheduling'
[eachtime | p cx r |
	 "This needs to be restructured"
	(rect has: (p ← user mp))
	  ifTrue:
		[cx ← rect center x - 2.
		p x < cx
		  ifTrue:
			[r ← Rectangle new origin: rect origin corner: cx  rect maxY.
			DownCursor showwhile [([r has: (p ← user mp)] whileTrueDo:
					[(self slide: p)
					  ifTrue: [owner scrollTo: (position minY - rect minY - 4) asFloat / (rect height - 12)]
					  ifFalse:
						[user redbug
						  ifTrue: [self reposition [(owner scrollUp: rect origin y - p y)]]]])]]
		  ifFalse:
			[r ← Rectangle new origin: cx  rect minY corner: rect corner.
			UpCursor showwhile [([r has: (p ← user mp)] whileTrueDo:
					[(self slide: p)
					  ifTrue: [owner scrollTo: (position minY - rect minY - 4) asFloat / (rect height - 12)]
					  ifFalse:
						[user redbug
						  ifTrue: [self reposition [(owner scrollUp: p y - rect origin y)]]]])]]]
	  ifFalse: [↑false]].
"41" ScrollBar$'Scheduling'
[lasttime | |
	].
"84" ScrollBar$'Initialization'
[on: f from: o | |
	self on: f from: o at: o scrollPos].
"181" ScrollBar$'Image'
[show | |
	 "Save background and turn gray"
	bitstr ← rect bitsIntoString.
	rect clear: black.
	(rect inset: 2  2 and: [1  2]) clear: white.
	position outline].
"398" ScrollBar$'Scheduling'
[slide: p | bug |
	(position has: p)
	  ifTrue:
		[JumpCursor showwhile [
			(bug ← false.
			[(position has: user mp) and: [bug  false]] whileTrueDo:
				[user redbug
				  ifTrue:
					[bug ← true.
					[user redbug] whileTrueDo: [self reshow [(position moveto: position origin x  ((user mp y max: rect origin y + 4) min: rect corner y - 12))]]]])].
		↑bug].
	↑false].
"189" ScrollBar$'Image'
[hide | |
	 "restore background"
	bitstr  nil
	  ifTrue: [user notify: 'Attempt to hide unshown scrollbar']
	  ifFalse:
		[rect bitsFromString: bitstr.
		bitstr ← nil]].
"159" ScrollBar$'Initialization'
[useBitmap | |
	bitstr  nil
	  ifFalse: [bitstr ← bitstr asBitmap] " | x. ScrollBar allInstances transform x to x useBitmap. "].
"193" ScrollBar$'Image'
[boxPosition← f | |
	position moveto: rect origin + (9  (4 + ((f < 0.0
	  ifTrue: [0.0]
	  ifFalse:
		[f > 1.0
		  ifTrue: [1.0]
		  ifFalse: [f]]) * (rect height - 16))))].
"87" ScrollBar$'Image'
[hidewhile expr | v |
	self hide.
	v ← expr eval.
	self show.
	↑v].
"988" ScrollBar$'Initialization'
[classInit | |
	UpCursor ← Cursor new fromtext: '
1000000000000000
1100000000000000
1110000000000000
1111000000000000
1111100000000000
1111110000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000'.
	DownCursor ← Cursor new fromtext: '
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1100000000000000
1111110000000000
1111100000000000
1111000000000000
1110000000000000
1100000000000000
1000000000000000'.
	JumpCursor ← Cursor new fromtext: '
0111000000000000
1111100000000000
1111100000000000
0111000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000' offset: 2  1].
"49" ScrollBar$'Scheduling'
[close | |
	owner ← nil].
"60" ScrollBar$'Scheduling'
[firsttime | |
	↑rect has: user mp].
"112" ScrollBar$'Image'
[reshow expr | r |
	r ← position inset: 2.
	expr eval.
	r clear: white.
	position outline].
"252" ScrollBar$'Initialization'
[on: frame from: t2 at: f | |
	owner ← t2.
	rect ← Rectangle new origin: frame origin - (32  2) extent: 32  (frame height + 4).
	position ← Rectangle new origin: rect origin + (9  4) extent: 16  8.
	self boxPosition← f].
"110" ScrollBar$'Image'
[reposition expr | |
	self reshow [
		(expr eval.
		self boxPosition← owner scrollPos)]].
"290" CodePane$'Initialization'
[showing: paragraph | |
	pared ← TextImage new para: paragraph asParagraph frame: nil.
	pared formerly: false.
	pared fixframe: frame.
	self windowenter.
	scrollBar ← (scrollBar  nil
			  ifTrue: [ScrollBar new]
			  ifFalse: [scrollBar]) on: frame from: pared].
"360" CodePane$'Window protocol'
[eachtime | |
	user kbck
	  ifTrue: [↑self kbd].
	(frame has: user mp)
	  ifTrue:
		[user anybug
		  ifTrue:
			[user redbug
			  ifTrue: [↑self redbug].
			user yellowbug
			  ifTrue: [↑self yellowbug].
			user bluebug
			  ifTrue: [↑false]]
		  ifFalse:
			[user anykeys
			  ifTrue: [↑self keyset]]]
	  ifFalse: [↑self outside]].
"57" PressPrinter$'Closing'
[toPrinter | |
	press toPrinter].
"65" PressPrinter$'Initialization'
[defaultframe | |
	↑defaultframe].
"601" PressPrinter$'Writing'
[print: para in: rect | result oldpara |
	(rect width = 0 or: [rect height = 0])
	  ifTrue: [user notify: 'zero dimension'].
	oldpara ← para.
	[(result ← para presson: press in: rect) is: Integer] whileFalseDo: 
		[self nextpage "rest of para goes on next page".
		para ← result.
		rect ← rect minX  frame minY rect: rect maxX  ypos "original para can hide information. if it split across page boundaries,
	the format may vary. other completion flags can be added later"].
	oldpara hidePress: press complete: (oldpara  para
	  ifTrue: [0]
	  ifFalse: [1]).
	↑ypos ← result].
"180" PressPrinter$'Initialization'
[classInit | inch |
	inch ← 2540 "1 inch in micas".
	defaultframe ← (1.1 * inch) asInteger  (1 * inch) rect: (7.75 * inch) asInteger  (10 * inch)].
"85" PressPrinter$'Initialization'
[init | |
	super init.
	page ← 1.
	ypos ← frame maxY].
"49" PressPrinter$'Closing'
[close | |
	press close].
"296" PressPrinter$'Writing'
[nextpage: h | n |
	press page.
	page ← page + 1.
	ypos ← frame maxY.
	h
	  ifTrue:
		[n ← page asString.
		press setp: frame maxX + 800  (ypos + 960).
		press selectfont: (press fontindex: 0 style: DefaultTextStyle) - 1.
		press append: n.
		press showchars: n length]].
"68" PressFile$'Bitmaps/Dots'
[setmode: m | |
	DL next← 2.
	DL next← m].
"378" PressFile$'Entity/Page/File Commands'
[box: rect hue: hue sat: sat bright: bright containing expr | w r |
	self entity: (self transrect: (w ← rect inset: 2)) containing [
		((w minus: rect) do: [:r | self showrect: r color: 0].
		ColorPrint
		  ifTrue:
			[self hue: hue.
			self saturation: sat.
			self showrect: rect color: bright.
			self brightness: 0].
		expr eval)]].
"151" PressFile$'Entity/Page/File Commands'
[entity: box containing expr | v |
	self startEntity.
	boundbox ← box.
	v ← expr eval.
	self closeEntity.
	↑v].
"128" PressFile$'EL commands'
[skipcontrol: n type: t | |
	EL next← 242 "n bytes have been put in DL".
	EL nextword← n.
	EL next← t].
"121" PressFile$'Bitmaps/Dots'
[setcoding: c dots: d lines: l | |
	DL next← 1.
	DL next← c.
	DL nextword← d.
	DL nextword← l].
"41" PressFile$'Aspects'
[scale | |
	↑scale].
"1065" PressFile$'Reading'
[readPart | t |
	estate ← false "read parts until we find a printed page or end".
	[t ← parts nextword] whileTrueDo:
		[Pstart ← parts nextword.
		t  0
		  ifTrue:
			[parts skip: 4 "not a printed page".
			t > 0 "font or other part" "a non-standard part. let document (estate?) interpret" "DL position ← Pstart*recordsize.
			estate fromPress: self name: t value: DL"]
		  ifFalse:
			[ "go to end of last record of entity list, ignoring padding"
			t ← parts nextword "length".
			DL position← Pstart + t * recordsize - (1 + parts nextword * 2).
			EL ← Set new vector: 50 "scan backwards for beginning of entity list, reading entities".
			[(t ← DL nextword) > 0] whileTrueDo:
				[t < 12
				  ifTrue: [user notify: 'illegal entity']
				  ifFalse:
					[DL skipwords: 0 - t "read entity and trailer (last 12 words of entity)".
					EL next← DL next: t - 12 * 2.
					EL next← DL next: 24.
					DL skipwords: 1 - t] "now reverse:  trailer, entity (1st), ... (last)"].
			↑EL ← (EL asArray  (EL length to: 1 by: 1)) asStream]].
	↑false].
"108" PressFile$'Bitmaps/Dots'
[setsizewidth: w height: h | |
	DL nextword← 2.
	DL nextword← w.
	DL nextword← h].
"65" PressFile$'Entity/Page/File Commands'
[clip: boundingbox | |
	].
"122" PressFile$'Bitmaps/Dots'
[dots exp | dlpos |
	dlpos ← self padword.
	exp eval.
	self showdots: DL wordposition - dlpos].
"119" PressFile$'Bitmaps/Dots'
[setwindowwidth: w height: h | |
	self setwindowwidth: w height: h skipdots: 0 skiplines: 0].
"106" PressFile$'EL commands'
[showrectwidth: w height: h | |
	EL next← 254.
	EL nextword← w.
	EL nextword← h].
"385" PressFile$'Lines/Objects'
[drawdiscat: pt radius: radius | dx dy i |
	radius  16
	  ifFalse:
		[dx ← #(5 4 3 1 1 3 4 5 5 4 3 1 1 3 4 5 ).
		dy ← #(1 3 4 5 5 4 3 1 1 3 4 5 5 4 3 1 ).
		self showobject [
			(self moveto: pt + (dx  16 * radius / 5  (dy  16 * radius / 5)).
			(1 to: 16) do: [:i | self drawto: pt + (dx  i * radius / 5  (dy  i * radius / 5))])]]].
"544" PressFile$'Lines/Objects'
[drawlinefrom: p1 to: p2 width: width | d length t1 t2 |
	(d ← p2 - p1) = (0  0)
	  ifFalse:
		[d x← d x asFloat.
		d y← d y asFloat.
		width ← width asFloat.
		length ← (d x * d x + (d y * d y)) sqrt.
		d x← (d x * width / length) asInteger.
		d y← (d y * width / length) asInteger.
		t1 ← d y  (0 - d x).
		t2 ← 0 - d y  d x.
		self showobject [
			(self moveto: p1 + t1.
			self drawto: p2 + t1.
			self drawto: p2 + t2.
			self drawto: p1 + t2.
			self drawto: p1 + t1)]].
	self drawdiscat: p2 radius: width].
"96" PressFile$'Entity/Page/File Commands'
[toPrinter | |
	self toPrinter: self defaultPrinterName].
"51" PressFile$'EL commands'
[space | |
	EL next← 247].
"104" PressFile$'Private'
[padpage | |
	↑(DL pad: recordsize with: 0) "words of padding to end of page" / 2].
"52" PressFile$'Private'
[append: x | |
	↑DL append: x].
"300" PressFile$'Initialization'
[of: t1 | |
	DL ← t1.
	EL ← Set new string: 200.
	FL ← Set new string: 40.
	parts ← Set new string: 40.
	fontcodes ← Vector new: 0.
	fontdefs ← Vector new: 0.
	estate ← Vector new: 3 "font, spacex, spacey, ...".
	prevstyle ← nil.
	self scale: PressScale.
	self startPage].
"174" PressFile$'Private'
[closePage | |
	self closeEntity.
	EL empty
	  ifFalse:
		[DL padNext← 0.
		DL nextword← 0.
		DL append: EL asReadStream.
		self part: 0 start: Pstart]].
"214" PressFile$'Private'
[part: type start: start | padding |
	padding ← self padpage.
	parts nextword← type.
	parts nextword← start.
	parts nextword← self recordnum - start.
	parts nextword← padding.
	self startPage].
"673" PressFile$'Bitmaps/Dots'
[bitmap: rect bits: bits | w w16 h |
	w ← rect width "some pecularities of spruce:
	scale must be 32, and multiples of 16 for width (maybe extra stuff prints)".
	w16 ← w + 15 | 16 "width to next word boundary".
	h ← rect height "origin should be set earlier".
	self dots [
		(self setcoding: 0 dots: w16 lines: h "bitmap".
		self setmode: 3 "to right and to bottom of page".
		self setsizewidth: scale * w16 height: scale * h.
		self setwindowwidth: (ColorPrint
		  ifTrue: [w]
		  ifFalse: [w16]) height: h.
		self dotsfollow.
		bits
		  ifTrue: [DL append: bits "bits supplied"]
		  ifFalse: [ "else from screen"
			rect bitsOntoStream: DL])]].
"72" PressFile$'EL commands'
[onlyoncopy: n | |
	EL next← 237.
	EL next← n].
"56" PressFile$'EL commands'
[resetspace | |
	EL next← 246].
"218" PressFile$'EL commands'
[setspacey: y | |
	estate  3 = y
	  ifFalse:
		[estate  3 ← y.
		(y  0 and: [y  2047])
		  ifTrue: [EL nextword← 26624 + y "short form"]
		  ifFalse:
			[EL next← 245.
			EL nextword← y]]].
"88" PressFile$'EL commands'
[showchar: char | |
	EL next← 243 "immediate".
	EL next← char].
"109" PressFile$'EL commands'
[skipcontrol: n | |
	EL next← 235 "immediate".
	EL next← n "now put n bytes in EL"].
"169" PressFile$'Lines/Objects'
[drawcurve: v | |
	v length  12
	  ifTrue: [user notify: 'illegal drawcurve']
	  ifFalse:
		[DL nextword← 2.
		v do: [:v | DL nextword← v]]].
"180" PressFile$'Lines/Objects'
[showobject exp | p |
	p ← self padword "expression containing moveto, drawto, drawcurve".
	exp eval.
	EL next← 251.
	EL nextword← DL wordposition - p].
"59" PressFile$'Bitmaps/Dots'
[dotsfollow | |
	DL nextword← 3].
"90" PressFile$'EL commands'
[showdots: nwords | |
	EL next← 252.
	EL nextNumber: 4 ← nwords].
"72" PressFile$'EL commands'
[brightness: b | |
	EL next← 248.
	EL next← b].
"96" PressFile$'EL commands'
[showdotsopaque: nwords | |
	EL next← 253.
	EL nextNumber: 4 ← nwords].
"516" PressFile$'Private'
[closeEntity: etype | |
	EL wordposition = ELstart
	  ifFalse:
		[ "Put a trailer into the EL"
		EL padNext← 255 "word-pad EL with <Nop>".
		EL next← etype.
		EL next← 0 "fontset" "dlstart relative to DL location in file".
		EL nextNumber: 4 ← DLstart - (Pstart * recordsize).
		EL nextNumber: 4 ← DL position - DLstart.
		EL nextPoint← eorigin "entity origin".
		EL nextPoint← boundbox origin.
		EL nextPoint← boundbox extent.
		EL nextword← EL wordposition - ELstart + 1.
		self startEntity]].
"122" PressFile$'Private'
[part exp code: c | fp |
	self closePage.
	fp ← self recordnum.
	exp eval.
	self part: c start: fp].
"169" PressFile$'Private'
[startEntity | |
	DLstart ← DL position.
	ELstart ← EL wordposition.
	boundbox ← 0 asRectangle.
	eorigin ← 0  0.
	estate all← 1.
	estate  1 ← 0].
"92" PressFile$'Private'
[startPage | |
	EL reset.
	Pstart ← self recordnum.
	self startEntity].
"110" PressFile$'Entity/Page/File Commands'
[pictureinit | |
	self pictureinit: user screenrect scale: PressScale].
"155" PressFile$'Private'
[padword | |
	 "make object (lines or dots) start on word boundary"
	DL padNext← 0
	  ifTrue: [self skipchars: 1].
	↑DL wordposition].
"72" PressFile$'EL commands'
[saturation: s | |
	EL next← 250.
	EL next← s].
"128" PressFile$'Lines/Objects'
[object expr atScreen: p | |
	self showobject [
		(self objectGotoScreen: p pen: 0.
		expr eval)]].
"77" PressFile$'Lines/Objects'
[drawto: p | |
	DL nextword← 1.
	DL nextPoint← p].
"160" PressFile$'Lines/Objects'
[drawlinefromscreen: p1 to: p2 width: width | |
	↑self drawlinefrom: (self transpt: p1) to: (self transpt: p2) width: width * scale].
"155" PressFile$'Entity/Page/File Commands'
[pictureinit: rect scale: t2 | |
	scale ← t2.
	boundbox ← boundbox include: (self transrect: rect).
	self somefont].
"112" PressFile$'Lines/Objects'
[objectGotoScreen: p pen: pen | |
	DL nextword← pen.
	DL nextPoint← self transpt: p].
"371" EFTPSender$'Initialization'
[net: n host: h | |
	super net: n host: h soc: (Int32 new "Each instance of an EFTPSender has a unique lclSocket, but
		always goes to socket 020 of the receiver" high: 0 low: 16) "unlike plain sockets, we only want acks from this dest.".
	filterInput ← true.
	self retransmit: 5 every: 180.
	outPac ← false.
	transaction ← 0.
	ackType ← 25].
"309" EFTPSender$'Receiving'
[process: packet | error |
	 "The printer is trying to tell me something"
	packet pupType = 27
	  ifTrue:
		[error ← packet dataString "error 33!!!".
		self freePacket: packet.
		user show: 'remote server aborted: '.
		user show: error  (3 to: error length).
		abortTransfer ← true]].
"374" RPPSocket$'Timer Interupts'
[timerFired | |
	(ackOK or: [abortTransfer]) "This piece of code only runs when a Timer fires;  
	Don't do an active return"
	  ifFalse:
		[ "This transaction has been terminated"
		self timerOn
		  ifTrue: [self completePup: outPac "retransmit"]
		  ifFalse:
			[user show: 'Excessive retransmits in RPP retransmit'.
			abortTransfer ← true]]].
"504" RPPSocket$'Sending Data'
[send: t1 | |
	myStream ← t1.
	 "Sends a whole stream, and an end sequence.
	let the caller hand in a stream, or a file already opened"
	outPac
	  ifFalse: [outPac ← self freePacket].
	seqNum ← 0.
	abortTransfer ← eof ← false.
	[eof or: [abortTransfer]] whileFalseDo:  [self sendData].
	abortTransfer
	  ifTrue:
		[self reset.
		↑false].
	 "We hit the end of file, do the end sequence and close the connection"
	self sendEndSequence
	  ifTrue: [↑myStream].
	↑false "all done!"].
"185" RPPSocket$'Intialization'
[init | |
	self retransmit: 10 every: 180.
	seqNum ← transaction ← 0.
	outPac ← ackOK ← false.
	abortTransfer ← true "stop an old timer from perhaps firing"].
"87" RPPSocket$'Termination'
[reset | |
	outPac ← self freePacket: outPac.
	self timerOff].
"354" RPPSocket$'Sending Data'
[sendPacket | |
	 "general routine to send the outPac packet, maybe retransmit, get ack"
	ackOK ← abortTransfer ← false.
	outPac pupID1← seqNum.
	outPac pupID0← transaction "pupID0 can be used by one of my subclasses".
	self setAddressesAndComplete: outPac.
	[abortTransfer or: [ackOK]] whileFalseDo:  [].
	seqNum ← seqNum + 1].
"377" RPPSocket$'Handle Input'
[socProcess: Ipac | |
	 "I have received a packet"
	Ipac pupType = ackType
	  ifTrue:
		[(Ipac pupID1 = seqNum and: [Ipac pupID0 = transaction])
		  ifTrue:
			[self timerOff "a legal acknowledgement".
			ackOK ← true] "an old acknowledgement".
		self freePacket: Ipac]
	  ifFalse:
		[ "must be a trasmission started elsewhere"
		self process: Ipac]].
"765" RPPSocket$'Sending Data'
[sendData | i t buf len |
	buf ← outPac pupString "send one packet of data from myStream".
	i ← 24 "data bytes are 1-512, 25-536".
	(myStream is: FileStream)
	  ifTrue: [len ← 512 - (myStream readString: buf from: i + 1 "read characters faster (should work especially well for the usual case:
		FileStreams starting on a page boundary, with page sizes of 512)" to: i + 512)]
	  ifFalse:
		[ "fill the buffer the slow, careful way"
		[i < 536 and: [(t ← myStream next)]] whileTrueDo: [buf  (i ← i + 1) ← t].
		len ← i - 24].
	eof ← len < 512.
	len = 0
	  ifFalse:
		[ "empty packet. don't send"
		outPac pupType← 24 "Data" "set the packet length".
		outPac dataLength← len "send packet reliably or abort, then return".
		self sendPacket]].
"413" RPPSocket$'Sending Data'
[sendEndSequence | |
	outPac pupType← 26 "This will do the 3-way handshake, and close the connection.
		send end, wait for ack" "end" "set the packet length".
	outPac pupLength← 22.
	self sendPacket "gets sent reliably, we hope".
	abortTransfer
	  ifTrue:
		[self reset.
		↑false].
	 "send the last gratuitous end, do not try to retransmit"
	.
	self sendPacketOnce.
	self reset.
	↑true].
"264" RPPSocket$'Sending Data'
[sendPacketOnce | |
	 "special routine to send the outPac packet, no retransmission"
	outPac pupID1← seqNum.
	outPac pupID0← transaction "pupID0 can be used by one of my subclasses".
	self setAddressesAndComplete: outPac.
	self timerOff].
"81" RPPSocket$'Termination'
[release | |
	self reset.
	inQ ← false.
	super release].
"221" RPPSocket$'Sending Data'
[sendBlock: str | |
	outPac dataString← str "Take the data from a string (1-532 bytes), send it out; uses outPac".
	self sendPacket "tries to do it reliably".
	abortTransfer
	  ifTrue: [↑false]].
"98" RPPSocket$'Handle Input'
[process: packet | |
	self freePacket: packet "my subclasses use this"].
"135" RetransmitSocket$'Subclass'
[timerFired | |
	self timerOn "subclass should redefine this" "again, e.g. self completePup: pac" "done"].
"271" RetransmitSocket$'Socket'
[setAddressesAndComplete: pac | |
	pac addressBlock← outAddBlock "this may need to be bracketed as critical?" "start timer".
	retransCount ← 0.
	retransTimer reset.
	self completePup: pac "self startTimer.
	super setAddressesAndComplete: pac"].
"82" RetransmitSocket$'Timer'
[startTimer | |
	retransCount ← 0.
	retransTimer reset].
"155" Queue$'FIFO access'
[next | |
	readposition  position
	  ifTrue:
		[readposition ← position ← 0.
		↑false].
	↑array  (readposition ← readposition + 1)].
"140" Queue$'FIFO access'
[peek | |
	readposition  position
	  ifTrue:
		[readposition ← position ← 0.
		↑false].
	↑array  (readposition + 1)].
"89" Queue$'Stream protocol'
[contents | |
	↑(array  (readposition + 1 to: position)) copy].
"106" Queue$'FIFO access'
[deQ1 | n |
	 "A noninterruptable dequeue"
	Top critical [(n ← self dequeue)].
	↑n].
"154" Queue$'Stream protocol'
[of: t1 from: t2 to: t3 | |
	array ← t1.
	position ← t2.
	limit ← t3.
	user notify: 'of:from:to: is not appropriate for Queues'].
"68" Queue$'FIFO access'
[skip: x | |
	readposition ← readposition + x].
"66" Queue$'Stream protocol'
[reset | |
	readposition ← position ← 0].
"63" Queue$'Stream protocol'
[empty | |
	↑readposition  position].
"61" Queue$'Stream protocol'
[end | |
	↑readposition  position].
"104" Queue$'FIFO access'
[enQ1: n | |
	 "A noninterruptable enqueue"
	Top critical [(super next← n)].
	↑n].
"107" Queue$'Stream protocol'
[of: t1 | |
	array ← t1.
	position ← 0.
	readposition ← 0.
	limit ← array length].
"158" Queue$'FIFO access'
[dequeue | |
	readposition  position
	  ifTrue:
		[readposition ← position ← 0.
		↑false].
	↑array  (readposition ← readposition + 1)].
"60" Queue$'FIFO access'
[length | |
	↑position - readposition].
"235" Queue$'Stream protocol'
[pastend← x | n |
	readposition = 0
	  ifTrue: [↑super pastend← x].
	n ← position - readposition.
	array  (1 to: n) ← array  (readposition + 1 to: position).
	readposition ← 0.
	position ← n.
	↑self next← x].
"197" Queue$'FIFO access'
[dequeue: num | n |
	position - readposition < num
	  ifTrue: [↑false].
	n ← (array  (readposition + 1 to: readposition + num)) copy.
	readposition ← readposition + num.
	↑n].
"246" Queue$'LIFO access'
[push: x | |
	 "treat as LIFO queue"
	readposition > 0
	  ifTrue:
		[array  readposition ← x.
		readposition ← readposition - 1]
	  ifFalse: [ "readpositon > 0, just jam it in"
		self insert: x] "otherwise insert on front"].
"271" Timer$'Timing Behavior'
[fire | |
	 "Time is up, add the action to the Queue to be evaled"
	timerActions next← action.
	Top wakeup: 12.
	activeTime ← nil.
	lastTimer ← nil.
	nextTimer  nil
	  ifTrue: [self shutoff]
	  ifFalse:
		[nextTimer startup.
		nextTimer ← nil]].
"197" Timer$'Initialization'
[init16 | |
	 "Initialize the process wakened by a Timer timing out"
	Top install [([true] whileTrueDo:
			[currentTimer fire.
			Top sleep: 16])] at: 16.
	Top enable: 16].
"362" Timer$'Timing Behavior'
[disable | |
	 "Remove this timer from the list"
	Top critical [
		((self  currentTimer and: [nextTimer  nil])
		  ifTrue:
			[self shutoff.
			Top deepsleep: 16].
		lastTimer  nil
		  ifFalse: [lastTimer deletenext].
		nextTimer  nil
		  ifFalse: [nextTimer deletelast].
		activeTime ← nil.
		lastTimer ← nil.
		nextTimer ← nil)]].
"132" Timer$'Timing Behavior'
[startup | |
	lastTimer ← nil "make this the next Timer to fire".
	currentTimer ← self.
	self primstartup].
"250" Timer$'Initialization'
[init12 | nextAction |
	 "Initialize the process which evals Timer actions"
	Top install [([true] whileTrueDo:
			[[nextAction ← timerActions next] whileTrueDo: [nextAction eval].
			Top sleep: 12])] at: 12.
	Top enable: 12].
"161" Timer$'Timing Behavior'
[activetime | |<primitive: 75>
	↑activeTime "If this is the current Timer return the time until it fires, otherwise return activeTime"].
"51" Timer$'List Behavior'
[nexttimer | |
	↑nextTimer].
"300" Timer$'List Behavior'
[insertlast: t1 | |
	lastTimer ← t1.
	activeTime ← self activetime "Insert a new Timer before this one. When inserting a Timer in front of another, the activeTime of the later one must be reduced so it is the amount of time after the new Timers firing" - lastTimer activetime].
"288" Timer$'List Behavior'
[deletelast | |
	activeTime ← activeTime + lastTimer activetime "Delete the Timer before this one. When deleting a Timer, the activeTime of the Timer after it must be increased by its activeTime".
	(lastTimer ← lastTimer lasttimer)  nil
	  ifTrue: [self startup]].
"107" Timer$'List Behavior'
[deletenext | |
	nextTimer ← nextTimer nexttimer "Delete the Timer after this one"].
"60" Timer$'List Behavior'
[insertnext: t1 | |
	nextTimer ← t1].
"51" Timer$'List Behavior'
[lasttimer | |
	↑lastTimer].
"141" Timer$'Timing Behavior'
[primstartup | |<primitive: 75>
	 "this message informs the virtual machine that this is the next Timer to fire"
	].
"162" Timer$'Initialization'
[classInit | |
	 "Initialize the processes used by the Timers"
	timerActions ← Queue new of: (Vector new: 4).
	self init16.
	self init12].
"100" Timer$'Initialization'
[for: t1 action t2 | |
	delay ← t1.
	action ← t2 "Initialize a new Timer"].
"936" Timer$'Initialization'
[reset | nextTimeout foundit |
	Top critical [
		 "Set up this Timer to add <action> to the Queue of remote Contexts to be evaled after an interval of <delay> sixtieths of a second. Find the proper place in the doubly linked list and calculate the amount of time to run after the preceeding timer fires"
		(activeTime  nil
		  ifFalse: [self disable].
		activeTime ← delay.
		nextTimer ← currentTimer.
		lastTimer ← nil.
		foundit ← false.
		[foundit] whileFalseDo: 
			[nextTimer  nil
			  ifTrue: [foundit ← true]
			  ifFalse:
				[.
				(nextTimeout ← nextTimer activetime) > activeTime
				  ifTrue: [foundit ← true]
				  ifFalse:
					[.
					activeTime ← activeTime - nextTimeout.
					lastTimer ← nextTimer.
					nextTimer ← lastTimer nexttimer]]].
		nextTimer  nil
		  ifFalse: [nextTimer insertlast: self].
		lastTimer  nil
		  ifTrue: [self startup]
		  ifFalse: [lastTimer insertnext: self])]].
"171" Timer$'Timing Behavior'
[shutoff | |<primitive: 75>
	currentTimer ← nil "this message informs the virtual machine and class Timer that there are no more Timers to fire"].
"87" Timer$'List Behavior'
[release | |
	lastTimer ← nil.
	nextTimer ← nil.
	action ← nil].
"158" RetransmitSocket$'Timer'
[retransmit: t1 every: delay | |
	retransMax ← t1.
	retransTimer ← Timer new.
	retransTimer for: delay action [(self timerFired)]].
"152" RetransmitSocket$'Socket'
[release | |
	retransTimer  nil
	  ifFalse:
		[ "release circular structure"
		retransTimer disable.
		retransTimer ← nil]].
"96" RetransmitSocket$'Timer'
[timerOff | |
	retransTimer  nil
	  ifFalse: [retransTimer disable]].
"193" RetransmitSocket$'Timer'
[timerOn | |
	(retransCount ← retransCount + 1 "turn on timer if retry count has not been reached")  retransMax
	  ifTrue: [retransTimer reset]
	  ifFalse: [↑false]].
"48" Socket$'Access to Parts'
[frnNet | |
	↑frnNet].
"80" Socket$'Overwrite by Subclasses'
[socProcess: Ipac | |
	self freePacket: Ipac].
"507" Socket$'Initialization'
[net: t1 host: t2 soc: t3 | |
	frnNet ← t1.
	frnHost ← t2.
	frnSocNum ← t3.
	lclSocNum ← Int32 new "default the local socket number:
	use some memory dependent info (space) for the high word so that no two
		sockets (instances) can be the same, also non-zero.
	use time for low word, so that same instance will not usually have the
		same socket number (odds = 1/65536)" high: self nail low: user ticks.
	self unNail.
	self from: lclSocNum net: frnNet host: frnHost soc: frnSocNum].
"146" Socket$'Initialization'
[default | |
	self net: 0 host: 0 soc: (Int32 new "default local socket number and leave frn port open" high: 0 low: 0)].
"69" Socket$'Access to Parts'
[frnHost← t1 | |
	frnHost ← t1.
	↑frnHost].
"124" Socket$'Process outgoing packet'
[setAddressesAndComplete: pac | |
	pac addressBlock← outAddBlock.
	self completePup: pac].
"140" RoutingUpdater$'Overwrite from Socket'
[timerFired | |
	self timerOn
	  ifTrue: [self completePup: outPac]
	  ifFalse: [resultSet ← true]].
"206" RoutingUpdater$'Sending'
[update | i |
	(1 to: 255) do:
		[:i | routingTable  i ← 0.
		routingHopCount  i ← 8].
	resultSet ← false.
	self setAddressesAndComplete: outPac.
	[resultSet] whileFalseDo:  []].
"241" RoutingUpdater$'Initialization'
[init | |
	super net: 0 host: 0 soc: 2 asInt32 "create a new local soc number, broadcast to socket 2".
	outPac ← self freePacket.
	outPac pupType← 128.
	outPac dataString← ''.
	self retransmit: 3 every: 300].
"550" RoutingUpdater$'Overwrite from Socket'
[socProcess: pac | block gateway net count i |
	pac pupType "an input has arrived, we are running at a higher level.
	Check the packet type" = 129
	  ifTrue:
		[self timerOff.
		resultSet ← NETNUM ← pac sourceNet.
		block ← pac pupString.
		gateway ← pac sourceHost.
		(25 to: 24 + pac dataLength by: 4) do:
			[:i | net ← block  i.
			count ← block  (i + 3) + 1.
			count < (routingHopCount  net)
			  ifTrue:
				[routingTable  net ← gateway.
				routingHopCount  net ← count]]].
	self freePacket: pac].
"48" Pacbuf$'Etc'
[ i ← v | |
	↑pupString  i ← v].
"40" Pacbuf$'Etc'
[ i | |
	↑pupString  i].
"98" Pacbuf$'PUP Header'
[pupID← pID | |
	pupString word: 5 ← pID high.
	pupString word: 6 ← pID low].
"54" Pacbuf$'PUP Header'
[pupID1 | |
	↑pupString word: 6].
"59" Pacbuf$'PUP Header'
[pupType← pT | |
	pupString  8 ← pT].
"60" Pacbuf$'PUP Header'
[destNet← dN | |
	pupString  13 ← dN].
"53" Pacbuf$'PUP Header'
[destHost | |
	↑pupString  14].
"56" Pacbuf$'PUP Header'
[destSoc0 | |
	↑pupString word: 8].
"82" Pacbuf$'Initialization'
[init | |
	pupString ← String new: 558.
	locked ← false].
"68" Pacbuf$'Ethernet header'
[ethType← eT | |
	pupString word: 2 ← eT].
"56" Pacbuf$'PUP Header'
[destSoc1 | |
	↑pupString word: 9].
"146" Pacbuf$'Etc'
[lock | |
	locked
	  ifTrue: [E notify: 'trying to lock a buffer already locked']
	  ifFalse:
		[locked ← true.
		↑pupString lock]].
"68" Pacbuf$'PUP Header'
[transportControl← tC | |
	pupString  7 ← tC].
"51" Pacbuf$'PUP Header'
[pupType | |
	↑pupString  8].
"48" Pacbuf$'Etc'
[word: i | |
	↑pupString word: i].
"52" Pacbuf$'PUP Header'
[destNet | |
	↑pupString  13].
"151" Pacbuf$'Etc'
[unlock | |
	locked
	  ifTrue:
		[locked ← false.
		pupString unlock]
	  ifFalse: [user notify: 'trying to unlock a buffer not locked']].
"56" Pacbuf$'Etc'
[word: i ← v | |
	↑pupString word: i ← v].
"86" Pacbuf$'Data '
[dataLength← len | |
	↑pupString word: 3 ← len + 22 "self pupLength"].
"59" Pacbuf$'Data '
[dataWord: i | |
	↑pupString word: i + 12].
"54" Pacbuf$'PUP Header'
[pupID0 | |
	↑pupString word: 5].
"52" Pacbuf$'Etc'
[header | |
	↑pupString  (1 to: 24)].
"69" Pacbuf$'Data '
[dataWord: i ← v | |
	↑pupString word: (i + 12) ← v].
"143" Pacbuf$'PUP Checksum'
[checksumOK | |
	 "Boolean, returns true or false"
	↑self checksum "just look at the current packet" = self doChecksum].
"101" Pacbuf$'PUP Header'
[destSocNum | |
	↑Int32 new high: (pupString word: 8) low: (pupString word: 9)].
"62" Pacbuf$'Ethernet header'
[imEthDestHost | |
	↑pupString  1].
"67" Pacbuf$'PUP Header'
[totLengthWords | |
	↑self pupLength + 5 / 2].
"96" Pacbuf$'PUP Header'
[pupID | |
	↑Int32 new high: (pupString word: 5) low: (pupString word: 6)].
"61" Pacbuf$'Ethernet header'
[imEthSrcHost | |
	↑pupString  2].
"66" Pacbuf$'PUP Header'
[addressBlock | |
	↑pupString  (13 to: 24)].
"63" Pacbuf$'PUP Header'
[destSoc1← i | |
	↑pupString word: 9 ← i].
"57" Pacbuf$'PUP Header'
[pupLength | |
	↑pupString word: 3].
"66" Pacbuf$'PUP Header'
[sourceSoc0← i | |
	↑pupString word: 11 ← i].
"66" Pacbuf$'PUP Header'
[sourceSoc1← i | |
	↑pupString word: 12 ← i].
"93" Pacbuf$'PUP Header'
[swapPorts | i |
	(13 to: 18) do: [:i | pupString swap: i with: i + 6]].
"60" Pacbuf$'PUP Header'
[transportControl | |
	↑pupString  7].
"83" Pacbuf$'PUP Checksum'
[checksum | |
	↑pupString word: self pupLength + 1 / 2 + 2].
"77" Pacbuf$'Data '
[dataLength | |
	↑(pupString word: 3) - 22 "self pupLength"].
"79" Pacbuf$'Data '
[dataString | |
	↑pupString copy: 25 to: 24 + self dataLength].
"60" Pacbuf$'Ethernet header'
[ethType | |
	↑pupString word: 2].
"65" Pacbuf$'PUP Header'
[pupID0← pID | |
	↑pupString word: 5 ← pID].
"65" Pacbuf$'PUP Header'
[pupID1← pID | |
	↑pupString word: 6 ← pID].
"63" Pacbuf$'PUP Header'
[destSoc0← i | |
	↑pupString word: 8 ← i].
"229" Pacbuf$'Data '
[dataString← str | i |
	i ← str length.
	i > 532
	  ifTrue: [user notify: 'Data string too big for single PUP']
	  ifFalse:
		[pupString copy: 25 to: 24 + i with: str from: 1 to: i.
		self dataLength← i.
		↑str]].
"63" Pacbuf$'Etc'
[pupString← t1 | |
	pupString ← t1.
	↑pupString].
"42" Pacbuf$'Etc'
[pupString | |
	↑pupString].
"66" Pacbuf$'PUP Header'
[pupLength← pL | |
	↑pupString word: 3 ← pL].
"36" Pacbuf$'Etc'
[locked | |
	↑locked].
"179" Pacbuf$'PUP Header'
[addressBlock← addBlock | |
	 "for quickly setting the 6 fields"
	pupString copy: 13 to: 24 with: addBlock from: 1 to: 12 "pupString(13 to: 24) ← addBlock"].
"61" Pacbuf$'PUP Header'
[destHost← dH | |
	pupString  14 ← dH].
"103" Pacbuf$'PUP Header'
[destSocNum← dSN | |
	pupString word: 8 ← dSN high.
	pupString word: 9 ← dSN low].
"54" Pacbuf$'PUP Header'
[sourceNet | |
	↑pupString  19].
"62" Pacbuf$'PUP Header'
[sourceNet← sN | |
	pupString  19 ← sN].
"55" Pacbuf$'PUP Header'
[sourceHost | |
	↑pupString  20].
"63" Pacbuf$'PUP Header'
[sourceHost← sH | |
	pupString  20 ← sH].
"59" Pacbuf$'PUP Header'
[sourceSoc0 | |
	↑pupString word: 11].
"59" Pacbuf$'PUP Header'
[sourceSoc1 | |
	↑pupString word: 12].
"107" Pacbuf$'PUP Header'
[sourceSocNum← sSN | |
	pupString word: 11 ← sSN high.
	pupString word: 12 ← sSN low].
"74" Pacbuf$'Ethernet header'
[imEthDestHost← iEDH | |
	pupString  1 ← iEDH].
"160" Pacbuf$'Etc'
[lockwith: string | |
	locked
	  ifTrue: [E notify: 'trying to lock a buffer already locked']
	  ifFalse:
		[locked ← string.
		↑pupString lock]].
"73" Pacbuf$'Ethernet header'
[imEthSrcHost← iESH | |
	pupString  2 ← iESH].
"308" Pacbuf$'PUP Checksum'
[doChecksum | i cs |<primitive: 75>
	cs ← 0.
	(3 to: self length + 1 / 2 + 2) do:
		[:i |  "does not work"
		cs ← cs + (pupString word: i) "for packets with carries".
		cs < 0
		  ifTrue: [cs ← (cs lshift: 1) + 1]
		  ifFalse: [cs ← cs lshift: 1]].
	cs = 1
	  ifTrue: [cs ← 0].
	↑cs].
"93" Pacbuf$'PUP Checksum'
[checksum← cs | |
	pupString word: (self pupLength + 1 / 2 + 2) ← cs].
"105" Pacbuf$'PUP Header'
[sourceSocNum | |
	↑Int32 new high: (pupString word: 11) low: (pupString word: 12)].
"382" Socket$'Initialization'
[from: t1 net: t2 host: t3 soc: t4 | |
	lclSocNum ← t1.
	frnNet ← t2.
	frnHost ← t3.
	frnSocNum ← t4.
	outAddBlock ← String new: 12 "this is the most general initialization, both lcl soc# and frnPort given".
	self setOutAddBlock.
	computeOutgoingCS ← filterInput ← false.
	sockeTable insert: lclSocNum with: self "put me in socket table".
	self doMoreInit].
"491" Socket$'Process outgoing packet'
[defaultAddresses: pac | |
	 "overwrites any fields which are 0"
	pac destNet = 0
	  ifTrue: [pac destNet← frnNet].
	pac destHost = 0
	  ifTrue: [pac destHost← frnHost].
	(pac destSoc0 = 0 and: [pac destSoc1 = 0])
	  ifTrue: [pac destSocNum← frnSocNum].
	pac sourceNet = 0
	  ifTrue: [pac sourceNet← NETNUM].
	pac sourceHost = 0
	  ifTrue: [pac sourceHost← ALTONUM].
	(pac sourceSoc0 = 0 and: [pac sourceSoc1 = 0])
	  ifTrue: [pac sourceSocNum← lclSocNum]].
"116" Socket$'Process outgoing packet'
[defaultAndComplete: pac | |
	self defaultAddresses: pac.
	self completePup: pac].
"70" Socket$'Access to Parts'
[computeOutgoingCS | |
	↑computeOutgoingCS].
"99" Socket$'Access to Parts'
[computeOutgoingCS← t1 | |
	computeOutgoingCS ← t1.
	↑computeOutgoingCS].
"846" Socket$'Process outgoing packet'
[completePup: pac | t |
	 "the user must have set all 6 address fields,ID, length, and type" "Now route the packet appropriately, assuming we have Ethernet..."
	NETNUM = pac destNet
	  ifTrue: [pac imEthDestHost← pac destHost]
	  ifFalse:
		[ "most common case"
		0 = pac destNet
		  ifTrue: [pac imEthDestHost← 0]
		  ifFalse:
			[ "broadcast"
			0 = (t ← routingTable  pac destNet)
			  ifTrue:
				[user show: '
Inaccessible destination net: ' + pac destNet asString + ', packet not sent.'.
				↑pac].
			.
			pac imEthDestHost← t]].
	pac imEthSrcHost← ALTONUM.
	pac ethType← 512.
	pac transportControl← 0 "as a socket we have an option about computing outgoing checksums".
	pac checksum← (computeOutgoingCS
	  ifTrue: [pac doChecksum]
	  ifFalse: [1]) "Fix this up later......".
	E sendOutput: pac.
	↑pac].
"82" Socket$'Initialization'
[wakeup | |
	 "when E goes from ethAsleep to ethAwak"
	].
"111" Socket$'Access to Parts'
[enable | |
	user show: 'someone did unnecessary enable' "now a no-op".
	self print].
"50" Socket$'Access to Parts'
[frnHost | |
	↑frnHost].
"309" Socket$'Initialization'
[setOutAddBlock | |
	outAddBlock  1 ← frnNet.
	outAddBlock  2 ← frnHost.
	outAddBlock word: 2 ← frnSocNum high.
	outAddBlock word: 3 ← frnSocNum low.
	outAddBlock  7 ← NETNUM.
	outAddBlock  8 ← ALTONUM.
	outAddBlock word: 5 ← lclSocNum high.
	outAddBlock word: 6 ← lclSocNum low].
"66" Socket$'Access to Parts'
[frnNet← t1 | |
	frnNet ← t1.
	↑frnNet].
"89" Socket$'Process outgoing packet'
[setAddresses: pac | |
	pac addressBlock← outAddBlock].
"58" Socket$'Access to Parts'
[filterInput | |
	↑filterInput].
"81" Socket$'Access to Parts'
[filterInput← t1 | |
	filterInput ← t1.
	↑filterInput].
"54" Socket$'Access to Parts'
[frnSocNum | |
	↑frnSocNum].
"75" Socket$'Access to Parts'
[frnSocNum← t1 | |
	frnSocNum ← t1.
	↑frnSocNum].
"54" Socket$'Access to Parts'
[lclSocNum | |
	↑lclSocNum].
"75" Socket$'Access to Parts'
[lclSocNum← t1 | |
	lclSocNum ← t1.
	↑lclSocNum].
"53" Socket$'Overwrite by Subclasses'
[doMoreInit | |
	].
"112" Socket$'Access to Parts'
[disable | |
	user show: 'unnecessary disable' "left for compatibility".
	self close].
"526" Socket$'Process incoming packet'
[acceptPacbuf: Ipac | temp |
	(filterInput and: [(frnNet  Ipac sourceNet "if we get here, we know that the input distributer has verified the
	PUP dest as being us (or a broadcast, if broadcast filter is off).
	We do not have responsibility for verifying incoming checksum.
	First, check if we've been asked to filter by source:" or: [(frnHost  Ipac sourceHost or: [frnSocNum  Ipac sourceSocNum])])])
	  ifTrue: [↑self socDispose: Ipac].
	 "It's good, take it..."
	↑self socProcess: Ipac].
"98" Socket$'Overwrite by Subclasses'
[release | |
	 "disable Timers, undo circular structures etc."].
"111" Socket$'Overwrite by Subclasses'
[sleep | |
	 "the user is quitting.  I don't care, but my subclasses might"].
"80" Socket$'Overwrite by Subclasses'
[socDispose: Ipac | |
	self freePacket: Ipac].
"113" Socket$'Overwrite by Subclasses'
[kill | |
	 "whole world about to go.  I don't care, but my subclasses might"].
"125" NameUser$'Handle input'
[timerFired | |
	self timerOn
	  ifTrue: [self completePup: outPac]
	  ifFalse: [resultSet ← true]].
"1095" NameUser$'Handle input'
[socProcess: Ipac | i j best bestHops |
	 "overwrite from Socket"
	 "called from Ether stuff, running at a very high level"
	resultSet "dummy block"
	  ifFalse:
		[ "we are not waiting!!" "must be the answer, or an error"
		self timerOff.
		resultSet ← true.
		146 = Ipac pupType "error"
		  ifFalse:
			[ "user show: (Ipac dataString). "
			.
			145  Ipac pupType "error"
			  ifFalse:
				[ "user show: 'unknown pup received by name user.'" "an answer arrived"
				.
				result ← Ipac dataString "1 or more 6 byte blocks".
				result length = 6
				  ifFalse:
					[ "all done" "more than one, find the nearest address"
					.
					best ← 1.
					bestHops ← 16.
					(1 to: result length by: 6) do:
						[:i | NETNUM = (result  i)
						  ifTrue:
							[best ← i.
							bestHops ← 0]
						  ifFalse:
							[.
							j ← routingHopCount  (result  i).
							j < bestHops
							  ifTrue:
								[best ← i.
								bestHops ← j]
							  ifFalse:
								[]]].
					result ← result copy: best to: best + 5]]]] "dummy block" "all done".
	self freePacket: Ipac].
"186" NameUser$'Initialization'
[init | |
	E wakeup "create a NameUser, to socket 4, from a default local socket number".
	self net: 0 host: 0 soc: 4 asInt32.
	self retransmit: 2 every: 300].
"283" NameUser$'Output requests'
[getAddressBlock: str | |
	result ← resultSet ← false "returns a string, 6 bytes: net/host/socket".
	outPac ← self freePacket.
	outPac pupType← 144.
	outPac dataString← str.
	self setAddressesAndComplete: outPac.
	[resultSet] whileFalseDo:  [].
	↑result].
"116" NameUser$'Output requests'
[getName: str | |
	 "convert string address back to host name"
	 "not implemented yet"].
"253" NameUser$'Output requests'
[getAddressString: str | temp |
	 "return string representation"
	(temp ← self getAddressBlock: str)
	  ifTrue: [↑(temp  1) base8 + '#' + (temp  2) base8 + '#' + (temp word: 2) base8 + '|' + (temp word: 3) base8].
	↑false].
"397" Socket$'Initialization'
[hostName: name | a nh |
	a ← NameUser init "lookup name, then set net and host numbers (maybe socket?)".
	nh ← a getAddressBlock: name "since this socket may get many responses,
	make sure socket is not half deleted from sockeTable after first response".
	Top critical [(a close)].
	nh
	  ifTrue: [self net: nh  1 host: nh  2]
	  ifFalse: [ "invalid name?"
		↑false]].
"97" Socket$'Initialization'
[to: h | |
	self net: NETNUM host: h "convenient default if on my net"].
"225" Socket$'Initialization'
[from: t1 | |
	lclSocNum ← t1.
	self from: lclSocNum net: 0 host: 0 soc: (Int32 new "set lcl soc number, leave frnPort open -- useful for creating
	a well-known socket as a listener" high: 0 low: 0)].
"127" Socket$'Access to Parts'
[close | |
	self release.
	(sockeTable lookup: lclSocNum)
	  ifTrue: [sockeTable delete: lclSocNum]].
"331" Socket$'Process outgoing packet'
[broadcast: packet to: t2 | |
	 "I want to broadcast this packet"
	socNumber ← t2.
	self setAddresses: packet.
	packet destHost← 0.
	packet destNet← 0.
	packet destSoc0← socNumber high.
	packet destSoc1← socNumber low "I assume that the length and type have been done".
	self completePup: packet].
"208" Socket$'Access to Parts'
[freePacket | p |
	freeQ
	  ifTrue:
		[ "get a packet"
		(p ← freeQ next)
		  ifTrue: [↑p].
		user show: 'Warning, empty freeQ, in Socket'.
		↑false]
	  ifFalse: [↑Pacbuf new init]].
"138" Socket$'Access to Parts'
[freePacket: p | |
	 "put a used packet into free queue"
	(freeQ and: [p])
	  ifTrue: [freeQ next← p].
	↑false].
"58" SafeQ$'As yet unclassified'
[enable | |
	enabled ← true].
"299" SafeQ$'As yet unclassified'
[next← arg | i |
	 "short comment"
	enabled
	  ifTrue: [(readposition + 1 to: position) do:
			[:i | array  i  arg
			  ifTrue: [E notify: 'putting same guy on Q twice']]].
	arg locked
	  ifTrue: [E notify: 'putting locked Pacbuf on Q']
	  ifFalse: [super next← arg]].
"52" SafeQ$'As yet unclassified'
[status | |
	↑enabled].
"68" SafeQ$'As yet unclassified'
[length | |
	↑position - readposition].
"60" SafeQ$'As yet unclassified'
[disable | |
	enabled ← false].
"221" PQueue$'FIFO access'
[next | n |<primitive: 75>
	Top critical [
		(readposition  position
		  ifTrue:
			[readposition ← position ← 0.
			n ← false]
		  ifFalse: [n ← array  (readposition ← readposition + 1)])].
	↑n].
"191" PQueue$'FIFO access'
[peek | n |
	Top critical [
		(readposition  position
		  ifTrue:
			[readposition ← position ← 0.
			n ← false]
		  ifFalse: [n ← array  (readposition + 1)])].
	↑n].
"118" PQueue$'Stream protocol'
[contents | n |
	Top critical [(n ← (array  (readposition + 1 to: position)) copy)].
	↑n].
"156" PQueue$'Stream protocol'
[of: t1 from: t2 to: t3 | |
	array ← t1.
	position ← t2.
	limit ← t3.
	user notify: 'of:from:to: is not appropriate for PQueues'].
"87" PQueue$'FIFO access'
[skip: x | |
	Top critical [(readposition ← readposition + x)]].
"41" PQueue$'FIFO access'
[myend | |
	↑true].
"85" PQueue$'Stream protocol'
[reset | |
	Top critical [(readposition ← position ← 0)]].
"107" PQueue$'Stream protocol'
[empty | l |<primitive: 75>
	Top critical [(l ← readposition  position)].
	↑l].
"90" PQueue$'Stream protocol'
[end | n |
	Top critical [(n ← readposition  position)].
	↑n].
"131" PQueue$'Stream protocol'
[of: t1 | |
	array ← t1.
	Top critical [
		(position ← 0.
		readposition ← 0.
		limit ← array length)]].
"392" PQueue$'FIFO access'
[pastend← x | n i |
	 "simple arg"
	Top critical [
		(position  limit
		  ifTrue:
			[readposition = 0
			  ifTrue: [super pastend← x]
			  ifFalse:
				[n ← position - readposition.
				(1 to: n) do: [:i | array  i ← array  (readposition + i)].
				readposition ← 0.
				position ← n.
				self next← x]]
		  ifFalse: [array  (position ← position + 1) ← x])].
	↑x].
"241" PQueue$'FIFO access'
[dequeue: num | n |
	Top critical [
		(position - readposition < num
		  ifTrue: [n ← false]
		  ifFalse:
			[n ← (array  (readposition + 1 to: readposition + num)) copy.
			readposition ← readposition + num])].
	↑n].
"89" PQueue$'FIFO access'
[length | l |
	Top critical [(l ← position - readposition)].
	↑l].
"273" PQueue$'LIFO access'
[push: x | |
	 "treat as LIFO queue"
	Top critical [
		(readposition > 0
		  ifTrue:
			[array  readposition ← x.
			readposition ← readposition - 1]
		  ifFalse: [ "readpositon > 0, just jam it in"
			self insert: x])] "otherwise insert on front"].
"1357" PressFile$'Entity/Page/File Commands'
[toPrinter: ndest | psocket dest np t perr |
	 "a printer name"
	ndest  false
	  ifTrue: [↑false].
	 "don't try to print"
	E  nil
	  ifTrue:
		[t ← (String new: 100) "use O.S. if Smalltalk ethercode not alive" asStream.
		t append: 'Empress. '.
		t append: self name.
		ndest length > 0
		  ifTrue:
			[t space.
			t append: ndest.
			t append: '/H'].
		t append: '; Resume.~ Small.Boot'.
		user quitThen: t asReadStream]
	  ifFalse:
		[dest ← ''.
		perr ← psocket ← false.
		np ← printers length + 1.
		DL readonly.
		[ndest] whileTrueDo:
			[(perr or: [ndest empty])
			  ifTrue:
				[perr ← false.
				ndest ← self selectPrinter: dest]
			  ifFalse:
				[dest = ndest
				  ifFalse:
					[ "to same printer"
					dest ← ndest "close previous socket".
					psocket
					  ifTrue:
						[psocket close.
						psocket ← false]].
				psocket
				  ifFalse:
					[ "create new socket"
					(psocket ← EFTPSender new hostName: dest)
					  ifTrue: [psocket wakeup]
					  ifFalse:
						[user cr.
						user show: 'name lookup failure']] "send file".
				(psocket and: [(user displayoffwhile [(psocket send: DL reset)])])
				  ifTrue: [ndest ← false "success--stop"]
				  ifFalse: [ "failure--switch servers?"
					perr ← true]] "cleanup after success or abort"].
		DL close.
		psocket
		  ifTrue: [psocket close]]].
"134" PressFile$'EL commands'
[setp: p | |
	EL next← 238 "self setx: p x; sety: p y".
	EL nextword← p x.
	EL next← 239.
	EL nextword← p y].
"86" PressFile$'Initialization'
[reset | |
	DL readwriteshorten.
	DL reset.
	self of: DL].
"3446" PressFile$'Reading'
[nextControl | command t entity |
	command ← nil "return the next skip-control information".
	[true] whileTrueDo:
		[(estate and: [command])  false
		  ifTrue:
			[(t ← EL next "either or both false. get next entity")
			  ifTrue:
				[estate ← EL next viewer.
				command ← nil.
				t  1  SMentity
				  ifTrue: [estate ← false "ignore this entity"]
				  ifFalse:
					[DLstart ← (t  (3 to: 6)) asStream nextNumber: 4.
					DL position← Pstart * recordsize + DLstart]]
			  ifFalse:
				[ "no more entities on current part (page)"
				self readPart
				  ifFalse: [ "no more pages"
					↑false]]]
		  ifFalse:
			[entity ← estate.
			[command ← entity next] whileTrueDo:
				[command < 64 "some stuff arranged by probable frequency"
				  ifTrue: [DL skip: (command land: 31) "show-characters-short (0-037)
		skip-characters-short (040-077)" + 1]
				  ifFalse:
					[command = 238
					  ifTrue: [entity nextword "set-x"]
					  ifFalse:
						[command = 239
						  ifTrue: [entity nextword "set-y"]
						  ifFalse:
							[command < 96
							  ifTrue: [DL skip: (command land: 31) "show-characters-and-skip (0100-0137)" + 2]
							  ifFalse:
								[command < 112
								  ifTrue: [entity next "set-space-x-short (0140-0147)
		set-space-y-short  (0150-0157)" "(command land: 7)*256 +"]
								  ifFalse:
									[command < 128
									  ifFalse:
										[ "font" "command land: 017"
										command = 242
										  ifTrue:
											[t ← entity nextword "skip-control-bytes".
											entity next  SMentity
											  ifTrue: [DL skip: t "ignore"]
											  ifFalse: [↑DL next: t]]
										  ifFalse:
											[command = 240
											  ifTrue: [DL skip: entity next "show-characters"]
											  ifFalse:
												[command = 255
												  ifFalse:
													[ "nop"
													command < 235
													  ifFalse:
														[ "available (0200-0237)
		spare (0240-0352)"
														command = 235
														  ifTrue: [↑entity next: entity next "skip-control-bytes-immediate"].
														command = 236
														  ifTrue: [entity skipwords: 5 "alternative"]
														  ifFalse:
															[command = 237
															  ifTrue: [entity next "only-on-copy"]
															  ifFalse:
																[command = 241
																  ifTrue: [DL skip: entity next "skip characters"]
																  ifFalse:
																	[command = 243
																	  ifTrue: [entity next "show-character-immediate"]
																	  ifFalse:
																		[command < 246
																		  ifTrue: [entity nextword "set-space-x (0364)
		set-space-y (0365)"]
																		  ifFalse:
																			[command < 248
																			  ifFalse:
																				[ "reset-space (0366)
		space (0367)"
																				command < 251
																				  ifTrue: [entity next "set-brightness (0370)
		set-hue (0371)
		set-saturation (0372)"]
																				  ifFalse:
																					[command = 251
																					  ifTrue: [DL skipwords: entity nextword "show-object"]
																					  ifFalse:
																						[command < 254
																						  ifTrue: [DL skipwords: (entity nextNumber: 4) "show-dots (0374)
		show-dots-opaque (0375)"]
																						  ifFalse:
																							[command = 254
																							  ifTrue: [entity skipwords: 2 "show-rectangle"]]]]]]]]]]]]]]]]]]]]]]]].
"1001" PressFile$'Private'
[classInit | a p |
	Smalltalk declare: #PressScale as: 32 "PressFile classInit.".
	recordsize ← 512.
	SMentity ← 5.
	a ← (String new: 250) asStream "from [Maxc1]<Altodocs>NetTopology.Press, October 1980. in order of net number".
	printers ← #('Navajo' 'Menlo' 'Clover' 'Lilac' 'Kanji' 'Wonder' 'Quake' 'Puff' 'White' 'Colorado' 'Niagara' 'Tioga' 'Yoda' 'Lily' 'Ranger' 'Windfall' 'Genesee' 'Amarok' 'Yankee' 'Cyclops' 'Rover' 'SPGEng' 'Emperor' 'Thud' 'Adelie' 'Daisy' 'RockHopper' 'Bud' ) "net #" "printer names" " 1" "HENRIETTA" " 3" "PARC: BLDG 35, FLOOR 2" " 5" "PARC:  BLDG 34" " 6" "PARC: BLDG 35, FLOOR 1&3" "10" "A&E" "12" "PASADENA" "14" "WEBSTER" "20" "PARC: BLDG 32" "21" "SPG" "23" "DALLAS" "26" "DC" "27" "WEBSTER" "33" "TORONTO" "34" "STAMFORD" "36" "LEESBURG" "54" "A&E" "55" "A&E" "56" "A&E" "60" "BAYHILL" "62" "?".
	printers do:
		[:p | a append: p.
		a cr].
	a append: 'same printer'.
	a cr.
	a append: 'no printer'.
	printerMenu ← Menu new string: a contents].
"184" PressFile$'Reading'
[filin | p |
	self open.
	[p ← self nextParagraph] whileTrueDo:
		[FilinSource ← self.
		user print: nil  p text.
		user space].
	FilinSource ← nil.
	self close].
"1763" PressFile$'Entity/Page/File Commands'
[close | p i font t4 |
	DL writing  false
	  ifTrue: [DL close]
	  ifFalse:
		[self closePage.
		(parts  false or: [parts empty])
		  ifFalse:
			[ "if present, include the external file part  --- added Sept 80"
			FL empty
			  ifFalse:
				[self part [(DL append: FL)] code: 2.
				FL reset.
				self padpage] "put font names and descriptions into font directory (part)".
			self part [((1 to: fontdefs length) do:
					[:i | font ← fontdefs  i.
					DL nextword← 16.
					DL nextword← i - 1.
					DL next← font min.
					DL next← font max.
					self Bcpl: font name pad: 20.
					DL next← font face.
					DL next← font min.
					DL nextword← font pointsize.
					DL nextword← 0])] code: 1 "write part directory. Pstart is current page position".
			DL append: parts asReadStream.
			self padpage.
			p ← self recordnum "document directory".
			DL nextword← 27183 "press password".
			DL nextword← p + 1 "number of records".
			DL nextword← parts position / 8 "number of parts".
			DL nextword← Pstart "part dir and length".
			DL nextword← p - Pstart.
			DL nextword← 1 "backpointer to obsolete doc dir".
			DL append: user timewords "2 time words".
			DL nextword← 1 "first and last copies".
			DL nextword← 1.
			DL nextword← 1 "first and last pages".
			DL nextword← 1.
			DL nextword← 'S'  1 "solid color (looked at by color printers)".
			DL next: (2 * (127 - 12)) ← 255.
			p ← user now.
			self Bcpl: self name pad: 52.
			self Bcpl: (currentProfile  nil
			  ifTrue: [dp0 diskID  1]
			  ifFalse: [currentProfile printedBy]) pad: 32.
			self Bcpl: ((t4 ← (String new: 40) asStream) print: p  1.
			t4 space.
			t4 print: p  2.
			t4 contents) pad: 40.
			self padpage.
			DL close.
			parts reset]]].
"138" PressFile$'EL commands'
[showrect: rect | |
	self setp: rect origin.
	EL next← 254.
	EL nextword← rect width.
	EL nextword← rect height].
"591" PressFile$'Bitmaps/Dots'
[AIS: file width: w height: h croprect: r at: pt scale: s | |
	self setp: (self transpt: pt).
	self dots [
		(self setcoding: 8 dots: w lines: h "byte samples".
		self setmode: 3 "to right and to bottom of page".
		self setsizewidth: (s * r width * scale) asInteger height: (s * r height * scale) asInteger.
		self setwindowwidth: r width height: r height skipdots: r minX skiplines: r minY.
		self dotsfromAIS: file)] "
(dp0 pressfile: 'pix.press') somefont; AIS: 'girl.ais' width: 512 height: 512 croprect: (5050 rect: 500500) at: 3680 scale: 0.65; close.
"].
"218" PressFile$'Bitmaps/Dots'
[dotsfromAIS: file | f |
	f ← file length inString + file + (file length even
			  ifTrue: [' ']
			  ifFalse: ['']) "BCPLize".
	DL nextword← 4.
	DL nextword← 4.
	DL append: f.
	FL append: f].
"173" PressFile$'Bitmaps/Dots'
[setwindowwidth: w height: h skipdots: sd skiplines: sl | |
	DL nextword← 1.
	DL nextword← sd.
	DL nextword← w.
	DL nextword← sl.
	DL nextword← h].
"135" PressFile$'Aspects'
[defaultPrinterName | |
	↑currentProfile  nil
	  ifTrue: [PrinterName]
	  ifFalse: [currentProfile printerName]].
"358" PressFile$'Entity/Page/File Commands'
[screenout: rect scale: t2 | |
	scale ← t2.
	user displayoffwhile [
		 "puts a bit map image onto the PressFile.  The standard
	scaling is 32 micas per Alto dot.  22 looks better, Dover only
	works with 32"
		(self somefont.
		self setp: (self transrect: rect) origin.
		self bitmap: rect bits: false.
		self close)]].
"217" PressFile$'Reading'
[nextParagraph | s p |
	(s ← self nextControl)
	  ifTrue:
		[s ← s asStream.
		p ← Paragraph new.
		s next = p pressCode
		  ifTrue: [↑p fromPress: self value: s].
		↑false]
	  ifFalse: [↑false]].
"77" PressFile$'Lines/Objects'
[moveto: p | |
	DL nextword← 0.
	DL nextPoint← p].
"66" PressFile$'Entity/Page/File Commands'
[page | |
	self closePage].
"504" PressFile$'Entity/Page/File Commands'
[selectPrinter: oldName | t |
	user cr.
	user show: 'select a printer (currently '.
	user show: ((oldName  false or: [oldName empty])
	  ifTrue: ['none']
	  ifFalse: [oldName]).
	user show: ')'.
	user cursorloc← user screenrect center.
	user restoredisplay.
	t ← 0.
	[t = 0] whileTrueDo: [t ← printerMenu wbug].
	↑t  printers length
	  ifTrue: [printers  t]
	  ifFalse:
		[t = (printers length + 1)
		  ifTrue: [oldName]
		  ifFalse: [ "same" "none"
			false]]].
"105" PressFile$'Entity/Page/File Commands'
[selectPrinter | |
	↑self selectPrinter: self defaultPrinterName].
"58" PressFile$'Private'
[data | |
	↑DL "slightly dangerous"].
"102" PressFile$'Fonts'
[codefont: code style: style | |
	↑fontdefs  (self fontindex: code style: style)].
"218" PressFile$'EL commands'
[setspacex: x | |
	estate  2 = x
	  ifFalse:
		[estate  2 ← x.
		(x  0 and: [x  2047])
		  ifTrue: [EL nextword← 24576 + x "short form"]
		  ifFalse:
			[EL next← 244.
			EL nextword← x]]].
"49" WidthTable$'Access'
[pointsize | |
	↑pointsize].
"39" WidthTable$'Access'
[face | |
	↑face].
"45" WidthTable$'Access'
[descent | |
	↑descent].
"37" WidthTable$'Access'
[tab | |
	↑tab].
"37" WidthTable$'Access'
[max | |
	↑max].
"43" WidthTable$'Access'
[tab← t | |
	tab ← t].
"367" WidthTable$'Initialization'
[lookup | key font i |
	key ← name + pointsize asString + (#('' 'I' 'B' 'BI' )  (face + 1)).
	(font ← WidthDict lookup: key)
	  ifTrue: [↑font].
	self fontfrom: (dp0 oldFile: 'Fonts.Widths') readonly.
	#(9 13 32 ) do:
		[:i | (i  min and: [i  max])
		  ifTrue: [widths  (i - min + 1) ← 0]].
	WidthDict insert: key with: self.
	↑self].
"37" WidthTable$'Access'
[min | |
	↑min].
"259" WidthTable$'Reading FONTS.WIDTHS'
[findfield: n on: file | IXH t4 |
	[IXH ← file nextword.
	(t4 ← IXH bits: (0 to: 3)) = 0 "type"
	  ifTrue: [user notify: 'field not found']
	  ifFalse: [t4  n]] whileTrueDo: [file skipwords: (IXH land: 4095) "length" - 1]].
"1231" WidthTable$'Reading FONTS.WIDTHS'
[fontfrom: file | i code fam fmin fmax start len found w scale |
	file reset "find code for font family".
	fam ← ''.
	[fam = name] whileFalseDo: 
		[self findfield: 1 on: file.
		code ← file nextword.
		fam ← file next: (len ← file next).
		file skip: 19 - len "now search for proper face"].
	found ← false "Convert from points to micas".
	scale ← (pointsize asFloat * 2540 / 72) asInteger.
	[found] whileFalseDo: 
		[self findfield: 4 on: file.
		found ← (file next = code).
		file next  face
		  ifTrue: [found ← false].
		fmin ← file next.
		fmax ← file next.
		i ← file nextword.
		(i  scale and: [i  0])
		  ifTrue: [found ← false].
		file skip: 4.
		start ← file nextword.
		file skip: 4].
	scale ← (i  0
			  ifTrue: [1]
			  ifFalse: [ "don't need to scale"
				pointsize asFloat * 254 / 7200]).
	min ← fmin.
	max ← fmax "get bb and x-tables".
	file wordposition← start + 1.
	descent ← 0 - (scale * file nextword) asInteger.
	file nextword.
	ascent ← (scale * file nextword) asInteger.
	file nextword.
	widths ← Vector new: max - min + 1.
	(1 to: widths length) do:
		[:i | w ← file nextword.
		widths  i ← (w > 0
		  ifTrue: [(scale * w) asInteger]
		  ifFalse: [0])].
	file close].
"39" WidthTable$'Access'
[space | |
	↑150].
"86" WidthTable$'Initialization'
[classInit | |
	WidthDict ← Dictionary init.
	tab ← 500].
"43" WidthTable$'Access'
[ascent | |
	↑ascent].
"489" WidthTable$'Access'
[scan: strm until: width exceeds: maxw | char w |
	[char ← strm next] whileTrueDo:
		[char < min
		  ifTrue:
			[(char = 32 or: [(char = 13 or: [char = 9])])
			  ifTrue: [↑{char , width}].
			user notify: 'char too low']
		  ifFalse:
			[char > max
			  ifTrue: [user notify: 'char too high']
			  ifFalse:
				[(w ← widths  (char + 1 - min)) = 0
				  ifTrue: [↑{char , width}].
				(width ← width + w) > maxw
				  ifTrue: [↑{true , width}]]]].
	↑{false , width}].
"39" WidthTable$'Access'
[name | |
	↑name].
"108" WidthTable$'Initialization'
[named: t1 pointsize: t2 face: t3 | |
	name ← t1.
	pointsize ← t2.
	face ← t3].
"755" PressFile$'Fonts'
[fontindex: code style: style | ix font n |
	code ← code land: 243 "return index if in font dictionary" "Remove underline and strikeout".
	style = prevstyle
	  ifTrue:
		[(ix ← fontcodes find: code) > 0
		  ifTrue: [↑ix]]
	  ifFalse:
		[fontcodes all← nil "invalid across style change".
		prevstyle ← style].
	n ← code / 16 + 1.
	font ← (WidthTable new named: (style fontfamily: n) pointsize: (style fontsize: n) face: (code / 2 land: 1) + (code * 2 land: 2)) lookup.
	(ix ← fontdefs find: font) > 0
	  ifTrue:
		[fontcodes  ix ← code.
		↑ix].
	 "add entry to font dictionary"
	fontdefs length = 16
	  ifTrue:
		[user notify: 'too many fonts'.
		↑1].
	fontcodes ← {fontcodes , code}.
	fontdefs ← {fontdefs , font}.
	↑fontcodes length].
"101" PressFile$'Fonts'
[selectfont: f | |
	estate  1 = f
	  ifFalse: [EL next← 112 + (estate  1 ← f)]].
"182" PressFile$'EL commands'
[skipchars: n | |
	n = 0
	  ifFalse:
		[(n  1 and: [n  32])
		  ifTrue: [EL next← 32 + n "short form" - 1]
		  ifFalse:
			[EL next← 241.
			EL next← n]]].
"177" PressFile$'EL commands'
[showchars: n | |
	n = 0
	  ifFalse:
		[(n  1 and: [n  32])
		  ifTrue: [EL next← n - 1 "short form"]
		  ifFalse:
			[EL next← 240.
			EL next← n]]].
"178" PressFile$'EL commands'
[showchars: n skip: t | |
	(t = 1 and: [(n  1 and: [n  32])])
	  ifTrue: [EL next← 64 + n - 1]
	  ifFalse:
		[self showchars: n.
		self skipchars: t]].
"307" PressFile$'Private'
[skipcode: code data: s | t |
	(t ← s length "called by hidePress:complete:. s is a String" + 1) < 256
	  ifTrue:
		[self skipcontrol: t "immediate, in EL".
		EL next← code.
		EL append: s]
	  ifFalse:
		[ "in DL"
		DL next← code.
		DL append: s.
		self skipcontrol: t type: SMentity]].
"219" PressFile$'Private'
[Bcpl: s pad: n | slen |
	slen ← s length "write a Bcpl string and padding to fill n bytes (used by close)" min: n - 1.
	DL next← slen.
	DL append: s  (1 to: slen).
	DL next: (n - (slen + 1)) ← 0].
"42" PressFile$'Aspects'
[name | |
	↑DL name].
"65" PressFile$'EL commands'
[hue: b | |
	EL next← 249.
	EL next← b].
"375" PressFile$'Reading'
[open | t |
	DL readonly "read the parts (and font directory?)" "reopen?".
	DL settoend.
	DL skip: 0 - recordsize.
	(DL nextword = 27183 and: [DL nextword = (self recordnum + 1)])
	  ifTrue:
		[t ← DL nextword.
		DL position: DL nextword size: recordsize.
		parts ← (DL next: t * 8) viewer.
		self readPart]
	  ifFalse: [self error: 'not a press file']].
"56" PressFile$'Initialization'
[scale: t1 | |
	scale ← t1].
"139" PressFile$'EL commands'
[showrect: rect color: c | |
	ColorPrint
	  ifTrue: [self brightness: c].
	self showrect: (self transrect: rect)].
"67" PressFile$'Private'
[closeEntity | |
	self closeEntity: SMentity].
"159" PressFile$'Transformations'
[transrect: rect | |
	↑Rectangle new origin: (self transpt: rect minX  rect maxY) corner: (self transpt: rect maxX  rect minY)].
"76" PressFile$'Entity/Page/File Commands'
[entityorigin: t1 | |
	eorigin ← t1].
"67" PressFile$'Private'
[recordnum | |
	↑DL positionSize: recordsize].
"70" PressFile$'EL commands'
[sety: y | |
	EL next← 239.
	EL nextword← y].
"70" PressFile$'EL commands'
[setx: x | |
	EL next← 238.
	EL nextword← x].
"122" PressFile$'Transformations'
[transpt: p | |
	↑Point new x: (p x * scale) asInteger y: (25400 - (p y * scale)) asInteger].
"127" PressFile$'Fonts'
[somefont | |
	 "fool self into writing non-empty fontdir"
	self fontindex: 5 * 16 style: DefaultTextStyle].
"88" PressPrinter$'Initialization'
[of: t1 | |
	strm ← t1.
	press ← PressFile new of: strm].
"127" PressPrinter$'Writing'
[print: para | |
	self print: para in: (Rectangle new origin: frame origin corner: frame maxX  ypos)].
"59" PressPrinter$'Initialization'
[press: t1 | |
	press ← t1].
"60" PressPrinter$'Writing'
[nextpage | |
	self nextpage: true].
"56" ParagraphPrinter$'Access to state'
[frame | |
	↑frame].
"64" ParagraphPrinter$'Access to state'
[style← t1 | |
	style ← t1].
"262" ParagraphPrinter$'Class stuff'
[printForget: selector class: class | |
	 "Print a line that causes a message to be forgotten"
	user cr.
	user show: '~' + class title + ' ' + selector.
	self print: (class title + ' derstands: ' + selector + '.
') asParagraph].
"70" ParagraphPrinter$'Access to state'
[defaultframe | |
	↑defaultframe].
"206" ParagraphPrinter$'Initialization'
[classInit | inch |
	inch ← 2540 "1 inch in micas".
	defaultframe ← (0.75 * inch) asInteger  (1 * inch) rect: (7.75 * inch) asInteger  (10 * inch).
	defaultleading ← 0].
"59" ParagraphPrinter$'Initialization'
[of: t1 | |
	strm ← t1].
"52" ParagraphPrinter$'Closing'
[close | |
	strm close].
"139" ParagraphPrinter$'Initialization'
[init | |
	self frame← self defaultframe.
	self leading← defaultleading.
	self style← DefaultTextStyle].
"1843" ParagraphPrinter$'Class stuff'
[printchanges: lis | selector class heading old mes s delFlg |
	 "prints Changes format: ('class message' 'class message' ...)
	or alternate format: (class (message ...) class () ...) or both
	If an element appears in the list of the form '~class message', this puts out a 
	line causing the system to forget that method.  These come after any additons,
	owing to the sort on Changes"
	lis empty
	  ifTrue: [↑lis].
	user displayoffwhile [
		(lis ← lis asStream.
		old ← mes ← false.
		[class] whileTrueDo:
			[ "get next class, selector pair"
			delFlg ← false.
			(mes and: [(selector ← mes next)])
			  ifFalse:
				[ "more of alternate form"
				(s ← lis next)
				  ifTrue:
					[(s is: UniqueString)
					  ifTrue:
						[class ← Smalltalk lookup: s.
						mes ← lis next asStream.
						selector ← mes next]
					  ifFalse:
						[ "Changes format"
						s ← s asStream.
						s peek = 126 "~"
						  ifTrue:
							[s next "take it off stream".
							delFlg ← true].
						class ← Smalltalk  (s upto: 32) unique.
						selector ← s upto: 32]]
				  ifFalse: [class ← false]].
			delFlg
			  ifTrue: [self printForget: selector class: class]
			  ifFalse:
				[ "same, different or no class"
				old  class
				  ifFalse:
					[old
					  ifTrue:
						[old endCategoryOn: self.
						old endChangesOn: self].
					class  false
					  ifFalse:
						[ "finished"
						user cr.
						user show: class title.
						old ← class.
						class startChangesOn: self.
						heading ← 'As yet unclassified']].
				class  false
				  ifFalse:
					[user space.
					user show: selector.
					s ← class organization invert: (selector ← selector unique).
					s
					  ifTrue:
						[s  heading
						  ifTrue: [class startCategory: (heading ← s) on: self].
						class printMethod: selector on: self]]]])]].
"74" ParagraphPrinter$'Access to state'
[defaultleading | |
	↑defaultleading].
"400" ParagraphPrinter$'Class stuff'
[printclass: class | c first |
	(class is: Vector)
	  ifTrue:
		[first ← true.
		class do:
			[:c | first
			  ifTrue: [first ← false]
			  ifFalse: [self nextpage].
			self printclass: c]]
	  ifFalse: [user displayoffwhile [
			((class is: UniqueString)
			  ifTrue: [class ← Smalltalk  class].
			user cr.
			user show: class title.
			class paraprinton: self)]]].
"108" ParagraphPrinter$'Writing'
[print: para | |
	 "A dummy, subclasses will override"
	strm append: para text].
"281" ParagraphPrinter$'Class stuff'
[stamp | s t |
	t ← user now "date and time".
	s ← Stream default.
	s append: '''From '.
	s append: user version.
	s append: ' on '.
	s print: t  1.
	s append: ' at '.
	s print: t  2.
	s append: '.'''.
	s cr.
	self print: s contents asParagraph].
"68" ParagraphPrinter$'Access to state'
[leading← t1 | |
	leading ← t1].
"64" ParagraphPrinter$'Access to state'
[frame← t1 | |
	frame ← t1].
"374" CodePane$'Window protocol'
[hardcopy: pf | t2 |
	selectorPane  self "if this is just part of a CodeWindow, then print entire Paragraph with no frame.
	unfortunately, the test for this is a kludge. otherwise, print clipped"
	  ifTrue:
		[(t2 ← PressPrinter init) press: pf.
		t2 print: pared contents]
	  ifFalse:
		[frame hardcopy: pf thickness: 1.
		pared hardcopy: pf]].
"49" CodePane$'Window protocol'
[kbd | |
	pared kbd].
"56" CodePane$'Window protocol'
[keyset | |
	↑pared keyset].
"56" CodePane$'Window protocol'
[leave | |
	scrollBar hide].
"62" CodePane$'Window protocol'
[picked | |
	↑frame has: user mp].
"59" CodePane$'Window protocol'
[redbug | |
	↑pared selecting].
"67" CodePane$'Browse/Notify protocol'
[contents | |
	↑pared contents].
"796" CodePane$'Window protocol'
[doit | s val d t4 |
	d ← (NoteTaker
			  ifTrue: [false]
			  ifFalse:
				[user leftShiftKey
				  ifTrue: [mem  55]
				  ifFalse: [false]]).
	d
	  ifTrue: [mem  55 ← 58].
	scrollBar hide "do automatic selection (ESC) on empty selections".
	(s ← pared selectRange) empty
	  ifTrue:
		[pared unselect.
		pared fintype.
		pared complement.
		s ← pared selectRange].
	val ← selectorPane execute: pared selectionAsStream for: self.
	(val  nil or: [s  pared selectRange])
	  ifFalse:
		[ "result is nil or error occurred" "automatically paste result"
		s ← s stop + 1.
		pared Scrap← ((t4 ← (String new: 100) asStream) space.
		t4 print: val.
		t4 contents asParagraph).
		pared selectRange: (s to: s).
		pared paste].
	scrollBar show.
	d
	  ifTrue: [mem  55 ← d]].
"56" CodePane$'Window protocol'
[enter | |
	scrollBar show].
"92" CodePane$'Browse/Notify protocol'
[dirty | |
	pared formerly
	  ifTrue: [↑frame].
	↑false].
"102" CodePane$'Browse/Notify protocol'
[selectRange: r | |
	pared selectRange: r.
	pared selectAndScroll].
"61" CodePane$'Initialization'
[from: t1 | |
	selectorPane ← t1].
"126" CodePane$'Initialization'
[classInit | |
	editmenu ← Menu new string: 'again
copy
cut
paste
doit
compile
undo
cancel
align'].
"62" CodePane$'Window protocol'
[outside | |
	↑scrollBar startup].
"103" CodePane$'Window protocol'
[close | |
	pared unselect.
	selectorPane ← pared ← nil.
	scrollBar close].
"74" CodePane$'Window protocol'
[windowenter | |
	self outline.
	pared enter].
"85" CodePane$'Window protocol'
[windowleave | |
	pared  nil
	  ifFalse: [pared leave]].
"172" LADVariableNode$'Initialization'
[NTinit | |
	 "rehash for new oops after Vmem write"
	(NoteTaker and: [initted  false])
	  ifTrue:
		[self classInit.
		initted ← true]].
"338" LADVariableNode$'Code Generation'
[emitStorePop: stack on: strm | |
	(code between: 0 and: [7])
	  ifTrue: [strm next← ShortStoP + code "short stopop inst"]
	  ifFalse:
		[(code between: 16 and: [23])
		  ifTrue: [strm next← ShortStoP + 8 + code - 16 "short stopop temp"]
		  ifFalse: [self emitLong: StorePop on: strm]].
	stack pop: 1].
"272" LADVariableNode$'Code Generation'
[emitForReturn: stack on: strm | |
	(code  LdSelf and: [code  LdNil])
	  ifTrue:
		[ "short returns"
		strm next← EndMethod - 4 + (code - LdSelf).
		stack push: 1 "doesnt seem right"]
	  ifFalse: [super emitForReturn: stack on: strm]].
"98" LADVariableNode$'Code Generation'
[emitStore: stack on: strm | |
	self emitLong: Store on: strm].
"91" LADVariableNode$'Code Generation'
[sizeForStore: encoder | |
	self reserve: encoder.
	↑2].
"148" LADVariableNode$'Code Generation'
[sizeForStorePop: encoder | |
	self reserve: encoder.
	(code < 24 and: [(code nomask: 8)])
	  ifTrue: [↑1].
	↑2].
"117" LADVariableNode$'Simplifying'
[canBeSpecialArgument | |
	 "can I be an argument of (e.g.) ifTrue:?"
	↑code < LdNil].
"141" LADVariableNode$'Initialization'
[name: varName key: objRef index: i type: type | |
	name ← varName.
	self key: objRef index: i type: type].
"81" LADVariableNode$'Printing'
[printon: strm indent: level | |
	strm append: name].
"120" LADVariableNode$'Initialization'
[name: string key: object code: byte | |
	name ← string.
	key ← object.
	code ← byte].
"175" LADLiteralNode$'Code Generation'
[emitForValue: stack on: strm | |
	code < 256
	  ifTrue: [strm next← code]
	  ifFalse: [self emitLong: LdInstLong on: strm].
	stack push: 1].
"208" LADLiteralNode$'Printing'
[printon: strm indent: level | |
	 "wouldn't handle UniqueString literals right"
	((key is: UniqueString) or: [(key is: Vector)])
	  ifTrue: [strm append: ''].
	key printon: strm].
"542" LADLeafNode$'Code Generation'
[emitLong: mode on: strm | type index |
	 "emit extended variable access"
	code < 256
	  ifTrue:
		[code < 16
		  ifTrue:
			[type ← 0.
			index ← code]
		  ifFalse:
			[code < 32
			  ifTrue:
				[type ← 1.
				index ← code - 16]
			  ifFalse:
				[code < 96
				  ifTrue:
					[type ← code / 32 + 1.
					index ← code \ 32]
				  ifFalse: [user notify: 'Sends should be handled in SelectorNode']]]]
	  ifFalse:
		[index ← code \ 256.
		type ← code / 256 - 1].
	strm next← mode.
	strm next← type * 64 + index].
"154" LADLeafNode$'Code Generation'
[emitOn: strm | |
	code < 256
	  ifTrue: [strm next← code]
	  ifFalse:
		[strm next← code / 256.
		strm next← code \ 256]].
"69" LADLeafNode$'Code Generation'
[emitForEffect: stack on: strm | |
	].
"98" LADLeafNode$'Aspects'
[= literal | t |
	↑key class  literal class and: [(key sameAs: literal)]].
"120" LADLeafNode$'Initialization'
[name: literal key: object index: i type: type | |
	self key: object index: i type: type].
"196" LADLeafNode$'Code Generation'
[reserve: encoder | |
	 "if this is a yet unused literal of type -code, reserve it"
	code < 0
	  ifTrue: [code ← self code: (encoder litIndex: key) type: 0 - code]].
"64" LADLeafNode$'Code Generation'
[sizeForEffect: encoder | |
	↑0].
"80" LADLeafNode$'Code Generation'
[size: encoder | |
	↑self sizeForValue: encoder].
"41" LADLeafNode$'Aspects'
[code | |
	↑code].
"47" LADLeafNode$'Aspects'
[hash | t |
	↑key hash].
"116" LADLeafNode$'Code Generation'
[sizeForValue: encoder | |
	self reserve: encoder.
	code < 256
	  ifTrue: [↑1].
	↑2].
"39" LADLeafNode$'Aspects'
[key | |
	↑key].
"87" LADLeafNode$'Initialization'
[key: object code: byte | |
	key ← object.
	code ← byte].
"118" LADLeafNode$'Initialization'
[key: object index: i type: type | |
	self key: object code: (self code: i type: type)].
"179" LADLeafNode$'Private'
[code: index type: type | |
	index  false
	  ifTrue: [↑0 - type].
	CodeLimits  type > index
	  ifTrue: [↑CodeBases  type + index].
	↑type * 256 + index].
"188" LADParseNode$'Code Generation'
[emitBranch: dist pop: stack on: strm | |
	stack pop: 1.
	dist = 0
	  ifTrue: [strm next← Pop]
	  ifFalse: [self emitShortOrLong: dist code: Bfp on: strm]].
"221" LADParseNode$'Private'
[emitShortOrLong: dist code: shortCode on: strm | |
	(1  dist and: [dist  JmpLimit])
	  ifTrue: [strm next← shortCode + dist - 1]
	  ifFalse: [self emitLong: dist code: shortCode + 16 on: strm]].
"126" LADParseNode$'Code Generation'
[emitForReturn: stack on: strm | |
	self emitForValue: stack on: strm.
	strm next← EndMethod].
"396" LADParseNode$'Private'
[emitLong: dist code: longCode on: strm | code |
	 "force a two-byte jump"
	code ← longCode.
	dist < 0
	  ifTrue: [dist ← dist + 1024]
	  ifFalse:
		[dist > 1023
		  ifTrue: [dist ← 1]
		  ifFalse: [code ← code + 4]].
	dist < 0
	  ifTrue: [user notify: 'A block compiles more than 1K bytes of code']
	  ifFalse:
		[strm next← dist / 256 + code.
		strm next← dist \ 256]].
"107" LADParseNode$'Printing'
[printon: strm indent: level precedence: p | |
	self printon: strm indent: level].
"71" LADParseNode$'Simplifying'
[asCollectionElements: length | |
	↑false].
"107" LADParseNode$'Simplifying'
[canBeSpecialArgument | |
	 "can I be an argument of (e.g.) ifTrue:?"
	↑false].
"113" LADParseNode$'Printing'
[printon: strm | |
	strm append: ''.
	self printon: strm indent: 0.
	strm append: ''].
"894" LADParseNode$'Initialization'
[classInit | |
	 "LADParseNode classInit.  LADVariableNode classInit." " | x. LADParseNode classvars contents sort transform x to x+' '+(LADParseNode classvars ref: x) refct asString " "Smalltalk allCallsOn: (LADParseNode classvars ref: NodeTrueFalse) from: (SystemOrganization superclassOrder: 'S80-Compiler') " "LADParseNode classvars clean."
	.
	LdInstType ← 1.
	LdTempType ← 2.
	LdLitType ← 3.
	LdLitIndType ← 4.
	SendType ← 5.
	CodeBases ← #(0 16 32 64 208 ).
	CodeLimits ← #(16 16 32 32 16 ).
	LdSelf ← 112.
	LdTrue ← 113.
	LdFalse ← 114.
	LdNil ← 115.
	LdMinus1 ← 116.
	LdInstLong ← 128.
	Store ← 129.
	StorePop ← 130.
	ShortStoP ← 96.
	SendLong ← 131.
	LdSuper ← 133.
	Pop ← 135.
	Dup ← 136.
	LdThisContext ← 137.
	EndMethod ← 124.
	EndRemote ← 125.
	Jmp ← 144.
	Bfp ← 152.
	JmpLimit ← 8.
	JmpLong ← 160.
	SendPlus ← 176.
	Send ← 208.
	SendLimit ← 16].
"96" LADParseNode$'Code Generation'
[sizeForEffect: encoder | |
	↑(self sizeForValue: encoder) + 1].
"132" LADParseNode$'Code Generation'
[emitJump: dist on: strm | |
	dist = 0
	  ifFalse: [self emitShortOrLong: dist code: Jmp on: strm]].
"136" LADParseNode$'Code Generation'
[emitLongJump: dist on: strm | |
	 "force a two byte jump"
	self emitLong: dist code: JmpLong on: strm].
"111" LADParseNode$'Code Generation'
[sizeBranch: dist | |
	dist = 0
	  ifTrue: [↑1].
	↑self sizeShortOrLong: dist].
"108" LADParseNode$'Private'
[sizeShortOrLong: dist | |
	(1  dist and: [dist  JmpLimit])
	  ifTrue: [↑1].
	↑2].
"45" LADParseNode$'Simplifying'
[simplify | |
	].
"96" LADParseNode$'Code Generation'
[sizeForReturn: encoder | |
	↑(self sizeForValue: encoder) + 1].
"109" LADParseNode$'Code Generation'
[sizeJump: dist | |
	dist = 0
	  ifTrue: [↑0].
	↑self sizeShortOrLong: dist].
"62" LADParseNode$'Encoding'
[encodeSelector: selector | |
	↑nil].
"135" LADParseNode$'Code Generation'
[emitForEffect: stack on: strm | |
	self emitForValue: stack on: strm.
	strm next← Pop.
	stack pop: 1].
"717" LADSelectorNode$'Code Generation'
[emit: stack args: nArgs on: strm super: supered | index |
	stack pop: nArgs.
	(supered  false and: [(code - Send < SendLimit and: [nArgs < 3])])
	  ifTrue: [ "short send"
		strm next← (code < Send
		  ifTrue: [code]
		  ifFalse: [ "special"
			nArgs * 16 + code])]
	  ifFalse:
		[index ← (code < 256
				  ifTrue: [code - Send]
				  ifFalse: [code \ 256]).
		(index < 32 and: [nArgs  7])
		  ifTrue:
			[ "medium send"
			strm next← SendLong + (supered
			  ifTrue: [2]
			  ifFalse: [0]).
			strm next← nArgs * 32 + index]
		  ifFalse:
			[ "long send"
			.
			strm next← SendLong + 1 + (supered
			  ifTrue: [2]
			  ifFalse: [0]).
			strm next← nArgs.
			strm next← index]]].
"484" LADSelectorNode$'Code Generation'
[size: encoder args: nArgs super: supered | index |
	self reserve: encoder.
	(supered  false and: [(code - Send < SendLimit and: [nArgs < 3])])
	  ifTrue: [↑1].
	 "short send"
	(supered and: [code < Send])
	  ifTrue: [ "super special:"
		code ← self code: (encoder litIndex: key) type: 5].
	index ← (code < 256
			  ifTrue: [code - Send]
			  ifFalse: [code \ 256]).
	(index < 32 and: [nArgs  7])
	  ifTrue: [↑2].
	 "medium send"
	↑3 "long send"].
"80" LADSelectorNode$'Printing'
[printon: strm indent: level | |
	strm append: key].
"126" LADSelectorNode$'Code Generation'
[emit: stack args: nArgs on: strm | |
	self emit: stack args: nArgs on: strm super: false].
"133" LADEncoder$'Encoding'
[encodeLiteral: object | |
	↑self name: object key: object class: LADLiteralNode type: LdLitType set: litSet].
"45" LADEncoder$'Results'
[maxTemp | |
	↑nTemps].
"126" LADEncoder$'Errors'
[notify: string | req |
	requestor
	  ifTrue:
		[req ← requestor.
		self release.
		req notify: string]].
"288" LADEncoder$'Initialization'
[initScopeAndLiteralTables | |
	scopeTable ← Dictionary new copyfrom: stdVariables.
	litSet ← HashSet new copyfrom: stdLiterals.
	selectorSet ← HashSet new copyfrom: stdSelectors.
	litIndSet ← HashSet new init: 16.
	literalStream ← (Vector new: 32) asStream].
"165" LADEncoder$'Initialization'
[nTemps: n literals: lits class: t3 | |
	 "Decompile"
	class ← t3.
	nTemps ← n.
	(literalStream ← lits asStream) position← lits length].
"122" LADEncoder$'Private'
[reallyBind: name | node |
	node ← self newTemp: name.
	scopeTable insert: name with: node.
	↑node].
"61" LADEncoder$'Initialization'
[noteSuper | |
	supered ← true].
"212" LADEncoder$'Initialization'
[fillDict: dict with: t2 mapping: keys to: codes | cs key |
	class ← t2.
	cs ← codes asStream.
	keys do: [:key | dict insert: key with: (class new name: key key: key code: cs next)]].
"189" LADEncoder$'Initialization'
[fillSet: set with: t2 mapping: keys to: codes | cs key |
	class ← t2.
	cs ← codes asStream.
	keys do: [:key | set insert: (class new key: key code: cs next)]].
"260" LADEncoder$'Initialization'
[bind: name | node |
	 "declare a temporary; error not if a field or class variable"
	((scopeTable has: name) or: [(class classvars has: name)])
	  ifTrue: [self notify: 'Name already used in this class'].
	↑self reallyBind: name].
"135" LADEncoder$'Private'
[global: ref name: name | |
	↑self name: name key: ref class: LADVariableNode type: LdLitIndType set: litIndSet].
"219" LADEncoder$'Private'
[name: name key: key class: leafNodeClass type: type set: set | t |
	(t ← set lookup: key)
	  ifTrue: [↑t].
	t ← leafNodeClass new name: name key: key index: false type: type.
	set insert: t.
	↑t].
"190" LADEncoder$'Initialization'
[autoBind: name | node |
	 "declare a block argument as a temp if not already declared"
	(node ← scopeTable lookup: name)
	  ifTrue: [↑node].
	↑self bind: name].
"195" LADEncoder$'Encoding'
[litIndex: literal | p |
	p ← literalStream position.
	p = 64
	  ifTrue:
		[requestor notify: 'MORE THAN 64 LITERALS REFERENCED'.
		↑0].
	literalStream next← literal.
	↑p].
"491" LADEncoder$'Encoding'
[encodeVariable: name | varNode global ref unq |
	(varNode ← scopeTable lookup: name)
	  ifTrue: [↑varNode].
	(unq ← name hasBeenUniqued)
	  ifTrue: [symbolTables do:
			[:global | (ref ← global lookupRef: unq)
			  ifTrue: [↑self global: ref name: unq]]].
	requestor interactive
	  ifTrue:
		[self notify: 'Undeclared'.
		↑0].
	user show: ' (' + name + ' is Undeclared) '.
	unq ← name unique.
	Undeclared declare: unq.
	↑self global: (Undeclared ref: unq) name: unq].
"139" LADEncoder$'Initialization'
[newTemp: name | |
	nTemps ← nTemps + 1.
	↑LADVariableNode new name: name index: nTemps - 1 type: LdTempType].
"145" LADEncoder$'Encoding'
[encodeSelector: selector | |
	↑self name: selector key: selector class: LADSelectorNode type: SendType set: selectorSet].
"414" LADEncoder$'Results'
[literals: primitive nArgs: nArgs | |
	(primitive > 0 or: [nArgs > 4])
	  ifTrue:
		[self litIndex: nArgs * 256 + primitive.
		self litIndex: (Smalltalk ref: class title unique)]
	  ifFalse:
		[supered
		  ifTrue:
			[literalStream last  (Smalltalk ref: class title unique)
			  ifFalse: [self litIndex: (Smalltalk ref: class title unique)]]].
	↑LiteralKeeperCrock ← literalStream contents].
"54" LADEncoder$'Errors'
[release | |
	requestor ← false].
"460" LADBlockNode$'Initialization'
[statements: stmts returns: returnBool | penult |
	 "decompile"
	statements ← ((stmts length > 1 and: [(penult ← stmts  (stmts length - 1).
			(penult is: LADMessageNode) and: [penult isReturningIf])])
			  ifTrue:
				[returnBool ← false.
				(stmts  (1 to: stmts length - 1)) copy]
			  ifFalse:
				[stmts length = 0
				  ifTrue: [NodeNullBlock]
				  ifFalse: [stmts]]).
	arguments ← Vector new: 0.
	returns ← returnBool].
"222" LADBlockNode$'Printing'
[printArgumentsOn: strm indent: level | arg |
	arguments length = 0
	  ifFalse:
		[arguments reverse do:
			[:arg | strm append: ':'.
			strm append: arg key.
			strm space].
		strm append: '| ']].
"93" LADBlockNode$'Initialization'
[arguments: argNodes | |
	 "decompile"
	arguments ← argNodes].
"169" LADBlockNode$'Code Generation'
[sizeExceptLast: encoder | i c |
	c ← 0.
	(1 to: statements length - 1) do: [:i | c ← c + (statements  i sizeForEffect: encoder)].
	↑c].
"177" LADBlockNode$'Initialization'
[default | |
	 "[] argument of missing kwyword in ifTrue: or ifFalse:"
	statements ← NodeNullBlock.
	arguments ← Vector new: 0.
	returns ← false].
"126" LADBlockNode$'Simplifying'
[simplify | i |
	(1 to: statements length) do: [:i | statements  i ← (statements  i) simplify]].
"333" LADBlockNode$'Initialization'
[arguments: argNodes statements: stmts returns: returnBool from: encoder | |
	 "compile"
	arguments ← argNodes.
	statements ← (stmts length > 0
			  ifTrue: [stmts]
			  ifFalse:
				[argNodes length > 0
				  ifTrue: [{stmts , arguments last}]
				  ifFalse: [NodeNullBlock]]).
	returns ← returnBool].
"308" LADBlockNode$'Initialization'
[transformRemoteVariable | |
	 "hack converts remote vars to [:x | x] so value← will work"
	(NoteTaker or: [returns])
	  ifTrue: [↑false].
	statements length  1
	  ifTrue: [↑false].
	(statements  1 isnt: LADVariableNode)
	  ifTrue: [↑false].
	arguments ← statements.
	↑true].
"128" LADBlockNode$'Simplifying'
[justNil | |
	returns
	  ifTrue: [↑false].
	↑statements length = 1 and: [statements  1  NodeNil]].
"132" LADBlockNode$'Simplifying'
[justFalse | |
	returns
	  ifTrue: [↑false].
	↑statements length = 1 and: [statements  1  NodeFalse]].
"55" LADBlockNode$'Initialization'
[returns | |
	↑returns].
"122" LADBlockNode$'Simplifying'
[canBeSpecialArgument | |
	 "can I be an argument of (e.g.) ifTrue:?"
	↑arguments length = 0].
"241" LADBlockNode$'Printing'
[printon: strm indent: level | |
	statements length  1
	  ifFalse: [strm crtab: level].
	strm append: '['.
	self printArgumentsOn: strm indent: level.
	self printStatementsOn: strm indent: level.
	strm append: ']'].
"158" LADBlockNode$'Code Generation'
[emitExceptLast: stack on: strm | i |
	(1 to: statements length - 1) do: [:i | statements  i emitForEffect: stack on: strm]].
"130" LADBlockNode$'Simplifying'
[justTrue | |
	returns
	  ifTrue: [↑false].
	↑statements length = 1 and: [statements  1  NodeTrue]].
"261" LADBlockNode$'Code Generation'
[emitForEvaluatedEffect: stack on: strm | |
	returns
	  ifTrue:
		[self emitForEvaluatedValue: stack on: strm.
		stack pop: 1]
	  ifFalse:
		[self emitExceptLast: stack on: strm.
		statements last emitForEffect: stack on: strm]].
"241" LADBlockNode$'Code Generation'
[emitForEvaluatedValue: stack on: strm | |
	self emitExceptLast: stack on: strm.
	returns
	  ifTrue: [statements last emitForReturn: stack on: strm]
	  ifFalse: [statements last emitForValue: stack on: strm]].
"206" LADBlockNode$'Code Generation'
[sizeForEvaluatedEffect: encoder | |
	returns
	  ifTrue: [↑self sizeForEvaluatedValue: encoder].
	↑(self sizeExceptLast: encoder) + (statements last sizeForEffect: encoder)].
"473" LADBlockNode$'Code Generation'
[emitForValue: stack on: strm | arg oldRemote |
	strm next← LdThisContext.
	stack push: 1.
	nArgsNode emitForValue: stack on: strm.
	remoteCopyNode emit: stack args: 1 on: strm.
	self emitLongJump: size on: strm "jmp-around must be 2 bytes".
	stack push: arguments length.
	arguments do: [:arg | arg emitStorePop: stack on: strm].
	self emitForEvaluatedValue: stack on: strm.
	self returns
	  ifFalse: [strm next← EndRemote].
	stack pop: 1].
"218" LADBlockNode$'Code Generation'
[sizeForEvaluatedValue: encoder | |
	↑(self sizeExceptLast: encoder) + (returns
	  ifTrue: [statements last sizeForReturn: encoder]
	  ifFalse: [statements last sizeForValue: encoder])].
"458" LADBlockNode$'Code Generation'
[sizeForValue: encoder | arg |
	nArgsNode ← encoder encodeLiteral: arguments length.
	remoteCopyNode ← encoder encodeSelector: #blockCopy:.
	size ← (self sizeForEvaluatedValue: encoder) + (self returns
			  ifTrue: [0]
			  ifFalse: [1]) "endBlock".
	arguments do: [:arg | size ← size + (arg sizeForStorePop: encoder)].
	↑1 + (nArgsNode sizeForValue: encoder) "current" + (remoteCopyNode size: encoder) + 2 "long jmp" + size].
"161" LADBlockNode$'Initialization'
[quickCode | |
	(statements length = 1 and: [(statements  1 is: LADVariableNode)])
	  ifTrue: [↑(statements  1) code].
	↑false].
"491" LADBlockNode$'Printing'
[printStatementsOn: strm indent: level | i len shown |
	len ← shown ← statements length.
	(level = 1 and: [statements  len  NodeSelf])
	  ifTrue: [shown ← 1 max: shown - 1]
	  ifFalse:
		[(len = 1 and: [statements  1  NodeNil])
		  ifTrue: [shown ← shown - 1]].
	(1 to: shown) do:
		[:i | (i = len and: [returns])
		  ifTrue: [strm append: '↑'].
		statements  i printon: strm indent: level.
		i < shown
		  ifTrue:
			[strm append: '.'.
			strm crtab: level]]].
"64" LADBlockNode$'Initialization'
[returnLast | |
	returns ← true].
"312" LADBlockNode$'Initialization'
[mustReturn | |
	returns
	  ifFalse:
		[((statements last is: LADMessageNode) and: [statements last isReturningIf])
		  ifFalse:
			[returns ← true.
			statements  NodeNullBlock
			  ifTrue: [statements ← NodeSelf inVector]
			  ifFalse: [statements ← {statements , NodeSelf}]]]].
"232" LADMessageNode$'Private Initialization'
[transformAnd: encoder | |
	(self transformBoolean: encoder)
	  ifTrue: [arguments ← {arguments  1 , (LADBlockNode new statements: NodeFalse inVector returns: false)}]
	  ifFalse: [↑false]].
"232" LADMessageNode$'Private Initialization'
[transformOr: encoder | |
	(self transformBoolean: encoder)
	  ifTrue: [arguments ← {(LADBlockNode new statements: NodeTrue inVector returns: false) , (arguments  1)}]
	  ifFalse: [↑false]].
"233" LADMessageNode$'Private Initialization'
[transformIfTrue: encoder | |
	(self transformBoolean: encoder)
	  ifTrue: [arguments ← {arguments  1 , (LADBlockNode new statements: NodeNil inVector returns: false)}]
	  ifFalse: [↑false]].
"157" LADMessageNode$'Private Initialization'
[transformWhile: encoder | |
	↑(self transformBoolean: encoder) and: [(self canBeSpecial: receiver from: encoder)]].
"716" LADMessageNode$'Code Generation'
[emitIf: stack on: strm value: forValue | thenExpr thenSize elseExpr elseSize |
	thenSize ← sizes  1.
	elseSize ← sizes  2.
	(forValue  false and: [elseSize > 0])
	  ifTrue: [super emitForEffect: stack on: strm]
	  ifFalse:
		[thenExpr ← arguments  1.
		elseExpr ← arguments  2.
		receiver emitForValue: stack on: strm.
		self emitBranch: thenSize pop: stack on: strm.
		(forValue  false and: [elseSize = 0])
		  ifTrue: [thenExpr emitForEvaluatedEffect: stack on: strm]
		  ifFalse:
			[thenExpr emitForEvaluatedValue: stack on: strm.
			stack pop: 1.
			thenExpr returns
			  ifFalse: [self emitJump: elseSize on: strm].
			elseExpr emitForEvaluatedValue: stack on: strm]]].
"707" LADMessageNode$'Code Generation'
[sizeIf: encoder value: forValue | thenExpr thenSize elseExpr elseSize |
	thenExpr ← arguments  1.
	elseExpr ← arguments  2.
	forValue  false
	  ifTrue:
		[(elseExpr justNil or: [elseExpr justFalse])
		  ifTrue:
			[elseSize ← 0.
			thenSize ← thenExpr sizeForEvaluatedEffect: encoder]
		  ifFalse: [↑super sizeForEffect: encoder]]
	  ifFalse:
		[elseSize ← elseExpr sizeForEvaluatedValue: encoder.
		thenSize ← (thenExpr sizeForEvaluatedValue: encoder) + (thenExpr returns
				  ifTrue: [0]
				  ifFalse: [self sizeJump: elseSize])].
	sizes  1 ← thenSize.
	sizes  2 ← elseSize.
	↑(receiver sizeForValue: encoder) + (self sizeBranch: thenSize) + thenSize + elseSize].
"677" LADMessageNode$'Code Generation'
[sizeWhile: encoder value: forValue | cond stmt bfpSize |
	cond ← receiver "L1: ... Bfp(L2) ... Jmp(L1) L2: nil (nil for value only)".
	stmt ← arguments  1.
	sizes ← Vector new: 3 "justStmt, wholeLoop, justJump".
	sizes  1 ← (stmt sizeForEvaluatedEffect: encoder) + 2.
	selector key  #whileFalseDo:
	  ifTrue:
		[sizes  3 ← self sizeJump: sizes  1.
		bfpSize ← self sizeBranch: sizes  3]
	  ifFalse:
		[sizes  3 ← self sizeBranch: sizes  1.
		bfpSize ← 0].
	sizes  2 ← (cond sizeForEvaluatedValue: encoder) + bfpSize + (sizes  3) + (sizes  1).
	↑sizes  2 + (forValue
	  ifTrue: [1]
	  ifFalse: [0]) "+1 (push nil) for value only"].
"57" LADMessageNode$'Printing'
[precedence | |
	↑precedence].
"247" LADMessageNode$'Private Initialization'
[transform: encoder | |
	special = 0
	  ifTrue: [↑false].
	(self perform: macroTransformers  special with: encoder)
	  ifTrue: [sizes ← Vector new: arguments length]
	  ifFalse:
		[special ← 0.
		↑false]].
"184" LADMessageNode$'Code Generation'
[sizeForEffect: encoder | |
	special > 0
	  ifTrue: [↑self perform: macroSizers  special with: encoder with: false].
	↑super sizeForEffect: encoder].
"152" LADMessageNode$'Private Initialization'
[isReturningIf | |
	special = 3
	  ifTrue: [↑(arguments  1) returns and: [(arguments  2) returns]].
	↑false].
"275" LADMessageNode$'Simplifying'
[simplify | n i s |
	((n ← #(asArray ) find: selector key) > 0 and: [(s ← self perform: #(simplifyCollection )  n)])
	  ifTrue: [↑s].
	receiver ← receiver simplify.
	(1 to: arguments length) do: [:i | arguments  i ← (arguments  i) simplify]].
"446" LADMessageNode$'Initialization'
[receiver: rcvr selector: selName arguments: args precedence: p from: encoder | |
	 "compile"
	self receiver: rcvr arguments: args precedence: p.
	special ← macroSelectors find: selName.
	(self transform: encoder)
	  ifTrue: [selector ← LADSelectorNode new key: macroSelectors  special code: #macro]
	  ifFalse:
		[selector ← encoder encodeSelector: selName.
		rcvr  NodeSuper
		  ifTrue: [encoder noteSuper]]].
"233" LADMessageNode$'Initialization'
[receiver: rcvr selector: selNode arguments: args precedence: p | |
	 "decompile"
	self receiver: rcvr arguments: args precedence: p.
	special ← macroSelectors find: selNode key.
	selector ← selNode].
"745" LADMessageNode$'Printing'
[printKeywords: key arguments: args on: strm indent: level | keywords part prev arg |
	args length = 0
	  ifTrue:
		[strm space.
		strm append: key.
		↑self].
	keywords ← key keywords.
	prev ← receiver.
	(1 to: args length) do:
		[:part | arg ← args  part.
		(((prev is: LADBlockNode) or: [((prev is: LADMessageNode) and: [prev precedence  3])]) or: [(part > 1 and: [(arg is: LADBlockNode)])])
		  ifTrue: [strm crtab: level + 1]
		  ifFalse: [ "newline after big args"
			strm space].
		key ← keywords  part.
		strm append: key.
		strm space.
		arg printon: strm indent: level + 2 precedence: (precedence = 2
		  ifTrue: [1]
		  ifFalse:
			[key = '←'
			  ifTrue: [4]
			  ifFalse: [precedence]]).
		prev ← arg]].
"219" LADMessageNode$'Code Generation'
[emitForEffect: stack on: strm | |
	special > 0
	  ifTrue: [self perform: macroEmitters  special with: stack with: strm with: false]
	  ifFalse: [super emitForEffect: stack on: strm]].
"353" LADMessageNode$'Initialization'
[store: expr from: encoder | |
	 "ctxt tempAt: n -> ctxt tempAt: n put: expr (see Assignment)"
	selector key  #tempAt:
	  ifTrue: [user notify: 'cant transform this message']
	  ifFalse: [↑LADMessageNode new receiver: receiver selector: #tempAt:put: arguments: {arguments , expr} precedence: precedence from: encoder]].
"296" LADMessageNode$'Printing'
[printon: strm indent: level precedence: p | parenthesize |
	parenthesize ← precedence > p or: [(p = 3 and: [precedence = 3 "both keywords"])].
	parenthesize
	  ifTrue: [strm append: '('].
	self printon: strm indent: level.
	parenthesize
	  ifTrue: [strm append: ')']].
"336" LADMessageNode$'Simplifying'
[asCollectionElements: length | s |
	 "{1,2,3}"
	(selector key  #elementStream and: [receiver key = length])
	  ifTrue: [↑(Vector new: length) asStream].
	(selector key  #nextElement: and: [(s ← receiver asCollectionElements: length + 1)])
	  ifTrue:
		[s next← (arguments  1) simplify.
		↑s].
	↑false].
"236" LADMessageNode$'Private Initialization'
[transformIfFalse: encoder | |
	(self transformBoolean: encoder)
	  ifTrue: [arguments ← {(LADBlockNode new statements: NodeNil inVector returns: false) , (arguments  1)}]
	  ifFalse: [↑false]].
"186" LADMessageNode$'Private Initialization'
[transformIfTrueIfFalse: encoder | |
	↑(self canBeSpecial: arguments  1 from: encoder) and: [(self canBeSpecial: arguments  2 from: encoder)]].
"628" LADMessageNode$'Code Generation'
[emitWhile: stack on: strm value: forValue | cond stmt stmtSize loopSize |
	cond ← receiver "L1: ... Bfp(L2)|(Bfp(1)Jmp(L2)) ... Jmp(L1) L2:  ".
	stmt ← arguments  1.
	stmtSize ← sizes  1.
	loopSize ← sizes  2.
	cond emitForEvaluatedValue: stack on: strm.
	selector key  #whileFalseDo:
	  ifTrue:
		[self emitBranch: sizes  3 pop: stack on: strm.
		self emitJump: stmtSize on: strm]
	  ifFalse: [self emitBranch: stmtSize pop: stack on: strm].
	stmt emitForEvaluatedEffect: stack on: strm.
	self emitJump: 0 - loopSize on: strm.
	forValue
	  ifTrue:
		[strm next← LdNil.
		stack push: 1]].
"184" LADMessageNode$'Private Initialization'
[receiver: rcvr arguments: args precedence: p | |
	receiver ← rcvr.
	arguments ← args.
	sizes ← Vector new: arguments length.
	precedence ← p].
"315" LADMessageNode$'Printing'
[printon: strm indent: level | |
	receiver
	  ifTrue: [receiver printon: strm indent: level precedence: precedence].
	(special between: 1 and: [5])
	  ifTrue: [self printIfOn: strm indent: level]
	  ifFalse: [self printKeywords: selector key arguments: arguments on: strm indent: level]].
"585" LADMessageNode$'Initialization'
[classInit | |
	 "LADMessageNode classInit."
	macroSelectors ← #(ifTrue: ifFalse: ifTrue:ifFalse: and: or: whileFalseDo: whileTrueDo: ).
	macroTransformers ← #(transformIfTrue: transformIfFalse: transformIfTrueIfFalse: transformAnd: transformOr: transformWhile: transformWhile: ).
	macroEmitters ← #(emitIf:on:value: emitIf:on:value: emitIf:on:value: emitIf:on:value: emitIf:on:value: emitWhile:on:value: emitWhile:on:value: ).
	macroSizers ← #(sizeIf:value: sizeIf:value: sizeIf:value: sizeIf:value: sizeIf:value: sizeWhile:value: sizeWhile:value: )].
"213" LADMessageNode$'Private Initialization'
[addLeftArrow: lastArg encoder: encoder | |
	 "for ST76 compatibility"
	selector ← encoder encodeSelector: (selector key + '←') unique.
	arguments ← {arguments , lastArg}].
"195" LADMessageNode$'Private Initialization'
[canBeSpecial: node from: encoder | |
	node canBeSpecialArgument
	  ifTrue: [↑node is: LADBlockNode].
	↑encoder notify: '←Must be a block or a variable'].
"122" LADMessageNode$'Private Initialization'
[transformBoolean: encoder | |
	↑self canBeSpecial: arguments  1 from: encoder].
"406" LADMessageNode$'Code Generation'
[emitForValue: stack on: strm | argument |
	special > 0
	  ifTrue: [self perform: macroEmitters  special with: stack with: strm with: true]
	  ifFalse:
		[receiver
		  ifTrue: [receiver emitForValue: stack on: strm].
		arguments do: [:argument | argument emitForValue: stack on: strm].
		selector emit: stack args: arguments length on: strm super: receiver  NodeSuper]].
"525" LADMessageNode$'Code Generation'
[sizeForValue: encoder | argument c s z |
	special > 0
	  ifTrue: [↑self perform: macroSizers  special with: encoder with: true].
	receiver  NodeSuper
	  ifTrue: [selector ← selector copy "only necess for splOops"].
	c ← (selector size: encoder args: arguments length super: receiver  NodeSuper) + (receiver
			  ifTrue: [receiver sizeForValue: encoder]
			  ifFalse: [0]).
	s ← sizes asStream.
	arguments do:
		[:argument | s next← z ← argument sizeForValue: encoder.
		c ← c + z].
	↑c].
"654" LADMessageNode$'Printing'
[printIfOn: strm indent: level | |
	(arguments  2) justNil
	  ifTrue: [↑self printKeywords: #ifTrue: arguments: (arguments  1) inVector on: strm indent: level].
	(arguments  2) justFalse
	  ifTrue: [↑self printKeywords: #and: arguments: (arguments  1) inVector on: strm indent: level].
	(arguments  1) justNil
	  ifTrue: [↑self printKeywords: #ifFalse: arguments: (arguments  2) inVector on: strm indent: level].
	(arguments  1) justTrue
	  ifTrue: [↑self printKeywords: #or: arguments: (arguments  2) inVector on: strm indent: level].
	self printKeywords: #ifTrue:ifFalse: arguments: arguments on: strm indent: level].
"316" LADCollectionNode$'Initialization'
[elements: vec from: encoder | |
	 "compile"
	elements ← vec.
	lengthAsNode ← encoder encodeLiteral: vec length.
	elementStreamNode ← encoder encodeSelector: #elementStream.
	insertIntoNode ← encoder encodeSelector: #nextElement:.
	asArrayNode ← encoder encodeSelector: #asArray].
"329" LADCollectionNode$'Code Generation'
[emitForValue: stack on: strm | element |
	lengthAsNode emitForValue: stack on: strm.
	elementStreamNode emit: stack args: 0 on: strm.
	elements do:
		[:element | element emitForValue: stack on: strm.
		insertIntoNode emit: stack args: 1 on: strm].
	asArrayNode emit: stack args: 0 on: strm].
"309" LADCollectionNode$'Code Generation'
[sizeForValue: encoder | element c |
	c ← (lengthAsNode sizeForValue: encoder) + (elementStreamNode size: encoder) + (asArrayNode size: encoder) + (elements length * (insertIntoNode size: encoder)).
	elements do: [:element | c ← c + (element sizeForValue: encoder)].
	↑c].
"111" LADCollectionNode$'Initialization'
[elements: vec | |
	 "Decompile via MessageNode simplify"
	elements ← vec].
"259" LADCollectionNode$'Printing'
[printon: strm indent: level | i len |
	len ← elements length.
	strm append: '{'.
	(1 to: len) do:
		[:i | elements  i printon: strm indent: level.
		i < len
		  ifTrue:
			[strm append: ','.
			strm space]].
	strm append: '}'].
"125" LADCollectionNode$'Simplifying'
[simplify | i |
	(1 to: elements length) do: [:i | elements  i ← (elements  i) simplify]].
"172" LADMessageNode$'Simplifying'
[simplifyCollection | strm |
	(strm ← receiver asCollectionElements: 0)
	  ifTrue: [↑LADCollectionNode new elements: strm contents].
	↑false].
"167" LADMessageNode$'Initialization'
[cascadeReceiver | rcvr |
	(receiver  NodeSuper or: [special > 0])
	  ifTrue: [↑false].
	rcvr ← receiver.
	receiver ← false.
	↑rcvr].
"774" LADEncoder$'Initialization'
[init: cls context: ctxt notifying: req | variable node n homeNode indexNode |
	requestor ← req.
	class ← cls.
	nTemps ← 0.
	supered ← false.
	symbolTables ← {class wholeEnvironment , Smalltalk}.
	self initScopeAndLiteralTables.
	n ← 1.
	class instvars do:
		[:variable | node ← LADVariableNode new name: variable index: (n ← n + 1) type: LdInstType.
		scopeTable insert: variable with: node].
	ctxt
	  ifTrue:
		[homeNode ← self bind: 'homeContext' "first temp = ctxt passed as arg".
		n ← 0.
		ctxt tempNames do:
			[:variable | indexNode ← self encodeLiteral: (n ← n + 1).
			node ← LADMessageNode new receiver: homeNode selector: #tempAt: arguments: indexNode inVector precedence: 3 from: self.
			scopeTable insert: variable with: node]]].
"854" LADVariableNode$'Initialization'
[classInit | encoder specials |
	 "LADVariableNode classInit."
	encoder ← LADEncoder new.
	stdVariables ← Dictionary new init: 16.
	encoder fillDict: stdVariables with: LADVariableNode mapping: #('self' 'thisContext' 'super' 'nil' 'false' 'true' ) to: {LdSelf , LdThisContext , LdSuper , LdNil , LdFalse , LdTrue}.
	stdSelectors ← HashSet new init: 64.
	specials ← (SpecialOops  (10 to: SpecialOops length)) copy.
	specials  (19 ~ 23) ← {#length , #next , 'next←' unique , #end , #}.
	encoder fillSet: stdSelectors with: LADSelectorNode mapping: specials to: (SendPlus to: SendPlus + 31).
	stdLiterals ← HashSet new init: 16.
	encoder fillSet: stdLiterals with: LADLiteralNode mapping: #(1 0 1 2 ) to: (LdMinus1 to: LdMinus1 + 3).
	encoder initScopeAndLiteralTables.
	self classInit2: encoder.
	initted ← NoteTaker].
"405" LADVariableNode$'Initialization'
[classInit2: encoder | |
	 "LADVariableNode classInit."
	NodeNil ← encoder encodeVariable: 'nil'.
	NodeTrue ← encoder encodeVariable: 'true'.
	NodeFalse ← encoder encodeVariable: 'false'.
	NodeSelf ← encoder encodeVariable: 'self'.
	NodeThisContext ← encoder encodeVariable: 'thisContext'.
	NodeSuper ← encoder encodeVariable: 'super'.
	NodeNullBlock ← NodeNil inVector].
"251" LADVariableNode$'Code Generation'
[emitForValue: stack on: strm | |
	code < 256
	  ifTrue:
		[strm next← (code = LdSuper
		  ifTrue: [LdSelf]
		  ifFalse: [code]).
		stack push: 1]
	  ifFalse:
		[self emitLong: LdInstLong on: strm.
		stack push: 1]].
"168" LADVariableNode$'Code Generation'
[sizeForReturn: encoder | |
	(code  LdSelf and: [code  LdNil])
	  ifTrue: [ "short returns"
		↑1].
	↑super sizeForReturn: encoder].
"127" LADVariableNode$'Initialization'
[name: varName index: i type: type | |
	self name: varName key: varName index: i type: type].
"342" LADParser$'Parser'
[argumentFreeExpression: cascading | rcvr |
	 "primaryExpression {unarySelector}  MessageNode"
	(rcvr ← self primaryExpression: cascading)
	  ifTrue:
		[[hereType  #word] whileTrueDo: [rcvr ← LADMessageNode new receiver: rcvr selector: self advance unique arguments: #() precedence: 1 from: encoder].
		↑rcvr].
	↑false].
"848" LADParser$'Parser'
[primaryExpression: cascading | |
	 "variable  VariableNode
		 constant  LiteralNode
		 '{' {expression ','} [expression] '}'  CollectionNode
		 ';'  ;  when allowed
		 - number  number
		 	|  '(' expression ')'  |  block   "
	hereType  #word
	  ifTrue: [↑encoder encodeVariable: self advance].
	(hereType  #string or: [(hereType  #number or: [hereType  #literal])])
	  ifTrue: [↑encoder encodeLiteral: self advance].
	hereType  #leftParenthesis
	  ifTrue: [↑self subExpression].
	hereType  #leftBracket
	  ifTrue: [↑self block].
	(hereType  #semicolon and: [cascading])
	  ifTrue: [↑self advance].
	hereType  #leftBrace
	  ifTrue: [↑self collection].
	((here  #- or: [here  '' unique]) and: [tokenType  #number])
	  ifTrue:
		[ "ST76"
		self advance.
		↑encoder encodeLiteral: self advance negated].
	↑false].
"636" LADParser$'Parser'
[arguments: maxArgs precedence: p | selector args type |
	 "unarySelector | binarySelector arg | keyword arg {keyword arg} 
		 {selector, arguments, precedence}"
	selector ← Stream default.
	args ← (Vector new: 4) asStream.
	type ← hereType.
	[hereType  type] whileTrueDo:
		[selector append: self advance.
		hereType  #word
		  ifTrue:
			[args position = maxArgs
			  ifTrue: [↑self notify: 'Too many arguments'].
			args next← encoder bind: self advance]
		  ifFalse:
			[maxArgs > 0
			  ifTrue: [↑self expected: 'argument name']]].
	↑{(encoder encodeSelector: selector contents unique) , args contents , p}].
"528" LADParser$'Parser'
[simpleExpression: cascading | rcvr msg |
	 "keywordFreeExpression {keyword keywordFreeExpression}  MessageNode"
	(rcvr ← self keywordFreeExpression: cascading)
	  ifTrue:
		[(hereType  #keyword and: [(msg ← self keywordMessage)])
		  ifTrue: [rcvr ← LADMessageNode new receiver: rcvr selector: msg  1 arguments: msg  2 precedence: 3 from: encoder].
		hereType  #leftArrow
		  ifTrue:
			[ "ST76"
			self advance.
			↑rcvr addLeftArrow: self expression encoder: encoder].
		↑rcvr]
	  ifFalse: [↑false]].
"472" LADParser$'Parser'
[keywordFreeExpression: cascading | rcvr msg |
	 "argumentFreeExpression {binarySelector argumentFreeExpression} 
			MessageNode"
	(rcvr ← self argumentFreeExpression: cascading)
	  ifTrue:
		[[(hereType  #binary or: [hereType  #verticalBar]) and: [(msg ← self binaryMessage "or hereTypecomma)" "ST76")]] whileTrueDo: [rcvr ← LADMessageNode new receiver: rcvr selector: msg  1 arguments: msg  2 precedence: 2 from: encoder].
		↑rcvr].
	↑false].
"50" LADParser$'Parser'
[more | |
	↑hereType  #doIt].
"351" LADParser$'Name Parsing for Debugger'
[parseArgsAndTemps: sourceStream notifying: req | args temps |
	 "for debugger"
	self init: sourceStream notifying: req.
	encoder ← self.
	args ← self pattern  2.
	temps ← self temporaries.
	encoder ← nil "break cycle".
	hereType  #leftBracket
	  ifTrue: [↑args concat: temps].
	self expected: 'Left bracket'].
"759" LADParser$'Parser'
[pattern | sap |
	 "unarySelector | binarySelector arg | keyword arg {keyword arg} 
			{selector, arguments, precedence}"
	sap ← (hereType  #keyword
			  ifTrue: [self arguments: 999 precedence: 3]
			  ifFalse:
				[(hereType  #binary or: [(hereType  #verticalBar or: [hereType  #comma])])
				  ifTrue: [self arguments: 1 precedence: 2]
				  ifFalse:
					[hereType  #word
					  ifTrue: [self arguments: 0 precedence: 1]
					  ifFalse: [↑false]]]).
	hereType  #leftArrow
	  ifTrue:
		[ "ST76"
		self advance.
		sap  1 ← encoder encodeSelector: ((sap  1) key + '←') unique.
		hereType  #word
		  ifTrue:
			[sap  2 ← {sap  2 , (encoder bind: self advance)}.
			↑sap].
		↑self expected: 'argument name']
	  ifFalse: [↑sap]].
"60" LADParser$'Name Parsing for Debugger'
[unbind: name | |
	].
"384" LADParser$'Parser'
[primitive | n |
	here  #<
	  ifTrue:
		[self advance.
		here = 'primitive:'
		  ifTrue:
			[self advance.
			((n ← self match: #number) and: [(n is: Integer)])
			  ifTrue:
				[here  #>
				  ifTrue:
					[self advance.
					↑n].
				↑self expected: '>']
			  ifFalse: [↑self expected: 'Number']]
		  ifFalse: [↑self expected: 'primitive:']]
	  ifFalse: [↑0]].
"63" LADParser$'Name Parsing for Debugger'
[bind: name | |
	↑name].
"758" LADParser$'Test'
[test: class | s |
	 "LADParser new test: Point."
	user waitnobug.
	#('noOp []' 'max: p2 [↑(x>p2 x and: [y>p2 y]) ifTrue: [self] ifFalse: [p2]]' 'coord: p2 [[x>p2 x and: [y>p2 y]] whileTrue: [self past: p2]]' '& z | a b c [a←z. b←z*a max: z/a length/(c←a length+2 min: z)]' 'to: p2 by: d [↑Interval new from: self to: p2 by: d]' 'incAll: coll [coll do: [:x. self inc: x with: ''string'']]' 'cascade: a [↑a+3 to: 4; from: 5; length]' ) do:
		[:s | user cr.
		user show: (self parse: s class: class noPattern: false context: false notifying: user) simplify asString.
		user cr.
		user waitnobug.
		user waitbug].
	[(s ← user read) length = 0] whileFalseDo: 
		[user cr.
		user show: (self compile: s in: class) simplify asString.
		user cr]].
"847" LADParser$'Parser'
[statements: argNodes doit: doit | stmts expr returns |
	 " 3. 4. 5. " "{expression '.'} [↑]expression  BlockNode with supplied arguments"
	hereType  #rightBracket
	  ifTrue: [↑LADBlockNode new arguments: argNodes statements: #() returns: false from: encoder].
	stmts ← (Vector new: 10) asStream.
	returns ← false.
	[returns ← self match: #upArrow.
	(expr ← self expression)
	  ifTrue: [stmts next← expr]
	  ifFalse:
		[doit
		  ifTrue: [stmts next← encoder encodeVariable: 'nil']
		  ifFalse: [↑self expected: 'Expression']].
	returns  false
	  ifTrue: [self match: #period]
	  ifFalse:
		[(hereType  #rightBracket or: [hereType  #doIt])
		  ifTrue: [false]
		  ifFalse: [↑self expected: 'end of block']]] whileTrueDo: [].
	↑LADBlockNode new arguments: argNodes statements: stmts contents returns: returns from: encoder].
"147" LADParser$'Scanner'
[advance | t |
	t ← here.
	here ← token.
	hereType ← tokenType.
	hereMark ← mark.
	hereType
	  ifTrue: [self scanToken].
	↑t].
"401" LADParser$'Public'
[parse: sourceStream class: class noPattern: noPattern context: ctxt notifying: req | m |
	self init: sourceStream notifying: req "noPattern is false for a compile".
	encoder ← LADEncoder new init: class context: ctxt notifying: self.
	m ← self method: noPattern context: ctxt.
	encoder ← nil "break cycle".
	hereType  #doIt
	  ifTrue: [↑m].
	self notify: 'Unexpected construct'].
"136" LADAssignmentNode$'Code Generation'
[sizeForEffect: encoder | |
	↑(value sizeForValue: encoder) + (variable sizeForStorePop: encoder)].
"97" LADAssignmentNode$'Initialization'
[variable: var value: exp | |
	variable ← var.
	value ← exp].
"188" LADAssignmentNode$'Printing'
[printon: strm indent: level precedence: p | |
	p < 4
	  ifTrue: [strm append: '('].
	self printon: strm indent: level.
	p < 4
	  ifTrue: [strm append: ')']].
"145" LADAssignmentNode$'Code Generation'
[emitForValue: stack on: strm | |
	value emitForValue: stack on: strm.
	variable emitStore: stack on: strm].
"132" LADAssignmentNode$'Code Generation'
[sizeForValue: encoder | |
	↑(value sizeForValue: encoder) + (variable sizeForStore: encoder)].
"72" LADAssignmentNode$'Simplifying'
[simplify | |
	value ← value simplify].
"163" LADAssignmentNode$'Printing'
[printon: strm indent: level | |
	variable printon: strm indent: level.
	strm append: ' ← '.
	value printon: strm indent: level + 2].
"193" LADAssignmentNode$'Initialization'
[variable: var value: exp from: encoder | |
	 "compile"
	(var is: LADMessageNode)
	  ifTrue: [↑var store: exp from: encoder].
	variable ← var.
	value ← exp].
"149" LADAssignmentNode$'Code Generation'
[emitForEffect: stack on: strm | |
	value emitForValue: stack on: strm.
	variable emitStorePop: stack on: strm].
"309" LADCascadeNode$'Code Generation'
[emitForValue: stack on: strm | i |
	receiver emitForValue: stack on: strm.
	(1 to: messages length - 1) do:
		[:i | strm next← Dup.
		stack push: 1.
		messages  i emitForValue: stack on: strm.
		strm next← Pop.
		stack pop: 1].
	messages last emitForValue: stack on: strm].
"214" LADCascadeNode$'Code Generation'
[sizeForValue: encoder | msg size |
	size ← (receiver sizeForValue: encoder) + (messages length - 1 * 2).
	messages do: [:msg | size ← size + (msg sizeForValue: encoder)].
	↑size].
"147" LADCascadeNode$'Initialization'
[receiver: rcvr messages: msgs | |
	 "user show: 'abc'; tab; show: 'abc'; cr"
	receiver ← rcvr.
	messages ← msgs].
"235" LADCascadeNode$'Printing'
[printon: strm indent: level | i |
	receiver printon: strm indent: level.
	(1 to: messages length) do:
		[:i | messages  i printon: strm indent: level.
		i < messages length
		  ifTrue: [strm append: ';']]].
"91" LADCascadeNode$'Simplifying'
[simplify | msg |
	messages do: [:msg | msg ← msg simplify]].
"1120" LADParser$'Parser'
[expression | var expr msgs temp rcvr |
	 "[variable '←'] expression  AssignmentNode
		 rcvr message {; message}  MessageNode | CascadeNode"
	(hereType  #word and: [tokenType  #leftArrow])
	  ifTrue:
		[var ← encoder encodeVariable: here.
		self advance.
		self advance.
		(expr ← self expression)
		  ifTrue: [↑LADAssignmentNode new variable: var value: expr from: encoder].
		↑self expected: 'Expression']
	  ifFalse:
		[(expr ← self simpleExpression: false)
		  ifTrue:
			[(hereType  #semicolon and: [(expr is: LADMessageNode)])
			  ifTrue:
				[msgs ← expr inVector asStream settoend.
				rcvr ← expr cascadeReceiver.
				rcvr  false
				  ifTrue: [↑self notify: 'cannot cascade super'].
				[hereType  #semicolon] whileTrueDo:
					[expr ← self simpleExpression: true.
					(expr is: LADMessageNode)
					  ifTrue:
						[expr cascadeReceiver
						  ifTrue: [msgs next← expr]
						  ifFalse: [↑self notify: 'invalid cascade']]
					  ifFalse: [↑self expected: 'Message']].
				↑LADCascadeNode new receiver: rcvr messages: msgs contents]
			  ifFalse: [↑expr]]
		  ifFalse: [↑false]]].
"319" LADParser$'Parser'
[subExpression | e |
	 "'(' expression ')'  expression"
	(self match: #leftParenthesis)
	  ifTrue:
		[(e ← self expression)
		  ifTrue:
			[(self match: #rightParenthesis)
			  ifTrue: [↑e].
			↑self expected: 'Right parenthesis']
		  ifFalse: [↑self expected: 'Expression']]
	  ifFalse: [↑false]].
"283" LADMethodNode$'Initialization'
[selector: selOrFalse arguments: args precedence: p temporaries: temps block: blk encoder: t6 primitive: prim | |
	encoder ← t6.
	selectorOrFalse ← selOrFalse.
	precedence ← p.
	arguments ← args.
	temporaries ← temps.
	block ← blk.
	primitive ← prim].
"48" ParseStack$'Results'
[position | |
	↑position].
"63" ParseStack$'Initialization'
[init | |
	length ← position ← 0].
"103" ParseStack$'Changes'
[push: n | |
	(position ← position + n) > length
	  ifTrue: [length ← position]].
"44" ParseStack$'Results'
[length | |
	↑length].
"116" ParseStack$'Changes'
[pop: n | |
	(position ← position - n) < 0
	  ifTrue: [user notify: 'Parse stack underflow']].
"269" LADMethodNode$'Code Generation'
[emitOn: strm | stack limit |
	limit ← strm limit.
	stack ← ParseStack init.
	block emitForValue: stack on: strm.
	strm next← EndMethod.
	strm position = limit
	  ifTrue: [↑strm asArray].
	user notify: 'Compiler code size discrepancy'].
"70" LADMethodNode$'Code Generation'
[selector | |
	↑selectorOrFalse key].
"1560" LADMethodNode$'Code Generation'
[generate | blkSize method headerSize lit stack strm nArgs |
	method ← ((primitive = 0 and: [arguments length = 0])
			  ifTrue: [self quickCode: selectorOrFalse]
			  ifFalse: [false]).
	method
	  ifTrue: [↑method].
	nArgs ← arguments length.
	blkSize ← block sizeForEvaluatedValue: encoder.
	literals ← encoder literals: primitive nArgs: nArgs.
	literals length > 63
	  ifTrue: [user notify: 'Too many literals referenced']
	  ifFalse:
		[headerSize ← 4 + (2 * literals length).
		method ← (NoteTaker
				  ifTrue: [CompiledMethod]
				  ifFalse: [String]) new: headerSize + blkSize + 3.
		strm ← method asStream.
		strm position← 2 * literals length + 4.
		stack ← ParseStack init.
		block emitForEvaluatedValue: stack on: strm.
		stack position  1
		  ifTrue: [user notify: 'Compiler stack discrepancy']
		  ifFalse:
			[strm position  (method length - 3)
			  ifTrue: [user notify: 'Compiler code size discrepancy']
			  ifFalse:
				[ "Header"
				method  3 ← ((nArgs  4 and: [primitive = 0])
				  ifTrue: [nArgs]
				  ifFalse: [7]) * 32 + encoder maxTemp.
				method  4 ← headerSize - 4 + (encoder maxTemp + stack length > 12
				  ifTrue: [128]
				  ifFalse: [0]) + 1 "Literals".
				NoteTaker
				  ifTrue:
					[method key: selectorOrFalse key.
					(1 to: literals length) do: [:lit | method literalAt: lit put: literals  lit]]
				  ifFalse:
					[method word: 1 ← selectorOrFalse key asOop.
					(1 to: literals length) do: [:lit | method word: (lit + 2) ← (literals  lit) asOop]].
				↑strm asArray]]]].
"1050" LADMethodNode$'Code Generation'
[install: sourceParagraph in: class | text cfile clname catname newMethod |
	class install: selectorOrFalse key method: (newMethod ← self generate) literals: literals code: sourceParagraph backpointers: nil "write source and set pointer to it.  Source format is:
	 '' length '' class$'category'<cr>[<code>].<cr>	".
	cfile ← SourceFiles  2.
	cfile readwriteshorten.
	cfile settoend "changes file".
	text ← sourceParagraph text "source code".
	clname ← class title.
	catname ← class organization invert: selectorOrFalse key.
	newMethod setSourcePosition: cfile position inFile: 1 "changes".
	cfile append: '"' " string lengths plus $''<cr>[].<cr> ".
	cfile append: (text length + clname length + catname length + 8) asString.
	cfile append: '" ' "put out length".
	cfile append: clname.
	cfile append: '$'''.
	cfile append: catname.
	cfile append: ''''.
	cfile cr.
	cfile append: '['.
	cfile append: text.
	cfile append: '].'.
	cfile cr "put out code".
	cfile readonly "leave readonly for browsing and to keep clean"].
"68" LADMethodNode$'Simplifying'
[simplify | |
	block ← block simplify].
"448" LADMethodNode$'Code Generation'
[quickCode: sel | v |
	sel  false
	  ifTrue: [↑false].
	(v ← block quickCode)
	  ifTrue:
		[v < 0
		  ifTrue: [↑false].
		v = LdSelf
		  ifTrue: [↑self quick: sel hi: 160 lo: 1].
		v < (CodeBases  LdInstType + (CodeLimits  LdInstType))
		  ifTrue: [↑self quick: sel hi: 192 + v lo: 1].
		(v / 256 = 1 and: [v \ 256 < 32])
		  ifTrue: [↑self quick: sel hi: 192 + (v \ 256) lo: 1].
		↑false]
	  ifFalse: [↑false]].
"656" LADMethodNode$'Printing'
[printon: strm | s args |
	selectorOrFalse
	  ifTrue:
		[(precedence = 1 and: [selectorOrFalse key isarrow  false])
		  ifTrue:
			[ "ST76"
			strm append: selectorOrFalse key.
			strm space]
		  ifFalse:
			[args ← arguments asStream.
			selectorOrFalse key keywords do:
				[:s | strm append: s.
				strm space.
				strm append: args next key.
				strm space]]].
	strm append: ' | '.
	temporaries do:
		[:s | strm append: s key.
		strm space].
	strm append: '|'.
	primitive > 0
	  ifTrue:
		[strm append: '  <primitive: '.
		strm print: primitive.
		strm append: '>'].
	strm crtab: 1.
	block printStatementsOn: strm indent: 1].
"327" LADMethodNode$'Code Generation'
[quick: selector hi: hibyte lo: lobyte | method |
	method ← (NoteTaker
			  ifTrue: [CompiledMethod]
			  ifFalse: [String]) new: 7.
	method  3 ← hibyte.
	method  4 ← lobyte.
	NoteTaker
	  ifTrue: [method key: selectorOrFalse key]
	  ifFalse: [method word: 1 ← selector key asOop].
	↑method].
"977" LADParser$'Parser'
[method: doit context: ctxt | sap blk prim temps |
	 "sap={selector, arguments, precedence}" "pattern [ | temporaries ] block  MethodNode"
	doit
	  ifTrue:
		[sap ← (ctxt  false
				  ifTrue: [{(encoder encodeSelector: #DoIt) , #() , 1}]
				  ifFalse: [{(encoder encodeSelector: #DoItIn:) , (encoder encodeVariable: 'homeContext') inVector , 3}]).
		temps ← (hereType  #verticalBar
				  ifTrue: [self temporaries]
				  ifFalse: [#()]).
		(blk ← self statements: #() doit: true)
		  ifTrue: [blk returnLast].
		prim ← 0]
	  ifFalse:
		[(sap ← self pattern)
		  ifTrue:
			[temps ← self temporaries.
			prim ← self primitive.
			blk ← self statements: #() doit: false]].
	(sap and: [blk])
	  ifTrue:
		[self more
		  ifTrue: [↑self expected: 'Nothing more'].
		↑LADMethodNode new selector: sap  1 arguments: sap  2 precedence: sap  3 temporaries: temps block: blk mustReturn encoder: encoder primitive: prim]
	  ifFalse: [↑self expected: 'pattern']].
"392" LADParser$'Errors'
[notify: string | |
	mark  false
	  ifTrue: [↑false].
	hereMark ← hereMark + (tokenType  #doIt
			  ifTrue: [1]
			  ifFalse: [0]) + (hereType  #doIt
			  ifTrue: [1]
			  ifFalse: [0]).
	tokenType ← mark ← false.
	encoder release "break cycles".
	source skip: hereMark - source position - 1.
	requestor notify: string.
	here ← 30 inString.
	hereType ← #doIt.
	↑false].
"92" LADParser$'Scanner'
[match: type | |
	hereType  type
	  ifTrue: [↑self advance].
	↑false].
"678" LADParser$'Parser'
[block | blk argNodes argument |
	 " '[' {:var.} (:var|statements) ']'  BlockNode"
	argNodes ← (Vector new: 1) asStream.
	(self match: #leftBracket)
	  ifTrue:
		[[(self match: #colon) and: [((argument ← self match: #word)
		  ifTrue: [argNodes next← encoder autoBind: argument]
		  ifFalse: [↑self expected: 'Argument name'])]] whileTrueDo: [].
		(argNodes empty or: [(self match: #verticalBar)])  false
		  ifTrue: [↑self expected: 'Vertical bar'].
		((blk ← self statements: argNodes contents doit: false) and: [(self match: #rightBracket)])
		  ifTrue: [↑blk].
		↑self expected: 'Period or right bracket']
	  ifFalse: [↑self expected: 'Left bracket']].
"120" LADParser$'Private'
[init: sourceStream notifying: req | |
	requestor ← req.
	super scan: sourceStream.
	self advance].
"79" LADParser$'Errors'
[expected: string | |
	↑self notify: string + ' expected'].
"242" LADParser$'Parser'
[binaryMessage | selector arg |
	 "binarySelector arg  {selector, {arg}}"
	selector ← self advance.
	(arg ← self argumentFreeExpression: false)
	  ifTrue: [↑{selector unique , arg inVector}].
	↑self expected: 'argument'].
"466" LADParser$'Parser'
[collection | exprs e |
	 "'{' {simpleExpression ','} [simpleExpression] '}'  CollectionNode"
	(self match: #leftBrace)
	  ifTrue:
		[exprs ← (Vector new: 10) asStream.
		[((e ← self simpleExpression: false) and: [exprs next← e]) and: [(self match: #comma)]] whileTrueDo: [].
		(self match: #rightBrace)
		  ifTrue: [↑LADCollectionNode new elements: exprs contents from: encoder].
		↑self expected: 'Comma or right brace']
	  ifFalse: [↑false]].
"71" LADParser$'Name Parsing for Debugger'
[encodeSelector: sel | |
	↑sel].
"390" LADParser$'Parser'
[keywordMessage | selector arg args |
	 "{keyword arg}  {selector, args}"
	selector ← Stream default.
	args ← (Vector new: 4) asStream.
	[hereType  #keyword] whileTrueDo:
		[selector append: self advance.
		(arg ← self keywordFreeExpression: false)
		  ifTrue: [args next← arg]
		  ifFalse: [↑self expected: 'argument']].
	↑{selector contents unique , args contents}].
"374" LADParser$'Parser'
[temporaries | vars |
	 "[ '|' {variable} ]  {variable, ..., variable}"
	(self match: #verticalBar) and: [((self match: #verticalBar)
	  ifTrue: [↑#()].
	vars ← (Vector new: 8) asStream.
	[hereType  #word] whileTrueDo: [vars next← encoder bind: self advance].
	(self match: #verticalBar)
	  ifTrue: [↑vars contents])].
	↑self expected: 'Vertical bar'].
"197" LADScanner$'Mulit-Character Scans'
[xAbbreviation | |
	 "     "
	tokenType ← #binary "token ← (<= ~= >= ==)  ((   ) find: self step inUniqueString)".
	token ← self step inUniqueString].
"591" LADScanner$'Mulit-Character Scans'
[xLitQuote | type s |
	 "UniqueStrings and Vectors"
	s ← Stream default.
	self step "litQuote".
	typeTable  hereChar  #leftParenthesis
	  ifTrue:
		[self step "leftPar".
		[typeTable  hereChar  #rightParenthesis] whileFalseDo:  [s next← self step].
		self step "rightPar".
		tokenType ← #literal.
		token ← s contents asVector]
	  ifFalse:
		[s next← self step "first char".
		[(type ← typeTable  hereChar)  #xLetter or: [(type = #xDigit or: [type  #colon])]] whileTrueDo: [s next← self step].
		tokenType ← #literal.
		token ← s contents unique]].
"179" LADScanner$'Mulit-Character Scans'
[xControlZ | |
	 "ignore trailer"
	(self skipThrough: 13)
	  ifTrue: [self scanToken]
	  ifFalse: [self error: 'Missing cr in Bravo trailer']].
"184" LADScanner$'Mulit-Character Scans'
[xDoubleQuote | |
	 "ignore comment"
	(self skipThrough: hereChar)
	  ifTrue: [self scanToken]
	  ifFalse: [self error: 'Unmatched comment quote']].
"329" LADScanner$'Mulit-Character Scans'
[xLetter | type s |
	 "form a word or keyword"
	s ← Stream default.
	[(type ← typeTable  hereChar)  #xLetter or: [type  #xDigit]] whileTrueDo: [s next← self step].
	type  #colon
	  ifTrue:
		[s next← self step.
		tokenType ← #keyword]
	  ifFalse: [tokenType ← #word].
	token ← s contents].
"491" LADScanner$'Mulit-Character Scans'
[xSingleQuote | start s |
	 "string"
	start ← source position.
	self step.
	s ← Stream default.
	[hereChar = 39 and: [(aheadChar = 39
	  ifTrue:
		[self step.
		false]
	  ifFalse: [true])]] whileFalseDo: 
		[s next← self step.
		(hereChar = 30 "doit" and: [source end])
		  ifTrue:
			[ "Ran off end, back up."
			source skip: start - 1 - source position.
			↑self error: 'Unmatched string quote']].
	self step.
	token ← s contents.
	tokenType ← #string].
"63" LADScanner$'Errors'
[notify: string | |
	user notify: string].
"184" LADScanner$'Subroutines'
[testDigit: char radix: radix | |
	↑(char  48 and: [char < (48 + radix) "0-9"]) or: [(radix > 10 and: [(char  65 and: [char < (65 - 10 + radix) "A-Z"])])]].
"236" LADScanner$'Mulit-Character Scans'
[xRelational | |
	 "check for <= ~= >= == "
	tokenType ← #binary.
	token ← self step inUniqueString.
	hereChar = 61
	  ifTrue:
		[ "="
		self step.
		token ← #(    )  (#(< ~ > = ) find: token)]].
"269" LADScanner$'Main Scanner'
[scanToken | |
	mark ← source position.
	tokenType ← typeTable  hereChar.
	tokenType  1 = 120
	  ifTrue: [ "x as first letter means perform to compute token & type"
		self perform: tokenType]
	  ifFalse: [token ← self step inUniqueString]].
"300" LADScanner$'Subroutines'
[skipThrough: char | start |
	 "false if unmatched."
	start ← source position.
	self step.
	[self step = char] whileFalseDo: 
		[(hereChar = 30 and: [source end "doit"])
		  ifTrue:
			[source skip: start - 1 "Ran off end, back up." - source position.
			↑false]].
	↑true].
"1003" LADScanner$'Initialization'
[classInit | |
	 "LADScanner classInit."
	typeTable ← Vector new: 256.
	typeTable  (1 to: 256) all← #binary "default".
	typeTable  #(9 10 12 13 32 ) all← #xDelimiter "tab lf ff cr space".
	typeTable  #(1 6 14 18 ) all← #xAbbreviation "     ".
	typeTable  15 ← #xLitQuote.
	typeTable  26 ← #xControlZ.
	typeTable  30 ← #doIt.
	typeTable  34 ← #xDoubleQuote.
	typeTable  39 ← #xSingleQuote.
	typeTable  40 ← #leftParenthesis.
	typeTable  41 ← #rightParenthesis.
	typeTable  44 ← #comma.
	typeTable  46 ← #period.
	typeTable  (48 to: 57) all← #xDigit.
	typeTable  #(3 58 ) all← #colon.
	typeTable  59 ← #semicolon.
	typeTable  #(60 61 62 126 ) all← #xRelational " < = > ~ ".
	typeTable  ((65 to: 90) concat: (97 to: 122)) all← #xLetter.
	typeTable  91 ← #leftBracket.
	typeTable  93 ← #rightBracket.
	typeTable  94 ← #upArrow.
	typeTable  95 ← #leftArrow.
	typeTable  123 ← #leftBrace.
	typeTable  124 ← #verticalBar.
	typeTable  125 ← #rightBrace].
"994" LADScanner$'Mulit-Character Scans'
[xDigit | fracPart exp real radix |
	 "form a number"
	tokenType ← #number.
	real ← false.
	radix ← self convert: (self scanInteger: 10) radix: 10.
	hereChar = 114
	  ifTrue:
		[ "<radix>r<number>"
		self step.
		token ← self convert: (self scanInteger: radix) radix: radix]
	  ifFalse:
		[token ← radix.
		radix ← 10].
	(hereChar = 46 and: [(self testDigit: aheadChar radix: radix)])
	  ifTrue:
		[ ".<fraction>"
		self step.
		real ← true.
		fracPart ← self scanInteger: radix.
		fracPart ← (self convert: fracPart radix: radix) asFloat / (radix asFloat ipow: fracPart length).
		token ← token asFloat + fracPart].
	hereChar = 101
	  ifTrue:
		[ "e<exponent>"
		self step.
		exp ← (hereChar = 45 "-"
				  ifTrue:
					[self step.
					0 - (self convert: (self scanInteger: 10) radix: 10)]
				  ifFalse: [self convert: (self scanInteger: 10) radix: 10]).
		token ← token * (real
				  ifTrue: [radix asFloat ipow: exp]
				  ifFalse: [radix ipow: exp])]].
"101" LADScanner$'Subroutines'
[convert: str radix: radix | |
	↑Integer new fromString: str radix: radix].
"207" LADScanner$'Subroutines'
[scanInteger: radix | s |
	 "Should be merged with Integer readFrom: "
	s ← Stream default.
	[self testDigit: hereChar radix: radix] whileTrueDo: [s next← self step].
	↑s contents].
"47" LADScanner$'Errors'
[interactive | |
	↑false].
"186" LADScanner$'Initialization'
[scan: inputStringOrStream | |
	source ← inputStringOrStream asStream "initialize reader".
	mark ← source position.
	self step.
	self step.
	self scanToken].
"62" LADScanner$'Errors'
[error: string | |
	self notify: string].
"204" LADScanner$'Subroutines'
[step | c |
	c ← hereChar.
	hereChar ← aheadChar.
	(aheadChar ← source next)
	  ifTrue:
		[aheadChar = 0
		  ifTrue: [aheadChar ← 256]]
	  ifFalse: [aheadChar ← 30 "doit"].
	↑c].
"156" LADScanner$'Mulit-Character Scans'
[xDelimiter | |
	 "ignore blanks etc."
	[typeTable  hereChar  #xDelimiter] whileTrueDo: [self step].
	self scanToken].
"516" LADCompiler$'Private'
[translate: stream noPattern: noPattern | tree |
	LADVariableNode new NTinit "post-vmem init once only".
	tree ← LADParser new parse: stream class: class noPattern: noPattern context: context notifying: self.
	NoteTaker  false
	  ifTrue:
		[self notify: (Statistics new symbolic: tree generate) "self notify: (LADDecompiler new classInit decompile: [context[DoItIn:] DoIt]
				 in: class method: tree generate asCompiledMethod) asString.".
		↑false].
	failure
	  ifTrue: [↑false].
	↑tree].
"214" LADCompiler$'Private'
[from: source class: cls instance: rcvr context: ctxt notifying: req | |
	sourceStream ← source asStream.
	class ← cls.
	instance ← rcvr.
	context ← ctxt.
	requestor ← req.
	failure ← false].
"527" LADCompiler$'Public'
[evaluate: stream in: ctxt to: receiver notifying: t4 | methodNode method cls |
	requestor ← t4.
	cls ← (ctxt
			  ifTrue: [ctxt receiver]
			  ifFalse: [receiver]) class.
	self from: stream class: cls instance: receiver context: ctxt notifying: requestor.
	(methodNode ← user displayoffwhile [(self translate: stream noPattern: true)])
	  ifTrue:
		[method ← methodNode generate.
		context
		  ifTrue: [↑instance execute: method with: context].
		↑instance execute: method]
	  ifFalse: [↑failureValue]].
"196" LADCompiler$'Errors'
[notify: string | |
	failure ← true.
	user restoredisplay.
	failureValue ← requestor notify: string at: (sourceStream position min: sourceStream limit) + 1 in: sourceStream].
"448" LADCompiler$'Public'
[compile: parag in: cls under: category notifying: t4 | methodNode selector |
	requestor ← t4.
	self from: parag class: cls instance: false context: false notifying: requestor.
	(methodNode ← user displayoffwhile [(self translate: sourceStream noPattern: false)])
	  ifTrue:
		[selector ← methodNode selector.
		methodNode install: parag in: cls.
		cls organization classify: selector under: category.
		↑selector].
	↑false].
"219" CodePane$'As yet unclassified'
[compiler: defaultClass | |
	((class  nil
	  ifTrue: [defaultClass]
	  ifFalse: [class]) usesNewSyntax or: [(NoteTaker or: [user leftShiftKey])])
	  ifTrue: [↑LADCompiler].
	↑Generator].
"60" CodePane$'Window protocol'
[outline | |
	frame outline: 1].
"82" Window$'Framing'
[show | |
	self outline.
	growing
	  ifFalse: [self showtitle]].
"543" Window$'Framing'
[editTitle | pared w |
	pared ← TextImage new para: titlepara frame: nil.
	pared formerly: false.
	pared fixframe: titleframe window + (1  2).
	pared enter.
	w ← titleframe window.
	[user anybug and: [(w has: user mp)  false]] whileFalseDo: 
		[user kbck
		  ifTrue: [pared kbd]
		  ifFalse:
			[user redbug
			  ifTrue:
				[(w has: user mp)
				  ifTrue: [pared selecting]]
			  ifFalse:
				[user yellowbug
				  ifTrue:
					[(w has: user mp)
					  ifTrue: [w flash]]]]].
	titlepara ← pared contents.
	self showtitle].
"101" Window$'Framing'
[fixframe: f | |
	↑Rectangle new origin: f origin extent: (f extent max: 32  32)].
"63" Window$'Default Event responses'
[yellowbug | |
	frame flash].
"100" Window$'Default Event responses'
[aboutToFrame | |
	 "My frame is about to change.  I dont care."].
"43" Window$'Framing'
[title | |
	↑'Untitled'].
"97" Window$'Framing'
[takeCursor | |
	user cursorloc← frame center "Move the cursor to my center."].
"158" Window$'Default Event responses'
[print | t1 |
	(t1 ← dp0 pressfile: (self title + '.press.') asFileName) screenout: frame scale: PressScale.
	t1 toPrinter].
"62" Window$'Default Event responses'
[hardcopy | |
	frame flash].
"68" Window$'Default Event responses'
[kbd | |
	user kbd.
	frame flash].
"60" Window$'Default Event responses'
[redbug | |
	frame flash].
"60" Window$'Default Event responses'
[keyset | |
	frame flash].
"558" Window$'Scheduling'
[eachtime | |
	(frame has: user mp)
	  ifTrue:
		[user kbck
		  ifTrue: [↑self kbd].
		user anybug
		  ifTrue:
			[user redbug
			  ifTrue: [↑self redbug].
			user yellowbug
			  ifTrue: [↑self yellowbug].
			user bluebug
			  ifTrue: [↑self bluebug]]
		  ifFalse:
			[user anykeys
			  ifTrue: [↑self keyset]]]
	  ifFalse:
		[self outside
		  ifFalse:
			[user anybug
			  ifTrue:
				[(frame has: user mp)
				  ifFalse: [↑false]]
			  ifFalse:
				[user kbck
				  ifTrue:
					[user kbd.
					frame flash] "flush typing outside"]]]].
"60" Window$'Scheduling'
[lasttime | |
	self leave.
	↑exitflag].
"48" Window$'Default Event responses'
[leave | |
	].
"58" Window$'Scheduling'
[schedule | |
	user restartup: self].
"586" Window$'Framing'
[fixedwidthfromuser: width | a b oldframe |
	user waitnobug.
	frame  nil
	  ifFalse:
		[self aboutToFrame.
		self erase].
	a ← OriginCursor showwhile [user waitbug].
	growing ← true.
	self frame: (frame ← self fixframe: (a rect: a + (width  32))).
	self show.
	CornerCursor showwhile [([a ← user mpnext] whileTrueDo:
			[a x← frame corner x.
			oldframe  nil
			  ifTrue: [user cursorloc← a max: frame corner].
			oldframe ← frame copy.
			self frame: (frame ← self fixframe: (frame growto: a)).
			self moveFrom: oldframe])].
	growing ← false.
	self takeCursor].
"90" Window$'Framing'
[erase | |
	(frame inset: 2  2) clear.
	self clearTitle: background].
"572" Window$'Framing'
[newframe | a oldframe |
	user waitnobug.
	user restoredisplay.
	frame  nil
	  ifFalse:
		[self aboutToFrame.
		self erase].
	a ← OriginCursor showwhile [user waitbug].
	growing ← true.
	frame ← self fixframe: (a rect: a + 32).
	frame outline.
	CornerCursor showwhile [([a ← user mpnext] whileTrueDo:
			[oldframe  nil
			  ifTrue: [user cursorloc← a max: frame corner].
			oldframe ← frame copy.
			frame ← self fixframe: (frame growto: a).
			(oldframe inset: 2) clear.
			frame outline])].
	self frame: frame.
	growing ← false.
	self takeCursor].
"38" Window$'Framing'
[frame | |
	↑frame].
"57" Window$'Default Event responses'
[enter | |
	self show].
"59" Window$'Framing'
[frame: f | |
	frame ← self fixframe: f].
"72" Window$'Initialization'
[reset | |
	exitflag ← true.
	growing ← false].
"296" Window$'Initialization'
[classInit | |
	 "Window classInit"
	border ← 2  2.
	titleframe ← Textframe new para: nil frame: nil.
	titleloc ← 3  (4 - titleframe lineheight).
	titlerun ← String new: 2.
	titlerun word: 1 ← 255.
	windowmenu ← Menu new string: 'under
frame
close
print
printbits
'].
"181" Window$'Default Event responses'
[outside | |
	(titleframe window has: user mp)
	  ifTrue:
		[user anybug
		  ifTrue: [self editTitle]
		  ifFalse: [↑false]]
	  ifFalse: [↑false]].
"48" Window$'Default Event responses'
[close | |
	].
"109" Window$'Scheduling'
[firsttime | |
	(frame has: user mp)
	  ifTrue:
		[self reset.
		↑self enter].
	↑false].
"353" Window$'Default Event responses'
[bluebug | t1 |
	(t1 ← windowmenu bug) = 1
	  ifTrue: [↑exitflag ← false].
	t1 = 2
	  ifTrue:
		[self newframe.
		self enter]
	  ifFalse:
		[t1 = 3
		  ifTrue:
			[self close.
			self erase.
			user unschedule: self.
			↑false].
		t1 = 4
		  ifTrue: [self hardcopy]
		  ifFalse:
			[t1 = 5
			  ifTrue: [self print]]]].
"91" Window$'Framing'
[clearTitle: color | |
	(titleframe window inset: 2  2) clear: color].
"83" Window$'Framing'
[moveFrom: oldframe | |
	(oldframe inset: 2) clear.
	self show].
"212" Window$'Framing'
[showtitle | |
	titlepara  nil
	  ifTrue: [titlepara ← Paragraph new text: self title runs: titlerun alignment: 0].
	titleframe put: titlepara at: frame origin + titleloc.
	titleframe outline].
"71" Window$'Framing'
[outline | |
	frame outline "Clear and outline me."].
"364" CodeWindow$'Initialization'
[class: class selector: selector para: para formerly: oldpara | codePane |
	codePane ← CodePane new class: class selector: selector para: nil.
	self title: class title + ' ' + selector with: codePane inVector at: stdTemplates.
	self newframe.
	self show.
	codePane showing: para.
	codePane formerly: oldpara.
	codePane from: codePane].
"70" CodeWindow$'Initialization'
[editTitle | |
	titleframe window flash].
"148" FilePane$'As yet unclassified'
[classInit | |
	 "FilePane classInit."
	editmenu ← Menu new string: 'again
copy
cut
paste
doit
put
undo
get
align'].
"892" FilePane$'As yet unclassified'
[yellowbug | t1 |
	(t1 ← editmenu bug) = 1
	  ifTrue: [pared again]
	  ifFalse:
		[t1 = 2
		  ifTrue: [pared copyselection]
		  ifFalse:
			[t1 = 3
			  ifTrue: [pared cut]
			  ifFalse:
				[t1 = 4
				  ifTrue: [pared paste]
				  ifFalse:
					[t1 = 5
					  ifTrue: [self doit]
					  ifFalse:
						[t1 = 6
						  ifTrue:
							[pared formerly
							  ifTrue: [user displayoffwhile [
									(file readwriteshorten.
									file reset.
									file append: pared contents.
									file close.
									pared formerly: false)]]
							  ifFalse: [frame flash]]
						  ifFalse:
							[t1 = 7
							  ifTrue: [pared undo]
							  ifFalse:
								[t1 = 8
								  ifTrue: [user displayoffwhile [(scrollBar hidewhile [(self showing: file contents asParagraph)])]]
								  ifFalse:
									[t1 = 9
									  ifTrue: [pared realign]]]]]]]]]].
"58" FilePane$'As yet unclassified'
[file: t1 | |
	file ← t1].
"256" CodeWindow$'Initialization'
[file: file | filePane |
	filePane ← FilePane new file: file.
	self title: file name with: filePane inVector at: stdTemplates.
	self newframe.
	self show.
	filePane showing: file contents asParagraph.
	filePane from: filePane].
"95" PanedWindow$'Window protocol'
[kbd | pane |
	(pane ← self pickedpane)
	  ifTrue: [↑pane kbd]].
"101" PanedWindow$'Window protocol'
[redbug | pane |
	(pane ← self pickedpane)
	  ifTrue: [↑pane redbug]].
"101" PanedWindow$'Window protocol'
[keyset | pane |
	(pane ← self pickedpane)
	  ifTrue: [↑pane keyset]].
"389" PanedWindow$'Window protocol'
[eachtime | pane |
	(frame has: user mp)
	  ifTrue:
		[user bluebug
		  ifTrue: [↑self bluebug].
		panes do: [:pane | pane startup]]
	  ifFalse:
		[self outside
		  ifFalse:
			[user anybug
			  ifTrue:
				[(frame has: user mp)
				  ifFalse: [↑false]]
			  ifFalse:
				[user kbck
				  ifTrue:
					[user kbd.
					frame flash] "flush typing outside"]]]].
"94" PanedWindow$'Window protocol'
[show | pane |
	super show.
	panes do: [:pane | pane outline]].
"86" PanedWindow$'Window protocol'
[leave | pane |
	panes do: [:pane | pane windowleave]].
"280" PanedWindow$'Window protocol'
[hardcopy: pf | pane |
	self hardcopyTitle: pf "print frame rectangle".
	frame hardcopy: pf "print all panes".
	panes do: [:pane | pane hardcopy: pf "print cursor if it's inside"].
	(frame has: user mp)
	  ifTrue: [user currentCursor hardcopy: pf]].
"115" PanedWindow$'Window protocol'
[fixframe: f | |
	↑Rectangle new origin: f origin extent: (f extent max: 160  80)].
"79" PanedWindow$'Window protocol'
[erase | |
	self titlerect clear.
	super erase].
"99" PanedWindow$'Window protocol'
[enter | pane |
	super show.
	panes do: [:pane | pane windowenter]].
"410" PanedWindow$'Window protocol'
[frame: t1 | templateStream template pane orig ext |
	 "(Re)initialize my frame, and tell my panes their locations."
	frame ← t1.
	templateStream ← templates asStream.
	orig ← frame origin - 1.
	ext ← frame extent + 2.
	panes do:
		[:pane | template ← templateStream next "It would be nice to have parallel fors as in MLISP.".
		pane frame← template * ext / 36 + orig inset: 1]].
"107" PanedWindow$'Window protocol'
[yellowbug | pane |
	(pane ← self pickedpane)
	  ifTrue: [↑pane yellowbug]].
"349" PanedWindow$'Window protocol'
[hardcopyTitle: pf | |
	self showtitle "refresh title (since it's a class var)" "draw title rectangle".
	titleframe window hardcopy: pf "print title text (make frame larger)".
	titleframe para presson: pf in: (pf transrect: (titleframe frame origin rect: titleframe frame corner + (999  2))) style: titleframe style].
"80" PanedWindow$'Window protocol'
[close | pane |
	panes do: [:pane | pane close]].
"91" PanedWindow$'Pane services'
[vanish | |
	self close.
	self erase.
	user unschedule: self].
"51" PanedWindow$'Window protocol'
[title | |
	↑title].
"72" PanedWindow$'Window protocol'
[takeCursor | |
	(panes  1) takeCursor].
"315" PanedWindow$'Initialization'
[title: t1 with: t2 at: t3 | pane |
	 "The instance variable templates is a set of Rectangles for the frames of the panes normalized such that the whole PanedWindow is a frame of 00 rect: 3636."
	title ← t1.
	panes ← t2.
	templates ← t3.
	self reset.
	panes do: [:pane | pane init]].
"144" PanedWindow$'Private'
[titlerect | |
	↑frame origin - (2  (DefaultTextStyle lineheight + 4)) rect: frame corner x  frame origin y + (2  0)].
"131" PanedWindow$'Window protocol'
[pickedpane | pane |
	panes do:
		[:pane | pane picked
		  ifTrue: [↑pane]].
	frame flash.
	↑false].
"178" PanedWindow$'Window protocol'
[hardcopy | p |
	user displayoffwhile [
		(p ← dp0 pressfile: (self title + '.press') asFileName.
		self hardcopy: p.
		p close.
		p toPrinter)]].
"166" FileStream$'CodePane Editor'
[edit | |
	NoteTaker
	  ifTrue: [user schedule: (CodeWindow new file: self)]
	  ifFalse: [user restartup: (CodeWindow new file: self)]].
"103" FileStream$'Print'
[asPressPrinter | |
	↑PressPrinter init "default format for printt etc." of: self].
"47" FileStream$'File'
[name | |
	↑self file name].
"109" FileStream$'Dictionary'
[release | |
	self obsolete
	  ifFalse:
		[dirty ← limit ← 0.
		self file release]].
"530" FileStream$'File'
[positionSize: size | len pos |
	len ← page dataLength "compute the position for an object of a given size,
		e.g. characters (1), words (2), fixed length (n),
	from the current character position and the current page".
	(size = 1 or: [len \ size  0])
	  ifTrue:
		[pos ← page pageNumber - 1 * len + (position - page dataBeginning).
		size = 1
		  ifTrue: [↑pos].
		↑pos / size]
	  ifFalse: [ "page length is a multiple of size"
		↑page pageNumber - 1 * (len / size) + (position - page dataBeginning / size)]].
"721" FileStream$'File'
[position: objpos size: size | len pn c pos |
	len ← page dataLength "set the current character position and the current page
	from the position of an object of a given size (see positionSize:)".
	size = len
	  ifTrue:
		[pn ← objpos + 1 "page size".
		c ← 0]
	  ifFalse:
		[pos ← objpos.
		size = 1
		  ifFalse:
			[len \ size = 0
			  ifTrue: [len ← len / size "page length is a multiple of size"]
			  ifFalse:
				[pos ← objpos * size.
				size ← 1]] "obtain quotient (page) and remainder (position)".
		pos ← pos intdiv: len.
		pn ← 1 + (pos  1) asSmall.
		c ← size * (pos  2) asSmall].
	(self positionPage: pn character: c)
	  ifTrue: [↑objpos].
	self error: 'cannot read page ' + pn asString].
"141" FileStream$'Access Modes'
[readwriteshorten | |
	self setMode: read + write "allow read and write and shorten File upon closing" + shorten].
"57" FileStream$'File'
[directory | |
	↑self file directory].
"127" FileStream$'Filin/Filout'
[filoutclass: class | t2 |
	(t2 ← self asParagraphPrinter) stamp.
	t2 printclass: class.
	t2 close].
"126" FileStream$'Access Modes'
[readwrite | |
	self setMode: read + write "allow read and write but don't automatically shorten"].
"64" FtpDirectory$'FileDirectory'
[commands | |
	↑command contents].
"120" FtpDirectory$'FileDirectory'
[delete: name | |
	command append: ' Delete/C '.
	command append: (self checkName: name)].
"327" FtpDirectory$'FileDirectory'
[replace: name | s |
	s ← self checkName: name.
	(directory compare: 'maxc') = 2
	  ifTrue:
		[self delete: s.
		self store: s]
	  ifFalse:
		[ "store as highest version (ifs only)"
		command append: ' Store/S '.
		command append: s.
		command space.
		command append: s.
		command append: '!H']].
"196" FtpDirectory$'FileDirectory'
[retrieve: remote as: local | |
	command append: ' Retrieve/S '.
	command append: (self checkName: remote).
	command space.
	command append: (self checkName: local)].
"190" FtpDirectory$'FileDirectory'
[store: local as: remote | |
	command append: ' Store/S '.
	command append: (self checkName: local).
	command space.
	command append: (self checkName: remote)].
"154" FtpDirectory$'FileDirectory'
[connect: name password: pw | |
	command append: ' Connect/C '.
	command append: name.
	command space.
	command append: pw].
"195" FtpDirectory$'FileDirectory'
[retrieve: s | t |
	(s is: Vector)
	  ifTrue: [s do: [:t | self retrieve: t]]
	  ifFalse:
		[command append: ' Retrieve/C '.
		command append: (self checkName: s)]].
"172" FtpDirectory$'FileDirectory'
[directoryName: name | |
	command append: ' Directory/C ' "this message should be directory:, but until rewriting...".
	command append: name].
"137" FtpDirectory$'FileDirectory'
[closeThen: s | |
	command append: '; '.
	command append: s.
	user quitThen: command contents.
	self open].
"203" FtpDirectory$'FileDirectory'
[rename: oldName newName: newName | |
	command append: ' Rename/C '.
	command append: (self checkName: oldName).
	command space.
	command append: (self checkName: newName)].
"80" FtpDirectory$'FileDirectory'
[close | |
	self closeThen: 'Resume. Small.Boot'].
"186" FtpDirectory$'FileDirectory'
[store: s | t |
	(s is: Vector)
	  ifTrue: [s do: [:t | self store: t]]
	  ifFalse:
		[command append: ' Store/C '.
		command append: (self checkName: s)]].
"180" FtpDirectory$'FileDirectory'
[login: name password: pw | |
	name empty
	  ifFalse:
		[command append: ' Login/C '.
		command append: name.
		command space.
		command append: pw]].
"194" FtpDirectory$'FileDirectory'
[open | |
	command ← Stream new of: (String new: 100).
	command append: 'Ftp '.
	command append: directory.
	self login: self userName password: self userPassword].
"73" FileDirectory$'FileStream'
[pressfilin: s | |
	self filin: s format: 2].
"73" FileDirectory$'FileStream'
[file: name | |
	↑(self get: name) asStream].
"62" FileDirectory$'DictionaryEntry'
[dictionary | |
	↑directory].
"70" FileDirectory$'DictionaryEntry'
[dictionary: t1 | |
	directory ← t1].
"79" FileDirectory$'FileStream'
[newFile: name | |
	↑(self insert: name) asStream].
"144" FileDirectory$'FTP'
[retrieve: s | t |
	(s is: Vector)
	  ifTrue: [s do: [:t | self retrieve: t as: t]]
	  ifFalse: [↑self retrieve: s as: s]].
"81" FileDirectory$'Dictionary'
[entryClass | |
	self subError "a subclass of File"].
"54" FileDirectory$'FTP'
[server: t1 | |
	directory ← t1].
"102" FileDirectory$'File'
[allocateSN: file | |
	self subError "allocate a new serial number for a File"].
"210" FileDirectory$'Dictionary'
[printon: strm | |
	strm append: (self obsolete
	  ifTrue: ['a closed ']
	  ifFalse: ['an open ']).
	strm append: self class title.
	strm append: ' on '.
	self server printon: strm].
"135" FileDirectory$'FTP'
[store: s | t |
	(s is: Vector)
	  ifTrue: [s do: [:t | self store: t as: t]]
	  ifFalse: [↑self store: s as: s]].
"84" FileDirectory$'FTP'
[login: name | |
	↑self login: name password: '' "or prompt?"].
"67" FileDirectory$'FTP'
[login: name password: pw | |
	self subError].
"126" FileDirectory$'FTP'
[userName | |
	↑currentProfile  nil
	  ifTrue: ['']
	  ifFalse: [currentProfile userName: self server]].
"67" FileDirectory$'Dictionary'
[open | |
	externalViews insert: self].
"134" FileDirectory$'FTP'
[userPassword | |
	↑currentProfile  nil
	  ifTrue: ['']
	  ifFalse: [currentProfile userPassword: self server]].
"822" FileDirectory$'Dictionary'
[insert: file | old |
	file ← self makeEntry: file "note: this changes the default behavior found in Dict.
	this creates a new version rather than generating an error if the name exists".
	self versionNumbers
	  ifTrue: [file ← self makeEntry: (file name "ignore explicit version and directory will create a next version" asStream upto: '!'  1)]
	  ifFalse:
		[(self Find: file)
		  ifTrue:
			[old ← self makeEntry: file name + '$' "otherwise, if the file already exists,
		rename it to name$, deleting that file first if it exists".
			(self Find: old)
			  ifTrue: [self Delete: old].
			self rename: file name newName: old name "reposition to original name".
			(self Find: file)
			  ifTrue: [self error: 'insert/rename ??' entry: file]] "file didn't exist"].
	self Insert: file.
	↑file].
"170" FileDirectory$'Dictionary'
[Find: file | name |
	(name ← self checkName: file name)
	  ifTrue:
		[file name: name.
		↑self Position← file].
	file error: 'illegal name'].
"119" FileDirectory$'File'
[newPage | |
	↑(self makeEntry: nullString) "return a dummy FilePage from a dummy File" newPage].
"71" FileDirectory$'Dictionary'
[error: e entry: file | |
	↑file error: e].
"248" FileDirectory$'FTP'
[retrieve: s1 as: s2 | f t4 |
	(self exists: s1)
	  ifTrue: [f ← self oldFile: s1]
	  ifFalse: [↑false].
	f readonly.
	(t4 ← ((s2 is: FileStream)
			  ifTrue: [s2]
			  ifFalse: [dp0 file: s2])) append: f.
	t4 close.
	f close].
"246" FileDirectory$'FTP'
[store: s1 as: s2 | f t4 |
	(s1 is: FileStream)
	  ifTrue: [f ← s1]
	  ifFalse:
		[(dp0 exists: s1)
		  ifTrue: [f ← dp0 oldFile: s1]
		  ifFalse: [↑false]].
	f readonly.
	(t4 ← self file: s2) append: f.
	t4 close.
	f close].
"77" FileDirectory$'FileStream'
[oldFile: name | |
	↑(self find: name) asStream].
"88" FileDirectory$'FileStream'
[pressfile: name | |
	↑PressFile new of: (self file: name)].
"46" FileDirectory$'FTP'
[server | |
	↑directory].
"279" FileDirectory$'FTP'
[asFtpDirectory | ftp |
	(ftp ← FtpDirectory new "to allow convenient (kludgey) access to file servers (e.g. phylum, dpj) via Ftp") server: self server.
	ftp open.
	ftp userName empty
	  ifTrue: [ftp login: self userName password: self userPassword].
	↑ftp].
"50" FileDirectory$'File'
[directory | |
	↑directory].
"77" FileDirectory$'Juniper'
[closeTransaction | |
	 "default is to do nothing"].
"267" FileDirectory$'Dictionary'
[checkName: s | |
	(s empty "default behavior is to get rid of ending period.
	subclasses can do any kind of checking they want and
	return false if name is no good" or: [s last  ('.'  1)])
	  ifTrue: [↑s].
	↑s copy: 1 to: s length - 1].
"114" FileDirectory$'Dictionary'
[close | |
	self obsolete
	  ifFalse:
		[externalViews delete: self.
		self release]].
"64" FileDirectory$'Initialize'
[directory: t1 | |
	directory ← t1].
"98" FileDirectory$'File'
[versionNumbers | |
	↑false "generally, version numbers are not supported"].
"68" FileDirectory$'FileStream'
[filin: s | |
	self filin: s format: 1].
"81" FileDirectory$'Juniper'
[exceptionHandler: eh | |
	 "default is to do nothing"].
"681" FileDirectory$'FileStream'
[filin: s format: ft | |
	user displayoffwhile [
		 "read Class definitions or Changes from FileStreams or PressFiles
	ft: 1 (FileStream=Bravo), 2 (Press)"
		((s is: Vector)
		  ifTrue: [s do: [:s | self filin: s format: ft]]
		  ifFalse:
			[ "special case for Alto and patterns"
			((s is: String) and: [((s has: '*'  1) or: [(s has: '#'  1)])])
			  ifTrue: [self filin: (self filesMatching: s) format: ft]
			  ifFalse:
				[(s is: UniqueString)
				  ifTrue: [s ← s +  "Class name"
							(ft = 1
							  ifTrue: ['.st']
							  ifFalse: ['.press'])].
				(ft = 1
				  ifTrue: [self oldFile: s]
				  ifFalse: [self pressfile: s]) filin]])]].
"116" FileStream$'Filin/Filout'
[backup | |
	self directory "assume ivy open"  dp0
	  ifTrue: [ivy replace: self name]].
"144" FileStream$'Access Modes'
[writing | |
	rwmode  nil
	  ifTrue: [↑self readwriteshorten "default mode. true"].
	↑(rwmode land: write) = write].
"257" FileStream$'Access Modes'
[setMode: m | |
	rwmode = m
	  ifFalse:
		[ "don't flush if first time or not write mode or continuing write mode"
		(rwmode  nil or: [((rwmode nomask: write) or: [(m anymask: write)])])
		  ifFalse: [self flush].
		rwmode ← m]].
"62" FileStream$'Access Modes'
[readonly | |
	self setMode: read].
"67" FileStream$'File'
[nextPage | |
	↑self read: page pageNumber + 1].
"458" FileStream$'Dictionary'
[reopen | pos |
	dirty
	  ifTrue:
		[ "self obsolete"
		pos ← position "reopen to current position".
		(self read: page pageNumber)
		  ifTrue: [position ← pos min: limit]
		  ifFalse:
			[ "if that page doesn't exist, go to last one that does.
		note that settoend would be recursive"
			(self read: self file lastPage)
			  ifTrue: [position ← limit]
			  ifFalse: [self error: 'cannot reopen or settoend']]]
	  ifFalse: [↑false]].
"484" BravoPrinter$'Writing'
[print: para | l r |
	para ← para asParagraph.
	eject
	  ifTrue:
		[self eject.
		eject ← false].
	strm append: para text.
	strm next← 26 "↑Z".
	l ← frame origin x.
	r ← frame corner x.
	l  self defaultframe origin x
	  ifTrue:
		[strm append: 'l'.
		strm print: l].
	r  self defaultframe corner x
	  ifTrue:
		[strm append: 'z'.
		strm print: r].
	leading  self defaultleading
	  ifTrue:
		[strm append: 'e'.
		strm print: leading].
	para bravoRuns: strm].
"61" BravoPrinter$'Writing'
[eject | |
	strm next← 12.
	strm cr].
"70" BravoPrinter$'Initialization'
[init | |
	super init.
	eject ← false].
"97" BravoPrinter$'Writing'
[nextpage | |
	eject
	  ifTrue: [self eject]
	  ifFalse: [eject ← true]].
"114" FileStream$'Filin/Filout'
[asParagraphPrinter | |
	↑BravoPrinter init "default format for filout etc." of: self].
"63" FileStream$'Stream'
[wordposition | |
	↑self positionSize: 2].
"81" File$'FileStream'
[asStream | |
	↑FileStream new on: (self open.
	self get: 1)].
"73" File$'DictionaryEntry'
[match: entry | |
	↑self name match: entry name].
"335" File$'FilePage'
[Get: page | p pn |
	pn ← page pageNumber.
	(p ← self Read: page)
	  ifTrue: [↑p].
	 "current last page of the file is assumed full"
	(lastpn + 1 to: pn - 1) "return an empty last page which is not written yet" do:
		[:p | page pageNumber: p.
		page ← self Write: page].
	page pageNumber: pn.
	page length: 0.
	↑page].
"283" File$'Initialize'
[classInit | |
	FilePool declare: #(read write shorten ) as: #(1 2 4 ) "subclasses of File may want to share variables in pools.
	execute before filin:
		Smalltalk declare: XFilePool as: (SymbolTable new init: 16).
	in classInit: XFilePool declare: () as: ()"].
"33" File$'Dictionary'
[close | |
	].
"66" File$'FilePage'
[read: pn | |
	↑self Read: (self makeEntry: pn)].
"116" File$'FileDirectory'
[type: t1 | |
	 "used by different Files in different ways, e.g. read/write mode"
	type ← t1].
"252" File$'Dictionary'
[makeEntry: page | t2 |
	(page is: self entryClass)
	  ifTrue:
		[page init.
		page serialNumber: serialNumber.
		↑page].
	↑(t2 ← self entryClass new) dictionary: self.
	t2 init.
	t2 pageNumber: page.
	t2 serialNumber: serialNumber].
"53" File$'DictionaryEntry'
[dictionary | |
	↑directory].
"61" File$'DictionaryEntry'
[dictionary: t1 | |
	directory ← t1].
"76" File$'Dictionary'
[entryClass | |
	self subError "a subclass of FilePage"].
"50" File$'DictionaryEntry'
[name: t1 | |
	name ← t1].
"76" File$'Dictionary'
[found: page | |
	self subError "read an existing page"].
"256" File$'FilePage'
[doCommand: com page: page error: s | |
	self subError "execute a File command on page. if an error occurs, include
	error ← 'some error message'.
	self error: s
	if s is false, returns false.
	otherwise s is passed to an error routine"].
"107" File$'File Length'
[lastFullPage | |
	(self read: self lastPage) full
	  ifTrue: [↑lastpn].
	↑lastpn - 1].
"42" File$'DictionaryEntry'
[name | |
	↑name].
"114" File$'FilePage'
[Write: page | |
	self subError "update lastpn, write page and return result (maybe next page)"].
"66" File$'Dictionary'
[open | |
	self findLastPage "compute lastpn"].
"35" File$'Dictionary'
[release | |
	].
"63" File$'Dictionary'
[Find: page | |
	↑page pageNumber  lastpn].
"51" File$'FilePage'
[newPage | |
	↑self makeEntry: 0].
"190" File$'Initialize'
[sameFile | |
	 "is File's current internal representation the same as what is stored externally? if so, usually can avoid some initialization, directory lookup"
	↑false].
"122" File$'File Length'
[endFile: page | |
	self subError "make File end with this FilePage. false means delete all of File"].
"106" File$'File Length'
[lastPage | |
	lastpn
	  ifTrue: [ "length in pages"
		↑lastpn].
	↑self findLastPage].
"56" File$'FilePage'
[newPage: pn | |
	↑self makeEntry: pn].
"72" File$'FilePage'
[Read: page | |
	self subError "return page or false"].
"141" File$'File Length'
[pageFrom: len | |
	↑(len - 1 "compute page number for a character index" / self entryClass new dataLength) asSmall + 1].
"50" File$'FileDirectory'
[directory | |
	↑directory].
"47" File$'Name'
[serialNumber | |
	↑serialNumber].
"436" File$'Name'
[serialNumber: s | |
	(s is: String) "stored as a String of 4 characters rather than as various Numbers"
	  ifTrue: [serialNumber ← s]
	  ifFalse:
		[(s is: Substring)
		  ifTrue: [serialNumber ← s copy]
		  ifFalse:
			[(s is: Integer)
			  ifTrue:
				[serialNumber word: 1 ← 0.
				serialNumber word: 2 ← s]
			  ifFalse:
				[ "Vector of Integers"
				serialNumber word: 1 ← s  1.
				serialNumber word: 2 ← s  2]]]].
"58" File$'FileDirectory'
[directory: t1 | |
	directory ← t1].
"60" File$'FileDirectory'
[delete | |
	↑directory delete: self].
"197" File$'File Length'
[findLastPage | |
	↑lastpn ← self pageFrom: self length "the default definitions for findLastPage and length are circular.
	at least one of them must be defined by a subclass"].
"129" File$'Dictionary'
[reopen | |
	self sameFile
	  ifFalse: [ "init and directory access"
		directory get: self init].
	self open].
"94" File$'File Length'
[lastPage: t1 | |
	 "for those who know what they're doing"
	lastpn ← t1].
"245" File$'FilePage'
[error: e | t2 |
	e
	  ifTrue:
		[e ← ((t2 ← Stream default) append: name.
				t2 append: ' in '.
				t2 append: e.
				t2 append: ', '.
				t2 append: error.
				t2 contents).
		error ← nullString.
		↑super error: e].
	↑false].
"40" File$'FileDirectory'
[type | |
	↑type].
"1350" File$'Documentation'
[help | |
	 "

A common way to access a File is through a FileStream.
	to create a FileStream on either an old or new file:
		<FileStream> ← <FileDirectory> file: <String>. (see also oldFile: and newFile:)
	e.g. f ← dp0 file: 'test'.

	The default access mode (readwriteshorten) allows you to read or write, and
	automatically shorten a File (to its current position) upon closing).  If you want to
	only read a file, readonly mode is faster and safer.

Some common ways to access a FileStream (see Stream and FileStream):
	reading a character (an Integer between 0 and 255)
		next, 
	reading a String of characters
		upto:	, next:, nextString, contents
	reading other kinds of objects
		nextword, word:, nextNumber:, nextParagraph

	writing characters
		next←, ←
	writing a String of characters
		append:, nextString←
	writing other kinds of objects
		nextword, word:←, print:

	finding position
		position, wordposition, length, end, positionSize:

	changing position (besides reading/writing)
		position←, skip:, skipTo:, reset, settoend, wordposition←, position:size:

When finished with a FileStream, <FileStream> close.

For information about using or creating other views of file organizations (Btree, file-based object dictionaries, Findit), about WFS and Juniper files, and general file problems, see Steve Weyer.
"].
"60" AltoFileDirectory$'Dictionary'
[entryClass | |
	↑AltoFile].
"245" AltoFileDirectory$'FileDirectory'
[allocateSN: file | sn |
	bitsFile position← 8.
	sn ← bitsFile next: 4.
	sn word: 2 ← (sn word: 2) + 1 = 0
	  ifTrue: [sn word: 1 ← (sn word: 1) "overflow" + 1].
	bitsFile skip: 4.
	bitsFile append: sn.
	↑sn].
"993" AltoFileDirectory$'Alto'
[growSmalltalkBy: n | zfpt i file page a zlen |
	i ← 1 "dp0 growSmalltalkBy: 100." "find and read last page of small.boot, then extend file".
	zlen ← 96.
	zfpt ← CoreLocs new base: Vmem specialLocs  7 length: zlen * 2.
	[zfpt  (i + zlen) = 0] whileFalseDo:  [i ← i + 1].
	a ← zfpt  (i + zlen - 1) + (zfpt  i) - (zfpt  (i - 1)) - 1.
	self open.
	file ← self makeEntry: 'small.boot.'.
	page ← file newPage.
	page address: (self virtualToReal: a).
	page doCommand: CRR error: 'cannot read last page. growSmalltalkBy:' "bypass reading file and creating random access table, just extend it".
	page lastPage
	  ifTrue:
		[file serialNumber: page serialNumber.
		file lastPage: page pageNumber.
		file pageAddresses: false "Read:, Write: check this".
		file Get: (page pageNumber: page pageNumber + n).
		user space.
		user print: self freePages.
		user show: ' pages left.']
	  ifFalse: [self error: 'growSmalltalkBy:. last page not last or 2 successive user grows']].
"715" AltoFileDirectory$'FileDirectory'
[realToVirtual: adr | |
	↑(adr lshift: 12) "see virtualToReal:.
	Alto address format is
	bits
	0-3	sector number (0 - 015, i.e. 12 or 14 sectors)
	4-12	cylinder number (0 - 0312, Model 31; 0-0625, Model 44)
	13		head number (0-1)
	14		disk number	(0-1)
	15		restore bit.

	in a system with two separable disks, addresses on disk 1 have a 0 disk bit, which is complemented by the disk primitive" "sector: field" + (nSectors * ((adr land: 4092) "cylinder and head: field*" lshift: 2)) +  "disk: field*pages per disk"
	((adr land: 2) = 2
	  ifTrue: [diskPages]
	  ifFalse: [0]) "diskPages*(adr land: 2)/2" "vadr < 0 or vadr  totalPages [
		self error: 'illegal disk address']"].
"535" AltoFileDirectory$'Alto'
[addEntry: file | entrysize holesize |
	 "called only by Insert: and rename:newName:"
	(holesize ← dirFile nextword)
	  ifTrue:
		[holesize ← holesize land: dfmask - 1 "either a deleted entry or rename entry".
		dirFile skip: 2] "at end".
	entrysize ← self entrySize: file.
	dirFile readwrite.
	dirFile nextword← entrysize + dfmask.
	file storeOn: dirFile.
	(holesize and: [entrysize < holesize])
	  ifTrue: [dirFile nextword← holesize - entrysize "mark remaining hole"].
	dirFile readonly.
	bitsFile flush].
"389" AltoFileDirectory$'Alto'
[deleteEntry: file | p |
	p ← dirFile position "called only by Delete: and rename:newName:
	read and save".
	self nextEntry: file.
	dirFile position← p "delete it from directory (turn off bit in entry length word)".
	p ← dirFile nextword land: dfmask - 1.
	dirFile skip: 2.
	dirFile readwrite.
	dirFile nextword← p.
	dirFile readonly.
	dirFile skip: 2.
	↑file].
"1142" AltoFileDirectory$'FileDirectory'
[rename: file newName: newName | holesize pos |
	(newName ← self checkName: newName)
	  ifTrue:
		[self position← newName
		  ifTrue: [self error: 'new name already exists: ' + newName]
		  ifFalse: [ "a possible insertion place"
			pos ← dirFile position]]
	  ifFalse: [self error: 'illegal new name: ' + newName].
	(self Find: (file ← self makeEntry: file))
	  ifTrue:
		[holesize ← dirFile nextword land: dfmask - 1.
		dirFile skip: 2.
		file name: newName.
		(self entrySize: file) "new size of entry"  holesize
		  ifTrue:
			[pos ← dirFile position "new entry will fit in current entry" "read and save entry".
			self nextEntry: file]
		  ifFalse: [ "delete and save entry"
			self deleteEntry: file] "position to same entry or hole discovered earlier".
		dirFile position← pos.
		self addEntry: (file name: newName).
		(file type is: Integer)
		  ifTrue: [file type: write "file is open. defer leader page change until someone closes it"]
		  ifFalse:
			[ "close file: updating name in leader page"
			file type: write.
			file close]]
	  ifFalse: [file error: 'rename: old name does not exist']].
"826" AltoFileDirectory$'Alto'
[checkName: fname fixing: fixing | x copy special |
	fname empty
	  ifTrue:
		[fixing
		  ifTrue: [↑'$'].
		 "empty name"
		↑false]
	  ifFalse:
		[fname length > 38
		  ifTrue:
			[fixing
			  ifTrue: [fname ← fname  (1 to: 38)]
			  ifFalse: [ "name too long"
				↑false]].
		copy ← (String new: fname length + 1) asStream.
		special ← '.-+$!?'.
		fname do:
			[:x | (x isletter "check characters: alphanumeric or 6 special" or: [((special has: x) or: [x isdigit])])
			  ifTrue: [copy next← x]
			  ifFalse:
				[fixing
				  ifTrue: [copy next← special  2]
				  ifFalse: [ "illegal character"
					↑false]]].
		fixing
		  ifTrue:
			[fname last = (special  1)
			  ifTrue: [copy skip: 1]]
		  ifFalse:
			[fname last  (special  1)
			  ifTrue: [copy next← special  1]].
		↑copy contents]].
"108" AltoFileDirectory$'Alto'
[diskNumber | |
	↑directory "directory is: Integer [" "] directory diskNumber"].
"477" AltoFileDirectory$'Alto'
[deallocate: page | index ch m |
	dirFile  nil
	  ifTrue: [self open].
	index ← self realToVirtual: page address "character position".
	bitsFile position← index / 8 + boffset.
	ch ← bitsFile next "bit position".
	m ← 128 lshift: 0 - (index land: 7) "make page free by turning off bit in DiskDescriptor".
	(ch land: m) = m
	  ifTrue:
		[bitsFile skip: 1.
		bitsFile next← ch - m]
	  ifFalse:
		[user cr.
		user show: 'page already free (dealloc:)']].
"1703" AltoFileDirectory$'Alto'
[allocate: nextPage after: address | index stop ch m vadr |
	index ← false.
	[true] whileTrueDo:
		[ "go around bittable from address to end, and beginning to address.
		we start over again if the table appears full or bitsFile is out of sync"
		(index and: [stop  totalPages])
		  ifTrue:
			[stop ← address "wrap around to where we started".
			index ← 0]
		  ifFalse:
			[index  false
			  ifFalse: [ "first time or bitsFile out of sync" "disk probabbly full"
				user quitThen: '//   YOUR DISK IS FULL - Please make some space available.
//   Then resume Smalltalk and interrupt or continue as desired...'].
			self open "index by bits rather than bytes? close enough for now".
			index ← address land: 8.
			stop ← totalPages].
		bitsFile position← index / 8 + boffset.
		[index and: [(index ← index + 8)  stop]] whileTrueDo:
			[(ch ← bitsFile next) = 255
			  ifFalse:
				[ "8 full" "check that bitsFile position is correct --
				possibly out of sync with index if  growSmalltalkBy: occurred?"
				bitsFile position  (index / 8 + boffset)
				  ifTrue: [index ← false]
				  ifFalse:
					[m ← 128.
					(index - 8 to: index - 1) do:
						[:vadr | (ch land: m) "nomask:" = 0
						  ifTrue:
							[bitsFile skip: 1 "page appears free. first update DiskDescriptor".
							bitsFile next← ch ← ch lor: m "then check if page is really free".
							vadr = 0
							  ifFalse:
								[ "O.S. boot"
								(nextPage init.
								nextPage freePage.
								nextPage address: (self virtualToReal: vadr).
								nextPage doCommand: CCR error: false)
								  ifTrue: [↑vadr] "page not really free"]] "page not free according to bit".
						m ← m lshift: 1]]]]]].
"63" AltoFileDirectory$'Dictionary'
[obsolete | |
	↑dirFile  nil].
"352" AltoFileDirectory$'Alto'
[freePages | npages ch i |
	self open.
	bitsFile position← boffset.
	npages ← 0.
	(1 to: totalPages by: 8) do:
		[:i | (ch ← bitsFile next) = 255
		  ifFalse:
			[ "all used" "possibly up to 8 unused"
			npages ← npages + 8.
			[ch = 0] whileFalseDo: 
				[npages ← npages - (ch land: 1).
				ch ← ch lshift: 1]]].
	↑npages].
"1983" AltoFileDirectory$'Dictionary'
[open | f s a page len elen type |
	nil  dirFile
	  ifFalse:
		[ "assume some defaults in case DSHAPE is not in SysDir leader page.
	these should only be needed if the disk is old (and not scavenged).
	they will not work if a 14 sector system is missing DSHAPE (unlikely) since addresses of first page of directory and of DiskDescriptor might be computed incorrectly.
	in a Smalltalk-76 system, nSectors, diskPages had better eventually match:
		| a. a ← Vmem specialLocs13. mem(a+5), (mem(a+6))
	"
		nSectors ← 12.
		diskPages ← 812 * nSectors.
		totalPages ← 2 * diskPages "read SysDir leader page to find out file system configuration.  see AltoFileSys.D".
		f ← self find: dirname "to prevent address of page 1 from being stored".
		f pageAddresses: false "length of property list, in words".
		page ← f read: 0.
		len ← page  494.
		len  210
		  ifFalse:
			[ "scan file properties for DSHAPE"
			s ← page asStream.
			s skipwords: page  493.
			[len > 0] whileTrueDo:
				[type ← s next.
				type = 0
				  ifTrue: [len ← 0 "0 terminates list.  property not found. try to read if from DiskDescriptor"]
				  ifFalse:
					[elen ← s next.
					(type = 1 and: [elen = 5])
					  ifTrue:
						[self configure: s "DSHAPE. read property" "set flags so configure and loop are not done again".
						s ← false.
						len ← 0]
					  ifFalse:
						[ "skip over other property"
						len ← len - elen.
						s skipwords: elen - 1]]]] "now, with the correct (or default) file system configuration,
	store the virtual address of next page (1), and create a FileStream on SysDir".
		a ← AltoFileAddressTable new.
		a  1 ← page header: nextp.
		f pageAddresses: a.
		(dirFile ← f asStream) readonly.
		(bitsFile ← self oldFile: 'DiskDescriptor') readwrite.
		s
		  ifTrue: [self configure: bitsFile "configuration not read from SysDir. this will work for 12 sector systems.
		14 sector systems should have had the DSHAPE property"].
		super open]].
"257" AltoFileDirectory$'Alto'
[filesMatching: pattern | files v i |
	files ← self match: (pattern last = ('.'  1)
			  ifTrue: [pattern]
			  ifFalse: [pattern + '.']).
	v ← Vector new: files length.
	(1 to: v length) do: [:i | v  i ← (files  i) name].
	↑v].
"72" AltoFileDirectory$'Dictionary'
[release | |
	dirFile ← bitsFile ← nil].
"102" AltoFileDirectory$'Dictionary'
[entrySize: file | |
	↑1 + (file fileSize "entry size in words" / 2)].
"142" AltoFileDirectory$'Dictionary'
[reset | |
	self obsolete
	  ifTrue: [self open]
	  ifFalse: [self flush].
	dirFile readonly.
	dirFile reset].
"127" AltoFileDirectory$'Dictionary'
[Delete: file | t2 |
	(t2 ← self deleteEntry: file) open.
	t2 endFile: false.
	bitsFile flush].
"470" AltoFileDirectory$'Dictionary'
[Insert: file | sn page |
	file serialNumber: (sn ← self allocateSN: file) "allocate a new page (more success after O.S. stuff, bittable etc.)".
	self allocate: (page ← file newPage) after: 800 "write 0th -- leader, in the process filling it in and then creating first page".
	page init.
	page serialNumber: sn.
	page length: page dataLength.
	file leader: page address.
	file type: write.
	file updateLeader: page.
	self addEntry: file].
"88" AltoFileDirectory$'FileDirectory'
[checkName: s | |
	↑self checkName: s fixing: false].
"179" AltoFileDirectory$'Dictionary'
[close | |
	self obsolete
	  ifFalse:
		[dirFile close.
		bitsFile  nil
		  ifFalse: [ "an interrupted open?"
			bitsFile close].
		super close]].
"649" AltoFileDirectory$'Alto'
[stampBoot | a file page |
	a ← Vmem specialLocs "dp0 stampBoot." "update the time stamps in leader page of current boot file" "find SafeId for current boot file"  13.
	file ← self makeEntry: ''.
	file serialNumber: {mem  a , (mem  (a + 1))} "read page one of the boot file to find out the leader address".
	page ← file makeEntry: 1.
	page address: mem  (a + 4) "then set leader address and dirty flag, and close file
		thereby updating create/write/read dates, but not name".
	file doCommand: CCR page: page error: 'cannot read page 1 of boot file'.
	file leader: (page header: backp).
	file type: write.
	file close].
"176" Textframe$'Printing'
[hardcopy | pf |
	user displayoffwhile [
		(pf ← dp0 pressfile: 'frame.press'.
		window hardcopy: pf.
		self hardcopy: pf.
		pf close.
		pf toPrinter)]].
"318" Textframe$'Measuring'
[measureall | starti stopi linei |
	 "Set up lines for text displayer"
	starti ← linei ← 1.
	stopi ← para length.
	[starti > stopi] whileFalseDo: 
		[self line: linei ← self measurefrom: starti to: stopi.
		starti ← (lines  linei) stopi + 1.
		linei ← linei + 1].
	self trimLinesTo: linei - 1].
"1201" Textframe$'Printing'
[hardcopy: pf | first last lasty len parag left right top bottom rect |
	para  nil
	  ifTrue: [self makeParagraph].
	parag ← para asParagraph.
	frame = window
	  ifTrue: [parag presson: pf in: (pf transrect: window) style: style]
	  ifFalse:
		[left ← frame minX max: window minX.
		right ← window maxX min: frame maxX.
		bottom ← window maxY min: frame maxY.
		top ← window minY max: frame minY.
		lasty ← top + 4 "slop for char finding and making print rect larger".
		first ← self charofpoint: left + 1  lasty andrect [:rect | rect].
		len ← parag length.
		(frame minX  left and: [frame maxX  right])
		  ifTrue: [(parag copy: first to: len) "paragraph is inset and may be scrolled" presson: pf in: (pf transrect: (left  top rect: right  (bottom + 4))) style: style]
		  ifFalse: [ "yuk, frame extends left or right so do it a line at a time for clipping"
			[first < len and: [lasty < bottom]] whileTrueDo:
				[last ← (self charofpoint: right - 1  lasty andrect [:rect | rect]) min: len.
				lasty ← lasty + rect height.
				(parag copy: first to: last) presson: pf in: (pf transrect: (left  rect minY rect: right  lasty)) style: style.
				first ← last + 1]]]].
"1054" Textframe$'Measuring'
[measurefrom: starti to: stopi | line chari spacecount rightbits P stopx |
	 "measure and return a line"
	line ← CharLine new starti: starti stopi: stopi spaces: 0 padwidth: 0.
	P ← self printer: false.
	P scanline: line at: 0 stopx: (stopx ← frame maxX) stopchar: stopi.
	chari ← P chari.
	spacecount ← P spacecount.
	(chari = stopi or: [para  chari = cr])
	  ifTrue:
		[ "CR or string end"
		rightbits ← stopx - P rightx.
		spacecount ← 0]
	  ifFalse:
		[spacecount > 0
		  ifTrue:
			[ "Back up to space"
			chari ← P spacei.
			rightbits ← stopx - P spacex.
			(chari > starti and: [para  (chari - 1) = space])
			  ifTrue:
				[spacecount ← spacecount - 1.
				rightbits ← rightbits + P rightx - P leftx]
			  ifFalse:
				[(chari < stopi and: [para  (chari + 1) = space])
				  ifTrue: [chari ← chari + 1]] "double spaces".
			spacecount ← 1 max: spacecount - 1]
		  ifFalse:
			[chari ← chari - 1.
			rightbits ← stopx - P leftx]] "Back 1 char".
	↑line starti: starti stopi: chari spaces: spacecount padwidth: rightbits].
"206" Textframe$'Line management'
[trimLinesTo: last | i |
	(last + 1 to: lastline) do: [:i | lines  i ← nil].
	(lastline ← last) < (lines length / 2)
	  ifTrue: [lines ← lines growby: 0 - (lines length / 2)]].
"49" Textframe$'Access to Parts'
[frame | |
	↑frame].
"117" Textframe$'Displaying'
[clearfrom: y | |
	((frame origin x  y rect: frame corner) intersect: window) clear: white].
"65" Textframe$'Access to Parts'
[lineheight | |
	↑style lineheight].
"255" Textframe$'Measuring'
[maxx: char | i rect maxx |
	self measureall.
	maxx ← 0.
	(1 to: lastline) do:
		[:i | self pointofchar: (lines  i) stopi andrect [:rect | rect].
		rect corner x > maxx
		  ifTrue: [maxx ← rect corner x]].
	↑maxx  rect corner y].
"165" Textframe$'Displaying'
[displayall | liney |
	 "display all the lines in window"
	liney ← self displaylines: 1 to: lastline.
	self clearfrom: liney "self outline"].
"940" Textframe$'Displaying'
[displaylines: startline to: stopline | liney line P lineheight boty leftx |
	 "display a range, windowed"
	lineheight ← style lineheight.
	startline ← startline max: (self lineofy: window minY).
	stopline ← stopline min: (self lineofy: window maxY - lineheight).
	liney ← self yofline: startline.
	boty ← liney + lineheight.
	P ← self printer: true "P should do left and right clearing, since it has clip rect".
	(startline to: stopline) do:
		[:startline | line ← lines  startline.
		para alignment > 1
		  ifTrue:
			[leftx ← frame minX + (para alignment = 4
					  ifTrue: [line padwidth]
					  ifFalse: [line padwidth / 2]).
			(window minX  liney rect: leftx  boty) clear: white].
		P scanline: line at: liney stopx: window maxX stopchar: line stopi.
		(para alignment nomask: 1)
		  ifTrue: [(P rightx  liney rect: window maxX  boty) clear: white].
		liney ← boty.
		boty ← boty + lineheight].
	↑liney].
"67" Textframe$'Displaying'
[erase | |
	(window inset: 2  2) clear].
"96" Textframe$'Displaying'
[put: t1 at: pt | |
	para ← t1.
	self put: para at: pt centered: false].
"4411" Textframe$'Editing'
[replace: starti to: stopi with: insert | i j k startline stopline oldlastline newline range stopped oldlines begini oldy newy moveRect |
	 "cut or paste"
	para replace: starti to: stopi by: insert "do the replacement in the string".
	lastline = 0
	  ifTrue:
		[self measureall.
		self displayall]
	  ifFalse:
		[ "if lines have never been set up,
									measure them and display all the
									lines falling in the window"
		oldlines ← lines copy.
		oldlastline ← lastline.
		i ← startline ← self lineofchar: starti "find the starting and stopping lines".
		stopline ← self lineofchar: stopi.
		range ← insert length - (stopi - starti + 1) "how many characters being
										inserted or deleted" "If the starting line is not also the first line, then measuring must commence from line preceding the one in which starti appears.  For example, deleting a line with only a carriage return may move characters following the deleted portion of text into the line preceding the deleted line.".
		begini ← (lines  i) starti.
		startline > 1
		  ifTrue:
			[newline ← self measurefrom: (lines  (startline - 1)) starti to: para length.
			lines  (startline - 1) = newline
			  ifFalse:
				[ "no backwrap" "start in line preceding that containing the starting character"
				startline ← startline - 1.
				self line: startline ← newline.
				begini ← newline stopi + 1]].
		begini > para length
		  ifTrue:
			[self trimLinesTo: (i - 1 max: 0) "nil lines after cut--remeasure last line below".
			para length = 0
			  ifTrue:
				[ "cut entire paragraph--clear and return"
				window clear: white.
				↑self]].
		stopped ← false.
		j ← stopline.
		[stopped or: [begini > para length]] whileFalseDo: 
			[self line: i ← newline ← self measurefrom: begini to: para length.
			[(j > oldlastline or: [newline stopi "no more old line to compare with" < (stopi ← (oldlines  j) stopi + range)]) or: [stopped]] whileFalseDo: 
				[stopi = newline stopi
				  ifTrue:
					[ "got the match"
					oldy ← self yofline: j +  "get source and destination y's for moving the unchanged lines"
							(range < 0
							  ifTrue: [0]
							  ifFalse: [1]).
					newy ← self yofline: i + (range < 0
							  ifTrue: [0]
							  ifFalse: [1]).
					stopline ← i.
					stopped ← true "fill in the new line vector with the old unchanged lines.
				Update their starting and stopping indices on the way.".
					((j ← j + 1) to: oldlastline) do: [:k | self line: (i ← i + 1) ← oldlines  k slide: range].
					self trimLinesTo: i "trim off obsolete lines, if any"]
				  ifFalse: [j ← j + 1]].
			begini ← newline stopi + 1.
			i ← i + 1 "Now the lines are up to date.  What remains is the move the 'unchanged' lines and display those which have changed."].
		begini > para length
		  ifTrue: [ "If at the end of previous lines simply display lines
						from the line in which the first character of the
						replacement occured through the end of the paragraph."
			self displaylines: startline to: (stopline ← i min: lastline)]
		  ifFalse:
			[ "Otherwise prepare to move the unchanged lines.  moveRect defines the portion of the window containing the lines which may be move en masse." "Deletion -- moving 'up' the screen or ..."
			moveRect ← window minX  (oldy max: window minY) rect: window corner "Insertion -- moving 'down' the screen.
					Shorten moveRect by height of insertion or ...".
			oldy  newy
			  ifTrue: [moveRect corner← window corner + (0  (oldy - newy))]
			  ifFalse:
				[ "Deletion, and top of moveRect will fall above top of window.
		Increase the origin of moveRect by the amount that would fall above
		(hence outside) the window."
				newy < window minY
				  ifTrue: [moveRect origin← window minX  (oldy + window minY - newy)]] "Move it.".
			moveRect blt: window minX  (newy max: window minY) mode: storing "Display the new lines.".
			self displaylines: startline to: stopline "A deletion may have 'pulled' previously undisplayed  lines into the window.
		If so, display them.".
			(newy < oldy and: [(self yofline: oldlastline + 1) > window maxY])
			  ifTrue: [self displaylines: (self lineofy: window maxY - (oldy - newy)) to: (stopline ← self lineofy: window maxY)]] "If we have done a deletion, obsolete material may remain at the bottom of the window.  If so, clear it out.".
		oldlastline  lastline
		  ifTrue: [self clearfrom: (self yofline: lastline + 1)]]].
"219" Textframe$'Line management'
[adjustLines: i by: delta | |
	 "add to indices of charlines beginning with stopi in i"
	lines  i stopi← (lines  i) stopi + delta.
	(i + 1 to: lastline) do: [:i | lines  i slide: delta]].
"175" Textframe$'Line management'
[lineofchar: index | i |
	 "Return line number (may be 0)"
	(1 to: lastline) do:
		[:i | index  (lines  i) stopi
		  ifTrue: [↑i]].
	↑lastline].
"848" Textframe$'Testing'
[Initializations | |
	 "
Smalltalk declare: Undeclared contents from: Undeclared.
Smalltalk declare: (Cream10 STBig TestSet TestStyle TestPara TD TDFlag NoteTaker).

NoteTaker ← false.
(dp0 file: 'Cream10.strike') append: DefaultTextStyle fonts1; close.
TextDisplayer classInit.
Cream10 ← Font new fromStrike: 'Cream10'.
STBig ← Font new fromStrike: 'STBig'.
TestSet ← FontSet init. TestSet  0 ← Cream10. TestSet1 ← STBig.
TestStyle ← StyleSheet new fontset: TestSet.
TestPara ← Paragraph new text:
'again
copy
cut
paste
doit
compile
undo
cancel
align
'.
TestPara text: TestPara text runs: TestPara runs alignment: 0.
TextEditor classInit.
TD ←TDTextImage new.
user schedule: (TD ← TDCodePane new showing: TestPara).

| r. TD frame: (r ← Rectangle new fromuser) window: r para: TestPara style: TestStyle.
TD measureall.
"].
"56" Textframe$'Initialization'
[style: t1 | |
	style ← t1].
"226" Textframe$'Line management'
[line: i ← line | |
	 "store a line, track last, and grow lines if necessary"
	i > lastline
	  ifTrue: [lastline ← i].
	lastline > lines length
	  ifTrue: [lines ← lines grow].
	↑lines  i ← line].
"129" Textframe$'Conversion'
[makeParagraph | |
	para  nil "simulate ListPane for hardcopy"
	  ifTrue: [para ← 'NIL !' asParagraph]].
"39" Textframe$'Image'
[style | |
	↑style].
"460" Menu$'Initialization'
[string: t1 | i pt tpara |
	str ← t1.
	str last  13
	  ifTrue: [str ← str + '
'].
	text ← Textframe new para: (tpara ← str asParagraph) frame: (Rectangle new origin: (pt ← 0  0) corner: 1000  1000).
	pt ← text maxx: str length + 1.
	text frame growto: pt + (4  0).
	text measureall.
	tpara center.
	frame ← text frame inset: 2  2.
	thisline ← Rectangle new origin: text frame origin corner: text frame corner x  text lineheight].
"263" Menu$'Internal'
[movingsetup | pt bits |
	pt ← user mp - thisline center "center prev item on mouse".
	text frame moveby: pt.
	thisline moveby: pt.
	frame moveby: pt.
	bits ← frame bitsIntoString "save background".
	frame clear: black.
	text displayall.
	↑bits].
"61" Menu$'User interactions'
[has: pt | |
	↑text frame has: pt].
"287" Menu$'User interactions'
[wbug | index bits |
	bits ← self movingsetup "save background, display menu" "wait until a mouse button is down".
	[user anybug] whileFalseDo:  [ "get selection (possibly 0)"
		].
	index ← self bugit "restore background".
	frame bitsFromString: bits.
	↑index].
"162" Menu$'Initialization'
[rescan | |
	 " | each. Menu allInstances notNil transform each to each rescan."
	self string: str "rescan (for new fonts, lineheight)"].
"212" Menu$'User interactions'
[bug | index bits |
	bits ← self movingsetup "set up and save background".
	index ← self bugit "get the index".
	frame bitsFromString: bits "restore background".
	↑index "return index"].
"2478" Form$'EDITING'
[edit: parentimage | pt f c file t6 |
	[false] whileFalseDo: 
		[ "Simple Form editor for now." "forever for now"
		pt ← parentimage mp " blink the current brush".
		BlankCursor topage1.
		self blinkbrush: parentimage.
		user redbug
		  ifTrue:
			[(parentimage contains: (pt ← self blinkbrush: parentimage))
			  ifTrue:
				[brush displayat: pt effect: color clippedBy: parentimage rectangle.
				[user redbug] whileTrueDo:
					[brush displayat: (self blinkbrush: parentimage) effect: color clippedBy: parentimage rectangle]]
			  ifFalse:
				[NormalCursor topage1.
				bits ← parentimage rectangle bitsIntoString.
				↑self]]
		  ifFalse:
			[user kbck
			  ifTrue:
				[c ← user kbd.
				c = 120
				  ifTrue:
					[user clearshow: 'x gridding is '.
					parentimage xgrid print.
					user cr.
					parentimage xgrid: (user request: 'x gridding . . . ') asInteger]
				  ifFalse:
					[c = 121
					  ifTrue:
						[user clearshow: 'y gridding is '.
						parentimage ygrid print.
						user cr.
						parentimage ygrid: (user request: 'y gridding . . . ') asInteger]
					  ifFalse:
						[c = 114
						  ifTrue:
							[file ← user request: 'filename of Form . . .'.
							brush ← Form new read: file.
							brush figure: 1.
							brush ground: 0]]]]
			  ifFalse:
				[user yellowbug
				  ifTrue:
					[NormalCursor topage1.
					(t6 ← formmenu bug) = 1
					  ifTrue: [self newbrush: parentimage]
					  ifFalse:
						[ "get a new brush"
						t6 = 2
						  ifTrue:
							[color ← 1]
						  ifFalse:
							[ "set the color of the brush to black"
							t6 = 3
							  ifTrue:
								[color ← 3]
							  ifFalse:
								[ "set the color of the brush to white"
								t6 = 4
								  ifTrue: [self line: parentimage]
								  ifFalse:
									[t6 = 5
									  ifTrue: [self arc: parentimage]
									  ifFalse:
										[t6 = 6
										  ifTrue:
											[self white.
											parentimage display]
										  ifFalse:
											[ "erase the whole form"
											t6 = 7
											  ifTrue: [self resize: parentimage]
											  ifFalse:
												[ "change size"
												t6 = 8
												  ifTrue: [self setfigure: parentimage]
												  ifFalse:
													[t6 = 9
													  ifTrue: [self setground: parentimage]]]]]]]]]]
				  ifFalse:
					[user bluebug
					  ifTrue:
						[bits ← parentimage rectangle bitsIntoString.
						NormalCursor topage1.
						↑self] "exit back to the parentimage"]]]]].
"114" Form$'MODULE ACCESS'
[figure: t1 | |
	figure ← t1 "set the figure ( color assiciated with black) for the form "].
"210" Form$'INIT'
[fromImage: image | |
	self extent: image extent "creates a virtual bit map with width = (image width) and height = (image height) with the bits in image.".
	bits ← image rectangle bitsIntoString].
"180" Form$'INIT'
[fromrectangle: r | |
	self extent: r extent "creates a virtual bit map with width = (r width) and height = (r height) with the bits in r.".
	bits ← r bitsIntoString].
"114" Form$'MODULE ACCESS'
[ground: t1 | |
	ground ← t1 "set the ground ( color assiciated with white) for the form "].
"107" Form$'SYSTEM'
[hidePress: press complete: c | |
	press skipcode: self pressCode data: (self hideData: c)].
"197" Form$'EDITING'
[setfigure: parentimage | |
	figure ← figure + 1 "for now just increment the figure color by 1 \ 14" \ 14.
	self displayat: parentimage origin effect: 0 clippedBy: user screenrect].
"197" Form$'EDITING'
[setground: parentimage | |
	ground ← ground + 1 "for now just increment the ground color by 1 \ 14" \ 14.
	self displayat: parentimage origin effect: 0 clippedBy: user screenrect].
"79" Form$'MODULE ACCESS'
[offset | |
	offset  nil
	  ifTrue: [↑0  0].
	↑offset].
"194" Form$'FILING'
[write: filename | t2 |
	(t2 ← dp0 file: filename "Saves the Form in the format width,height,bits.") nextword← self width.
	t2 nextword← self height.
	t2 append: bits.
	t2 close].
"82" Form$'PATTERN ACCESS'
[bits | |
	↑bits "return the string containing the bits)"].
"142" Form$'INIT'
[halftoneInteger | screen i |
	screen ← 0.
	(1 to: 4) do: [:i | screen ← (screen lshift: 4) lor: (bits  i land: 15)].
	↑screen].
"216" Form$'INIT'
[fromHalftone: halftone | i j line |
	self extent: 16  16.
	(1 to: 4) do:
		[:i | line ← (halftone land: 15) * 4369.
		(0 to: 3) do: [:j | bits  (j * 4 + i) ← line].
		halftone ← halftone lshift: 4]].
"300" Form$'SYSTEM'
[presson: press in: r | hs y |
	(hs ← press scale * self height) > r height
	  ifTrue: [↑self].
	 "not enough room left on current page.
		assume for now that it will at least fit on an entire page"
	press setp: r origin x  (y ← r corner y - hs).
	press bitmap: self bits: bits.
	↑y].
"418" Form$'INIT'
[classInit | |
	black ← 0 - 1 "sets up colors and effects for BITBLT.".
	white ← 0.
	over ← 0.
	under ← 1.
	reverse ← 2.
	brush ← Form new extent: 5  5.
	brush black.
	color ← 1.
	formmenu ← Menu new string: 'brush
black
white
line
arc
erase
size
figure
ground
'.
	dotsetter ← BitBlt new init " a BitBlt for pattern access.".
	dotsetter extent: 1  1.
	aurorarunning ← false.
	aurora ← nil "Aurora new"].
"91" Form$'MODULE ACCESS'
[extent | |
	↑extent "return the extent (widthheight) of the Form"].
"179" Form$'SYSTEM'
[asInstance | s |
	s ← Stream new default.
	s nextPoint← extent.
	s nextPoint← offset.
	s nextword← figure.
	s nextword← ground.
	s nextString← bits.
	↑s contents].
"396" Form$'PATTERN ACCESS'
[black: pt | |
	(0  0 "sets the bit at pt in the  form to black ( to one)"  pt and: [pt  extent])
	  ifTrue:
		[dotsetter dest: (NoteTaker
		  ifTrue: [bits]
		  ifFalse: [bits lock]).
		dotsetter destRaster: extent x + 15 / 16.
		dotsetter destOrigin: pt.
		dotsetter screen: black.
		dotsetter effect: 12.
		dotsetter callBLT.
		NoteTaker
		  ifFalse: [bits unlock]]].
"78" Form$'MODULE ACCESS'
[height | |
	↑extent y "return the height of the Form"].
"90" Form$'MODULE ACCESS'
[offset: t1 | |
	offset ← t1.
	↑self "set the offset of the form "].
"401" Form$'FILING'
[read: filename | f strip w h form stripheight leftoverlines i |
	f ← dp0 oldFile: filename "Reads the Form from the disk in the format width,height,bits.".
	f readonly.
	w ← f nextword.
	h ← f nextword.
	extent ← w  h.
	w * h < 64000
	  ifTrue:
		[bits ← (Form new extent: extent) bits.
		f into: bits.
		f close]
	  ifFalse:
		[f close.
		user notify: 'too many bits to be a Form']].
"196" Form$'INIT'
[extent: t1 | |
	extent ← t1.
	self extent: extent figure: 0 ground: 1 offset: 0  0 "creates a virtual bit map with width = (extent x) and height = (extent y) with the bits all 1."].
"89" Form$'PATTERN ACCESS'
[bits: t1 | |
	bits ← t1 "reset the string containing the bits)"].
"174" Form$'SYSTEM'
[fromInstance: file | |
	extent ← file nextPoint.
	offset ← file nextPoint.
	figure ← file nextword.
	ground ← file nextword.
	bits ← file nextString.
	↑self].
"27" Form$'INIT'
[close | |
	].
"171" Form$'INIT'
[fromuser | r |
	r ← Rectangle new "create a new Form whose rectangle is specified by the user. " fromuser.
	self extent: r extent.
	bits ← r bitsIntoString].
"253" Form$'SYSTEM'
[fromPress: press value: s | nbytes |
	extent ← s nextPoint.
	offset ← s nextPoint.
	figure ← s nextword.
	ground ← s nextword.
	nbytes ← 2 * extent y * (extent x + 15 / 16).
	press data skip: 0 - nbytes.
	bits ← press data next: nbytes].
"248" Form$'INIT'
[fromuserevenword | r |
	r ← Rectangle new "create a new Form whose rectangle is specified by the user,
		truncated to nearest multiple of 16 (for Spruce printing). " fromuserevenword.
	self extent: r extent.
	bits ← r bitsIntoString].
"157" BitBlt$'Operations'
[callBLT | |<primitive: 66>
	(screen is: Form)
	  ifTrue:
		[screen ← screen halftoneInteger.
		self callBLT]
	  ifFalse: [user croak]].
"141" BitBlt$'Setup'
[window: rect | |
	 "this is public"
	NoteTaker
	  ifTrue: [self clipRect: (rect intersect: (0  0 rect: destForm extent))]].
"185" BitBlt$'Setup'
[forCursor | |
	self effect: 0.
	self screen: black.
	dest ← source ← 281.
	width ← height ← 16.
	destRaster ← sourceRaster ← 1.
	destX ← destY ← sourceX ← sourceY ← 0].
"121" BitBlt$'Setup'
[init | |
	self effect: 0.
	self screen: black.
	destX ← destY ← width ← height ← sourceX ← sourceY ← 0].
"1558" BitBlt$'Operations'
[stringReplace: destString with: sourcestring from: start to: stop and: replacement from: rstart to: rstop | slock |
	NoteTaker
	  ifTrue: [↑false].
	 "Works for BitBlt parameters less than 4096. Replaces a subrange of a string.  Called only by String replace:to:by:from:to:.  Concatenates into destString:
		sourcestring(1 to: start - 1)
		replacement(rstart to: rstop)
		sourcestring(stop + 1 to: sourcestring length).
	assumes String arguments"
	destString length = 0
	  ifTrue: [↑destString].
	(replacement is: String)  false
	  ifTrue: [↑false].
	((stop  4096 or: [sourcestring length - stop  4096]) or: [(start + rstop - rstart  4096 or: [rstart > 4096])])
	  ifTrue: [↑false].
	((start < 1 or: [stop > sourcestring length]) or: [(rstart < 1 or: [rstop > replacement length])])
	  ifTrue: [user notify: 'illegal subscript']
	  ifFalse:
		[destRaster ← destY ← sourceRaster ← sourceY ← 0.
		self effect: 0.
		self screen: black.
		height ← 1.
		dest ← destString lock.
		source ← slock ← sourcestring lock.
		width ← start - 1 * 8.
		width = 0
		  ifFalse:
			[sourceX ← destX ← 0.
			self callBLT].
		destX ← width.
		width ← 1 + rstop - rstart * 8.
		width = 0
		  ifFalse:
			[sourceX ← rstart - 1 * 8.
			source ← replacement lock.
			self callBLT.
			replacement unlock].
		destX ← destX + width.
		width ← sourcestring length - stop * 8.
		width = 0
		  ifFalse:
			[source ← slock.
			sourceX ← stop * 8.
			self callBLT].
		destString  1 ← destString  1.
		sourcestring unlock.
		destString unlock.
		↑destString]].
"64" BitBlt$'Setup'
[fromDisplay | |
	self sourceForm: DisplayForm].
"223" BitBlt$'Setup'
[toDisplay | |
	NoteTaker
	  ifTrue:
		[self destForm: DisplayForm.
		source  nil
		  ifTrue: [self sourceForm: DisplayForm]]
	  ifFalse:
		[dest ← mem  54.
		destRaster ← user screenrect width / 32 * 2]].
"197" BitBlt$'Access to Parts'
[effect: anInteger | |
	NoteTaker
	  ifTrue: [effect ← #(35 39 38 36 44 45 41 33 51 55 54 52 19 23 22 20 )  ((anInteger land: 15) + 1)]
	  ifFalse: [effect ← anInteger]].
"56" BitBlt$'Access to Parts'
[height: t1 | |
	height ← t1].
"139" BitBlt$'Access to Parts'
[screen: t1 | |
	screen ← t1.
	(screen is: Form)
	  ifTrue:
		[screenForm ← screen.
		screen ← screenForm bits]].
"56" BitBlt$'Access to Parts'
[source: t1 | |
	source ← t1].
"102" BitBlt$'Access to Parts'
[window | |
	↑clipX  clipY rect: clipX + clipWidth  (clipY + clipHeight)].
"52" BitBlt$'Access to Parts'
[dest: t1 | |
	dest ← t1].
"265" BitBlt$'Operations'
[copyRect: rect toPoint: point effect: eff screen: halftone | |
	self screen: halftone "careful -- assumes dest, destRaster, source and sourceRaster are set!!".
	self effect: eff.
	self destOrigin: point.
	self sourceRect: rect.
	self callBLT].
"1051" BitBlt$'Operations'
[stringCopy: destString from: start to: stop with: replacement from: rstart to: rstop | |
	NoteTaker
	  ifTrue: [↑false].
	 "Copies equal subranges from one string to another.  Works for BitBlt parameters up to 4096. maybe too much set up for short strings.  Currently, called by String copy:to:with:from:to:"
	width ← 1 + stop - start.
	width = 0
	  ifTrue: [↑destString].
	((start > 4096 or: [rstart > 4096]) or: [width  4096])
	  ifTrue: [↑false].
	((width < 0 or: [width  (1 + rstop - rstart)]) or: [((start < 1 or: [stop > destString length]) or: [(rstart < 1 or: [rstop > replacement length])])])
	  ifTrue: [user notify: 'illegal range or subscript']
	  ifFalse:
		[destRaster ← destY ← sourceRaster ← sourceY ← 0.
		self effect: 0.
		self screen: black.
		height ← 1.
		width ← width * 8.
		dest ← destString lock.
		destX ← start - 1 * 8.
		source ← replacement lock.
		sourceX ← rstart - 1 * 8.
		self callBLT.
		replacement unlock "mark dirty".
		destString  1 ← destString  1.
		destString unlock.
		↑destString]].
"83" BitBlt$'Setup'
[classInit | |
	pageOneCursor ← 281 "location of hardware cursor"].
"75" BitBlt$'Setup'
[extent: extent | |
	width ← extent x.
	height ← extent y].
"1010" BitBlt$'Operations'
[bltObj: t1 field: t2 to: last fromObj: t4 field: t5 | |
	 "Dangerous non-refct copy specific to method literals."
	destForm ← t1.
	destY ← t2.
	sourceForm ← t4.
	sourceY ← t5.
	destY < 1
	  ifTrue: [user notify: 'bltObj field spec is 1-origin, like vectors']
	  ifFalse:
		[sourceX ← destX ← clipX ← 0.
		width ← clipWidth ← 16.
		height ← clipHeight ← last - destY + 1.
		clipY ← destY ← destY - 1.
		sourceY ← sourceY - 1 "the bits are 0-origin".
		sourceForm  nil
		  ifTrue:
			[screen ← (NoteTaker
					  ifTrue: [0]
					  ifFalse: [1]).
			self effect: 12]
		  ifFalse:
			[screen ← 0.
			self effect: 0].
		sourceRaster ← destRaster ← 1.
		NoteTaker
		  ifTrue:
			[source ← sourceForm.
			dest ← destForm "word fields".
			self callBLT]
		  ifFalse:
			[dest ← destForm nail.
			sourceForm  nil
			  ifTrue: [source ← dest]
			  ifFalse: [source ← sourceForm nail].
			self callBLT.
			dest ← destForm unNail.
			sourceForm  nil
			  ifFalse: [source ← sourceForm unNail]]]].
"119" BitBlt$'Access to Parts'
[destRaster: t1 | |
	 "length of a 'scanline' destination in 16-bit words"
	destRaster ← t1].
"347" Rectangle$'Conversion'
[bitsFromString: str mode: mode | t3 |
	NoteTaker
	  ifTrue:
		[(t3 ← BitBlt new toDisplay) effect: mode.
		t3 sourceForm: (Form new extent: corner - origin bits: str offset: nil).
		t3 destOrigin: origin.
		t3 sourceRect: (0  0 rect: corner - origin).
		t3 callBLT]
	  ifFalse: [self ALTObitsFromString: str mode: mode]].
"338" Rectangle$'Conversion'
[bitsIntoString: str mode: mode | t3 |
	NoteTaker
	  ifTrue:
		[(t3 ← BitBlt new fromDisplay) effect: mode.
		t3 destForm: (Form new extent: corner - origin bits: str offset: nil).
		t3 destOrigin: 0  0.
		t3 sourceRect: (origin rect: corner).
		t3 callBLT]
	  ifFalse: [self ALTObitsIntoString: str mode: mode]].
"73" Rectangle$'Altering'
[translateto: pt | |
	self translate: pt - origin].
"1160" Rectangle$'Image'
[blowup: at by: scale spacing: spacing | extent z inc sinc slice width height dest i j spread |
	extent ← self extent.
	scale ← scale asPoint.
	spacing ← spacing asPoint.
	dest ← Rectangle new origin: at extent: extent * scale.
	z ← 1  0.
	width ← extent x.
	height ← 0  extent y.
	spread ← (scale - spacing) x.
	(1 to: 2) do:
		[:i |  "first do horiz, then vert"
		inc ← z * 1.
		sinc ← z * scale.
		slice ← Rectangle new origin: z * width + (i = 1
				  ifTrue: [self origin]
				  ifFalse: [at]) extent: z + height.
		dest ← at + (z * (scale * width)).
		(1 to: width) do:
			[:j |  "slice it up"
			dest ← dest - sinc.
			slice moveby: inc.
			slice blt: dest mode: storing].
		slice ← Rectangle new origin: at + z extent: height + (z * (scale - 1)).
		(1 to: width) do:
			[:j |  "clear slice source"
			slice clear: white.
			slice moveby: sinc].
		slice ← Rectangle new origin: at extent: height + (z * (scale * width - 1)).
		(1 to: spread - 1) do: [:j |  "spread it out"
			slice blt: at + z mode: oring].
		z ← 0  1 "flip to do vertical".
		width ← extent y.
		height ← (scale * extent) x  0.
		spread ← (scale - spacing) y]].
"1136" Rectangle$'Conversion'
[bitsFromString: bitmap mode: mode clippedBy: clipRect | destRect t5 t6 |
	NoteTaker
	  ifTrue:
		[ "Load the screen bits within my area from those stored in bitmap.  If clipRect is not nil, then load only those bits within both  myself and clipRect"
		(t5 ← BitBlt new toDisplay window: clipRect) effect: mode.
		t5 sourceForm: (Form new extent: corner - origin bits: bitmap offset: nil).
		t5 destOrigin: origin.
		t5 sourceRect: (0  0 rect: corner - origin).
		t5 callBLT]
	  ifFalse:
		[self bitmapLength  bitmap length
		  ifTrue: [user notify: 'wrong bitmap length']
		  ifFalse:
			[destRect ← self intersect: user screenrect.
			nil  clipRect
			  ifFalse: [destRect ← destRect intersect: clipRect].
			(t6 ← BitBlt init) dest: mem  54.
			t6 destRaster← user screenrect width / 16 | 2.
			t6 destOrigin: destRect origin.
			t6 sourceRaster: corner x - origin x + 15 / 16.
			t6 sourceRect: (destRect origin - origin rect: destRect origin - origin + destRect extent).
			t6 source: bitmap lock.
			t6 effect: 16 + (mode land: 3) "dest in bank 1, source in bank 0".
			t6 callBLT.
			bitmap unlock]]].
"1181" Rectangle$'Conversion'
[bitsIntoString: bitmap mode: mode clippedBy: clipRect | sourceRect t5 t6 |
	NoteTaker
	  ifTrue:
		[ "Store the screen bits within my area into bitmap.  If clipRect is not nil,
		then store only those bits within both myself and clipRect,
		leaving alone the other bits in bitmap"
		(t5 ← BitBlt new fromDisplay window: clipRect) effect: mode.
		t5 destForm: (Form new extent: corner - origin bits: bitmap offset: nil).
		t5 destOrigin: 0  0.
		t5 sourceRect: (origin rect: corner).
		t5 callBLT]
	  ifFalse:
		[self bitmapLength  bitmap length
		  ifTrue: [user notify: 'wrong bitmap length']
		  ifFalse:
			[sourceRect ← self intersect: user screenrect.
			clipRect  nil
			  ifFalse: [sourceRect ← sourceRect intersect: clipRect].
			(t6 ← BitBlt init) destRaster: corner x - origin x + 15 / 16.
			t6 destOrigin: sourceRect origin - origin.
			t6 sourceRect: (sourceRect origin - origin rect: sourceRect origin - origin + sourceRect extent).
			t6 source: mem  54.
			t6 sourceRaster: user screenrect width / 16 | 2.
			t6 dest: bitmap lock.
			t6 effect: 32 + (mode land: 3) "dest in bank 0, source in bank 1".
			t6 callBLT.
			bitmap unlock]]].
"1020" Rectangle$'Image'
[blt: dest mode: mode clippedBy: clipRect | destRect clippedSource t6 t7 |
	NoteTaker
	  ifTrue:
		[ "Copy the screen bits within my area to the rectangle whose
		origin is dest and whose extent is the same as mine.
		If clipRect is not nil, then copy only those bits within both
		the destination rectangle and clipRect"
		(t6 ← DisplayBLTer copy) window: clipRect.
		t6 copyRect: self toPoint: dest effect: (mode land: 3) screen: 0]
	  ifFalse:
		[destRect ← (Rectangle new origin: dest extent: self extent) intersect: user screenrect.
		nil  clipRect
		  ifFalse: [destRect ← destRect intersect: clipRect] "find the source for the bits after clipping".
		clippedSource ← origin + destRect origin - dest.
		(t7 ← BitBlt init toDisplay) destOrigin: destRect origin.
		t7 source: mem  54.
		t7 sourceRaster: user screenrect width / 16 | 2.
		t7 sourceRect: (clippedSource rect: clippedSource + destRect extent).
		t7 effect: 48 + (mode land: 3) "source and dest in bank 1 (display)".
		t7 callBLT]].
"1110" Rectangle$'Image'
[brush: dest mode: mode color: color clippedBy: clipRect | destRect clippedSource t7 t8 |
	NoteTaker
	  ifTrue:
		[ "Brush the screen bits within my area to the rectangle whose
		origin is dest and whose extent is the same as mine.
		If clipRect is not nil, then brush only those bits within both
		the destination rectangle and clipRect"
		(t7 ← DisplayBLTer copy) window: clipRect.
		t7 copyRect: self toPoint: dest effect: 8 + (mode land: 3) screen: color]
	  ifFalse:
		[destRect ← (Rectangle new origin: dest extent: self extent) intersect: user screenrect.
		nil  clipRect
		  ifFalse: [destRect ← destRect intersect: clipRect] "find the source for the bits after clipping".
		clippedSource ← origin + destRect origin - dest.
		(t8 ← BitBlt init) screen: color.
		t8 dest: mem  54.
		t8 destRaster: user screenrect width / 16 | 2.
		t8 destOrigin: destRect origin.
		t8 source: mem  54.
		t8 sourceRaster: user screenrect width / 16 | 2.
		t8 sourceRect: (clippedSource rect: clippedSource + destRect extent).
		t8 effect: 8 + (mode land: 3) + 48 "paint on display".
		t8 callBLT]].
"47" Rectangle$'Aspects'
[leftside | |
	↑origin x].
"42" Rectangle$'Aspects'
[top | |
	↑origin y].
"54" Turtle$'As yet unclassified'
[pen: t1 | |
	pen ← t1].
"58" Turtle$'As yet unclassified'
[width: w | |
	self pen: w].
"66" Turtle$'As yet unclassified'
[home | |
	location ← frame center].
"69" Turtle$'As yet unclassified'
[color: color | |
	self screen: color].
"61" Turtle$'As yet unclassified'
[place: t1 | |
	location ← t1].
"807" Turtle$'As yet unclassified'
[drawLoopX: xDelta Y: yDelta | dx dy px py P i |<primitive: 77>
	 "This is the Bresenham plotting algorithm (IBM Systems Journal Vol 4 No. 1, 1965).
	It chooses a principal direction, and maintains a potential, P.
	When P's sign changes, it is time to move in the minor direction as well."
	dx ← xDelta sign.
	dy ← yDelta sign.
	px ← yDelta abs.
	py ← xDelta abs.
	super callBLT "first point".
	py > px
	  ifTrue:
		[ "more horizontal"
		P ← py / 2.
		(1 to: py) do:
			[:i | destX ← destX + dx.
			(P ← P - px) < 0
			  ifTrue:
				[destY ← destY + dy.
				P ← P + py].
			super callBLT]]
	  ifFalse:
		[ "more vertical"
		P ← px / 2.
		(1 to: px) do:
			[:i | destY ← destY + dy.
			(P ← P - py) < 0
			  ifTrue:
				[destX ← destX + dx.
				P ← P + px].
			super callBLT]]].
"62" Turtle$'As yet unclassified'
[black | |
	self screen: black].
"50" Turtle$'As yet unclassified'
[width | |
	↑width].
"69" Turtle$'As yet unclassified'
[erase | |
	super window clear: white].
"107" Turtle$'As yet unclassified'
[go: dist | |
	self goto: direction asRadians asDirection * dist + location].
"58" Turtle$'As yet unclassified'
[up | |
	direction ← 270.0].
"58" Turtle$'As yet unclassified'
[pendn | |
	penDown ← true].
"59" Turtle$'As yet unclassified'
[penup | |
	penDown ← false].
"134" Turtle$'As yet unclassified'
[goto: p | old |
	old ← location.
	location ← p.
	penDown
	  ifTrue: [self drawfrom: old to: location]].
"83" Turtle$'As yet unclassified'
[turn: degrees | |
	direction ← direction + degrees].
"60" Turtle$'As yet unclassified'
[inking: t1 | |
	inking ← t1].
"58" Turtle$'As yet unclassified'
[frame: t1 | |
	frame ← t1].
"357" Turtle$'As yet unclassified'
[init | |
	source ← sourceRaster ← (NoteTaker
					  ifFalse: [0]).
	super init.
	super toDisplay.
	frame ← user screenrect.
	self pendn.
	self color: black.
	self width: 1.
	self inking: storing.
	self home.
	self up " | n i [n←Turtle init. n color: gray; width: 4; inking: oring.
	 for i to: 50 do [n go: i*4; turn: 89]]"].
"50" Turtle$'As yet unclassified'
[frame | |
	↑frame].
"62" Turtle$'As yet unclassified'
[white | |
	self screen: white].
"648" Turtle$'As yet unclassified'
[drawfrom: p1 to: p2 | offset delta dx dy px py P i |
	(pen is: Integer)
	  ifTrue:
		[self effect: 16 + 12 + (inking land: 3).
		width ← height ← pen.
		offset ← pen / 2  (pen / 2)]
	  ifFalse:
		[(pen is: Form)
		  ifTrue:
			[self effect: 16 + (inking land: 3).
			super sourceForm: pen.
			width ← pen width.
			height ← pen height.
			offset ← pen offset]
		  ifFalse: [user notify: 'pen must be a Form or Integer']].
	destX ← (p1 x - offset x) asInteger.
	destY ← (p1 y - offset y) asInteger.
	self drawLoopX: (p2 x - p1 x) asInteger Y: (p2 y - p1 y) asInteger.
	(pen is: Form)
	  ifTrue: [super release: pen]].
"860" Rectangle$'Image'
[fillin: color mode: mode | T bits p s dirs i which |
	 "Rectangle new fromuser fillin: gray"
	T ← Turtle init.
	p ← origin + (self width  0).
	s ← Rectangle new origin: p extent: self extent.
	dirs ← {1  0 , (1  0) , (0  1) , (0  1)}.
	bits ← s bitsIntoString.
	self blt: p mode: storing "s ← self".
	user waitbug.
	T place: user mp.
	T pendn.
	[user anybug] whileTrueDo: [ "draw seed in self"
		T goto: user mp].
	self blt: p mode: xoring "s ← seed only".
	s blt: origin mode: xoring "take seed out of self".
	user waitbug.
	[user anybug] whileTrueDo: [(0 to: 2 by: 2) do:
			[:which | (1 to: 2) "smear seed around" do: [:i | s blt: dirs  (which + i) + p mode: oring].
			self blt: p mode: erasing]].
	s brush: origin mode: mode color: color "then clip to outline" "paint it in".
	s bitsFromString: bits "restore background to s"].
"113" InspectWindow$'Initialization'
[classInit | |
	stdTemplates ← {(0  0 rect: 12  36) , (12  0 rect: 36  36)}].
"152" VariablePane$'Notify/Inspect protocol'
[execute: parseStream for: t2 | |
	valuePane ← t2.
	↑valuePane execute: parseStream in: context to: values  1].
"182" VariablePane$'Window protocol'
[yellowbug | |
	selection = 0
	  ifTrue: [window flash]
	  ifFalse: [scrollBar hidewhile [
			(varmenu bug = 1
			  ifTrue: [self value inspect])]]].
"85" VariablePane$'Initialization'
[classInit | |
	varmenu ← Menu new string: 'inspect'].
"118" VariablePane$'Private'
[value | |
	selection = 1
	  ifTrue: [↑values  1].
	↑values  2 inspectfield: selection - 1].
"112" VariablePane$'Initialization'
[names: vars values: t2 wrt: t3 | |
	values ← t2.
	context ← t3.
	self of: vars].
"60" VariablePane$'Initialization'
[to: t1 | |
	valuePane ← t1].
"89" VariablePane$'ListPane protocol'
[selected | |
	valuePane showing: self value asString].
"84" VariablePane$'Notify/Inspect protocol'
[compile: parag | |
	window flash.
	↑false].
"74" VariablePane$'ListPane protocol'
[deselected | |
	valuePane showing: ''].
"987" ListPane$'Private'
[scrollUp: amount | linetomove |
	self compselection.
	amount ← amount | style lineheight.
	linetomove ← (self lineofy: window minY + amount "abs") max: 1.
	amount > 0
	  ifTrue:
		[lastline = lastShown
		  ifFalse:
			[self locked
			  ifTrue:
				[selection + 1 = firstShown
				  ifTrue: [window flash]
				  ifFalse: [self firstShown: (linetomove min: selection + 1)]]
			  ifFalse: [self firstShown: (linetomove min: lastline - (window height / style lineheight) + 1)]]]
	  ifFalse:
		[firstShown = 1
		  ifFalse:
			[self locked
			  ifTrue:
				[selection + 1 = lastShown
				  ifTrue: [window flash]
				  ifFalse: [self lastShown: (lastShown - (firstShown - linetomove) max: selection + 1)]]
			  ifFalse:
				[.
				self lastShown: (lastShown - (firstShown - linetomove) max: (lastline min: window height / style lineheight))]]].
	(window origin x  ((self yofline: lastline) + style lineheight) rect: window corner) clear: white.
	↑self select: selection].
"658" ListPane$'Private'
[fill | |
	firstShown  nil
	  ifTrue: [self makeParagraph]
	  ifFalse: [lastShown ← self lineofy: window maxY - (style lineheight - 1)].
	(self locked or: [selection > 0])
	  ifTrue:
		[selection < firstShown
		  ifTrue: [frame origin y← window minY - (selection * style lineheight) + style lineheight]
		  ifFalse:
			[selection > lastShown
			  ifTrue: [frame origin y← window minY - (selection * style lineheight + style lineheight) + (window maxY - window minY | style lineheight) min: window minY]]].
	firstShown ← self lineofy: window minY + (style lineheight - 1).
	lastShown ← self lineofy: window maxY - (style lineheight - 1)].
"116" ListPane$'Subclass defaults'
[deselected | |
	 "I just lost my selection.  I dont care, but my subclasses might."].
"56" ListPane$'Pane protocol'
[yellowbug | |
	window flash].
"223" ListPane$'Initialization'
[of: t1 | |
	 "Acquire the specified list and show me scrolled to the top"
	list ← t1.
	selection ← 0.
	self makeParagraph.
	self frame← window.
	self outline.
	self displayall.
	self deselected].
"58" ListPane$'Private'
[init | |
	self para: nil frame: nil].
"119" ListPane$'Subclass defaults'
[selected | |
	 "A new selection is highlighted.  I dont care, but my subclasses might"].
"261" ListPane$'Pane protocol'
[frame← t1 | |
	 "(Re)initialize my window"
	window ← t1.
	(frame ← window inset: 2  0 and: [0  0]) width← 999.
	self fill.
	scrollBar ← (scrollBar  nil
			  ifTrue: [ScrollBar new]
			  ifFalse: [scrollBar]) on: window from: self].
"61" ListPane$'Pane protocol'
[kbd | |
	window flash.
	user kbd].
"361" ListPane$'Pane protocol'
[eachtime | |
	(window has: user mp)
	  ifTrue:
		[user kbck
		  ifTrue: [↑self kbd].
		user anybug
		  ifTrue:
			[user redbug
			  ifTrue: [↑self redbug].
			user yellowbug
			  ifTrue: [↑self yellowbug].
			user bluebug
			  ifTrue: [↑false]]
		  ifFalse:
			[user anykeys
			  ifTrue: [↑self keyset]]]
	  ifFalse: [↑self outside]].
"882" ListPane$'Pane protocol'
[hardcopy: pf | t cr first last lasty lineNum parag left right lineheight |
	window hardcopy: pf thickness: 1.
	para  nil
	  ifTrue: [self makeParagraph].
	parag ← para asParagraph.
	t ← para asStream.
	last ← 0.
	cr ← 13.
	left ← frame minX.
	right ← window maxX.
	lasty ← frame minY.
	lineheight ← self lineheight.
	(firstShown to: lastShown) do:
		[:lineNum | first ← last.
		((t skipTo: cr) or: [lineNum = lastShown])
		  ifTrue: [last ← t position]
		  ifFalse: [user notify: 'not enough lines'].
		(lineNum = selection and: [selection > 0])
		  ifTrue: [(self selectionRect "outline selection; complementing doesn't look good" - (0  1) inset: 0  1) hardcopy: pf thickness: 1].
		(parag copy: first + 1 to: last - 1) presson: pf in: (pf transrect: (left  lasty rect: right  (lasty + lineheight + 4))) style: style.
		lasty ← lasty + lineheight]].
"453" ListPane$'Pane protocol'
[keyset | c t2 |
	c ← user currentCursor "As long as any keyset keys are down, react to keys 2 and 8 down by scrolling up or down a line at a time.  If key 4 is down as well, scroll faster.".
	self scrollControl [
		((t2 ← user keyset) = 6
		  ifTrue: [2]
		  ifFalse:
			[t2 = 12
			  ifTrue: [2]
			  ifFalse:
				[t2 = 2
				  ifTrue: [1]
				  ifFalse:
					[t2 = 8
					  ifTrue: [1]
					  ifFalse: [0]]]])].
	c show].
"53" ListPane$'Pane protocol'
[lasttime | |
	self leave].
"54" ListPane$'Pane protocol'
[leave | |
	scrollBar hide].
"61" ListPane$'Pane protocol'
[picked | |
	↑window has: user mp].
"444" ListPane$'Pane protocol'
[redbug | newSel f |
	 "Deselect selection and select cursor item, if any"
	(f ← self locked)
	  ifFalse:
		[self compselection.
		newSel ← ((self lineofy: user mp y) max: 1) - 1.
		XeqCursor showwhile [(self select: (newSel = selection
			  ifTrue: [0]
			  ifFalse: [newSel]))]].
	[user redbug and: [(window has: user mp)]] whileTrueDo:
		[f
		  ifTrue:
			[f flash.
			self compselection.
			self compselection]]].
"164" ListPane$'Subclass defaults'
[locked | |
	 "My subclasses may want to prohibit a change of selection"
	↑selection = 0
	  ifTrue: [false]
	  ifFalse: [self dirty]].
"82" ListPane$'Private'
[displayall | |
	self displaylines: firstShown to: lastShown].
"54" ListPane$'Pane protocol'
[enter | |
	scrollBar show].
"111" ListPane$'Subclass defaults'
[dirty | |
	 "My subclasses may want to prohibit a change of selection"
	↑false].
"44" ListPane$'Private'
[dummy | |
	↑''].
"496" ListPane$'Initialization'
[revise: newlist with: sel | changing |
	 "Acquire newlist. Do not change firstShown. Select sel if in list."
	(changing ← list  newlist)
	  ifTrue:
		[list ← newlist.
		window clear: white.
		self makeParagraph.
		self fill.
		self displayall]
	  ifFalse:
		[selection > 0
		  ifTrue:
			[(changing ← list  selection  sel)
			  ifTrue: [self compselection]]
		  ifFalse: [changing ← true]].
	changing
	  ifTrue:
		[selection ← 1.
		self select: (list find: sel)]].
"581" ListPane$'Initialization'
[select: lineNum | oldSel |
	oldSel ← selection "Select my non-dummy displayed entry whose subscript is lineNum; highlight it; if it is different from selection, tell me to select.  If there is no such entry, set selection to 0 and if it wasnt 0 before, tell me to deselect.".
	((1 max: firstShown - 1)  lineNum and: [lineNum  (list length min: lastShown - 1)])
	  ifTrue:
		[selection ← lineNum.
		self compselection.
		oldSel  selection
		  ifTrue: [self selected]]
	  ifFalse:
		[selection ← 0.
		oldSel  selection
		  ifTrue: [self deselected]]].
"60" ListPane$'Pane protocol'
[outside | |
	↑scrollBar startup].
"143" ListPane$'Pane protocol'
[close | |
	 "Zero my selection so it wont be grayed when I close.  Break cycles."
	selection ← 0.
	scrollBar close].
"110" ListPane$'Pane protocol'
[firsttime | |
	(window has: user mp)
	  ifTrue: [self enter]
	  ifFalse: [↑false]].
"163" ListPane$'Pane protocol'
[scrollPos | |
	((firstShown  nil or: [list  nil]) or: [list length = 0])
	  ifTrue: [↑0.0].
	↑(firstShown - 1) asFloat / list length].
"140" ListPane$'Pane protocol'
[windowenter | |
	 "Refresh my image.  Reaffirm selection."
	self outline.
	self displayall.
	self compselection].
"85" ListPane$'Pane protocol'
[windowleave | |
	self compselection.
	self grayselection].
"141" ListPane$'Private'
[compselection | |
	 "If I have a selection, complement its image."
	selection  0
	  ifTrue: [self selectionRect comp]].
"258" ListPane$'Private'
[selectionRect | newy |
	↑(Rectangle new "I have a selection.  Return its highlighting rectangle." origin: frame minX  (newy ← selection * style lineheight + frame minY) corner: frame maxX  (newy + style lineheight)) intersect: window].
"371" ListPane$'Private'
[firstShown: new | delta deltaPt |
	delta ← new - firstShown.
	deltaPt ← 0  (0 - delta * style lineheight) "negative".
	firstShown ← new.
	lastShown ← lastShown + delta.
	frame moveby: deltaPt.
	(window origin - deltaPt rect: window corner) blt: window origin mode: storing.
	self displaylines: (firstShown max: lastShown - delta + 1) to: lastShown].
"130" ListPane$'Pane protocol'
[scrollTo: f | place y |
	↑self scrollUp: (f * lastline) asInteger - firstShown + 1 * style lineheight].
"113" ListPane$'Private'
[grayselection | |
	selection  0
	  ifTrue: [self selectionRect color: ltgray mode: oring]].
"454" ListPane$'Private'
[lastShown: new | delta deltaPt |
	delta ← new - lastShown "negative".
	deltaPt ← 0  (0 - delta * style lineheight) "positive".
	lastShown ← new.
	firstShown ← firstShown + delta.
	frame moveby: deltaPt.
	(Rectangle new origin: window origin extent: window width  (window height - deltaPt y | style lineheight)) blt: window origin + deltaPt mode: storing.
	self displaylines: firstShown to: (firstShown - delta - 1 min: lastShown)].
"59" ListPane$'Pane protocol'
[outline | |
	window outline: 1].
"565" ListPane$'Private'
[makeParagraph | i len s |
	 "Given firstShown, compute lastShown."
	firstShown  nil
	  ifTrue:
		[firstShown ← 1.
		selection ← 0].
	s ← (String new: 200) asStream.
	s append: self dummy.
	s cr.
	list  nil
	  ifFalse: [(1 to: list length) do:
			[:i | list  i printon: s.
			s cr]].
	s append: self dummy.
	s cr.
	para ← s contents asParagraph.
	self measureall.
	lastShown ← self lineofy: window maxY - (style lineheight - 1).
	frame corner y← (self yofline: lastline) + style lineheight.
	selection > lastShown
	  ifTrue: [selection ← 0]].
"501" InspectWindow$'Initialization'
[of: object | instanceVarPane instanceValuePane safeVec n |
	instanceVarPane ← VariablePane new.
	instanceValuePane ← CodePane new.
	self title: object class title with: {instanceVarPane , instanceValuePane} at: stdTemplates.
	self newframe.
	self show.
	instanceVarPane to: instanceValuePane.
	instanceValuePane from: instanceVarPane.
	safeVec ← Vector new: 2.
	safeVec all← object.
	instanceVarPane names: (#(self ) concat: object fields) values: safeVec wrt: false].
"83" InspectWindow$'Private'
[contents | |
	 "called by of: via Class fieldNamesInto"].
"85" InspectWindow$'Private'
[comment: s | |
	 "called by of: via Class fieldNamesInto"].
"85" InspectWindow$'Private'
[trailer: s | |
	 "called by of: via Class fieldNamesInto"].
"107" InspectWindow$'Private'
[identifier: s | |
	 "called by of: via Class fieldNamesInto"
	variables next← s].
"87" InspectWindow$'Private'
[separator: c | |
	 "called by of: via Class fieldNamesInto"].
"178" Object$'Aspects'
[inspect | |
	NoteTaker
	  ifTrue: [user schedule: (InspectWindow new of: self)]
	  ifFalse:
		[user leaveTop.
		user restartup: (InspectWindow new of: self)]].
"48" Object$'Classification'
[isNumber | |
	↑false].
"156" Object$'System Primitives'
[startup | |
	 "loopless scheduling"
	self firsttime
	  ifTrue:
		[[self eachtime] whileTrueDo: [].
		↑self lasttime].
	↑false].
"58" Object$'Comparison'
[sameAs: object | |
	↑self  object].
"136" Object$'Construction'
[inVector | vec |
	vec ← Vector new: 1 "Return me as the sole element of a new Vector.".
	vec  1 ← self.
	↑vec].
"50" Object$'Compiler Defaults'
[returns | |
	↑false].
"111" Object$'Printing'
[asString | strm |
	strm ← (String new: 16) asStream.
	self printon: strm.
	↑strm contents].
"150" Object$'System Primitives'
[swap variable | x |
	 "assign me to variable and return its old value"
	x ← variable value.
	variable value← self.
	↑x].
"146" Object$'System Primitives'
[perform: message | |
	 "Send an arbitrary message to self"
	message mustTake: 0.
	↑self performDangerously: message].
"67" Object$'System Primitives'
[refct | |<primitive: 34>
	user croak].
"50" Object$'Compiler Defaults'
[isField | |
	↑false].
"62" Object$'Classification'
[Isnt: x | |
	↑(self Is: x)  false].
"51" Object$'Comparison'
[empty | |
	↑self length = 0].
"121" Object$'System Primitives'
[doesNotUnderstand: message | |
	user notify: 'Message not understood: ' + message selector].
"77" Object$'System Primitives'
[execute: method | |<primitive: 78>
	user croak].
"99" Object$'System Primitives'
[execute: method with: arg1 with: arg2 | |<primitive: 78>
	user croak].
"388" Object$'System Primitives'
[execute: method withArgs: vec | t3 |
	(t3 ← vec length) = 0
	  ifTrue: [↑self execute: method].
	t3 = 1
	  ifTrue: [↑self execute: method with: vec  1].
	t3 = 2
	  ifTrue: [↑self execute: method with: vec  1 with: vec  2].
	t3 = 3
	  ifTrue: [↑self execute: method with: vec  1 with: vec  2 with: vec  3].
	user notify: 'More than 3 args for execute:'].
"110" Object$'System Primitives'
[execute: method with: arg1 with: arg2 with: arg3 | |<primitive: 78>
	user croak].
"52" Object$'As yet unclassified'
[comment: cccc | |
	].
"117" Object$'As yet unclassified'
[Altonail | |<primitive: 75>
	user croak "Nail me in core and return my core address"].
"69" Object$'Construction'
[asParagraph | |
	↑self asString asParagraph].
"115" Object$'Printing'
[fullprint | strm |
	strm ← Stream default.
	self fullprinton: strm.
	user show: strm contents].
"441" Object$'Aspects'
[instfields | field |
	self class "Return an Array of all my field values or many of my elements." isVariable
	  ifTrue: [↑(1 ~ self class instsize transform [:field | field] to [(self instfield: field)]) concat: self  (self length  50
		  ifTrue: [1 ~ self length]
		  ifFalse: [1 ~ 20 concat: (self length - 20 to: self length)])].
	↑1 ~ self class instsize transform [:field | field] to [(self instfield: field)]].
"271" Object$'Aspects'
[inspectfield: n | fixedSize |
	 "used by variable panes"
	self class isVariable
	  ifTrue:
		[fixedSize ← self class instsize.
		n > fixedSize
		  ifTrue: [↑self  (self fields  n - fixedSize)].
		↑self instfield: n]
	  ifFalse: [↑self instfield: n]].
"62" Object$'Compiler Defaults'
[sizeForEffect: nextPush | |
	↑0].
"70" Object$'Aspects'
[instfield: n ← val | |<primitive: 38>
	user croak].
"184" Object$'System Primitives'
[perform: selector with: arg1 | |
	 "Send the 1-argument message, selector, to self"
	selector mustTake: 1.
	↑self performDangerously: selector with: arg1].
"88" Object$'Compiler Defaults'
[asRemoteCode: generator | |
	↑ParsedRemote new expr: self].
"52" Object$'Compiler Defaults'
[emitsLoad | |
	↑false].
"58" Object$'Compiler Defaults'
[emittedReceiver | |
	↑false].
"58" Object$'Compiler Defaults'
[emittedVariable | |
	↑false].
"54" Object$'Compiler Defaults'
[interactive | |
	↑false].
"264" Object$'Printing'
[fullprinton: strm | |
	self  nil
	  ifTrue: [strm append: 'nil']
	  ifFalse:
		[self  false
		  ifTrue: [strm append: 'false']
		  ifFalse:
			[self  true
			  ifTrue: [strm append: 'true']
			  ifFalse: [self class print: self on: strm]]]].
"276" Object$'System Primitives'
[installError | code old |
	code ← Object md method: #error.
	old ← SpecialOops  1.
	old asOop  (mem  3)
	  ifTrue: [user notify: 'Object installError failed']
	  ifFalse: [Top critical [
			(mem  3 ← code asOop.
			SpecialOops  1 ← code)]]].
"119" Object$'Printing'
[asFullString | strm |
	strm ← (String new: 20) asStream.
	self fullprinton: strm.
	↑strm contents].
"105" Object$'As yet unclassified'
[AltounNail | |<primitive: 75>
	user croak "Release me from being nailed"].
"84" Object$'As yet unclassified'
[printon: strm indent: level | |
	self printon: strm].
"84" Object$'Compiler Defaults'
[findMacros: macros compilerTemps: compilerTemps | |
	].
"49" Object$'As yet unclassified'
[comment | |
	↑''].
"86" Object$'Construction'
[, x | v |
	v ← Vector new: 2.
	v  1 ← self.
	v  2 ← x.
	↑v].
"42" Object$'Comparison'
[= x | |
	↑self  x].
"50" Object$'Comparison'
[ x | |
	↑self > x  false].
"167" Object$'Compiler Defaults'
[ code | |
	↑(NoteTaker
	  ifTrue: [LADCompiler]
	  ifFalse: [Generator]) new evaluate: code asStream in: false to: self notifying: self].
"50" Object$'Comparison'
[ x | |
	↑self < x  false].
"50" Object$'Comparison'
[ x | |
	↑self = x  false].
"142" Object$'Classification'
[Is: x | |
	 "Is the class x a superclass or class of self"
	self class  x
	  ifTrue: [↑true].
	↑self class Isa: x].
"95" Object$'Comparison'
[ x | |<primitive: 78>
	↑self  x "In case this is reached by perform:"].
"55" Object$'System Primitives'
[PTR | |<primitive: 39>
	].
"54" Object$'Classification'
[is: x | |
	↑self class  x].
"114" Object$'System Primitives'
[unNail | |
	NoteTaker
	  ifFalse: [↑self AltounNail] "Release me from being nailed"].
"150" Object$'System Primitives'
[performDangerously: selector | |<primitive: 36>
	 "Send self the message, selector; it had better be unary"
	user croak].
"206" Object$'System Primitives'
[perform: selector with: arg1 with: arg2 | |
	 "Send the 2-argument message, selector, to self"
	selector mustTake: 2.
	↑self performDangerously: selector with: arg1 with: arg2].
"228" Object$'System Primitives'
[perform: selector with: arg1 with: arg2 with: arg3 | |
	 "Send the 3-argument message, selector, to self"
	selector mustTake: 3.
	↑self performDangerously: selector with: arg1 with: arg2 with: arg3].
"136" Object$'System Primitives'
[performDangerously: selector with: arg1 | |<primitive: 36>
	 "selector had better take 1 arg"
	user croak].
"148" Object$'System Primitives'
[performDangerously: selector with: arg1 with: arg2 | |<primitive: 36>
	 "selector had better take 2 args"
	user croak].
"66" Object$'Compiler Defaults'
[emitForEffect: code on: stack | |
	].
"222" Object$'Compiler Defaults'
[emitForTruth: trueSkip falsity: falseSkip into: code on: stack | |
	self emitForValue: code on: stack.
	trueSkip jmpSize + falseSkip emitBfp: code on: stack.
	trueSkip emitJmp: code on: stack].
"476" StackPane$'Private'
[spawn | mclass selector parag oldparag |
	mclass ← (list  (selection max: 1)) mclass.
	selector ← self selector.
	parag ← (codePane
			  ifTrue: [codePane contents]
			  ifFalse:
				[(mclass canunderstand: selector)
				  ifTrue: [mclass code: selector]
				  ifFalse: ['']]).
	oldparag ← (codePane
			  ifTrue: [codePane oldContents]
			  ifFalse: [false]).
	self compselection.
	self select: 0.
	mclass edit: selector para: parag formerly: oldparag].
"86" StackPane$'Private'
[terminate | |
	 "called by parser close during initialization"].
"70" StackPane$'Initialization'
[interrupt: flag | |
	proceed  1 ← flag].
"966" StackPane$'Private'
[continue: restarting | ctxt |
	 "Close my window and resume my selected context, if any, else my first context.  If interrupted (proceed1) or restarting or a recompiled method, don't return a value; otherwise, return proceed2."
	user leftShiftKey
	  ifTrue: [mem  55 ← 58 "turn display off"].
	selection = 0
	  ifTrue: [selection ← 1].
	ctxt ← list  selection.
	self releaseAboveSelection "release abandoned contexts".
	NoteTaker
	  ifFalse:
		[restarting
		  ifTrue: [ctxt restart]
		  ifFalse:
			[(proceed  1 and: [selection = 1])
			  ifFalse: [ "resume after interrupt"
				ctxt push: proceed  2]]].
	list ← false "Inhibit me closing.".
	user topWindow vanish.
	list ← nil.
	NoteTaker
	  ifTrue:
		[thisContext sender release.
		thisContext sender← ctxt.
		↑proceed  2].
	proceed  3 = 1
	  ifTrue: [thisContext sender release].
	Top run: ctxt at: proceed  3.
	Top enable: proceed  3.
	Top wakeup: proceed  3.
	Top resetCurrent].
"102" StackPane$'ListPane protocol'
[locked | |
	↑contextVarPane and: [(selection > 0 and: [self dirty])]].
"84" StackPane$'Private'
[contents | |
	 "called by selected via Class fieldNamesInto"].
"98" StackPane$'Private'
[declaration: dummy1 name: string asArg: dummy2 | |
	variables next← string].
"86" StackPane$'Private'
[notify: msg | |
	 "selected context doesnt know its variables"].
"86" StackPane$'Private'
[comment: s | |
	 "called by selected via Class fieldNamesInto"].
"86" StackPane$'Private'
[trailer: s | |
	 "called by selected via Class fieldNamesInto"].
"80" StackPane$'NotifyWindow protocol'
[dirty | |
	↑codePane and: [codePane dirty]].
"246" StackPane$'ListPane protocol'
[deselected | |
	contextVarPane  false
	  ifFalse:
		[codePane showing: ''.
		contextVarPane names: (Vector new: 0) values: #(nil ) wrt: false.
		instanceVarPane names: (Vector new: 0) values: #(nil ) wrt: false]].
"210" StackPane$'NotifyWindow protocol'
[execute: parseStream for: t2 | |
	codePane ← t2.
	↑proceed  2 ← codePane execute: parseStream in: (selection = 0
	  ifTrue: [false]
	  ifFalse: [list  selection]) to: nil].
"104" StackPane$'Initialization'
[classInit | |
	stackmenu ← Menu new string: 'stack
spawn
proceed
restart'].
"557" StackPane$'Window protocol'
[yellowbug | t1 |
	scrollBar hidewhile [
		((t1 ← stackmenu bug) = 1
		  ifTrue: [self revise: (list  1) "show a full backtrace" stack with: (selection = 0
			  ifFalse: [list  selection])]
		  ifFalse:
			[t1 = 2
			  ifTrue: [self spawn "spawn a code editor"]
			  ifFalse:
				[t1 = 3
				  ifTrue: [self continue: false "return to selected context"]
				  ifFalse:
					[t1 = 4
					  ifTrue:
						[NoteTaker
						  ifTrue: [ "restart selected context"
							frame flash]
						  ifFalse: [self continue: true]]]]])]].
"178" StackPane$'Window protocol'
[close | |
	NoteTaker
	  ifTrue: [super close]
	  ifFalse:
		[Top enable: proceed  3.
		super close.
		list
		  ifTrue: [(list  1) releaseFully]]].
"210" StackPane$'Private'
[code | mclass selector |
	 "code of my selected context"
	mclass ← (list  selection) mclass.
	selector ← self selector.
	↑(mclass canunderstand: selector) and: [(mclass code: selector)]].
"155" StackPane$'Private'
[selector | context |
	context ← list  (selection max: 1).
	↑context sender  nil
	  ifTrue: [false]
	  ifFalse: [context selector]].
"239" StackPane$'Initialization'
[context: t1 at: level instance: t3 code: t4 | |
	contextVarPane ← t1.
	instanceVarPane ← t3.
	codePane ← t4.
	variables ← (Vector new: 16) asStream.
	proceed  nil
	  ifTrue: [proceed ← {false , nil , level}]].
"308" StackPane$'Initialization'
[context: t1 instance: t2 code: t3 | |
	contextVarPane ← t1.
	instanceVarPane ← t2.
	codePane ← t3.
	variables ← (Vector new: 16) asStream.
	proceed  nil
	  ifTrue: [proceed ← (NoteTaker
				  ifTrue: [{false , nil , nil}]
				  ifFalse: [{false , nil , Top currentPriority}])]].
"219" StackPane$'Private'
[releaseAboveSelection | |
	selection > 1
	  ifTrue:
		[list  (selection - 1) sender← nil.
		(list  1) release "Fully"].
	NoteTaker
	  ifFalse: [ "??"
		(list  (selection max: 1)) verifyFrames]].
"514" StackPane$'NotifyWindow protocol'
[compile: parseStream | ctxt selector method mcl |
	ctxt ← list  (selection max: 1).
	mcl ← ctxt mclass.
	proceed  2 ← selector ← codePane compile: parseStream in: mcl under: 'As yet unclassified'
	  ifTrue:
		[(codePane reflects: selection)
		  ifTrue:
			[(method ← mcl md methodorfalse: selector)
			  ifTrue:
				[self releaseAboveSelection.
				ctxt restartWith: method.
				proceed  1 ← true.
				self of: list  (selection to: list length) copy.
				self select: 1]]]].
"997" StackPane$'ListPane protocol'
[selected | context instance code safeVec |
	contextVarPane  false
	  ifFalse:
		[context ← list  selection.
		instance ← context receiver.
		NoteTaker
		  ifFalse: [Decompiler new findPC: context pc].
		code ← self code.
		codePane showing: (code
		  ifTrue: [code]
		  ifFalse: ['']).
		NoteTaker
		  ifFalse: [codePane selectRange: Decompiler new highlight].
		variables reset.
		context variableNamesInto: self with: nil.
		code
		  ifTrue:
			[contextVarPane names: (#(thisContext ) concat: variables contents) values: {context , context tempframe} wrt: context.
			context tempframe  nil
			  ifTrue: [user notify: 'NIL TEMPFRAME']]
		  ifFalse: [contextVarPane names: #(thisContext ) values: context inVector wrt: context].
		variables reset.
		instance class fieldNamesInto: self.
		safeVec ← Vector new: 2.
		safeVec all← instance.
		instanceVarPane names: (#(self ) concat: variables contents) values: safeVec wrt: context.
		contextVarPane select: 1]].
"108" StackPane$'Private'
[identifier: s | |
	 "called by selected via Class fieldNamesInto"
	variables next← s].
"88" StackPane$'Private'
[separator: c | |
	 "called by selected via Class fieldNamesInto"].
"534" NotifyWindow$'Initialization'
[of: titleString level: level interrupt: flag | stackPane |
	NotifyFlag ← false.
	stackPane ← StackPane new.
	self title: titleString with: stackPane inVector at: smallTemplates.
	smallFrame moveto: (level > 1
	  ifTrue: [300  50]
	  ifFalse: [user screenrect center - (smallFrame extent / 2)]).
	self frame: (self fixframe: smallFrame).
	self show.
	stackPane context: false at: level instance: false code: false.
	stackPane interrupt: flag.
	stackPane of: (Top  level) inVector.
	NotifyFlag ← true].
"305" NotifyWindow$'Initialization'
[classInit | |
	smallTemplates ← (0  0 rect: 36  36) inVector.
	bigTemplates ← {(0  0 rect: 12  18) , (12  0 rect: 36  18) , (0  18 rect: 12  27) , (12  18 rect: 36  27) , (0  27 rect: 12  36) , (12  27 rect: 36  36)}.
	smallFrame ← 204  366 rect: 404  402].
"149" NotifyWindow$'Window protocol'
[close | |
	super close.
	NoteTaker
	  ifTrue:
		[self erase.
		user unschedule: self.
		thisContext systemRestart]].
"155" NotifyWindow$'Window protocol'
[enter | |
	enoughpanes
	  ifTrue: [super enter]
	  ifFalse: [self of: title stackPane: panes  1 codePane: CodePane new]].
"988" NotifyWindow$'As yet unclassified'
[of: t1 stackPane: stackPane codePane: codePane | contextVarPane contextValuePane instanceVarPane instanceValuePane |
	title ← t1.
	NotifyFlag ← false "Create the remaining four panes.".
	contextVarPane ← VariablePane new.
	contextValuePane ← CodePane new.
	instanceVarPane ← VariablePane new.
	instanceValuePane ← CodePane new "Create the six-paned window.".
	self title: title with: {stackPane , codePane , contextVarPane , contextValuePane , instanceVarPane , instanceValuePane} at: bigTemplates.
	self frame: frame.
	self show "Initialize the six panes.".
	stackPane context: contextVarPane instance: instanceVarPane code: codePane.
	codePane from: stackPane.
	contextVarPane to: contextValuePane.
	contextValuePane from: contextVarPane.
	instanceVarPane to: instanceValuePane.
	instanceValuePane from: instanceVarPane.
	stackPane select: 0.
	stackPane makeParagraph.
	stackPane displayall.
	stackPane deselected.
	enoughpanes ← NotifyFlag ← true].
"104" NotifyWindow$'Window protocol'
[aboutToFrame | |
	enoughpanes ← panes length = 6.
	super aboutToFrame].
"548" NotifyWindow$'Initialization'
[of: titleString stack: stack interrupt: flag | stackPane |
	NotifyFlag ← false.
	stackPane ← StackPane new.
	self title: titleString with: stackPane inVector at: smallTemplates.
	smallFrame moveto: ((NoteTaker or: [Top currentPriority  1])
	  ifTrue: [user screenrect center - (smallFrame extent / 2)]
	  ifFalse: [300  50]).
	self frame: (self fixframe: smallFrame).
	self show.
	stackPane context: false instance: false code: false.
	stackPane interrupt: flag.
	stackPane of: stack inVector.
	NotifyFlag ← true].
"225" SyntaxWindow$'As yet unclassified'
[aboutToFrame | nw t s c |
	t ← title.
	s ← panes  1.
	c ← panes  2.
	user unschedule: self.
	nw ← NotifyWindow new frame: frame.
	nw of: t stackPane: s codePane: c.
	user restartup: nw].
"150" SyntaxWindow$'Initialization'
[classInit | |
	stdTemplates ← {(0  0 rect: 12  36) , (12  0 rect: 36  36)}.
	stdFrame ← 60  320 rect: 570  500].
"609" SyntaxWindow$'Initialization'
[of: errorString at: position in: stream for: class from: context | stackPane codePane |
	stackPane ← StackPane new.
	codePane ← CodePane new class: class selector: nil para: nil.
	self title: class title with: {stackPane , codePane} at: stdTemplates.
	stdFrame moveto: user screenrect center - (stdFrame extent / 2).
	self frame: (self fixframe: stdFrame).
	self show.
	stackPane context: false instance: false code: codePane.
	stackPane of: context inVector.
	codePane showing: stream asArray.
	codePane from: stackPane.
	codePane notify: errorString at: position in: stream].
"347" Object$'Compiler Defaults'
[notify: errorString at: position in: stream for: class | syntaxWindow |
	NotifyFlag
	  ifTrue:
		[syntaxWindow ← SyntaxWindow new of: errorString at: position in: stream for: class from: thisContext sender.
		thisContext sender← nil.
		user restartup: syntaxWindow]
	  ifFalse:
		[user notify: errorString.
		↑false]].
"163" Object$'Compiler Defaults'
[sizeForTruth: trueSkip falsity: falseSkip | jump |
	jump ← trueSkip jmpSize.
	↑self sizeForValue + (jump + falseSkip) bfpSize + jump].
"138" Object$'Construction'
[recopy | |
	 "recursively copy whole structure"
	(self is: Object)
	  ifTrue: [↑self].
	↑self class recopy: self].
"148" Object$'System Primitives'
[perform: selector withArgs: vec | |
	selector mustTake: vec length.
	↑self performDangerously: selector withArgs: vec].
"453" Object$'System Primitives'
[performDangerously: selector withArgs: vec | t3 |
	(t3 ← vec length) = 0
	  ifTrue: [↑self performDangerously: selector].
	t3 = 1
	  ifTrue: [↑self performDangerously: selector with: vec  1].
	t3 = 2
	  ifTrue: [↑self performDangerously: selector with: vec  1 with: vec  2].
	t3 = 3
	  ifTrue: [↑self performDangerously: selector with: vec  1 with: vec  2 with: vec  3].
	user notify: 'More than 3 args for perform:'].
"147" Object$'Printing'
[filout | file |
	↑user displayoffwhile [
		(file ← dp0 file: self title asFileName.
		self fullprinton: file.
		file close)]].
"305" Object$'Aspects'
[fields | |
	self class "Return an Array of all my field names or many of my subscripts." isVariable
	  ifTrue: [↑self class instvars concat: (self length  50
		  ifTrue: [1 to: self length]
		  ifFalse: [(1 to: 20) concat: (self length - 20 to: self length)])].
	↑self class instvars].
"33" Object$'Aspects'
[itself | |
	].
"77" Object$'As yet unclassified'
[become: other | |<primitive: 35>
	user croak].
"81" Object$'As yet unclassified'
[growTo: newLength | |<primitive: 33>
	user croak].
"80" Object$'Aspects'
[subError | |
	self error: 'message not defined by subclass'].
"87" Object$'System Primitives'
[execute: method with: arg | |<primitive: 78>
	user croak].
"51" Object$'Compiler Defaults'
[sizeForValue | |
	↑0].
"65" Object$'Compiler Defaults'
[emitForValue: code on: stack | |
	].
"49" Object$'Compiler Defaults'
[firstPush | |
	↑1].
"50" Object$'Aspects'
[error: s | |
	↑user notify: s].
"369" FontSet$'Access'
[ n ← font | |
	(n > (fonts length - 1) or: [n < 0])
	  ifTrue: [user notify: 'fontset offset < 0 or > 15 illegal']
	  ifFalse:
		[names  (n + 1) ← font name asUppercase.
		fonts  (n + 1) ← font.
		ascent < font ascent
		  ifTrue: [ascent ← font ascent].
		descent < font descent
		  ifTrue: [descent ← font descent].
		height ← ascent + descent]].
"40" FontSet$'Access'
[ascent | |
	↑ascent].
"118" FontSet$'Initialization'
[init | |
	fonts ← Vector new: 16.
	names ← Vector new: 16.
	height ← ascent ← descent ← 0].
"48" Font$'Access to Parts'
[descent | |
	↑descent].
"50" Font$'Access to Parts'
[maxascii | |
	↑maxascii].
"50" Font$'Access to Parts'
[minascii | |
	↑minascii].
"46" Font$'Access to Parts'
[ascent | |
	↑ascent].
"46" Font$'Access to Parts'
[glyphs | |
	↑glyphs].
"46" Font$'Access to Parts'
[raster | |
	↑raster].
"46" Font$'Access to Parts'
[xtable | |
	↑xtable].
"73" Font$'Access to Parts'
[height | |
	↑ascent + descent "height of font"].
"42" Font$'Access to Parts'
[name | |
	↑name].
"93" Font$'Access to Parts'
[widthof: glyph | |
	↑xtable  (glyph + 2) - (xtable  (glyph + 1))].
"620" Font$'Initialization'
[fromStrike: t1 | strike i |
	 "Build instance from strike file."
	name ← t1.
	strike ← dp0 oldFile: name + '.strike.'.
	strike nextword "skip header".
	minascii ← strike nextword.
	maxascii ← strike nextword.
	maxwidth ← strike nextword.
	length ← strike nextword.
	ascent ← strike nextword.
	descent ← strike nextword.
	xoffset ← strike nextword "If (horrors!) we should ever kern.".
	raster ← strike nextword.
	glyphs ← (Bitmap new: raster * self height) fromStream: strike.
	xtable ← (Vector new: maxascii + 3) all← 0.
	(minascii + 1 to: maxascii + 3) do: [:i | xtable  i ← strike nextword]].
"92" Font$'Access to Parts'
[charForm: ascii | |
	 "should return a Form copied out of glyphs"].
"50" Font$'Access to Parts'
[maxwidth | |
	↑maxwidth].
"94" Font$'Access to Parts'
[spacewidth | w |
	w ← self widthof: 32.
	w = 0
	  ifTrue: [↑4].
	↑w].
"301" FontSet$'Access'
[ n | |
	(n > (fonts length - 1) or: [n < 0])
	  ifTrue: [user notify: 'fontset offset < 0 or > 15 illegal']
	  ifFalse:
		[(fonts  (n + 1) Is: Font)
		  ifTrue: [↑fonts  (n + 1)].
		(fonts  1 Is: Font)
		  ifTrue: [↑fonts  1].
		user notify: 'No valid fonts in this FontSet']].
"240" FontSet$'Access'
[family: n | s char |
	 "return the family name taken out of names"
	names  n  nil
	  ifTrue: [n ← 1].
	s ← Stream default.
	names  n do:
		[:char | char isletter
		  ifTrue: [s next← char]
		  ifFalse: [↑s contents]]].
"40" FontSet$'Access'
[height | |
	↑height].
"42" FontSet$'Access'
[descent | |
	↑descent].
"256" FontSet$'Access'
[size: n | s c size |
	 "return size from fontname"
	names  n  nil
	  ifTrue: [n ← 1].
	size ← 0.
	s ← (names  n) asStream.
	[(c ← s next) isletter] whileTrueDo: [].
	[size ← size * 10 + (c - 48).
	c ← s next] whileTrueDo: [].
	↑size].
"42" FontSet$'Access'
[baseline | |
	↑ascent].
"38" FontSet$'Access'
[names | |
	↑names].
"62" Paragraph$'Normal access'
[textStyle | |
	↑DefaultTextStyle].
"151" Paragraph$'Filing'
[readFrom: file | |
	text ← file nextString.
	runs ← file nextString.
	alignment ← file next.
	runs empty
	  ifTrue: [runs ← nil]].
"192" Paragraph$'Manipulation of format runs'
[runfind: index | run t |
	 "index into run"
	run ← 1.
	[(t ← index - (runs  run)) > 0] whileTrueDo:
		[index ← t.
		run ← run + 2].
	↑{run , index}].
"122" Paragraph$'Manipulation of format runs'
[maskrunsunder: m to: val | |
	self maskrun: 1 to: text length under: m to: val].
"483" Paragraph$'Bravo conversions'
[fromBravo | newpara newtext loc i j |
	 "Find Bravo trailers and return a copy of self with them applied"
	newpara ← self copy.
	loc ← 1.
	[(i ← (newtext ← newpara text) find: 26)  0] whileTrueDo:
		[j ← newtext  (i + 1 to: newtext length) find: 13.
		newpara applyBravo: newtext  (i + 1 to: i + j) at: loc to: i - 1.
		newpara replace: i to: (i + j = newtext length
		  ifTrue: [i + j]
		  ifFalse: [i + j - 1]) by: ''.
		loc ← i + 1].
	↑newpara].
"105" Paragraph$'Press printing'
[presson: press in: r | |
	↑self presson: press in: r style: self textStyle].
"56" Paragraph$'Text alignment'
[alignment | |
	↑alignment].
"64" Paragraph$'Text alignment'
[alignment← t1 | |
	alignment ← t1].
"115" Paragraph$'Initialization of parts'
[text: t1 runs: t2 alignment: t3 | |
	text ← t1.
	runs ← t2.
	alignment ← t3].
"1587" Paragraph$'Bravo conversions'
[applyBravo: s at: i to: j | v ch t bslash cr |
	s ← s asStream "Alter runs of characters i through j according to trailer.
	see Ibis<Bravo>Trailer.Memo for further info.
	some functions may not be implemented, thus parsed and ignored.

	paragraph looks.
	implemented: justification (j), centering (c).
	ignored: left margin (l), first line left margin (d), right margin (z),
	line leading (x), paragraph leading (e), vertical tab (y), keep (k), profile (q),
	tab tables ( () )".
	cr ← 13.
	bslash ← '\'  1.
	[(ch ← s next) = bslash] whileFalseDo: 
		[(ch  false or: [ch = cr])
		  ifTrue: [↑self].
		 "no more"
		(t ← 'jcq' find: ch) > 0
		  ifTrue:
			[t = 1
			  ifTrue: [self justify]
			  ifFalse:
				[t = 2
				  ifTrue: [self center]]]
		  ifFalse:
			[(t ← '(ldzxeyk' find: ch) > 0
			  ifTrue:
				[t = 1
				  ifTrue: [s skipTo: ')'  1]
				  ifFalse: [s integerScan]]] "character looks.
	implemented: font (f), bold (bB), italic (iI), underline (uU).
	ignored: graphic (g), visible (v), overstrike (s), superscript (o), tabcolor (t)"].
	[(ch ← s next) and: [ch  cr]] whileTrueDo:
		[ "run length"
		((ch  48 and: [ch  57 "isdigit"])
		  ifTrue: [s skip: 1]
		  ifFalse: [ch = 32])
		  ifTrue: [i ← i + s integerScan]
		  ifFalse:
			[(t ← 'bBiIuU' find: ch) > 0
			  ifTrue: [self maskrun: i to: j under: #(1 1 2 2 4 4 )  t to: #(1 0 2 0 4 0 )  t]
			  ifFalse:
				[(t ← 'fot' find: ch) > 0
				  ifTrue:
					[v ← s integerScan "new value follows".
					t = 1
					  ifTrue: [self maskrun: i to: j under: 240 to: (v lshift: 4)]]]]]].
"167" Paragraph$'Manipulation of format runs'
[allFont: n | |
	(n is: String)
	  ifTrue: [n ← (self textStyle fontnames find: n) - 1].
	self maskrunsunder: 240 to: n * 16].
"294" Paragraph$'Manipulation of format runs'
[runAndVal: index | run t |
	 "length and value at index"
	runs  nil
	  ifTrue: [↑{text length - index + 1 , 0}].
	run ← 1.
	[(t ← index - (runs  run)) > 0] whileTrueDo:
		[index ← t.
		run ← run + 2].
	↑{runs  run - index + 1 , (runs  (run + 1))}].
"59" ParagraphScanner$'Initialization'
[in: t1 | |
	rect ← t1].
"135" ParagraphScanner$'Scanning'
[tab | |
	spaces ← 0.
	tabpos next← textstrm position.
	tabpos next← width ← width + font tab | font tab].
"47" ParagraphScanner$'Access'
[width | |
	↑width].
"195" ParagraphScanner$'Initialization'
[of: t1 to: t2 style: t3 | |
	para ← t1.
	press ← t2.
	style ← t3.
	textstrm ← '' asStream.
	runstrm ← para runs asStream.
	tabpos ← (Vector new: 10) asStream].
"246" ParagraphScanner$'Private scanning'
[newrun | len pos |
	(len ← runstrm next)
	  ifTrue:
		[pos ← textstrm position.
		textstrm of: para text from: pos + 1 to: pos + len.
		font ← press codefont: runstrm next style: style]
	  ifFalse: [↑false]].
"61" ParagraphScanner$'Scanning'
[backup | |
	textstrm skip: 1].
"62" ParagraphScanner$'Access'
[position | |
	↑textstrm position].
"100" ParagraphScanner$'Initialization'
[init | |
	ascent ← descent ← width ← spaces ← 0.
	tabpos reset].
"1187" ParagraphScanner$'Scanning'
[scan | maxw sp char t spos slim srunpos sasc sdesc swidth ssp sfont stpos |
	 "Scan up to a zero-width character, back up to last blank if width exceeded" "Save state"
	(textstrm end and: [self newrun  false])
	  ifTrue: [↑false].
	maxw ← rect width.
	[ascent ← ascent max: font ascent.
	descent ← descent max: font descent.
	sp ← font space.
	[t ← font scan: textstrm until: width exceeds: maxw.
	(char ← t  1)  true
	  ifFalse: [width ← t  2].
	char = 32] whileTrueDo:
		[spos ← textstrm position "Save state".
		slim ← textstrm limit.
		srunpos ← runstrm position.
		stpos ← tabpos position.
		sasc ← ascent.
		sdesc ← descent.
		swidth ← width.
		ssp ← spaces.
		sfont ← font.
		spaces ← spaces + 1.
		width ← width + sp].
	char
	  ifTrue:
		[((char  true and: [nil  spos]) and: [2 * ascent  rect height])
		  ifTrue:
			[textstrm of: para text "Back up to just past last blank (if another line fits)" from: spos + 1 to: slim.
			runstrm position← srunpos.
			tabpos position← stpos.
			ascent ← sasc.
			descent ← sdesc.
			width ← swidth.
			spaces ← ssp.
			font ← sfont.
			↑32].
		↑char]
	  ifFalse: [self newrun]] whileTrueDo: [].
	↑false].
"2777" ParagraphScanner$'Printing'
[printfrom: charpos aligned: align skip: n | ybot a b ix iy px xs sp rs len tpos ts ntab rval ifont w ps t21 |
	 "Returns false if goes below bottom"
	(ybot ← rect corner "this code basically writes the EL (entity list) for a line" "bottom of character -- ascent not really ascent but height" y - ascent) < rect origin y
	  ifTrue: [↑false].
	 "won't fit"
	a ← charpos + 1.
	b ← textstrm position - n.
	a > b
	  ifFalse:
		[ "No text"
		ts ← tabpos viewer.
		tpos ← ts next.
		px ← false.
		xs ← rect width - width.
		ix ← rect minX + (align = 2 "left margin offset"
				  ifTrue: [xs / 2]
				  ifFalse:
					[align = 4
					  ifTrue: [xs]
					  ifFalse: [0]]) "set baseline of character.  do setx before showchars".
		press sety: (iy ← ybot + descent).
		sp ← font space "kludge?".
		align = 1
		  ifFalse: [ "do setspacex before showchars"
			press setspacex: sp].
		rs ← (para run: a to: b) asStream.
		[len ← rs next] whileTrueDo:
			[press selectfont: (press fontindex: (rval ← rs next) style: style) - 1.
			b ← a + len.
			(rval land: 4) = 0
			  ifFalse:
				[ "no underlining" "unfortunately, we must rescan this part of line to find out how wide it is"
				ifont ← press codefont: rval style: style "a WidthTable".
				ps ← (para  (a to: b - 1)) asStream.
				w ← {true , 0}.
				[w  1] whileTrueDo:
					[w ← ifont scan: ps until: w  2 exceeds: rect width.
					(t21 ← w  1) = 32
					  ifTrue: [w  2 ← w  2 + ifont space]
					  ifFalse:
						[t21 = 9
						  ifTrue: [w  2 ← w  2 + ifont tab | ifont tab]]].
				px
				  ifFalse: [ "use current x position"
					press setx: ix] "change y position to show rectangle, then change y back again".
				press sety: iy - 40.
				press showrectwidth: w  2 height: 30.
				press sety: iy].
			ntab ← 0.
			[tpos and: [tpos < b]] whileTrueDo:
				[ "Put out tabs"
				tpos = a
				  ifFalse:
					[ "no text between this tab and last" "put out accumulated tabs or initial x"
					ntab > 0
					  ifTrue:
						[press skipchars: ntab.
						press setx: px.
						ntab ← 0]
					  ifFalse:
						[px
						  ifFalse: [press setx: (px ← ix)]].
					press showchars: tpos - a].
				ntab ← ntab + 1.
				px ← ix + ts next.
				a ← tpos + 1.
				tpos ← ts next].
			ntab > 0
			  ifTrue:
				[press skipchars: ntab.
				press setx: px]
			  ifFalse:
				[px
				  ifFalse: [press setx: (px ← ix)]].
			(align = 1 and: [tpos  false])
			  ifTrue:
				[ "Reset space width"
				spaces = 0
				  ifFalse: [press setspacex: xs / spaces + sp].
				align ← 0].
			rs end
			  ifTrue:
				[press showchars: b - a "for more compactness, maybe" skip: n.
				↑ybot].
			press showchars: b - a.
			a ← b]].
	n > 0
	  ifTrue: [press skipchars: n "skip over ending blank or carriage return"].
	↑ybot].
"1414" Paragraph$'Press printing'
[presson: press in: r style: style | char pos s3 y chop |
	(text length "Output paragraph inside rectangle (page coordinates)" "probably ParagraphScanner should handle this" > 0 and: [text  1 = 12])
	  ifTrue: [↑self copy: 2 to: text length "formfeed --> page break"].
	y ← r corner y "We change corner y later".
	s3 ← ParagraphScanner new of: self to: press style: style.
	s3 init in: r.
	pos ← s3 position.
	chop ← (alignment = 1
			  ifTrue: [0]
			  ifFalse: [alignment]).
	[y and: [(char ← s3 scan)]] whileTrueDo:
		[char = 9
		  ifTrue: [s3 tab]
		  ifFalse:
			[(char = 32 or: [char = 13])
			  ifTrue:
				[(y ← s3 printfrom: pos aligned:  "carriage return or exceeded max width and backed up to blank"
						(char = 32
						  ifTrue: [alignment]
						  ifFalse: [chop]) skip: 1)
				  ifTrue:
					[r corner y← y.
					s3 init in: r.
					pos ← s3 position]]
			  ifFalse:
				[char  true
				  ifTrue:
					[s3 backup "exceeded max width with no blanks in line".
					(y ← s3 printfrom: pos aligned: 0 skip: 0)
					  ifTrue:
						[r corner y← y.
						s3 init in: r.
						pos ← s3 position]] "user notify: 'unimplemented control char'"]] "Put out trailing text if any"].
	(y and: [(pos = s3 position or: [(y ← s3 printfrom: pos aligned: chop skip: 0)])])
	  ifTrue:
		[press append: text.
		↑y].
	press append: text  (1 to: pos).
	↑self copy: pos + 1 to: text length].
"79" Paragraph$'Initialization of parts'
[text: t1 | |
	text ← t1.
	alignment ← 0].
"456" Paragraph$'Manipulation of format runs'
[makeBoldPattern | s i c |
	s ← text asStream.
	i ← 0.
	[(c ← s next)
	  ifTrue:
		[ " scan to bracket, bar or comment "
		c = 91
		  ifTrue: [true]
		  ifFalse:
			[c = 124
			  ifTrue: [true]
			  ifFalse:
				[c = 34
				  ifTrue: [true]
				  ifFalse:
					[c = 25
					  ifTrue: [true]
					  ifFalse: [false]]]]]
	  ifFalse: [true]] whileFalseDo:  [ "end"
		i ← i + 1].
	self maskrun: 1 to: i under: 1 to: 1].
"56" Paragraph$'Text alignment'
[center | |
	alignment ← 2].
"108" Paragraph$'Normal access'
[subst: x for: y | |
	 "runs are not supported yet here"
	↑text subst: x for: y].
"489" Paragraph$'Press printing'
[fromPress: press value: s | len x |
	s next = 0
	  ifTrue:
		[len ← s nextword "text is in DL" "amount to skip from where we are now to end of text".
		x ← (s limit > 255
				  ifTrue: [s limit "control info came from DL"]
				  ifFalse: [ "from EL"
					0]).
		press data skip: 0 - x - len.
		text ← press data next: len.
		press data skip: x]
	  ifFalse: [text ← s nextString].
	runs ← s nextString.
	alignment ← s next.
	runs empty
	  ifTrue: [runs ← nil]].
"167" Paragraph$'Bravo conversions'
[toBravo | s |
	s ← (String new: text length * 2) asStream.
	s append: text.
	s next← 26.
	self bravoRuns: s.
	↑s contents asParagraph].
"119" RemoteParagraph$'As yet unclassified'
[asParagraph | |
	file position← self position.
	↑Paragraph new readFrom: file].
"78" RemoteParagraph$'As yet unclassified'
[asString | |
	↑self asParagraph text].
"95" RemoteParagraph$'As yet unclassified'
[on: t1 | |
	 "Refer me to a specific file"
	file ← t1].
"303" Cursor$'Initialization'
[fromtext: str offset: t2 | i s n c |
	offset ← t2.
	bitstr ← Bitmap new: 16 "Not great, but compatible with printon.".
	s ← str asStream.
	s next.
	(1 to: 16) do:
		[:i | n ← 0.
		[(c ← s next) = 48 or: [c = 49]] whileTrueDo: [n ← (n lshift: 1) + (c - 48)].
		bitstr  i ← n]].
"108" Cursor$'Printing'
[hardcopy: pf | |
	self hardcopy: pf at: user mp "use current cursor position" - offset].
"55" Cursor$'Showing'
[show | |
	user currentCursor: self].
"146" Cursor$'Showing'
[showwhile expr | oldcursor value |
	oldcursor ← user currentCursor.
	self show.
	value ← expr eval.
	oldcursor show.
	↑value].
"48" Cursor$'Access to Parts'
[offset | |
	↑offset].
"97" Cursor$'Initialization'
[asForm | |
	↑Form new extent: self extent bits: bitstr offset: offset].
"46" Cursor$'Access to Parts'
[bits | |
	↑bitstr].
"220" Cursor$'Printing'
[printon: strm | i |
	strm append: 'Cursor new fromtext: '''.
	(1 to: 16) do:
		[:i | strm cr.
		bitstr  i printon: strm base: 2].
	strm append: ''' offset: '.
	strm print: offset.
	strm append: '.'].
"211" Cursor$'Printing'
[hardcopy: pf at: loc | rect |
	rect ← loc extent: 16  16 "print cursor image at some point location into a presssfile".
	pf setp: (pf transrect: rect) origin.
	pf bitmap: rect bits: bitstr].
"84" Cursor$'Initialization'
[fromString: t1 offset: t2 | |
	bitstr ← t1.
	offset ← t2].
"49" Cursor$'Access to Parts'
[extent | |
	↑16  16].
"43" Cursor$'Showing'
[topage1 | |
	self show].
"56" Cursor$'Access to Parts'
[offset: t1 | |
	offset ← t1].
"79" Cursor$'Initialization'
[fromtext: str | |
	self fromtext: str offset: 0  0].
"99" Cursor$'Initialization'
[fromString: t1 | |
	bitstr ← t1.
	self fromString: bitstr offset: 0  0].
"387" UserView$'Mouse, Cursor, Keys'
[currentCursor: c | coff p t4 |
	currentCursor ← c.
	coff ← c offset.
	p ← self mp.
	mxoffset ← coff x - htab.
	myoffset ← coff y - vtab.
	self cursorloc← p "Cursor ref pt contin across boundary".
	NoteTaker
	  ifTrue: [self mapDisplay]
	  ifFalse:
		[(t4 ← BitBlt new) forCursor.
		t4 source: c bits lock.
		t4 effect: 0.
		t4 callBLT.
		c bits unlock]].
"68" UserView$'Mouse, Cursor, Keys'
[currentCursor | |
	↑currentCursor].
"66" UserView$'Changes'
[changedMessages | |
	↑Changes contents sort].
"78" UserView$'As yet unclassified'
[primEIAPeek | |<primitive: 75>
	↑self croak].
"79" UserView$'As yet unclassified'
[primKbdBlock | |<primitive: 47>
	↑self croak].
"78" UserView$'As yet unclassified'
[primPort: n | |<primitive: 75>
	↑self croak].
"234" UserView$'Screen Views'
[screenrect: t1 vtab: t2 htab: t3 scale: t4 color: t5 projectWindow: t6 disp: t7 sched: t8 | |
	screenrect ← t1.
	vtab ← t2.
	htab ← t3.
	scale ← t4.
	color ← t5.
	projectWindow ← t6.
	disp ← t7.
	sched ← t8].
"50" UserView$'Dialog Window'
[space | |
	disp space].
"315" UserView$'System quit/resume'
[quitThen: s continue: r | t3 |
	s
	  ifTrue:
		[(t3 ← dp0 oldFile: 'rem.cm.' "something for O.S. to do") settoend.
		t3 append: s.
		t3 append: '; '.
		t3 append: (r
		  ifTrue: ['Resume.~ small.boot']
		  ifFalse: ['Quit.~; Resume.~ small.boot']).
		t3 cr.
		t3 flush].
	self quit].
"136" UserView$'Mouse, Cursor, Keys'
[leftShiftKey | |
	 "left shift key down?"
	NoteTaker
	  ifTrue: [↑false].
	↑(mem  482 land: 64) = 0].
"62" UserView$'Mouse, Cursor, Keys'
[tablet | |
	↑mem  448  0].
"50" UserView$'Changes'
[noChanges | |
	Changes init].
"272" UserView$'Mouse, Cursor, Keys'
[rawkbd | stroke |
	(NoteTaker and: ['NoEventQ'])
	  ifTrue:
		[[self rawkbck] whileFalseDo:  [].
		↑self primKbdNext].
	[stroke ← self rawkbck] whileFalseDo:  [ "wait for activity"
		].
	Events next.
	↑stroke "if key down, return stroke"].
"555" UserView$'As yet unclassified'
[forAllMethods mvar do expr | n md sel |
	AllClassNames do: [:n | user displayoffwhile [
			(user show: n.
			user cr.
			md ← (Smalltalk  n) md.
			md do:
				[:sel | mvar value← md method: sel.
				expr eval])]] " | dict x m
	[dict← Dictionary init.
	user forAllMethods m do
		[m length<8[]
		(m3)>12[]
		dict tally: m5].
	dict contents sort transform x to x,(dictx)]
 ((1 381 ) (2 640 ) (3 638 ) (4 464 ) (5 365 ) (6 215 ) (7 179 ) (8 140 ) (9 70 ) (10 61 ) (11 45 ) (12 20 ) (13 10 ) (14 2 ) (15 1 ) )
"].
"78" UserView$'Dialog Window'
[croak | |
	self notify: 'A primitive has failed.'].
"176" UserView$'As yet unclassified'
[currentDisplay: form | |
	DisplayForm ← form.
	screenrect ← 0  0 rect: form extent.
	vtab ← htab ← mxoffset ← myoffset ← 0.
	self mapDisplay].
"652" MessageDict$'Inserting and Deleting'
[insert: name method: m literals: l code: c backpointers: b | i copy |
	(i ← self find: name)
	  ifTrue:
		[ "if name is already there"
		self freeMethod: methods  i.
		NoteTaker
		  ifFalse: [self holdLiterals: l] "CompiledMethod already did it".
		methods  i ← m.
		NoteTaker
		  ifFalse: [code  i ← c]]
	  ifFalse:
		[ "then insert it, and return self"
		copy ← (self sparse
				  ifTrue: [self]
				  ifFalse: [self growto: methods length * 2]) "Otherwise, copy if necessary".
		copy objects  (copy findornil: name) ← name "and insert".
		↑copy insert: name method: m literals: l code: c backpointers: b]].
"372" MessageDict$'Private'
[growto: size | name copy i |
	copy ← MessageDict new init: size "create a copy of the new size".
	self do:
		[:name | i ← self findorerror: name "hash each entry into it".
		copy ← copy insert: name method: methods  i literals: (literals  nil
				  ifFalse: [literals  i]) code: (NoteTaker
				  ifFalse: [code  i]) backpointers: nil].
	↑copy].
"298" MessageDict$'Code aspect of Strings'
[literalsIn: method | |
	 "return the literal vector imbedded in this method"
	NoteTaker
	  ifTrue:
		[method  nil
		  ifTrue: [↑Vector new: 0].
		↑method literals]
	  ifFalse: [ "CompiledMethod knows how"
		↑self holdLiterals: (self rawLiteralsIn: method)]].
"339" MessageDict$'Code aspect of Strings'
[holdLiterals: v | |
	 "raise refct of all literals"
	NoteTaker
	  ifTrue: [↑v].
	 "CompiledMethod already did it"
	v  nil
	  ifTrue: [↑v].
	v length = 0
	  ifTrue: [↑v].
	 "make a copy and blt nils over it before freeing"
	BitBlt new bltObj: v copy field: 1 to: v length fromObj: nil field: 0.
	↑v].
"249" MessageDict$'Code aspect of Strings'
[freeLiterals: v | m i t |
	 "lower refct of all literals"
	v length = 0
	  ifFalse:
		[m ← v nail.
		(1 to: v length) do:
			[:i | t ← mem  (m + i - 1).
			v  i ← nil.
			mem  (m + i - 1) ← t].
		v unNail]].
"200" MessageDict$'Inserting and Deleting'
[delete: name | i |
	i ← self findorerror: name.
	self freeMethod: methods  i.
	methods  i ← nil.
	NoteTaker
	  ifFalse: [code  i ← nil].
	super delete: name].
"211" MessageDict$'Code aspect of Strings'
[holdMethods: v | i |
	 "a random insertion just to make it legal form"
	(1 to: v length) do: [:i | self insert: i method: v  i literals: nil code: nil backpointers: nil]].
"483" MessageDict$'Code aspect of Strings'
[freeMethod: m | |
	 "method pointed to by some vector (dict or keeper)
		and (upon entry) by m.  If any other owners, refct will be >2.
		*Expects Interpreter to nil args on callers stack*"
	m  nil
	  ifFalse:
		[NoteTaker
		  ifTrue: [(nil swap [:m | m]) free]
		  ifFalse:
			[ "CompiledMethod knows how, but refct must be the same"
			m refct > 2
			  ifTrue: [MethodKeeper next← m]
			  ifFalse: [ "keep it"
				self rawLiteralsIn: m]]]].
"138" MessageDict$'Initialization'
[copyfrom: dict | |
	self objects← dict objects copy.
	methods ← dict methods copy.
	code ← dict code copy].
"141" MessageDict$'Private'
[swap: i with: j | |
	methods swap: i with: j.
	NoteTaker
	  ifFalse: [code swap: i with: j].
	super swap: i with: j].
"220" MessageDict$'Code aspect of Strings'
[freeMethods | v i |
	 "Free kept methods no longer used"
	v ← MethodKeeper contents.
	MethodKeeper ← (Vector new: 10) asStream.
	(1 to: v length) do: [:i | self freeMethod: v  i]].
"117" MessageDict$'Access to parts'
[methodorfalse: name | i |
	(i ← self find: name)
	  ifTrue: [↑methods  i].
	↑false].
"55" MessageDict$'Access to parts'
[methods | |
	↑methods].
"377" MessageDict$'Code aspect of Strings'
[rawLiteralsIn: method | v nlits |
	 "returns the literal vector WITHOUT REFI (for freeMethod: and literalsIn:)"
	method  nil
	  ifTrue: [↑Vector new: 0].
	method length < 10
	  ifTrue: [↑Vector new: 0].
	nlits ← method  6 - 6 / 2.
	v ← Vector new: (nlits max: 2).
	BitBlt new bltObj: v field: 1 to: nlits fromObj: method field: 4.
	↑v].
"149" MessageDict$'Access to parts'
[code: name ← str | |
	NoteTaker
	  ifTrue: [↑str].
	 "NT doesnt store code"
	↑code  (self findorerror: name) ← str].
"208" MessageDict$'Inserting and Deleting'
[close | i |
	 "recycle all code and literals pointed to"
	(1 to: methods length) do:
		[:i | methods  i  nil
		  ifFalse: [self freeMethod: methods  i]].
	self init].
"49" MessageDict$'Access to parts'
[code | |
	↑code].
"148" MessageDict$'Access to parts'
[invert: method | i |
	(1 to: methods length) do:
		[:i | methods  i  method
		  ifTrue: [↑objects  i]].
	↑false].
"87" MessageDict$'Access to parts'
[method: name | |
	↑methods  (self findorerror: name)].
"130" MessageDict$'Access to parts'
[code: name | |
	NoteTaker
	  ifTrue: [↑'no code' asParagraph].
	↑code  (self findorerror: name)].
"144" MessageDict$'Initialization'
[init: size | |
	methods ← Vector new: size.
	NoteTaker
	  ifFalse: [code ← Vector new: size].
	super init: size].
"106" MessageDict$'Access to parts'
[literals: name | |
	↑self literalsIn: methods  (self findorerror: name)].
"979" UserView$'Misc System Stuff'
[initCompilerUnspecialize | c code sel i class m bother oldChanges |
	 "user initCompilerUnspecialize.
	SpecialOops(32~41)← (end class blockCopy: value value: nil new new: x y).
	SpecialOops37← nil.
	user initCompilerSpecialize."
	oldChanges ← Changes.
	Changes ← HashSet init "Unspecialize the last 10 selectors".
	SpecialOops  (32 ~ 41) all← nil.
	self initCompilerSelectors.
	user displayoffwhile [(AllClassNames do:
			[:c | user show: c + ' 1'.
			user cr.
			class ← Smalltalk  c.
			class md do:
				[:sel |  "recompile all methods w/special bytes"
				m ← class method: sel.
				m length  8
				  ifFalse:
					[ "quick"
					bother ← false.
					(m  6 + 1 to: m length) do:
						[:i | (m  i  198 and: [m  i  207])
						  ifTrue: [bother ← true]].
					bother
					  ifTrue: [class recompile: sel]]].
			Changes init])].
	PriorityScheduler new initsched.
	nil installError.
	MessageDict new freeMethods.
	Changes ← oldChanges].
"443" UserView$'Misc System Stuff'
[initCompilerSelectors | c code sel |
	c ← Dictionary new init: 64.
	code ← 176 - 1.
	SpecialOops  (10 ~ 41) do:
		[:sel | code ← code + 1 "Atoms not wanted here -- only strings and characters".
		sel  nil
		  ifFalse:
			[sel ← ((sel length = 1 and: [(sel  1) isletter  false])
					  ifTrue: [sel  1]
					  ifFalse: [sel asString]).
			c insert: sel with: code]].
	ByteCodes declare: #stdSelectors as: c].
"591" UserView$'Notify Window'
[notifier: titleString level: lev interrupt: flag | |
	self restoredisplay "Restore the full display.  Schedule a one-paned window to notify the user that errorString happened.".
	NotifyFlag  false
	  ifTrue:
		[disp cr.
		disp append: 'NotifyFlag is false...'.
		disp cr.
		disp append: ' top-blank shows stack, user restart aborts,'.
		disp cr.
		disp append: ' tempframe shows args, ctrl-d proceeds'.
		disp cr.
		disp append: titleString.
		disp cr.
		disp show.
		(Top  lev) debug.
		↑false].
	↑NotifyWindow new of: titleString level: lev interrupt: flag].
"44" UserView$'Time'
[today | |
	↑self now  1].
"414" UserView$'Screen Views'
[screenextent: extent tab: tab | |
	mem  53 ← color * 16384 + (scale = 2
	  ifTrue: [32768]
	  ifFalse: [0]) + (tab x / 16 * 256) + (extent x / 16 | 2).
	mem  55 ← extent y * scale / 2.
	mem  51 ← 1 max: tab y / 2.
	htab ← tab x | 16.
	vtab ← mem  51 * 2.
	screenrect ← 0  0 rect: extent x | 32  (extent y | 2).
	self currentCursor: currentCursor.
	self reconfigure.
	self restore].
"593" UserView$'Notify Window'
[notifier: titleString stack: stack interrupt: flag | |
	self restoredisplay "Restore the full display.  Schedule a one-paned window to notify the user that errorString happened.".
	NotifyFlag  false
	  ifTrue:
		[disp cr.
		disp append: 'NotifyFlag is false...'.
		disp cr.
		disp append: ' sender debug shows stack, user restart aborts,'.
		disp cr.
		disp append: ' tempframe shows args, ctrl-d proceeds'.
		disp cr.
		disp append: titleString.
		disp cr.
		disp show.
		stack debug.
		↑false].
	↑NotifyWindow new of: titleString stack: stack interrupt: flag].
"61" UserView$'Dialog Window'
[request: s | |
	↑disp request: s].
"493" UserView$'Notify Window'
[notify: errorString | notifyWindow |
	notifyWindow ← self notifier: errorString stack: thisContext sender "Create a notify window looking at the Context stack" interrupt: false.
	notifyWindow
	  ifTrue:
		[NoteTaker
		  ifTrue:
			[self schedule: notifyWindow.
			user run]
		  ifFalse:
			[thisContext sender← nil.
			Top currentPriority = 1
			  ifTrue: [self restartup: notifyWindow]
			  ifFalse:
				[self scheduleOnBottom: notifyWindow.
				Top errorReset]]]].
"140" UserView$'System quit/resume'
[InLd: fileid | |<primitive: 75>
	 "write out the core image, then load in OS"
	user notify: 'file problem'].
"50" UserView$'Window Scheduling'
[sched | |
	↑sched].
"72" UserView$'Dialog Window'
[show: str | |
	disp append: str.
	disp show].
"82" UserView$'Time'
[time expr | t |
	t ← self ticks.
	expr eval.
	↑self ticks - t].
"159" UserView$'Screen Views'
[displayoffwhile expr | t v |
	NoteTaker
	  ifTrue: [↑expr eval].
	t ← mem  55.
	mem  55 ← 58.
	v ← expr eval.
	mem  55 ← t.
	↑v].
"163" UserView$'Window Scheduling'
[scheduleOnBottom: window | |
	sched  nil
	  ifTrue: [sched ← window asVector]
	  ifFalse: [sched ← sched concat: window asVector]].
"89" UserView$'Time'
[ticks | |
	 "Return the 38.08-millisecond interval timer"
	↑mem  280].
"132" Date$'Aspects'
[daysinmonth: m | |
	↑#(31 28 31 30 31 30 31 31 30 31 30 31 )  m + (m = 2
	  ifTrue: [self leap]
	  ifFalse: [0])].
"235" Date$'Aspects'
[weekdayIndex | a d |
	day  (self monthday: 3)
	  ifTrue:
		[a ← year - 1.
		d ← 306]
	  ifFalse:
		[a ← year.
		d ← 59 - self leap] "Tuesday=1,..., Monday=7".
	↑d + day + a + (a / 4) + (a / 400) - (a / 100) \ 7 + 1].
"204" Date$'Arithmetic'
[previous: di | |
	↑self + (0 - (7 + self weekdayIndex "e.g. previous: 6 (Sunday) returns Date which is previous closest Sunday.
	note: di=self weekdayIndex returns self+0" - di \ 7))].
"186" Date$'Arithmetic'
[+ days | t |
	days ← day + days.
	t ← Date new.
	(days > 0 and: [days < 366])
	  ifTrue:
		[t day← days "same year".
		t year← year.
		↑t].
	↑t day: days year: year].
"227" Date$'Setting state'
[day: t1 year: t2 | d |
	day ← t1.
	year ← t2.
	[day > (d ← self daysinyear)] whileTrueDo:
		[year ← year + 1.
		day ← day - d].
	[day  0] whileTrueDo:
		[year ← year - 1.
		day ← day + self daysinyear]].
"179" Date$'Aspects'
[monthday: m | |
	 "Return first day-in-year of m'th month"
	↑#(0 31 59 90 120 151 181 212 243 273 304 334 )  m + (m > 2
	  ifTrue: [self leap]
	  ifFalse: [0])].
"232" Date$'Arithmetic'
[- date | |
	(date is: Date)
	  ifTrue:
		[year = date year
		  ifTrue: [↑day - date day].
		↑year - 1 / 4 - (date year / 4) + day + date daysleft + (year - 1 - date year * 365)]
	  ifFalse: [↑self + (0 - date)]].
"374" Date$'Setting state'
[day: t1 month: month year: t3 | |
	day ← t1.
	year ← t3.
	year < 100
	  ifTrue: [year ← 1900 + year].
	(month ← self whichmonth: month)  false
	  ifTrue: [user notify: 'illegal month']
	  ifFalse:
		[(day < 1 or: [day > (self daysinmonth: month)])
		  ifTrue: [user notify: 'illegal day in month']
		  ifFalse: [day ← day + (self monthday: month)]]].
"51" Date$'Aspects'
[daysinyear | |
	↑365 + self leap].
"293" Date$'Aspects'
[whichmonth: m | a |
	 "M may be a (partial) month name, or a number.  Return the month number, or false"
	(m Is: String)
	  ifTrue:
		[m ← m + '*'.
		(1 to: 12) do:
			[:a | (m match: monthnames  a "first partial match")
			  ifTrue: [↑a]].
		↑false].
	↑m  1 and: [m  12]].
"801" Date$'Printing and reading'
[printon: strm format: f | i m t5 t6 |
	m ← self month "f is print format.
	1-3	positions to print day,month,year respectively
	4	character separator
	5	month format (1 month #, 2 first 3 chars, 3 entire name)
	6	year format (1 year #, 2 year #\100)".
	(1 to: 3) do:
		[:i | (t5 ← f  i) = 1
		  ifTrue: [day - (self monthday: m) printon: strm]
		  ifFalse:
			[t5 = 2
			  ifTrue:
				[(t6 ← f  5) = 1
				  ifTrue: [m printon: strm]
				  ifFalse:
					[t6 = 2
					  ifTrue: [strm append: monthnames  m  (1 to: 3)]
					  ifFalse: [strm append: monthnames  m]]]
			  ifFalse:
				[t5 = 3
				  ifTrue: [(f  6 = 1
					  ifTrue: [year]
					  ifFalse: [year \ 100]) printon: strm]]].
		i < 3
		  ifTrue:
			[f  4  0
			  ifTrue: [strm next← f  4 "separator"]]]].
"94" Date$'Printing and reading'
[printon: strm | |
	self printon: strm format: #(1 2 3 32 3 1 )].
"59" Date$'Setting state'
[default | |
	↑user now "today"  1].
"137" Date$'Aspects'
[asSeconds | |
	 "Seconds since the beginning of time (local time)"
	↑secsinday * (self - (Date new day: 1 year: 1901))].
"58" Date$'Aspects'
[monthname | |
	↑monthnames  self month].
"99" Date$'Arithmetic'
[< date | |
	year = date year
	  ifTrue: [↑day < date day].
	↑year < date year].
"73" Date$'Arithmetic'
[= date | |
	↑day = date day and: [year = date year]].
"99" Date$'Arithmetic'
[> date | |
	year = date year
	  ifTrue: [↑day > date day].
	↑year > date year].
"121" Date$'Printing and reading'
[format: f | strm |
	strm ← Stream default.
	self printon: strm format: f.
	↑strm contents].
"56" Date$'Aspects'
[hash | |
	↑(year lshift: 3) lxor: day].
"294" Date$'Setting state'
[fromDays: d | |
	d ← d asInteger "d = days since Jan 1 1901. There are 1461 days in a 4-year cycle.
	2000 is a leap year, so no extra correction is necessary.
	day:year: will fix things up" intdiv: 1461.
	self day: 1 + (d  2) asSmall year: 1901 + ((d  1) asSmall * 4)].
"42" Date$'Aspects'
[year← t1 | |
	year ← t1].
"256" Date$'Aspects'
[month | m leap |
	leap ← self leap.
	(12 to: 1 by: 1) do:
		[:m | #(0 31 59 90 120 151 181 212 243 273 304 334 )  m + (m > 2
		  ifTrue: [leap]
		  ifFalse: [0]) "self monthday: m" < day
		  ifTrue: [↑m]].
	user notify: 'illegal month'].
"40" Date$'Aspects'
[day← t1 | |
	day ← t1].
"89" Date$'Printing and reading'
[readfrom: strm | |
	self readfrom: strm format: #(1 2 3 )].
"55" Date$'Aspects'
[daysleft | |
	↑self daysinyear - day].
"297" Date$'Printing and reading'
[readfrom: strm format: order | dmy i |
	strm  #today
	  ifTrue: [↑self default].
	order  nil
	  ifTrue: [order ← #(1 2 3 )].
	dmy ← Vector new: 3.
	(1 to: 3) do: [:i |  "dmy length"
		dmy  (order  i) ← strm next].
	self day: dmy  1 month: dmy  2 year: dmy  3].
"97" Date$'Printing and reading'
[from: s | |
	self readfrom: s asVector "asSet" viewer format: nil].
"170" Date$'Initialization'
[classInit | |
	monthnames ← #(January February March April May June July August September October November December ).
	secsinday ← 24 * 60 * 60].
"113" Date$'Aspects'
[weekday | |
	↑#(Tuesday Wednesday Thursday Friday Saturday Sunday Monday )  self weekdayIndex].
"34" Date$'Aspects'
[year | |
	↑year].
"163" Date$'Aspects'
[leap | |
	year \ 4 = 0
	  ifTrue:
		[year \ 100 = 0
		  ifTrue:
			[year \ 400 = 0
			  ifTrue: [↑1].
			↑0]
		  ifFalse: [↑1]]
	  ifFalse: [↑0]].
"32" Date$'Aspects'
[day | |
	↑day].
"69" Date$'Aspects'
[dayinmonth | |
	↑day - (self monthday: self month)].
"38" Date$'Aspects'
[dayinyear | |
	↑day].
"65" Date$'Aspects'
[daysinmonth | |
	↑self daysinmonth: self month].
"239" Number$'Arithmetic'
[ipow: x | |
	 "fixed powers in log n steps"
	x = 0
	  ifTrue: [↑1].
	x = 1
	  ifTrue: [↑self].
	x > 1
	  ifTrue: [↑(self * self ipow: x / 2) * (self ipow: x \ 2)].
	user notify: 'power must be positive for integers'].
"46" Number$'Arithmetic'
[> n | |
	↑self - n > 0].
"46" Number$'Arithmetic'
[< n | |
	↑self - n < 0].
"75" Number$'Conversions'
[asPtY | |
	 "pretend to be a Point for Point +-*/"].
"75" Number$'Conversions'
[asPtX | |
	 "pretend to be a Point for Point +-*/"].
"46" Number$'Arithmetic'
[= n | |
	↑self - n = 0].
"93" Number$'Conversions'
[printon: strm | |
	self printon: strm base: 10 "default print radix"].
"54" Number$'Arithmetic'
[ arg | |
	↑self = arg  false].
"80" Number$'Arithmetic'
[between: min and: max | |
	↑min  self and: [self  max]].
"63" Number$'Intervals, Points'
[ y | |
	↑Point new x: self y: y].
"56" Number$'As yet unclassified'
[hex | |
	↑self base: 16].
"76" Number$'Subscripts'
[cansubscript: a | |
	↑self asInteger cansubscript: a].
"62" Number$'Subscripts'
[subscripts: a | |
	↑a  self asInteger].
"74" Number$'Subscripts'
[subscripts: a ← val | |
	↑a  self asInteger ← val].
"65" Number$'Arithmetic'
[abs | |
	self < 0
	  ifTrue: [↑self * 1]].
"78" Number$'Intervals, Points'
[to: x | |
	↑Interval new from: self to: x by: 1].
"96" Number$'Arithmetic'
[compare: i | |
	self < i
	  ifTrue: [↑1].
	self = i
	  ifTrue: [↑2].
	↑3].
"41" Number$'Compatibility'
[isNumber | |
	].
"121" Number$'Conversions'
[asRectangle | |
	↑self  self "Return a Rectangle with me as all coordinates." rect: self  self].
"90" Number$'Conversions'
[asRectCorner | |
	 "pretend to be a Rectangle for Rectangle +-*/"].
"90" Number$'Conversions'
[asRectOrigin | |
	 "pretend to be a Rectangle for Rectangle +-*/"].
"66" Number$'Arithmetic'
[max: arg | |
	self < arg
	  ifTrue: [↑arg]].
"138" Number$'Arithmetic'
[factorial | |
	 "I only work for positive integer values"
	self = 0
	  ifTrue: [↑1].
	↑self * (self - 1) factorial].
"245" Number$'Arithmetic'
[log2 | i cnt |
	 "floor of log base 2"
	self < 0
	  ifTrue: [↑(self * 1) log2].
	self < 1
	  ifTrue: [↑(self / self / self) log2 * 1].
	i ← 1.
	cnt ← 0.
	[self  i] whileTrueDo:
		[i ← i + i.
		cnt ← cnt + 1].
	↑cnt - 1].
"117" Number$'Arithmetic'
[sign | |
	↑self = 0
	  ifTrue: [0]
	  ifFalse:
		[self < 0
		  ifTrue: [1]
		  ifFalse: [1]]].
"84" Number$'Intervals, Points'
[to: x by: y | |
	↑Interval new from: self to: x by: y].
"66" Number$'Arithmetic'
[min: arg | |
	self > arg
	  ifTrue: [↑arg]].
"92" Number$'Intervals, Points'
[for: n | |
	↑Interval new from: self to: self + (n - 1) by: 1].
"49" Number$'Conversions'
[base8 | |
	↑self base: 8].
"88" Number$'Intervals, Points'
[within: int | |
	↑int start  self and: [self  int stop]].
"46" Number$'Compatibility'
[isLarge | |
	↑false].
"150" Number$'Conversions'
[base: b | s |
	s ← Stream default.
	s append: '0'.
	self printon: s base: b.
	b = 16
	  ifTrue: [s append: 'H'].
	↑s contents].
"97" Number$'As yet unclassified'
[bits: interval | |
	↑self bits: interval start to: interval stop].
"96" Number$'Conversions'
[asPoint | |
	↑self  self "Return a Point with me as both coordinates."].
"76" Number$'Intervals, Points'
[~ x | |
	↑Interval new from: self to: x by: 1].
"841" Number$'As yet unclassified'
[hex4 | strm i x bytes d t |
	strm ← (String new: 5) asStream.
	strm space.
	x ← self asInteger.
	x isLarge
	  ifTrue:
		[bytes ← x bytes.
		d ← bytes last.
		d > 15
		  ifTrue:
			[t ← d / 16.
			strm next← (t < 10
			  ifTrue: [48 + t]
			  ifFalse: [55 + t])].
		t ← d \ 16.
		strm next← (t < 10
		  ifTrue: [48 + t]
		  ifFalse: [55 + t]).
		(bytes length - 1 to: 1 by: 1) do:
			[:i | d ← bytes  i.
			t ← d / 16.
			strm next← (t < 10
			  ifTrue: [48 + t]
			  ifFalse: [55 + t]).
			t ← d \ 16.
			strm next← (t < 10
			  ifTrue: [48 + t]
			  ifFalse: [55 + t])].
		↑strm contents].
	bytes ← String new: 4.
	(1 to: 4) do:
		[:i | bytes  i ← x \ 16.
		x ← x lshift: 4].
	(4 to: 1 by: 1) do:
		[:i | t ← bytes  i.
		strm next← (t < 10
		  ifTrue: [48 + t]
		  ifFalse: [55 + t])].
	↑strm contents].
"48" Time$'Setting state'
[seconds: t1 | |
	s ← t1].
"48" Time$'Setting state'
[minutes: t1 | |
	m ← t1].
"46" Time$'Setting state'
[hours: t1 | |
	h ← t1].
"32" Time$'Aspects'
[hours | |
	↑h].
"58" Time$'Aspects'
[asSeconds | |
	↑3600 * h + (60 * m + s)].
"217" Time$'Setting state'
[fromSeconds: sec | |
	sec ← sec asInteger "seconds since midnight (adjusted for time zone and DST)" intdiv: 3600.
	h ← (sec  1) asSmall.
	sec ← (sec  2) asSmall.
	m ← sec / 60.
	s ← sec \ 60].
"382" Time$'Printing'
[printon: strm | |
	 "Format is h:mm:ss am/pm"
	strm print: (h > 12
	  ifTrue: [h - 12]
	  ifFalse:
		[h < 1
		  ifTrue: [12]
		  ifFalse: [h]]).
	strm append: (m < 10
	  ifTrue: [':0']
	  ifFalse: [':']).
	strm print: m.
	strm append: (s < 10
	  ifTrue: [':0']
	  ifFalse: [':']).
	strm print: s.
	strm space append: (h < 12
	  ifTrue: ['am']
	  ifFalse: ['pm'])].
"63" Time$'Setting state'
[default | |
	↑user now "right now"  2].
"1642" UserView$'Time'
[convertTime: s returnSecs: format | d dd t dfirst dlast m570 m571 |
	 "s is total seconds from midnight Jan 1 1901 GMT (Greenwich mean time).
	see maxc <AltoDocs>AltoTime.Press for details" "time zone specific parameters"
	NoteTaker
	  ifTrue:
		[m570 ← 16505.
		m571 ← 305 "Zap! Youre in Palo Alto!"]
	  ifFalse:
		[m570 ← mem  376.
		m571 ← mem  377] "adjust for time zone".
	s ← s + ((m570  0
			  ifTrue: [1]
			  ifFalse: [ "west" "east"
				1]) * (3600 * (m570 bits: (1 to: 4) "hours") + (60 * (m571 bits: (1 to: 6) "additonal minutes")))).
	t ← s intdiv: 86400 "current day (in local standard time)".
	d ← Date new fromDays: t  1.
	format
	  ifFalse: [t ← Time new fromSeconds: t  2] "check for DST. correct DST parameters for nonleap years and
	round to previous Sunday if necessary" "day of the year on or before which DST takes effect".
	dfirst ← m570 land: 511 "bits: (7 to: 15)".
	(dfirst = 366
	  ifTrue: [false]
	  ifFalse:
		[ "DST not in effect"
		(dd ← d day)  (dfirst ← dfirst + d leap - 1)
		  ifTrue:
			[dlast ← (m571 land: 511) "day of the year on or before which DST ends" "bits: (7 to: 15)" + d leap - 1.
			dd < dlast "if false, definitely after" and: [dd < ((Date new day: dlast year: d year) previous: 6) day]]
		  ifFalse: [ "possibly earlier than or at beginning of range"
			dd  ((Date new day: dfirst year: d year) previous: 6) day]])
	  ifTrue:
		[format
		  ifTrue: [ "daylight savings time in effect. add an hour"
			s ← s + 3600]
		  ifFalse:
			[t hours = 23
			  ifTrue:
				[d ← d + 1.
				t hours: 0]
			  ifFalse: [t hours: t hours + 1]]].
	format
	  ifTrue: [↑s].
	↑{d , t}].
"124" UserView$'Screen Views'
[restoredisplay | |
	NoteTaker
	  ifFalse:
		[mem  272 ← 48.
		mem  55 ← screenrect height / 2]].
"166" UserView$'Misc System Stuff'
[versionName | s |
	s ← self version asStream "skip Smalltalk".
	s skipTo: 32 "return version identification, e.g. 5.5f".
	↑s upto: 32].
"2002" UserView$'Misc System Stuff'
[printCrossReference: classNames on: f | dict m md frame l each s class |
	 "user displayoffwhile [
	user printCrossReference: user classNames
		on: (dp0 file: 'CrossReference.Press')].

		user classNames
		(SystemOrganization category: 'xyz')
		(class1 class2)"
	dict ← Dictionary init: 200.
	(1 to: 32) do: [:m | dict insert: SpecialOops  (9 + m) with: #((Primitives ) () ) copy].
	classNames transform [:each | each] to [
		(user show: each.
		user space.
		md ← (Smalltalk  each) md.
		md do:
			[:m |  "Tally all the UniqueString literals"
			(s ← dict lookup: m)
			  ifFalse: [dict insert: m with: (s ← #(() () ) copy)].
			(s  1 has: each)
			  ifFalse:
				[s  1 ← {s  1 , each}.
				(md literals: m) do:
					[:l | (l is: UniqueString)
					  ifTrue:
						[(s ← dict lookup: l)
						  ifFalse: [dict insert: l with: (s ← #(() () ) copy)].
						(s  2 has: each)
						  ifFalse: [s  2 ← {s  2 , (each , m)}]]]]])].
	f ← f asPressPrinter.
	f stamp.
	frame ← f defaultframe "Print the messages out sorted".
	dict contents sort do:
		[:m | user show: m.
		user space.
		f frame← frame.
		md ← dict  m.
		s ← (String new: 200) asStream.
		s append: m.
		s append: ((md  1) length = 0
		  ifTrue: [' ( - undefined -  ']
		  ifFalse: [' (']).
		(md  1) sort do:
			[:l | s append: l.
			s append: ', '].
		s skip: 2.
		s append: ')'.
		f print: (s contents asParagraph maskrun: 1 to: m length under: 1 to: 1).
		f frame← frame minX + 500  frame minY rect: frame corner.
		s reset.
		(md  1 has: #Primitives)
		  ifTrue:
			[s append: 'untallied.'.
			md  2 ← #()]
		  ifFalse:
			[(md  2) length = 0
			  ifTrue: [s append: '- unreferenced -']].
		class ← #-.
		(md  2) sort do:
			[:l | l  1 = class
			  ifTrue: [s append: ', ']
			  ifFalse:
				[class  #-
				  ifTrue: [s cr].
				s append: '('.
				s append: l  1.
				s append: ') '.
				class ← l  1].
			s append: l  2].
		f print: s contents asParagraph].
	f close.
	f toPrinter].
"235" SystemOrganizer$'Filout and printing'
[filoutCategory: cat | all a |
	user displayoffwhile [
		(all ← self superclassOrder: cat.
		(dp0 file: (cat + '.st.') asFileName) filoutclass: all.
		all do: [:a | (Smalltalk  a) noChanges])]].
"110" SystemOrganizer$'Filout and printing'
[printAll | cat |
	commentVector do: [:cat | self printCategory: cat]].
"174" SystemOrganizer$'Filout and printing'
[printCategory: cat | |
	user displayoffwhile [((dp0 file: (cat + '.press') asFileName) printoutclass: (self superclassOrder: cat))]].
"804" SystemOrganizer$'Filout and printing'
[superclassOrder: cat | all lis title i c sup |
	 "Arrange classes in superclass order so they can be filed in"
	lis ← (self category: cat) copy.
	all ← (Vector new: lis length) asStream.
	[lis length > 0] whileTrueDo:
		[i ← 1.
		title ← lis  i.
		sup ← c ← Smalltalk  title.
		sup ← sup superclass.
		[ "Make sure it doesn't have an as yet uncollected superclass"
		sup  nil or: [(lis has: sup title unique)]] whileFalseDo:  [sup ← sup superclass].
		[sup  nil] whileFalseDo: 
			[i ← i + 1.
			title ← lis  i.
			sup ← c ← Smalltalk  title.
			sup ← sup superclass "check as yet uncollected superclass".
			[sup  nil or: [(lis has: sup title unique)]] whileFalseDo:  [sup ← sup superclass]].
		all next← title.
		lis ← lis delete: title].
	↑all contents].
"452" UserView$'Misc System Stuff'
[writeSources: newSources | |
	user file: newSources classes: SystemOrganization changesOnly: newSources end "write a new Sources file (usually on [phylum]Smalltalk.Sources.xxx
		(i.e. xxx = user versionName))
	if it's a new file or empty, write all Sources. otherwise it better be a copy of
	the previous Sources file (only changes will be appended. do the copy with ftp)"  false.
	Sources close.
	Sources ← newSources].
"195" UserView$'Misc System Stuff'
[classInit | |
	 " UserView classInit. "
	screenMenu ← Menu new string: 'exit to overview
snapshot
quit
open a subview
open a browser
open a workspace
turtle demo'].
"104" UserView$'Dialog Window'
[next← x | |
	disp cr "simulate a Vector Stream".
	disp print: x.
	disp show].
"555" UserView$'Misc System Stuff'
[writeChangedMessages: ChangedMessages | class m ms |
	ChangedMessages settoend "append changed messages to a file (usually on [phylum])".
	ChangedMessages cr.
	ChangedMessages cr.
	ChangedMessages asParagraphPrinter stamp.
	class ← ''.
	user changedMessages do:
		[:m | ms ← m asStream.
		(ms upto: 32) = class
		  ifTrue:
			[ChangedMessages append: ', '.
			ChangedMessages append: (ms upto: 32)]
		  ifFalse:
			[ChangedMessages cr.
			ChangedMessages append: m.
			class ← m asStream upto: 32]].
	ChangedMessages close].
"318" UserView$'Changes'
[changedCategories | titles space str |
	space ← ' '  1 "return a vector of the names of class categories which have been changed".
	titles ← HashSet new init.
	Changes contents do: [:str | titles insert: (SystemOrganization invert: ((Stream new of: str) upto: space) unique)].
	↑titles contents].
"97" UserView$'Misc System Stuff'
[releaseMessage | |
	user clearshow: 'Welcome to ' + user version].
"3060" UserView$'Misc System Stuff'
[systemworkspace1 | |
	 "for system releasers only!!!

this has been partitioned into three workspaces for editing convenience:
	systemworkspace1
		steps 0-4: general comments, handling Sources, creating a release.
	systemworkspace2
		steps 5-7: doing a vmem write or surgery, storing finished files on Phylum
	systemworkspace3
		step 8: after a release, e.g. updating press files


0. This boot file should be named small.boot for vmem writing, surgery, and command file purposes.  If you made changes to the Sources disk be sure to update the current versions of (Xm)Smalltalk.Run, (Xm)Smalltalk.Syms, and (Xm)Byterp.mb on [Ivy]<Smalltalk>. This procedure works best on a Dorado for speed and disk space reasons, and it also can be done on an Alto (double disk O.S. required for vmem write).  Microcode changes (including making non-xm versions) must(?) be done on an Alto.  Step 5 (vmem writing) assumes enough space for another boot file.  To turn off display during execution, hold down left shift key while selecting 'doit'.

For those who want to vmem write their own versions, do not execute steps 4, 7 or 8 without further editing of file and directory names. Underlined items are typical values and normally must be edited to be useful.


1. to create an xm version:  filin changes and selected goodies. Undeclared must be empty for release to work (step 4). copy the categories of classes which have changed to systemworkspace3 (for later printing) and recompile it.
	dp0 filin: ('changes.st').
	phylum filin: ('<Small-goodies>xx.st').
	Undeclared contents inVector, user changedCategories


2. update version number/letter and comments in UserView version


3. the Sources file will be ordinarily be created in step 4. if only a few changes are involved, it may be somewhat faster to copy the old sources file to the new sources file (this step). then step 4 will only append changes.
	phylum store: Sources reset as: 'Smalltalk.Sources.' + user versionName.


4. checks Undeclared, writes all or appends changed messages to Sources file, updates ChangedMessages, inits Changes, puts up greeting, and sets the default user name & password. note: this is only to be executed for releasing the Smalltalk system itself (supply the proper password!!). if you plan to do a vmem write next, better to do this as first line of step 5.
	user releaseExternalViews.
	phylum name: 'Smalltalk' password: 'password'.
	user release.
	phylum name: 'Smalltalk-User' password: 'Smalltalk'.

	to write out the sources for a private version, specify which directory to use (don't leave Smalltalk as the default) and which categories and/or classes are to be included.
	| c classes. user releaseExternalViews. classes ← (Vector new: 50) asStream.
	phylum name: 'name' password: 'password'.
	for c from: ('category1' class1) do [
		c is: String [classes append: (SystemOrganization category: c)]
		classes next ← c].
	user file: (phylum file: '<ddd>xx.Sources.' + user versionName)
		classes: classes contents changesOnly: false.
"].
"2101" UserView$'Misc System Stuff'
[systemworkspace2 | |
	 "for system releasers only!!!


5. if no surgery or vmem write involved, skip to step 7. start here with an xm version to make a non-xm version.  specify option below:
	1 vmem write (includes xm surgery)
	2 xm surgery
	3 non-xm surgery
to make things totally automatic, edit in your valid Maxc name and password, otherwise Ftp will ask you later (some of the file transfers can be edited out (i.e. if files are already present; also Ramload is superfluous on Dorado). in the case of surgery only, at the end you will have to hit a key after safing.

	| option prefix dir file.
option ← 1.
dir ← phylum asFtpDirectory.
dir directoryName: 'Smalltalk-76'.
prefix ← [option=3 [''] 'Xm'].
for file from: ('Smalltalk.Run' 'Smalltalk.Syms' 'Byterp.Mb') do [
	dir retrieve: prefix + file as: file].
dir closeThen: ([option=1 ['delete oldsmall.boot;
copy newsmall.boot ← small.boot; '] '']) + 
'ftp maxc Login/c yourname yourpassword directory/c alto retrieve/c packmu.run ramload.run;
Resume small.boot;
Ramload/N Byterp.mb/F 1000/A;
Smalltalk.run'.

option=1 [(VirtualMemory new) giveBirth3. user quit]
Vmem ramwrite: (dp0 oldFile: 'byterp.mb').
Vmem surgery: (dp0 oldFile: 'Smalltalk.run').


6. after a successful vmem write or surgery, execute this (selecting here is tricky or type in a Dispframe)
	user systemStartup.


7. edit lastversion (and Smalltalk password) and execute the following, then close this window (clean up screen for non-xm?), and quit. it then renames old versions of files, stores new versions of files, e.g. remote XmSmall.Boot becomes XmSmall.Boot.5.5g and local Small.Boot becomes remote XmSmall.Boot
	| lastversion dir file remotefile.
	lastversion ← '5.5j'.
	dir ← phylum asFtpDirectory.
	dir login: 'Smalltalk' password: 'password'.
	for file from: ('Small.Boot' 'Smalltalk.Syms') do [
		remotefile ← ([user hasXM ['Xm'] '']) + file.
		dir rename: remotefile newName: remotefile + '.' + lastversion;
			store: file as: remotefile].
	(dp0 file: 'rem.cm') append: dir commands; cr; close.
	user releaseMessage.
"].
"1103" UserView$'Misc System Stuff'
[systemworkspace3 | |
	 "for system releasers only!!!


8. to update press files for system categories or cross reference listing directly on Phylum, browse or spawn this window.  edit pf to specify a list of system categories to print, usually from step 1, e.g. user changedCategories: ('Basic Data Structures' ...) or SystemOrganization categories (for all); delete toPrinter if you don't want the press files printed. edit xref to be user classNames if you want to generate a cross reference listing.
	 | pf xref cat.
	pf ←   ('Text Objects' 'Kernel Classes' 'Press File Support' 'IFS File System' 'Alto File System' 'Panes and Menus' 'Files' 'Juniper' 'Windows' 'Graphical Objects' 'Numbers' 'Basic Data Structures' ).
	xref ← ().

	user releaseExternalViews.
	phylum name: 'Smalltalk' password: 'password'.
	for cat from: pf do [
		((phylum file: (cat + '.Press') asFileName) asPressPrinter) stamp;
			printclass: (SystemOrganization category: cat); close; toPrinter].
	xref empty []
	user printCrossReference: xref on: (phylum file: 'CrossReference.Press').
"].
"921" UserView$'Misc System Stuff'
[initCompilerSpecialize | c code sel i class m bother oldChanges special |
	oldChanges ← Changes.
	Changes ← HashSet init "Specialize the last 10 selectors".
	(1 to: 10) do: [:i | mem  (i + 31 + 2) ← (SpecialOops  (i + 31)) asOop].
	self initCompilerSelectors.
	special ← (SpecialOops  (32 ~ 41)) copy.
	user displayoffwhile [(AllClassNames do:
			[:c | user show: c + ' 1'.
			user cr.
			class ← Smalltalk  c.
			class md do:
				[:sel |  "recompile all methods w/special selectors"
				m ← class method: sel.
				m length  8
				  ifFalse:
					[ "quick"
					bother ← false.
					(class md literals: sel) do:
						[:i | ((i is: UniqueString) and: [(special has: i)])
						  ifTrue: [bother ← true]].
					bother
					  ifTrue: [class recompile: sel]]].
			Changes init])].
	PriorityScheduler new initsched.
	nil installError.
	MessageDict new freeMethods.
	Changes ← oldChanges].
"130" UserView$'System quit/resume'
[snapshotPrimitive | |<primitive: 83>
	 "write the OT and Data of this Smalltalk out"
	user croak].
"90" UserView$'Dialog Window'
[clearshow: str | |
	disp clear.
	disp append: str.
	disp show].
"49" UserView$'Dialog Window'
[read | |
	↑disp read].
"90" UserView$'Mouse, Cursor, Keys'
[waitnobug | |
	[self anybug] whileTrueDo: [].
	↑self mp].
"171" UserView$'Window Scheduling'
[unschedule: window | t |
	0 < (t ← sched find: window)
	  ifTrue: [sched ← sched  (1 to: t - 1) concat: sched  (t + 1 to: sched length)]].
"649" UserView$'Window Scheduling'
[run: topFlag | i w forward |
	 "topFlag means sched1 already is awake"
	forward ← (topFlag
			  ifTrue:
				[w ← sched  1.
				[w eachtime] whileTrueDo: [].
				w lasttime]
			  ifFalse: [true]).
	[true] whileTrueDo:
		[i ← 0.
		[(i ← i + 1) > sched length
		  ifFalse:
			[w ← (forward
					  ifTrue: [sched  i]
					  ifFalse: [sched  (sched length + 1 - i)]).
			w firsttime]] whileFalseDo:  [].
		i > sched length
		  ifTrue:
			[ "check for bug in empty space"
			user yellowbug
			  ifTrue: [self bugScreenMenu]]
		  ifFalse:
			[sched promote: w.
			[w eachtime] whileTrueDo: [].
			forward ← w lasttime]]].
"112" ProjectWindow$'Changing views'
[runParent | |
	 "leave this view by installing the one above"
	parent install].
"95" ProjectWindow$'Window behavior'
[yellowbug | |
	actionMenu bug = 1
	  ifTrue: [self install]].
"87" ProjectWindow$'Initialization'
[classInit | |
	actionMenu ← Menu new string: 'enter'].
"95" ProjectWindow$'Window behavior'
[close | |
	 "break circular links"
	userview ← parent ← nil].
"173" ProjectWindow$'Initialization'
[init | |
	 "a new window"
	self userview: (user copyIn: self) changes: HashSet init parent: user projectWindow.
	self newframe.
	self show].
"133" ProjectWindow$'Initialization'
[userview: t1 changes: t2 parent: t3 | |
	 "load state"
	userview ← t1.
	changes ← t2.
	parent ← t3].
"212" ProjectWindow$'Changing views'
[putTitle | |
	titlepara  nil
	  ifTrue: [titlepara ← 'Top View' asParagraph allBold].
	titleframe put: titlepara centered: user screenrect extent x / 3  8.
	titleframe outline].
"195" ProjectWindow$'Changing views'
[install | |
	 "Establish this project and its userview as the current screen view"
	Changes ← changes.
	(user ← userview) install.
	self putTitle.
	user restart].
"203" UserView$'Screen Views'
[projectWindow | |
	projectWindow  nil
	  ifTrue:
		[projectWindow ← ProjectWindow new.
		projectWindow userview: self changes: Changes parent: projectWindow].
	↑projectWindow].
"63" UserView$'Dialog Window'
[show | |
	disp outline.
	disp show].
"58" SystemPane$'Initialization'
[to: t1 | |
	classPane ← t1].
"88" SystemPane$'Initialization'
[classInit | |
	sysmenu ← Menu new string: 'filout
print'].
"317" SystemPane$'Window protocol'
[yellowbug | t1 |
	selection < 3
	  ifTrue: [window flash]
	  ifFalse: [scrollBar hidewhile [
			((t1 ← sysmenu bug) = 1
			  ifTrue: [SystemOrganization filoutCategory: list  selection]
			  ifFalse:
				[t1 = 2
				  ifTrue: [SystemOrganization printCategory: list  selection]])]]].
"191" SystemPane$'Window protocol'
[enter | |
	 "be sure I am up to date"
	mySysOrgVersion  user classNames
	  ifTrue: [super enter]
	  ifFalse:
		[window outline.
		self update.
		super enter]].
"162" SystemPane$'Initialization'
[update | |
	self of: (#(AllClasses SystemOrganization ) concat: SystemOrganization categories).
	mySysOrgVersion ← user classNames].
"111" SystemPane$'Window protocol'
[leave | |
	 "I am up to date"
	mySysOrgVersion ← user classNames.
	super leave].
"75" SystemPane$'ListPane protocol'
[selected | |
	classPane of: self classes].
"80" SystemPane$'ListPane protocol'
[deselected | |
	classPane of: (Vector new: 0)].
"657" SystemPane$'Browser protocol'
[compile: parag | class cat className |
	selection = 2
	  ifTrue:
		[SystemOrganization fromParagraph: parag.
		self update]
	  ifFalse:
		[ "new organization"
		cat ← (selection  1
				  ifTrue: [false]
				  ifFalse: [list  selection]).
		class ← nil  parag.
		(class Is: Class)
		  ifTrue:
			[className ← class title unique.
			cat
			  ifTrue: [SystemOrganization classify: className under: cat].
			mySysOrgVersion  user classNames
			  ifTrue:
				[selection > 0
				  ifTrue: [classPane of: (cat
					  ifTrue: [SystemOrganization category: cat]
					  ifFalse: [user classNames])]]
			  ifFalse: [self update]]]].
"256" SystemPane$'Browser protocol'
[noCode | |
	selection = 0
	  ifTrue: [↑''].
	selection = 2
	  ifTrue: [↑SystemOrganization].
	↑'Class new title: ''NameOfClass''
	subclassof: Object
	fields: ''names of fields''
	declare: ''names of class variables''' copy].
"61" SystemPane$'Browser protocol'
[dirty | |
	↑classPane dirty].
"354" SystemPane$'Browser protocol'
[forget: className | t2 |
	user notify: 'Class ' + className + ' will disappear if you proceed...'.
	(t2 ← Smalltalk  className) noChanges.
	t2 obsolete.
	Smalltalk delete: className.
	SystemOrganization delete: className.
	AllClassNames ← AllClassNames delete: className.
	classPane revise: self classes with: className].
"242" SystemPane$'Browser protocol'
[classes | |
	 "return a Vector of the classes in my selected category"
	selection = 1
	  ifTrue: [↑user classNames].
	selection  2
	  ifTrue: [↑Vector new: 0].
	↑SystemOrganization category: list  selection].
"148" ClassPane$'ListPane protocol'
[deselected | |
	organizationPane class: nil "I just lost my selection.  Tell organizationPane to display nothing."].
"95" ClassPane$'Initialization'
[classInit | |
	editmenu ← Menu new string: 'filout
print
forget'].
"442" ClassPane$'Window protocol'
[yellowbug | t1 |
	selection = 0 "If there is a selection, let the user choose a command from the menu."
	  ifTrue: [window flash]
	  ifFalse:
		[(t1 ← editmenu bug) = 1
		  ifTrue: [(Smalltalk  (list  selection) "filout") filout]
		  ifFalse:
			[t1 = 2
			  ifTrue: [(Smalltalk  (list  selection) "print") printout]
			  ifFalse:
				[t1 = 3
				  ifTrue: [systemPane forget: list  selection "forget"]]]]].
"73" ClassPane$'Window protocol'
[close | |
	systemPane ← nil.
	super close].
"78" ClassPane$'Browser protocol'
[compile: parag | |
	systemPane compile: parag].
"208" ClassPane$'ListPane protocol'
[selected | |
	organizationPane class: Smalltalk  (list  selection) "My selection just changed.  Tell organizationPane to display the categories of my newly selected Class."].
"67" ClassPane$'Browser protocol'
[dirty | |
	↑organizationPane dirty].
"96" ClassPane$'Browser protocol'
[noCode | |
	selection = 0
	  ifTrue: [↑systemPane noCode].
	↑''].
"91" ClassPane$'Initialization'
[from: t1 to: t2 | |
	systemPane ← t1.
	organizationPane ← t2].
"197" OrganizationPane$'Browser protocol'
[spawn: selector with: parag formerly: oldparag | |
	selectorPane compselection.
	selectorPane select: 0.
	class edit: selector para: parag formerly: oldparag].
"197" OrganizationPane$'Initialization'
[listFor: t1 | |
	class ← t1.
	↑class  nil
	  ifTrue: [Vector new: 0]
	  ifFalse: [#(ClassDefinition ClassOrganization ) concat: class organization categories]].
"70" OrganizationPane$'Browser protocol'
[dirty | |
	↑selectorPane dirty].
"263" OrganizationPane$'Browser protocol'
[forget: selector | cat |
	class derstands: selector.
	cat ← list  selection.
	self revise: (self listFor: class) with: cat.
	selection > 0
	  ifTrue: [selectorPane revise: (class organization category: cat) with: selector]].
"93" OrganizationPane$'Initialization'
[from: t1 to: t2 | |
	classPane ← t1.
	selectorPane ← t2].
"156" OrganizationPane$'ListPane protocol'
[deselected | |
	selectorPane of: (Vector new: 0) "I just lost my selection.  Tell selectorPane to display nothing."].
"95" OrganizationPane$'Initialization'
[classInit | |
	editmenu ← Menu new string: 'filout
print'].
"621" OrganizationPane$'Window protocol'
[yellowbug | t1 |
	selection  1 "If there is a selection, let the user choose a command from the menu."
	  ifTrue: [window flash]
	  ifFalse:
		[ "Can't filout or print definition by itself"
		(t1 ← editmenu bug) = 1
		  ifTrue:
			[selection = 2 "filout the selected category"
			  ifTrue: [class filoutOrganization]
			  ifFalse: [class filoutCategory: list  selection]]
		  ifFalse:
			[t1 = 2
			  ifTrue:
				[selection = 2 "print the selected category"
				  ifTrue: [window flash]
				  ifFalse: [ "Can't print organization"
					class printoutCategory: list  selection]]]]].
"79" OrganizationPane$'Window protocol'
[close | |
	classPane ← nil.
	super close].
"81" OrganizationPane$'Browser protocol'
[code: selector | |
	↑class code: selector].
"168" OrganizationPane$'As yet unclassified'
[syntaxChoice | |
	 "kludge for new choosing syntax"
	class  nil
	  ifFalse:
		[class usesNewSyntax
		  ifTrue: [↑class new]]].
"654" OrganizationPane$'Browser protocol'
[compile: parag | sel cat |
	(class  nil or: [selection = 1])
	  ifTrue: [classPane compile: parag]
	  ifFalse:
		[ "new definition"
		selection = 2
		  ifTrue:
			[class organization fromParagraph: parag.
			self class: class]
		  ifFalse:
			[ "new organization"
			cat ← (selection = 0
					  ifTrue: ['As yet unclassified']
					  ifFalse: [list  selection]).
			(sel ← selectorPane compile: parag in: class under: cat)
			  ifTrue:
				[self revise: (self listFor: class) with: cat.
				selection  0
				  ifTrue: [selectorPane revise: (class organization category: cat) with: sel]]
			  ifFalse: [↑false]]]].
"174" OrganizationPane$'ListPane protocol'
[selected | |
	selectorPane of: (selection  2
	  ifTrue: [Vector new: 0]
	  ifFalse: [class organization category: list  selection])].
"349" OrganizationPane$'Browser protocol'
[noCode | |
	class  nil
	  ifTrue: [↑classPane noCode].
	selection = 0
	  ifTrue: [↑''].
	selection = 1
	  ifTrue: [↑class definition].
	selection = 2
	  ifTrue: [↑class organization].
	↑'Message name and Arguments  | Temporary variables |  "short comment"
	"long comment if necessary"
	Smalltalk
	Statements'].
"96" OrganizationPane$'Initialization'
[class: t1 | |
	class ← t1.
	self of: (self listFor: class)].
"74" OrganizationPane$'Browser protocol'
[execute: parag | |
	↑class  parag].
"130" SelectorPane$'Browser protocol'
[compile: parag in: class under: heading | |
	↑codePane compile: parag in: class under: heading].
"91" SelectorPane$'Initialization'
[classInit | |
	editmenu ← Menu new string: 'spawn
forget'].
"355" SelectorPane$'Window protocol'
[yellowbug | t1 |
	selection = 0
	  ifTrue: [window flash]
	  ifFalse: [scrollBar hidewhile [
			((t1 ← editmenu bug) = 1
			  ifTrue: [organizationPane spawn: list  selection with: codePane contents formerly: codePane oldContents]
			  ifFalse:
				[t1 = 2
				  ifTrue: [organizationPane forget: list  selection]])]]].
"82" SelectorPane$'Window protocol'
[close | |
	organizationPane ← nil.
	super close].
"160" SelectorPane$'Browser protocol'
[execute: parseStream for: t2 | |
	codePane ← t2.
	↑codePane execute: parseStream in: false to: organizationPane syntaxChoice].
"94" SelectorPane$'ListPane protocol'
[deselected | |
	codePane showing: organizationPane noCode].
"88" SelectorPane$'Browser protocol'
[compile: parag | |
	↑organizationPane compile: parag].
"110" SelectorPane$'ListPane protocol'
[selected | |
	codePane showing: (organizationPane code: list  selection)].
"62" SelectorPane$'Browser protocol'
[dirty | |
	↑codePane dirty].
"92" SelectorPane$'Initialization'
[from: t1 to: t2 | |
	organizationPane ← t1.
	codePane ← t2].
"727" BrowseWindow$'Initialization'
[default | systemPane classPane orgPane selectorPane codePane |
	 "Let the user draw a five-paned window to browse through classes."
	systemPane ← SystemPane new "Create the panes.".
	classPane ← ClassPane new.
	orgPane ← OrganizationPane new.
	selectorPane ← SelectorPane new.
	codePane ← CodePane new "Acquire them.".
	self title: 'Classes' with: {systemPane , classPane , orgPane , selectorPane , codePane} at: stdTemplates.
	self newframe.
	self show "Interconnect them.".
	systemPane to: classPane.
	classPane from: systemPane to: orgPane.
	orgPane from: classPane to: selectorPane.
	selectorPane from: orgPane to: codePane.
	codePane from: selectorPane "Display them.".
	systemPane update].
"187" BrowseWindow$'Initialization'
[classInit | |
	stdTemplates ← {(0  0 rect: 10  14) , (10  0 rect: 18  14) , (18  0 rect: 28  14) , (28  0 rect: 36  14) , (0  14 rect: 36  36)}].
"799" UserView$'Screen Views'
[bugScreenMenu | n i t3 |
	(t3 ← screenMenu bug) = 1
	  ifTrue:
		[projectWindow  nil
		  ifFalse: [projectWindow runParent]]
	  ifFalse:
		[t3 = 2
		  ifTrue: [user snapshot]
		  ifFalse:
			[t3 = 3
			  ifTrue: [user quit]
			  ifFalse:
				[t3 = 4
				  ifTrue: [self schedule: ProjectWindow init]
				  ifFalse:
					[t3 = 5
					  ifTrue: [self schedule: BrowseWindow default]
					  ifFalse:
						[t3 = 6
						  ifTrue: [self schedule: (CodeWindow new class: UserView selector: #workspace para: (UserView code: #workspace) formerly: false)]
						  ifFalse:
							[t3 = 7
							  ifTrue:
								[n ← Turtle init.
								n color: black.
								n width: 4.
								n inking: oring.
								(1 to: 50) do:
									[:i | n go: i * 4.
									n turn: 89]]]]]]]]].
"91" UserView$'Screen Views'
[color: t1 scale: t2 | |
	color ← t1.
	scale ← t2.
	self install].
"397" UserView$'As yet unclassified'
[NTshrink | i j |
	self NTshrink1.
	UserView understands: 'NTshrink1' "1st time only".
	Undeclared init.
	(1 to: USTable length) do: [:i |  "delete obsolete atoms"
		(1 to: (USTable  i) length) do:
			[:j | (USTable  i  j) refct = 1
			  ifTrue: [USTable  i  j ← nil]]].
	#a rehash "shrink USTable".
	user  'disp' of: (String new: 256) "reduce disp buffer"].
"75" UserView$'Window Scheduling'
[promote: window | |
	sched promote: window].
"150" UserView$'Mouse, Cursor, Keys'
[kbck | t |
	(t ← self rawkbck)
	  ifTrue: [↑kbMap  t].
	NoteTaker
	  ifTrue: [↑false].
	self purgealittle.
	↑false].
"90" UserView$'Dialog Window'
[clear | |
	 "clear disp of debris and characters"
	disp clear].
"90" UserView$'Mouse, Cursor, Keys'
[waitbug | |
	[self anybug] whileFalseDo:  [].
	↑self mp].
"331" UserView$'Time'
[dateAndTime: secs | |
	↑self convertTime: (self rawtotalsecs: secs) "secs is a String of 4 characters representing seconds (in GMT) since Jan 1 1901.
	convert it to a LargeInteger (rawtotalsecs:), then return a Vector (Date, Time),
	which is corrected for local time zone and daylight savings" returnSecs: false].
"336" UserView$'Time'
[rawtotalsecs: secs | s |
	s ← Natural new: 4 "secs is a String of 4 characters representing seconds (in GMT) since Jan 1 1901.
	copy (in reverse order) to a Natural string, then return a LargeInteger".
	s  1 ← secs  4.
	s  2 ← secs  3.
	s  3 ← secs  2.
	s  4 ← secs  1.
	↑LargeInteger new bytes: s neg: false].
"163" UserView$'Time'
[totalsecs: secs | |
	↑self convertTime: (self rawtotalsecs: secs) "convert from GMT to local and correct for Daylight Savings" returnSecs: true].
"58" UserView$'Window Scheduling'
[topWindow | |
	↑sched  1].
"272" UserView$'System quit/resume'
[st80FileInit | |
	 " user st80FileInit. "
	dp0 release.
	SourceFiles ← Vector new: 4.
	SourceFiles  1 ← dp0 file: 'ST80Sources.v00'.
	(SourceFiles  1) readonly.
	SourceFiles  2 ← dp0 file: 'ST80Changes.v00'.
	(SourceFiles  2) readonly].
"123" UserView$'Mouse, Cursor, Keys'
[yellowbug | |
	↑self buttons "From Smalltalk 5.4i on 30 October 1979 at 2:28:57 pm." = 2].
"599" UserView$'Misc System Stuff'
[file: file classes: classes changesOnly: ch | cl |
	 "called by UserView release to write just changes or entire system on a
	new file.  also, see comment in Class archiveOn:changesOnly:.

	write class comment and message text onto a FileStream (which could refer
	to an AltoFile, ILFile, etc.). either just changes or everything are
	written and replaced with RemoteParagraph references"
	ch
	  ifTrue: [file settoend]
	  ifFalse: [file reset].
	file readwriteshorten.
	classes do: [:cl | Smalltalk  cl archiveOn: file changesOnly: ch].
	file close.
	file readonly].
"70" UserView$'As yet unclassified'
[save | |<primitive: 75>
	user croak].
"381" UserView$'Window Scheduling'
[restartup: window | |
	NoteTaker
	  ifTrue: [ "Equivalent to schedule new window, restart, and redbug in window, except firsttime is already done."
		self schedule: window]
	  ifFalse:
		[thisContext sender releaseFully.
		thisContext sender← nil.
		NormalCursor topage1.
		self schedule: window.
		thisContext tempframe all← nil.
		self run: true]].
"290" ILFileDirectory$'Dictionary'
[Find: file | |
	↑self openFile: file mode:  "since there can be many readers but only one writer, default mode is for
	read only. writing will cause file to be closed and reopened for writing"
	(file type = write
	  ifTrue: [WriteOld]
	  ifFalse: [ReadOld])].
"102" ILFileDirectory$'IFS'
[allocatePage | |
	isocket  nil
	  ifTrue: [self open].
	↑isocket freePacket].
"58" ILFile$'IFS'
[allocatePage | |
	↑directory allocatePage].
"180" ILFile$'File'
[endFile: page | |
	self writeMode: page "make sure we can write" "update length. this will end file with this page".
	lastpn ← page pageNumber.
	↑self Write: page].
"280" ILFile$'File'
[Read: page | |
	page pageNumber > lastpn
	  ifTrue: [↑false].
	 "no page" "don't extend beyond eof. length of page is 0, but request is for 512 bytes"
	page mode: NoExtend.
	page header: 5 ← 512 "self dataLength".
	↑self doCommand: Read page: page error: 'Read:'].
"345" ILFilePage$'IFS'
[mode: m | |
	page  29 ← (page  29 "current meaning of 5 read/write bits (from high to low):
		0-1
			0 read or write anywhere
			1 no holes (read or write) zeros past end
			2 don't extend on read or write
			3 check extend (Error)
		2
			1 set eof
		3-4
			0 undefined" "m is a byte which is already shifted" land: 7) + m].
"123" ILFilePage$'FilePage'
[serialNumber | sn |
	sn ← String new: 4.
	sn  1 ← sn  2 ← 0.
	sn word: 2 ← self header: 2.
	↑sn].
"75" ILFilePage$'FilePage'
[serialNumber: sn | |
	self header: 2 ← sn word: 2].
"338" ILFilePage$'FilePage'
[length: len | |
	self header: 1 ← 10 + len "10 bytes in a normal header block. ILParameterBlock can change things.
	also negative lengths can shorten it and change pupLength" "length of command block, including data" "number of data bytes to read/write".
	self header: 5 ← len "set pupLength".
	super length: len].
"57" ILFilePage$'FilePage'
[headerLength | |
	↑34 "4+20+10"].
"79" ILFilePage$'FilePage'
[length | |
	↑self header: 5 "valid for read or write"].
"354" ILFilePage$'FilePage'
[pageNumber | |
	↑((self header: 3) "extract page number from 27-bit byte address. ignore high 5 mode bits.
	dividing byte adress (which may be a LargeInteger) by self dataLength (512)
	is the correct but slow way to do this. byte address 0 = page 1" land: 2047) * 128 "lshift: 7, maybe large" + ((self header: 4) lshift: 9) + 1].
"197" ILFilePage$'FilePage'
[pageNumber: pn | |
	pn ← pn - 1 "inverse of pageNumber. set 5 mode bits to 0".
	self header: 3 ← pn / 128 "lshift: 7, except for large pn".
	self header: 4 ← pn lshift: 9].
"447" ILFilePage$'IFS'
[command: com | |
	page pupType← LeafType "operation word (header 1)
		0-4
			opcode
		5
			0 request
			1 answer
		6-15
			inclusive byte length of operation block" "make operation a request, preserve length set earlier".
	page  25 ← (page  25 land: 3) + (com lshift: 3) "left half pupID1".
	page  11 ← (com = Reset
	  ifTrue: [OpenConnection]
	  ifFalse:
		[com = Quit
		  ifTrue: [DestroyConnection]
		  ifFalse: [Data]])].
"117" EtherFilePage$'FilePage'
[init | |
	page  nil
	  ifTrue: [page ← file allocatePage "self page:"].
	self length: 0].
"89" EtherFilePage$'FilePage'
[length: len | |
	page pupLength← len + self headerLength - 2].
"60" EtherFilePage$'FilePage'
[dataString | |
	↑page pupString].
"112" EtherFilePage$'FilePage'
[headerLength | |
	↑44 "ethernet encap.(4), pup header(20), file label (20=default)"].
"82" EtherFilePage$'FilePage'
[length | |
	↑page pupLength - (self headerLength - 2)].
"61" EtherFilePage$'FilePage'
[trailerLength | |
	↑2 "checksum"].
"178" EtherFilePage$'FilePage'
[header: n | |
	↑page word: 12 + n "for accessing information after pup header, e.g. file commands and parameters.
	n = 1 to (self headerLength-24)/2"].
"52" EtherFilePage$'Ether'
[pupType | |
	↑page pupType].
"58" EtherFilePage$'Ether'
[pupType← p | |
	↑page pupType← p].
"72" EtherFilePage$'FilePage'
[header: n ← v | |
	↑page word: (12 + n) ← v].
"43" EtherFilePage$'Ether'
[packet | |
	↑page].
"51" ILFile$'Dictionary'
[entryClass | |
	↑ILFilePage].
"885" ILFile$'File'
[classInit | i sym names |
	ILFilePool declare: #NotFound as: '207' "ILFile classInit.".
	names ← #(1011 (BadLeafHandle ) 1024 (AnswerBit ) 1024 (RequestBits ) 176 (LeafType ) 0 (Error Open Close Delete ) 6 (Read Write Reset ) 96 (SetEof ) 128 (NoExtend ) 64 (NoHoles ) 6400 (WriteOld ) 30976 (ReadOld ) 4224 (CreateNew ) 0 (Data Ack Noop ) 5 (OpenConnection ) 9 (DestroyConnection Dally Quit BrokenConnection ) ) asStream "5-bit operations for left field command block word" "read/write modes" "no holes, set eof" "don't extend file on read or write" "for writing past end" "open file modes" "read, write, extend, any explicit, highest" "read, any explicit, highest" "read, write, extend, create, any explicit, next" "control codes for left half of pupID1 field" "if Reset".
	names do: [:i | names next do:
			[:sym | ILFilePool declare: sym as: i.
			i ← i + 1]]].
"134" ILFile$'File'
[close | |
	self close:  "ignore errors if file was readonly"
	(type = read
	  ifTrue: [false]
	  ifFalse: ['close'])].
"1313" ILFile$'File'
[doCommand: com page: page error: e | in ecode t6 |
	page command: com.
	[true] whileTrueDo:
		[directory open "make sure connection is open".
		error ← nullString.
		(in ← directory socket sendPacket: page packet)
		  ifTrue:
			[in  11 = BrokenConnection
			  ifTrue: [ecode ← 1]
			  ifFalse:
				[ "turn packet into a ILFilePage"
				in ← ((t6 ← self entryClass new) dictionary: self.
						t6 page: in) "check if answer is of same type as request".
				((page header: 1) land: RequestBits) + AnswerBit = ((in header: 1) land: RequestBits)
				  ifTrue: [↑in].
				ecode ← in header: 2]]
		  ifFalse: [ "no response?"
			ecode ← false] "some kind of problem".
		com = Quit
		  ifTrue: [↑false].
		 "ignore"
		(ecode  false or: [ecode = 1])
		  ifTrue: [directory release "make new connection"].
		(ecode = 1 or: [ecode = 1011])
		  ifTrue:
			[self reopen "try again after some reinitializing" "reopen file" "init page with new handle only -- don't lose mode, length, etc.".
			page serialNumber: serialNumber]
		  ifFalse:
			[error ← (ecode
					  ifTrue:
						[e
						  ifTrue: [self errorString: ecode]
						  ifFalse: [ecode asString]]
					  ifFalse: [directory directory + ' not responding']).
			e
			  ifTrue: [self error: e "proceeding tries again"]
			  ifFalse: [↑false]]]].
"1316" ILFile$'File'
[errorString: errorCode | ef ename errorString notfound dollar cr t8 |
	(errorCode is: String)
	  ifTrue:
		[errorString ← errorCode.
		errorCode ← ((errorString  1) isdigit
				  ifTrue: [errorString asInteger]
				  ifFalse: [0])]
	  ifFalse: [errorString ← errorCode asString].
	ename ← '<System>Ifs.Errors'.
	(self name compare: ename) = 2
	  ifTrue: [↑errorString + ' (cannot access Ifs.Errors !!!)' "recursion"].
	notfound ← errorString + '	(error code not found)'.
	errorCode  0
	  ifTrue: [↑notfound].
	dollar ← '$'  1.
	cr ← 13.
	ef ← directory oldFile: ename.
	ef readonly.
	errorString ← false "scan through the errors file looking for lines of the form:
$$nn	some message
".
	[errorString] whileFalseDo: 
		[(ef skipTo: dollar)
		  ifTrue:
			[ef next = dollar
			  ifTrue:
				[(t8 ← ef integerScan "valid line") > errorCode
				  ifTrue: [errorString ← notfound "since errors are ordered"]
				  ifFalse:
					[t8 = errorCode
					  ifTrue:
						[errorString ← (String new: 200) asStream.
						errorString print: errorCode.
						[ef peek = dollar or: [ef peek = cr]] whileFalseDo: 
							[errorString append: (ef upto: cr).
							errorString space].
						errorString ← errorString contents]]]]
		  ifFalse: [ "end of file"
			errorString ← notfound]].
	ef close.
	↑errorString].
"385" ILFile$'File'
[writeMode: page | |
	type = write "make sure we can write on file"
	  ifFalse:
		[ "turn on writing by closing and reopening file. eventually there might be
	a simpler way to change file mode"
		self close.
		type ← write.
		(directory Find: self)
		  ifTrue: [page serialNumber: serialNumber "file handle changed"]
		  ifFalse: [self error: 'file failed to reopen']]].
"69" ILFile$'File'
[findLastPage | |
	↑lastpn "already known from open"].
"245" ILFile$'File'
[close: e | p |
	type ← read "close file, possibly ignoring errors" "for next open" "shorten header block to first 2 words: command&length,  file handle".
	p ← self newPage.
	p length: 6.
	self doCommand: Close page: p error: e].
"392" ILFile$'File'
[Write: page | pn |
	(pn ← page pageNumber) > (lastpn + 1)
	  ifTrue: [self error: 'illegal page number']
	  ifFalse:
		[ "make sure we can write"
		self writeMode: page.
		page mode: (pn  lastpn
		  ifTrue: [SetEof]
		  ifFalse: [NoHoles]).
		self doCommand: Write page: page error: 'Write:' "file possibly extended".
		pn = (lastpn + 1)
		  ifTrue: [lastpn ← pn].
		↑page]].
"78" ILFile$'File'
[open | |
	 "do nothing. lastpn set by ILFileDirectory Find:"].
"48" ILFile$'File'
[release | |
	self close: false].
"56" ILFileDirectory$'Dictionary'
[entryClass | |
	↑ILFile].
"46" ILFileDirectory$'IFS'
[socket | |
	↑isocket].
"86" ILFileDirectory$'IFS'
[name: t1 password: t2 | |
	userName ← t1.
	userPassword ← t2].
"221" ILFileDirectory$'Dictionary'
[Delete: file | t2 |
	(t2 ← file newPage "delete a file (highest version)
	shorten header block to 2 words: command&length,  file handle") length: 6.
	t2 doCommand: Delete error: 'Delete:'].
"164" ILFileDirectory$'Dictionary'
[Insert: file | |
	file type: write.
	(self openFile: file mode: CreateNew)
	  ifTrue: [↑file].
	file error: 'Insert: cannot create'].
"58" ILFileDirectory$'Dictionary'
[versionNumbers | |
	↑true].
"61" ILFileDirectory$'Dictionary'
[obsolete | |
	↑isocket  nil].
"95" ILFileDirectory$'IFS'
[noAck | |
	isocket noAck "an optimization for intense ether activity"].
"118" ILFileDirectory$'IFS'
[userName | |
	(userName  nil or: [userName empty])
	  ifTrue: [↑super userName].
	↑userName].
"284" ILSocket$'Socket'
[timerFired | |
	(result or: [abortTransfer]) "timer has fired -- retransmit or abort"
	  ifFalse:
		[ "bug?--timer may not have been disabled yet"
		self timerOn
		  ifTrue: [self completePup: outPac "retransmit"]
		  ifFalse: [ "abort"
			abortTransfer ← true]]].
"381" ILSocket$'Socket'
[socProcess: Ipac | |
	(Ipac  12 "check if this is a packet we want. normally left half of pupID1 = Data (0).
	in case of DestroyConnection, control code might be Dallying (10)" "pupID1" = seqNum and: [Ipac pupType = LeafType])
	  ifTrue:
		[self timerOff "turn off timer, save result".
		result ← Ipac]
	  ifFalse: [ "recycle packet"
		self freePacket: Ipac]].
"1346" ILSocket$'Socket'
[sendPacket: t1 | nseq |
	outPac ← t1.
	result ← abortTransfer ← false "send a packet, wait for result, and acknowledge.
	RetransmitSocket setAddressesAndComplete: sets timer
	ILSocket socProcess: receives answers
	ILSocket timerFired handles retransmissions" "alloc, receiver seq".
	outPac pupID0← outPac  12 ← seqNum "command, send seq" "pupID1 ← (outPac pupID1 land: 0177400) +".
	self setAddressesAndComplete: outPac "while waiting for packet to arrive, set up ack".
	nseq ← seqNum + 1 \ 256.
	outPac  11 = DestroyConnection
	  ifTrue:
		[ "assume reply will be Dally. send Quit to shut down connection a little faster"
		outAck
		  ifFalse:
			[ "create ack"
			self setAck.
			outAck pupID0← outAck  12 ← seqNum].
		outAck  11 ← Quit.
		retransMax ← 0 "same sequence numbers as previous"]
	  ifFalse:
		[outAck
		  ifTrue: [outAck pupID0← outAck  12 ← nseq "acknowledgement for Open & Data"] "in rapid interchanges, the next request is an implicit ack, so it's faster not to send one. however, packets unacknowledged for ~5 secs. at the server end can cause degraded performance"] "now wait for socProcess: to set result, or timerFired to set abortTransfer".
	[result or: [abortTransfer]] whileFalseDo:  [].
	result
	  ifTrue:
		[seqNum ← nseq.
		outAck
		  ifTrue: [self completePup: outAck "send ack"]].
	↑result].
"84" ILSocket$'Socket'
[noAck | |
	outAck ← false "if acknowledgements are not needed"].
"204" ILSocket$'Socket'
[setAck | |
	outAck ← self freePacket "create acknowledgement packet".
	outAck pupType← LeafType.
	outAck dataString← '' "control code".
	outAck  11 ← Ack.
	self setAddresses: outAck].
"226" ILSocket$'Socket'
[net: n host: h | |
	seqNum ← 0 "usually called by hostName:".
	super net: n host: h soc: 35 asInt32.
	self retransmit: 8 every: (n = NETNUM
	  ifTrue: [400]
	  ifFalse: [ "same net"
		1800]).
	self setAck].
"147" ILParameterBlock$'Initialization'
[packet← t1 | |
	packet ← t1.
	self position: 26 "default is an empty (data) packet, except first header word"].
"165" ILParameterBlock$'Changing values'
[nextword← w | strm |
	strm ← packet pupString asStream.
	strm skip: position.
	strm nextword← w.
	self position: strm position].
"209" ILParameterBlock$'Changing values'
[nextString← s | strm |
	strm ← packet pupString asStream.
	strm skip: position.
	strm nextword← s length.
	strm append: s.
	strm padNext← 0.
	self position: strm position].
"239" ILParameterBlock$'Changing values'
[position: t1 | |
	position ← t1.
	packet pupLength← position - 2 "changing length of data in packet" "set inclusive byte length in first command word; rest set later".
	packet word: 13 ← position - 24].
"604" ILFileDirectory$'Dictionary'
[open | page t2 |
	isocket  nil "self obsolete"
	  ifTrue:
		[(isocket ← ILSocket new hostName: directory "name of IFS/Leaf server")
		  ifFalse:
			[isocket ← nil.
			user notify: directory + ' (name not found)'].
		super open.
		page ← self newPage "treat packet in page as a parameter block".
		(t2 ← ILParameterBlock new) packet← page packet.
		t2 nextword← 0 "host number (0 = this, 1 = all)".
		t2 nextString← self userName.
		t2 nextString← self userPassword.
		(page doCommand: Reset error: false)
		  ifFalse:
			[isocket ← nil.
			user notify: 'open (reset)']]].
"271" ILFileDirectory$'Dictionary'
[release | t1 |
	self obsolete
	  ifFalse:
		[ "shorten header block to 0 words.
	DestroyConnection. after this the connection is gone"
		(t1 ← self newPage) length: 10.
		t1 doCommand: Quit error: false.
		isocket close.
		isocket ← nil]].
"1273" ILFileDirectory$'IFS'
[openFile: file mode: m | page t4 |
	self open "open bit modes
	read
	write
	extend
	multiple (0)
	create name
	explicit version in name (2b)
		no, old, next or old, any
	default (if no version specified) (2b)
		no, lowest, highest, next
	unused (7b)".
	page ← file newPage "treat packet in page as a parameter block".
	(t4 ← ILParameterBlock new) packet← page packet.
	t4 nextword← 0 "file handle".
	t4 nextword← m "modes".
	t4 nextString← self userName.
	t4 nextString← self userPassword.
	t4 nextString← '' "connect name".
	t4 nextString← '' "connect password".
	t4 nextString← self checkName: file name "answer bits (in page header: 5)
	same (5b)
	version (4b)
		bad, default lowest, default highest, default next, !*, !L, !H, !N, explicit old, explicit lowest, explicit highest, explicit next, explicit new, explicit-less, explicit between, explicit greater".
	(page ← file doCommand: Open page: page error: false)
	  ifTrue:
		[file serialNumber: page serialNumber "open returns file length".
		file lastPage: (page pageNumber - (((page header: 4) land: 511) = 0
		  ifTrue: [1]
		  ifFalse: [ "full last page"
			0]) max: 1)]
	  ifFalse:
		[file error = NotFound
		  ifTrue: [↑false].
		↑file error: 'open ' + (file errorString: file error)]].
"138" ILFileDirectory$'IFS'
[userPassword | |
	(userPassword  nil or: [userPassword empty])
	  ifTrue: [↑super userPassword].
	↑userPassword].
"875" UserView$'Misc System Stuff'
[release | m |
	(m ← Undeclared contents "prepare to release this version (after editing UserView version)
	and possibly copying Sources file (see writeSources:)") length > 0
	  ifTrue: [user notify: 'Undeclared contains ' + m asString]
	  ifFalse:
		[user displayoffwhile [
			(m ← Sources directory "either create a new Sources file (write all messages) or append only changes" checkName: '<Smalltalk>Smalltalk.Sources.' + user versionName "for repeated releases in same version.
		should also work for Sources local (if renamed)".
			user writeSources: (m = Sources name
			  ifTrue: [Sources]
			  ifFalse: [Sources directory file: m]) "make workspace local".
			UserView md code: #workspace ← UserView code: #workspace.
			user writeChangedMessages: (phylum file: '<Smalltalk>ChangedMessages'))].
		user noChanges.
		user releaseMessage]].
"78" UserView$'As yet unclassified'
[primKbdPeek | |<primitive: 44>
	↑self croak].
"78" UserView$'As yet unclassified'
[primKbdNext | |<primitive: 45>
	↑self croak].
"208" UserView$'Window Scheduling'
[restart | i |
	Events  nil
	  ifTrue:
		[Events ← EventQueue init "Top init3.  initialize Event queue and Time interrupt"].
	NormalCursor topage1.
	self restart [(user run)]].
"200" UserView$'Mouse, Cursor, Keys'
[cursorloc← pt | |
	NoteTaker
	  ifTrue: [↑self primCursorLoc← pt - (mxoffset  myoffset)].
	mem  276 ← pt x - mxoffset * scale.
	mem  277 ← pt y - myoffset * scale].
"96" UserView$'Dialog Window'
[frame | |
	 "return rectangle of dialogue window"
	↑disp text frame].
"119" VariableLengthClass$'Initialization'
[classInit | |
	 "gets propagated to a dummy instance"
	(self new: 1) classInit].
"269" VariableLengthClass$'Instance access'
[allInstances | |
	user notify: 'use allInstances: instead to specify the length range' "the length ranges are 0,1,2,3,4,5,6,7,8 individually and groups 9 (to 16), 17 (to 32), 33 (to 64), 65, 129, 257, 513, 1025, 2049, and 4197"].
"214" VariableLengthClass$'Instance access'
[howMany: len | v |
	 "how many instances of this class and length are in use now?"
	v ← self allInstancesEver: len.
	thisContext destroyAndReturn: v length - (v count: nil)].
"405" VariableLengthClass$'Instance access'
[new: length | |<primitive: 30>
	length > 16384
	  ifTrue: [user notify: length asString + ' is too big a String']
	  ifFalse:
		[length > 8192
		  ifTrue: [user notify: length asString + ' is too big a Vector']
		  ifFalse:
			[length < 0
			  ifTrue: [user notify: length asString + ' -- negative length is invalid']
			  ifFalse: [↑self new: length asInteger]]]].
"142" VariableLengthClass$'Instance access'
[copy: inst | t i |
	t ← self new: inst length.
	(1 to: inst length) do: [:i | t  i ← inst  i].
	↑t].
"153" VariableLengthClass$'Instance access'
[recopy: inst | t i |
	t ← self new: inst length.
	(1 to: inst length) do: [:i | t  i ← (inst  i) recopy].
	↑t].
"602" VariableLengthClass$'Instance access'
[allInstancesEver: len | indx vec PCLs i |
	 "returns a vector containing all instances of this class and length mixed with nils"
	NoteTaker
	  ifTrue: [user notify: 'not implemented']
	  ifFalse:
		[ "for large lengths, instances come in groups with lengths within a single power of 2"
		PCLs ← Vmem pclassesOf: self length: len "vector of PCLs".
		vec ← Vector new: 128 * PCLs length.
		(1 to: PCLs length) do: [:i | vec  (i - 1 * 128 + 1 to: i * 128) all← PCLs  i].
		thisContext destroyAndReturn: (self fromFreelist: (Vmem freelistOffset: len) fill: vec)]].
"101" VariableLengthClass$'Instance access'
[allInstances: len | |
	↑(self allInstancesEver: len) notNil].
"97" VariableLengthClass$'Instance access'
[new | |
	user notify: 'use new: <Integer=length> here.'].
"63" VariableLengthClass$'Instance access'
[isVariable | |
	↑true].
"423" UserView$'Misc System Stuff'
[classNames | classes x c |
	 "an alphabetized Vector of all Smalltalk class titles uniqued"
	AllClassNames  nil
	  ifTrue:
		[classes ← (Vector new: 20) asStream.
		Smalltalk do:
			[:x | c ← Smalltalk  x.
			((c is: Class) or: [(c is: VariableLengthClass)])
			  ifTrue: [classes next← x]
			  ifFalse:
				[]].
		AllClassNames ← classes contents sort]
	  ifFalse:
		[.
		↑AllClassNames]].
"66" UserView$'Mouse, Cursor, Keys'
[nobug | |
	↑self anybug  false].
"156" UserView$'System quit/resume'
[hasXM | |
	NoteTaker
	  ifTrue: [ "return true if this is XM Smalltalk"
		↑true].
	↑mem  103  0 "1 for XM, 0 for normal"].
"69" UserView$'System quit/resume'
[quit | |
	self quitFrom: self "yup"].
"43" UserView$'Time'
[time | |
	↑self now  2].
"355" UserView$'Mouse, Cursor, Keys'
[kbd: char | |
	 "stuff char into the event queue"
	(char is: String)
	  ifTrue: [char ← char  1].
	Events next← UserEvent new x: self x "event x" y: self y "event y" type: 1 stroke: (kbMap find: char) "2=up, 1=down" elapsed: Events elapsedtime "1-336" "1-32767 sixtieths of a sec" time: Events time + Events elapsedtime].
"59" UserView$'System quit/resume'
[Swat | |<primitive: 75>
	].
"360" UserView$'System quit/resume'
[releaseExternalViews | t |
	Sources close "close some things that we know about, everything else gets released".
	dp0 close.
	dp1 close "release (obsolete) some external views, usually File related".
	(externalViews length to: 1 by: 1) do:
		[:t | (externalViews  t) release.
		externalViews  t ← nil].
	externalViews reset].
"341" UserView$'As yet unclassified'
[calibrate | t1 t2 |
	user primPort: 330 mask: 0 ← 32 "center display".
	((50  50) asRectangle inset: 4) comp.
	((550  350) asRectangle inset: 4) comp.
	user waitclickbug.
	t1 ← (user touchPrim: 1)  (user touchPrim: 0).
	user waitclickbug.
	t2 ← (user touchPrim: 1)  (user touchPrim: 0).
	↑t1 rect: t2].
"315" UserView$'As yet unclassified'
[mapDisplay | t1 |
	(DisplayBLTer ← BitBlt init) sourceForm: DisplayForm.
	DisplayBLTer destForm: DisplayForm.
	(t1 ← BitBlt init) sourceForm: currentCursor asForm.
	t1 destForm: DisplayForm.
	t1 sourceRect: (0  0 rect: currentCursor extent).
	t1 effect: oring.
	t1 installDisplay].
"65" UserView$'Mouse, Cursor, Keys'
[bluebug | |
	↑self buttons = 1].
"64" UserView$'Mouse, Cursor, Keys'
[anykeys | |
	↑self keyset > 0].
"237" UserView$'Mouse, Cursor, Keys'
[buttons | t |
	NoteTaker
	  ifTrue: [↑self primMouseKeys land: 7].
	t ← 7 - (mem  488 land: 7).
	t = 0
	  ifTrue: [↑t].
	↑(t land: 1) * 2 + ((t land: 2) "force red-yel-blu to 4-2-1" / 2) + (t land: 4)].
"83" UserView$'As yet unclassified'
[cursorLink: bool | |<primitive: 75>
	↑self croak].
"316" UserView$'As yet unclassified'
[displayHeight: h | |
	h ← h | 16.
	DisplayForm refct > 4
	  ifTrue: [user croak]
	  ifFalse:
		[user currentDisplay: (Form new extent: 640  16 bits: (String new: 16 * 80) offset: nil).
		user currentDisplay: (Form new extent: 640  h bits: (String new: h * 80) offset: nil).
		↑h]].
"84" UserView$'As yet unclassified'
[primCursorLoc← pt | |<primitive: 43>
	↑self croak].
"919" UserView$'As yet unclassified'
[NTpreshrink | i |
	Class derstands: #(archiveOn:changesOnly: asFollows bytesof: changelist: endCategoryOn: endChangesOn: filout filoutCategory: filoutOrganization paraprinton: printCategory:on: printMethod:on: printout printoutCategory: readfrom: readfrom:format: startCategory:on: startChangesOn: textLocal ).
	UserView derstands: #(backup changedClasses file:classes:changesOnly: hasXM initCompiler makeSources: oopsToFile printCrossReference: quitFrom: reclaim release sourcesTo:changesOnly: systemStartup time NTpreshrink ).
	Paragraph derstands: #(bravoRuns fromBravo toBravo applyBravo:at:to: ).
	Form derstands: #(newbrush: blinkbrush: line: arc: resize: edit: classInit ).
	Number derstands: #hex4.
	{Form , Paragraph , TextImage} do: [:i | i derstands: #(hidePress:complete: fromPress:value: presson:in: )].
	gJuniperConstants ← WoodstockFilePool ← nil.
	AllClassNames ← nil].
"347" UserView$'Mouse, Cursor, Keys'
[kbdnext | event |
	NoteTaker
	  ifTrue:
		[self kbck
		  ifTrue: [↑self kbd].
		↑false]
	  ifFalse:
		[ "returns next character (mapped) if any; otherwise false"
		[(event ← Events dequeue) or: [(event ← Events primitiveDequeue)]] whileTrueDo:
			[event isKbdDown
			  ifTrue: [↑kbMap  event stroke]].
		↑false]].
"375" UserView$'Mouse, Cursor, Keys'
[rawkbck | event rdpt stroke |
	 "flush events until key down or no event."
	(NoteTaker and: ['NoEventQ'])
	  ifTrue:
		[[stroke ← user primKbdPeek] whileTrueDo:
			[stroke  0
			  ifTrue: [↑stroke].
			user primKbdNext].
		↑false].
	[event ← Events peek] whileTrueDo:
		[event isKbdDown
		  ifTrue: [↑event stroke].
		Events next].
	↑false].
"1262" UserView$'As yet unclassified'
[NTshrink1 | i |
	Class derstands: #(archiveOn:changesOnly: asFollows bytesof: changelist: endCategoryOn: endChangesOn: filout filoutCategory: filoutOrganization paraprinton: printCategory:on: printMethod:on: printout printoutCategory: readfrom: readfrom:format: startCategory:on: startChangesOn: textLocal ).
	UserView derstands: #(backup changedClasses convertTime:returnSecs: file:classes:changesOnly: growSmalltalk: hasXM initCompiler InLd: makeSources: now oopsToFile overlay: printCrossReference: quitFrom: rawtotalsecs reclaim release releaseExternalViews sourcesTo:changesOnly: systemStartup ticks time time timewords today totalsecs ).
	Paragraph derstands: #(bravoRuns fromBravo toBravo applyBravo:at:to: ).
	Form derstands: #(newbrush: blinkbrush: line: arc: resize: edit: classInit ).
	Number derstands: #hex4.
	{Form , Paragraph , TextImage} do: [:i | i derstands: #(hidePress:complete: fromPress:value: presson:in: )].
	EtherPool ← gJuniperConstants ← AltoFilePool ← WoodstockFilePool ← nil.
	Smalltalk do:
		[:i |  "delete unused globals, esp clamped classes"
		((Smalltalk ref: i) refct = 1 and: [Smalltalk  i  nil])
		  ifTrue:
			[Smalltalk delete: i.
			SystemOrganization delete: i]].
	AllClassNames ← nil].
"330" UserView$'As yet unclassified'
[NTshrink2 | i j |
	 "prompt for deleting unrefd messages"
	self classNames do: [:i | (Smalltalk  i) md do:
			[:j | user redbug
			  ifFalse:
				[j refct = 4
				  ifTrue:
					[ "UST, md, contents, j"
					(user request: i + ' ' + j) length = 0
					  ifTrue: [Smalltalk  i derstands: j]]]]]].
"78" UserView$'As yet unclassified'
[primEIANext | |<primitive: 75>
	↑self croak].
"44" UserView$'Dialog Window'
[cr | |
	disp cr].
"80" UserView$'As yet unclassified'
[primMouseKeys | |<primitive: 46>
	↑self croak].
"78" UserView$'As yet unclassified'
[primMousePt | |<primitive: 42>
	↑self croak].
"92" UserView$'As yet unclassified'
[primPort: n mask: m ← val | |<primitive: 75>
	↑self croak].
"216" UserView$'As yet unclassified'
[touchPrim: channel | t |
	self primPort: 96 mask: 0 ← channel + 1 * 256.
	self primPort: 256 mask: (1 - 448) ← channel.
	t ← self primPort: 448.
	self primPort: 96 mask: 0 ← 0.
	↑t].
"260" UserView$'Mouse, Cursor, Keys'
[mp | |
	NoteTaker
	  ifTrue: [↑self primMousePt + (mxoffset  myoffset)].
	scale = 2
	  ifTrue: [↑Point new x: mem  276 + mxoffset / 2 y: mem  277 + myoffset / 2].
	↑Point new x: mem  276 + mxoffset y: mem  277 + myoffset].
"46" UserView$'Dialog Window'
[tab | |
	disp tab].
"79" UserView$'As yet unclassified'
[notifyNT: pString | |
	↑self notify: pString].
"294" UserView$'System quit/resume'
[snapshot | i |
	 "write the OT and Data of this Smalltalk out"
	(1 to: 4) do:
		[:i | SourceFiles  i  nil
		  ifFalse: [(SourceFiles  i) close]].
	dp0 close.
	dp1 close.
	InitialContext ← thisContext.
	self snapshotPrimitive.
	self mapDisplay.
	self restore].
"44" UserView$'Dialog Window'
[ev | |
	disp ev].
"52" UserView$'Mouse, Cursor, Keys'
[x | |
	↑self mp x].
"52" UserView$'Mouse, Cursor, Keys'
[y | |
	↑self mp y].
"68" UserView$'Dialog Window'
[print: x | |
	disp print: x.
	disp show].
"154" UserView$'System quit/resume'
[quitFrom: controller | |
	self overlay: #(0 0 0 0 0 ).
	self hasXM
	  ifTrue:
		[screenrect clear.
		controller restore]].
"376" UserView$'System quit/resume'
[overlay: fileid | t |
	dp0 stampBoot.
	self releaseExternalViews "put the ethernet to sleep".
	E  nil
	  ifFalse: [E sleep] "turn off display during quit/resume".
	t ← mem  272.
	mem  272 ← 0.
	self InLd: fileid "we start here after a resume".
	mem  272 ← t.
	[user keyset > 0] whileTrueDo:
		[user show: 'The keyset is stuck'.
		user cr]].
"286" UserView$'Changes'
[changedClasses | titles space str |
	space ← ' '  1 "return a vector of the names of classes which have been changed".
	titles ← HashSet new init.
	Changes contents do:
		[:str | titles insert: ((Stream new of: str) upto: space) "class title"].
	↑titles contents].
"143" UserView$'Mouse, Cursor, Keys'
[kbd | |
	[self rawkbck] whileFalseDo: 
		[NoteTaker
		  ifFalse: [self purgealittle]].
	↑kbMap  self rawkbd].
"3544" UserView$'Misc System Stuff'
[version | |
	↑'Smalltalk 5.5k ' + (user hasXM
	  ifTrue: ['XM ']
	  ifFalse: ['']) + 'November 20?' "user version

low level disk address calculations are more general (necessary for 14-sector Dorado/Dolphin file systems)
better error recovery for broken and timed out Leaf connections
AltoFileDirectory disk page allocation/deallocation bugs fixed
miscellaneous printing fixes
Juniper fixes (2)
goodie: again-del-forget.st
Phylum account changes 
	default Leaf connection is logged in to <Smalltalk-User>
	system release uses [Phylum]<Smalltalk-76> instead of [Ivy]<Smalltalk>
see UserView workspace for logging into your account on Phylum, changing default printer

September 3, 5.5j
	duplicate packet fix
	fixes to ether (routing table, name lookup, phylum, Int32), printer names,
		files, UserView time messages, context simulation,
		replace in BitBlt & Paragraph, NotifyWindow cleanup,
		Class code: always decompiles with left shift key, window printing fixes,
		SystemOrganization globalComment contains no nulls
	the following changes files were included:
	[phylum]<small-goodies>
		5.5i.changes.st, notifychange.st, window-print-changes.st
	[phylum]<findit>5.5i.more.changes.st
	[maxc]<dolbec>int32change.st
	[maxc>ingalls>fixes.st
	[ivy]<kaehler>context-simulation.st
	[ivy]<borning>context-changes.st

May 1, 5.5i
	obscure file bugs eliminated; version features added (goody: File-version.st).
	Ifs multiple connections fixed; Ifs error numbers looked up in Ifs.Errors.
	duplicate packets eliminated at lowest level.
	Int32 primitive fix. Juniper retransmit parameters increased
	Integer compare: LargeInteger now works
	CodePane/FilePane 'print' (within a CodeWindow) now prints entire Paragraph
		rather than only part within window
	ScrollBars hide during CodePane again & cancel. cancel saves your old text, so
		an immediate undo will replace the current selection with your previous text.

April 11, 5.5h
	Alto file names limited to 39 characters ('somestring' asFileName will fix
		name, truncating if necessary). other misc. file, ether, simulator fixes.
	BitBlt fixed so that BitRects don't lose their bits
	BitBlt used to speedup reading&writing files, sending Press files to printers
	ParagraphScanner puts underlining into Press files
	printer names updated (PressFile classInit). hashing-changes.st included.
	after font cataclysm, get new version of Fonts.Widths before printing
	system release procedure modified

March 6, 5.5g
	ether, file, vmem writing fixes.  cursor clipping on screen boundary.
	BitBlt used for String growing, copying, replacing
	goodies included: display-off-after-notify.st, CodePane-doit.st,
		context-simfix2.st, ILchanges.st, string-changes.st

see [Phylum]<Smalltalk> for the following files.  () surround an optional prefix or suffix.
	Document.Press
		mini-guide to Smalltalk system and user interface
	VersionHistory
		information about versions up to 5.5g
	ChangedMessages
		a list of  messages which have changed
	xxx.Press
		press file for CrossReference or for system category 'xxx' in current version
		to save paper, consider consulting the LRG alcove copies
	(Xm)Small.Boot(.version)
	(Xm)Smalltalk.Syms(.version)
		older versions of .Boot and .Syms are explicitly named.
	Smalltalk.Sources.version
		all Smalltalk.Sources (including the current one) are explicitly named

[Phylum]<Small-Goodies> contains miscellaneous bug fixes and new features (and even some documentation: goodies.bravo, .press) offered by the community of Smalltalk Users.
"].
"284" UserView$'Window Scheduling'
[restart code | u |
	u ← code cleancopy.
	u sender← nil.
	thisContext sender releaseFully.
	thisContext sender← nil.
	code ← nil "release caller chain".
	MessageDict new freeMethods "release held code".
	disp frame flash.
	[true] whileTrueDo: [u eval]].
"246" UserView$'Window Scheduling'
[restore | w |
	NoteTaker
	  ifTrue:
		[Dorado
		  ifFalse: [kbMap ← NTkbMap]].
	screenrect clear.
	projectWindow  nil
	  ifFalse: [projectWindow putTitle].
	(sched length to: 1 by: 1) do: [:w | (sched  w) show]].
"94" UserView$'Screen Views'
[install | |
	self screenextent: screenrect extent tab: htab  vtab].
"62" UserView$'Time'
[now | |
	↑self dateAndTime: self timewords].
"77" UserView$'As yet unclassified'
[touched | |
	↑screenrect has: self touchPt].
"316" UserView$'As yet unclassified'
[touchPt | t1 t2 t3 |
	false
	  ifTrue: [user calibrate]
	  ifFalse:
		[ "paste result below"
		t1 ← 880  833 rect: 609  671.
		t2 ← 50  50 rect: 550  350.
		t3 ← (self touchPrim: 1) asFloat  (self touchPrim: 0) asFloat.
		↑t2 origin + (t3 - t1 origin / t1 extent * t2 extent)]].
"57" UserView$'Window Scheduling'
[run | |
	self run: false].
"66" Etherworld$'Utility messages'
[SIO: sioArg | |<primitive: 75>
	].
"318" Etherworld$'Utility messages'
[fill | outstanding |
	 "I want to replenish the freeQ"
	(freeQ  false or: [freeQ  nil])
	  ifFalse:
		[outstanding ← Pacbuf howMany - freeQ length.
		user cr.
		user show: outstanding asString + ' packets outstanding'.
		[freeQ length = 10] whileFalseDo:  [freeQ next← Pacbuf init]]].
"70" Etherworld$'Output Routines'
[doOutput: string | |<primitive: 75>
	].
"599" Etherworld$'Utility messages'
[printon: s | |
	etherState = ethDead
	  ifTrue: [s append: 'Etherworld,  etherState = ethDead.']
	  ifFalse:
		[.
		s append: 'Etherworld running on '.
		s print: NETNUM.
		s append: '#' + ALTONUM base8 + '#'.
		s cr.
		freeQ
		  ifTrue:
			[s print: freeQ length.
			s append: ' Pacbufs in freeQ']
		  ifFalse: [s append: 'no freeQ'].
		s cr.
		s append: 'etherState = '.
		etherState = ethAsleep
		  ifTrue: [s append: 'etherAsleep']
		  ifFalse:
			[.
			etherState = ethAwake
			  ifTrue: [s append: 'etherAwake']
			  ifFalse:
				[.
				s print: etherState]]]].
"1077" Etherworld$'Initialization/Termination'
[wakeup | socket |
	 "Try to get everything up and running"
	etherState = ethAwake
	  ifTrue: [self etherStart]
	  ifFalse:
		[ "do nothing, kick the receiver"
		.
		etherState = ethDead
		  ifTrue: [self sleep].
		etherState = ethAsleep
		  ifTrue:
			[ALTONUM ← self getMachineID "this is the tricky one, need to get our machine # and routing table.
		may have come up on a different network and host, assume the worst".
			self setMachineID: ALTONUM.
			NETNUM ← 0.
			sockeTable values do:
				[:socket | socket  nil
				  ifFalse: [socket setOutAddBlock]].
			etherState ← ethAwake.
			self etherStart.
			routingUpdateUser update.
			NETNUM = 0
			  ifTrue:
				[etherState ← ethAsleep.
				user notify: 'no routing tables']
			  ifFalse:
				[ "tell leftover sockets current net&host, and that we are awake again"
				sockeTable values do:
					[:socket | socket  nil
					  ifFalse:
						[socket setOutAddBlock.
						socket wakeup]]]]
		  ifFalse:
			[.
			self notify: 'In wakeup, found Ethernet in some unknown state.']]].
"85" Etherworld$'User messages'
[broadcastFilterSet: val | |<primitive: 75>
	user croak].
"1005" Etherworld$'Initialization/Termination'
[kill | socket |
	 "shuts down ethernet and PUP world completely"
	etherState = ethDead "Should free up all of the storage, etc.....
		Would need to wakeup or Init, to get started again.
		Device may have been running"
	  ifFalse:
		[ "do nothing"
		etherState = ethAwake
		  ifTrue: [self sleep].
		sockeTable values do:
			[:socket | socket  nil
			  ifFalse: [socket kill]].
		Top terminate: IntProcLevel.
		Top terminate: InputProcLevel.
		ethInPacNext
		  ifTrue:
			[ethInPacNext  nil
			  ifFalse:
				[ethInPacNext locked
				  ifTrue: [ethInPacNext unlock]]].
		ethInPacNext ← false "Release the PQueues to avoid circular data structures".
		(freeQ and: [freeQ  nil])
		  ifTrue:
			[freeQ release.
			freeQ ← nil].
		justArrivedQ  nil
		  ifTrue:
			[justArrivedQ release.
			justArrivedQ ← nil].
		routingUpdateUser  nil
		  ifFalse: [routingUpdateUser release].
		routingUpdateUser ← routingTable ← routingHopCount ← nil.
		etherState ← ethDead]].
"239" Etherworld$'Initialization/Termination'
[setLights | |
	IntLight ← Rectangle new origin: 576  0 extent: 16  16.
	InputLight ← Rectangle new origin: 592  0 extent: 16  16.
	OutputLight ← Rectangle new origin: 576  16 extent: 16  16].
"934" Etherworld$'Initialization/Termination'
[Init | i |
	 "move from state ethDead to ethAsleep"
	 "if we were already running, bring it all down, just in case!!"
	etherState = ethDead
	  ifFalse: [self kill] "now sure we are ethDead".
	NETNUM ← ALTONUM ← 0 "may get reset later".
	self setLights.
	(justArrivedQ ← SafeQ new of: (Vector new: 20)) enable.
	freeQ
	  ifTrue:
		[(freeQ ← SafeQ new of: (Vector new: 20)) enable.
		(1 to: 10) do: [:i | freeQ next← Pacbuf init]]
	  ifFalse: [justArrivedQ disable].
	ethInPacNext ← self freePacket.
	sockeTable ← Dictionary new init: 10.
	routingTable ← String new: 255.
	routingTable all← 0 "1-255, 0 is special".
	routingHopCount ← String new: 255.
	routingHopCount all← 8.
	routingUpdateUser ← RoutingUpdater init.
	self installIntProc.
	self installInputProc.
	IntProc enable.
	InputProc enable.
	etherState ← ethAsleep "we are still asleep, must do a wakeup to get numbers, start, etc."].
"1036" Etherworld$'Input Interrupt Routines'
[installIntProc | |
	IntProc ← Top install [([true] whileTrueDo:
					[IntLight comp "infinite loop for process in scheduler.
			Interrupt just happened, running at a high level, interface off.
			Something just happened, do the common cases first.
			Input is wired down below; only comes here if OK.
			Note: we can only come here if last action was to start the rec!!" "copy out the packet first".
					ethInPacNext
					  ifTrue: [self copyinput: ethInPacNext pupString]
					  ifFalse:
						[ "user cr; show: 'warning, no packet pre-fetched. tell John'."
						(ethInPacNext ← self freePacket)
						  ifTrue: [self copyinput: ethInPacNext pupString] "user cr; show: 'input lost'"] "start the receiver".
					self SIO: 2.
					ethInPacNext
					  ifTrue:
						[justArrivedQ next← ethInPacNext "now process this input".
						ethInPacNext ← self freePacket.
						Top wakeup: InputProcLevel "all done"].
					IntLight comp.
					IntProc sleep "last action in the loop"])] at: IntProcLevel].
"888" Etherworld$'Input Interrupt Routines'
[installInputProc | inBuf destSoc |
	InputProc ← Top install [([true] whileTrueDo:
					[InputLight comp "infinite loop for process in scheduler".
					[inBuf ← justArrivedQ next] whileTrueDo:
						[(checkIncomingCS and: [inBuf checksumOK "process each incoming buffer, know it's a PUP" "verify the incoming checksum"  false])
						  ifTrue: [self freePacket: inBuf "reject it, done"]
						  ifFalse:
							[ "To be honest, we should check the destNet and destHost,
				but they generally have to be OK.....
				OK to pass the packet on"
							(destSoc ← sockeTable lookup: inBuf destSocNum)
							  ifTrue: [destSoc acceptPacbuf: inBuf]
							  ifFalse:
								[ "couldn't find a socket for it, done"
								.
								self freePacket: inBuf]]].
					InputLight comp.
					InputProc sleep "last action in the loop"])] at: InputProcLevel].
"635" Etherworld$'Initialization/Termination'
[sleep | socket |
	 "be sure to do this before a user quit"
	etherState = ethDead
	  ifTrue: [self Init]
	  ifFalse:
		[ "that is, go from dead to asleep"
		etherState = ethAsleep
		  ifFalse:
			[ "already asleep"
			etherState = ethAwake
			  ifTrue:
				[sockeTable values "try to shut down gracefully" do:
					[:socket | socket  nil
					  ifFalse: [socket sleep] "warn the sockets, leaves them in table"].
				self etherStop.
				etherState ← ethAsleep "when next we wake up, may be on a new machine/net"]
			  ifFalse:
				[ "when next we wake up, may be on a new machine/net"
				]]]].
"167" Etherworld$'Initialization/Termination'
[etherStop | |
	 "temporarily shuts off the ether stuff"
	Top critical [
		(mem  385 ← 0.
		self SIO: 3.
		mem  384 ← 0)]].
"285" Etherworld$'Utility messages'
[notify: strng | |
	 "turn off the Ethernet before doing a user notify"
	self etherStop.
	user show: ' Etherworld stopped'.
	Top currentPriority  1
	  ifTrue:
		[user cr.
		user show: 'priority is ' + Top currentPriority asString].
	user notify: strng].
"72" Etherworld$'Utility messages'
[getMachineID | |
	↑(self SIO: 0) \ 256].
"70" Etherworld$'Utility messages'
[setMachineID: ID | |
	mem  392 ← ID].
"361" Etherworld$'Initialization/Termination'
[etherStart | |
	 "allows ether to start running again"
	etherState = ethAwake "makes sure the interrupt is on, and kicks the device"
	  ifTrue:
		[mem  385 = 0
		  ifTrue: [mem  385 ← ethIntBits].
		self SIO: 3 "forces it to wake up again"]
	  ifFalse:
		[.
		self notify: 'Attempt to etherStart when not awake!!.']].
"64" Etherworld$'User messages'
[awake | |
	↑etherState = ethAwake].
"283" Etherworld$'Utility messages'
[printSocketTable | i |
	sockeTable  nil
	  ifTrue:
		[user cr.
		user show: 'no socketTable']
	  ifFalse: [sockeTable objects do:
			[:i | i  nil
			  ifFalse:
				[user cr.
				user print: i.
				user show: ', '.
				user print: sockeTable  i]]]].
"643" Etherworld$'Initialization/Termination'
[classInit | |
	Smalltalk declare: #(E ) "if this needs to be filed in again, execute this first
	Smalltalk declare: EtherPool as: (SymbolTable new init: 32).

access variables from outside with (for example) with EtherPoolethAwake".
	EtherPool declare: #(ethInPacNext checkIncomingCS IntProcLevel InputProcLevel ethIntBits etherState ethAwake ethAsleep ethDead ) as: {false , false , 14 , 13 , 16 , 0 , 3 , 1 , 0}.
	EtherPool declare: #(NETNUM ALTONUM freeQ justArrivedQ sockeTable routingTable routingHopCount routingUpdateUser IntProc InputProc broadcastFilter IntLight InputLight OutputLight )].
"90" Etherworld$'Input Interrupt Routines'
[copyinput: string | |<primitive: 75>
	user croak].
"725" Etherworld$'Output Routines'
[sendOutput: ethOutPac | post |
	 "This is the one and only place from which we  send output.
			Only one packet gets passed in to us at a time.
			For performance, we wait here for the transmitter to post!!!!
			Nominally, we are running at level 0;  thus, this must be run
			at a Top critical, to protect from multiple calls."
	etherState  ethAwake
	  ifTrue:
		[self wakeup.
		user show: 'starting Ethernet...'].
	Top critical [
		(OutputLight comp.
		mem  390 ← ethOutPac totLengthWords "EthOutCntLoc".
		(post ← self doOutput: ethOutPac pupString)  511
		  ifTrue:
			[user cr.
			user show: 'Warning, bad output post: ' + post base8].
		OutputLight comp)] "end of the critical part"].
"198" Etherworld$'User messages'
[broadcastFilter: val | |
	val
	  ifTrue:
		[broadcastFilter ← true.
		self broadcastFilterSet: 1]
	  ifFalse:
		[broadcastFilter ← false.
		self broadcastFilterSet: 0]].
"214" Etherworld$'User messages'
[freePacket | p |
	freeQ
	  ifTrue:
		[ "get a packet"
		(p ← freeQ next)
		  ifTrue: [↑p].
		user show: 'Warning, empty freeQ, in Etherworld'.
		↑false]
	  ifFalse: [↑Pacbuf new init]].
"140" Etherworld$'User messages'
[freePacket: p | |
	 "put a used packet into free queue"
	(freeQ and: [p])
	  ifTrue: [freeQ next← p].
	↑false].
"74" Etherworld$'Utility messages'
[error: str | |
	user cr.
	user show: str].
"274" Etherworld$'Utility messages'
[printRoutingTable | i |
	(1 to: 255) do:
		[:i | routingTable  i  0
		  ifTrue:
			[user cr.
			user show: 'To net ' + i asString + ' via host ' + (routingTable  i) asString + ', hop count = ' + (routingHopCount  i) asString]].
	user cr].
"889" UserView$'As yet unclassified'
[Doradowritem | today image space table i n t7 |
	 "user Doradowritem."
	Changes init.
	MethodKeeper ← (Vector new: 10) asStream.
	E  nil
	  ifTrue: [E ← Etherworld new].
	NTmapper new mapDorado.
	(t7 ← dp0 file: 'Disp.nt') append: (user instfield: 7) contents.
	t7 close.
	user displayoffwhile [
		(image ← dp0 file: (n ← (user today format: #(2 1 0 0 2 0 )) + '.im').
		space ← dp0 file: 'objectspace.nt'.
		space readonly.
		table ← dp0 file: 'objecttable.nt'.
		table readonly.
		image append: (space length / 2) asLarge inFourBytes.
		image append: (table length / 2) asLarge inFourBytes.
		image pad: 512 with: 0.
		image append: space.
		image pad: 512 with: 0.
		image append: table.
		space close.
		table close.
		image close)].
	user quitThen: 'ftp Phylum log/c guest guest conn/c smalltalk-80 st80 sto/c st80sources.v00 st80changes.v00 ' + n].
"164" UserView$'Mouse, Cursor, Keys'
[mpnext | |
	self redbug "return next mouse point if red button or tablet is down; otherwise false"
	  ifTrue: [↑self mp].
	↑false].
"70" UserView$'As yet unclassified'
[core | |<primitive: 48>
	user croak].
"218" UserView$'Time'
[timewords | s |
	s ← String new: 4 "seconds (in GMT) since Jan 1 1901: as a String".
	NoteTaker
	  ifTrue: [self timeWordsInto: s]
	  ifFalse:
		[s word: 1 ← mem  378.
		s word: 2 ← mem  379].
	↑s].
"55" UserView$'Screen Views'
[screenrect | |
	↑screenrect].
"171" UserView$'Screen Views'
[copyIn: p | |
	↑UserView new screenrect: screenrect copy vtab: vtab htab: htab scale: scale color: color projectWindow: p disp: disp sched: #()].
"136" UserView$'Window Scheduling'
[leaveTop | |
	 "leave the top window if there is one"
	sched length = 0
	  ifFalse: [(sched  1) leave]].
"983" Dispframe$'Dialog'
[kbd | n t |
	 "false if user pauses, nil if ctrl-d, all input since prompt if "
	[user kbck] whileTrueDo:
		[t ← user kbd.
		t = 132
		  ifTrue:
			[self append: 'done.'.
			self show.
			↑nil].
		 "ctl-d for done"
		t = 8
		  ifTrue:
			[self last = prompt
			  ifFalse: [self skip: 1]]
		  ifFalse:
			[ "backspace"
			t = 30
			  ifTrue:
				[n ← array  (position to: 1 by: 1) find: prompt.
				n = 0
				  ifTrue:
					[self append: 'lost beginning'.
					self prompt]
				  ifFalse:
					[t ← self last: n - 1.
					self next← doit.
					self show.
					↑t]]
			  ifFalse:
				[ "do-it (LF)"
				t = 145
				  ifTrue:
					[self last = prompt
					  ifFalse:
						[self skip: 1 "ctl-w for backspace word".
						[position > 0 and: [self last tokenish]] whileTrueDo: [self skip: 1]]]
				  ifFalse:
					[t = 151
					  ifTrue:
						[self reset.
						self prompt]
					  ifFalse: [ "ctl-x clears frame"
						self next← t]]]]].
	self show.
	↑false].
"330" Dispframe$'Scheduler'
[eachtime | t |
	(text window has: user mp)
	  ifTrue:
		[user kbck
		  ifTrue:
			[(t ← self kbd)
			  ifTrue:
				[t  nil
				  ifFalse:
					[self space.
					self print: nil  t].
				self prompt]]
		  ifFalse:
			[user bluebug
			  ifTrue: [↑false]]]
	  ifFalse:
		[user anybug
		  ifTrue: [↑false]]].
"124" Dispframe$'Scheduler'
[lasttime | |
	self last = prompt
	  ifTrue:
		[self skip: 2.
		self show].
	↑user bluebug  false].
"115" Dispframe$'Dialog'
[request: s | |
	 "false if ctrl-d, all input since prompt if "
	self append: s.
	↑self read].
"89" Dispframe$'Image'
[moveto: pt | |
	(text window inset: 2  2) dragto: pt - (2  2)].
"37" Dispframe$'Scheduler'
[leave | |
	].
"82" Dispframe$'Initialization'
[rect: r | |
	self init.
	self frame← r.
	self clear].
"332" Dispframe$'Image'
[show | t |
	text show: self contents asParagraph.
	[text lastshown  position] whileFalseDo: 
		[position < (t ← text scrolln: 1)
		  ifFalse:
			[t ← array copy: t + 1 to: position.
			text show: t asParagraph.
			position ← 0.
			self append: t "self dequeue: (text scrolln: 1).
		text show: self contents"]]].
"54" Dispframe$'Access to Parts'
[frame | |
	↑text frame].
"55" Dispframe$'Image'
[clear | |
	self reset.
	self show].
"47" Dispframe$'Access to Parts'
[text | |
	↑text].
"125" Dispframe$'Dialog'
[ev | t |
	[self cr.
	t ← self request: ''] whileTrueDo:
		[self space.
		self print: nil  t].
	↑false].
"74" Dispframe$'Dialog'
[prompt | |
	self cr.
	self next← prompt.
	self show].
"79" Dispframe$'Initialization'
[classInit | |
	prompt ← ''  1.
	doit ← ''  1].
"89" Dispframe$'Initialization'
[init | |
	text ← Textframe new.
	self of: (String new: 16)].
"131" Dispframe$'Scheduler'
[firsttime | |
	(text window has: user mp)
	  ifTrue:
		[self outline.
		self prompt]
	  ifFalse: [↑false]].
"55" Dispframe$'Access to Parts'
[text: t1 | |
	text ← t1].
"57" Dispframe$'Image'
[outline | |
	text window outline: 2].
"226" Dispframe$'Dialog'
[read | t |
	 "false if ctrl-d, all input since prompt if "
	self next← prompt.
	self show.
	[user kbck
	  ifTrue: [t ← self kbd]
	  ifFalse: [false]] whileFalseDo:  [].
	t  nil
	  ifTrue: [↑false].
	↑t].
"68" Dispframe$'Initialization'
[frame← r | |
	text para: nil frame: r].
"254" UserView$'Dialog Window'
[newdisp | |
	 "for when some class associated with running Dispframe  changed"
	self unschedule: disp.
	disp ← Dispframe new rect: (8  0 rect: 150  96).
	self schedule: disp.
	self clearshow: 'New Dialogue window created.
'].
"258" UserView$'System quit/resume'
[quitThen: str | rem rest |
	rem ← (dp0 file: 'rem.cm') "quit, then have OS execute str" readonly.
	rest ← rem next: rem length.
	rem readwrite.
	rem reset.
	rem append: str.
	rem cr.
	rem append: rest.
	rem close.
	self quit].
"64" UserView$'Mouse, Cursor, Keys'
[anybug | |
	↑self buttons > 0].
"64" UserView$'Mouse, Cursor, Keys'
[redbug | |
	↑self buttons = 4].
"67" UserView$'Mouse, Cursor, Keys'
[tabletabsolute | |
	mem  86 ← 1].
"65" UserView$'Mouse, Cursor, Keys'
[tabletbug | |
	↑mem  448 < 0].
"1889" UserView$'Misc System Stuff'
[initCompiler | code sel c t |
	 "Initialize shared variables of parser and generators" "user initCompiler."
	Smalltalk declare: #(TokenCodes ByteCodes ).
	TokenCodes  nil
	  ifTrue: [TokenCodes ← SymbolTable new init: 32].
	ByteCodes  nil
	  ifTrue:
		[ByteCodes ← SymbolTable new init: 32.
		Integer sharing: ByteCodes].
	TokenCodes declare: #(aRightBrack aPeriod aLeftPar aSemicolon aCondArrow aHand aReturnArrow aLeftBrack aRightPar aLeftArrow aBinary aNumber aString aKeyword aGibberish aColon aDigit aWord ) as: #(1 2 3 4 5 6 7 8 9 10 20 30 31 41 42 43 44 45 ) "First 2 in this order" "All above must be less, all below must be greater" "All below must be in that order".
	ByteCodes declare: #(toLoadField toLoadTemp toLoadLit toLoadLitInd toLoadCtxt toLoadTempframe toLoadConst toLoad0 toLoad1 toLoadSelf toLoadNil toLoadFalse toLoadTrue toSmashPop toSmash toPop toReturn toEnd toLoadThisCtxt toSuper toShortJmp toShortBfp toLongJmp toLongBfp toPlus toMinus toGtr toGeq toNext toEq toSendLit toLoadFieldLong toLoadTempLong toLoadLitLong toLoadLitIndLong toSendLitLong codeLoadField codeLoadTemp codeLoadLit codeLoadLitInd codeSendLit ) as: #(0 16 32 64 112 116 120 121 122 113 125 126 127 128 129 130 131 132 133 134 144 152 160 168 176 177 179 181 194 197 208 136 137 138 139 140 256 512 768 1024 1280 ).
	c ← Dictionary new init: 16.
	c insertall: #('self' 'thisContext' 'super' 'nil' 'false' 'true' ) with: #(113 133 134 125 126 127 ).
	ByteCodes declare: #stdPrimaries as: c.
	self initCompilerSelectors.
	c ← Dictionary new init: 8.
	c insertall: #('whiledo' 'untildo' 'forto:do' 'forfrom:do' 'forfrom:to:by:do' 'forfrom:to:do' 'ifthenelse' 'ifthen' ) with: #(whiledo:args: untildo:args: fortodo:args: forfromdo:args: forfromtobydo:args: forfromtodo:args: ifthenelse:args: ifthen:args: ).
	ByteCodes declare: #inLineMsgs as: c].
"622" UserView$'Misc System Stuff'
[oopsToFile | a c i t s cs f ts |
	f ← dp0 file: 'oops'.
	cs ← user classNames transform [:a | a] to [Smalltalk  a].
	t ← cs transform [:a | a] to [a asOop].
	ts ← t permutationToSort.
	ts do:
		[:i | f append: (t  i) base8.
		f tab.
		f append: (cs  i) title.
		f cr].
	cs  ts do:
		[:c | f cr.
		f append: c title.
		f cr.
		s ← c md contents "selectors".
		t ← s transform [:a | a] to [(c md method: a) asOop] "method oops".
		t permutationToSort do:
			[:i | f tab.
			f append: (t  i) base8.
			f tab.
			f append: s  i.
			f cr].
		user show: c title.
		user cr].
	f close].
"2104" UserView$'Misc System Stuff'
[workspace | |
	user notify: 'Not meant to be executed' "
XEROX - Learning Research Group
 
user screenextent: 640580 tab: 050.
NotifyFlag ← true.
Changes init.
user changedMessages
user changedClasses
user changedCategories
Undeclared contents

to set the default printer
PrinterName←'Menlo'.
PrinterName←(PressFile new) selectPrinter: PrinterName.

to change phylum to access your account
user releaseExternalViews. phylum name: 'name' password: 'password'.

dp0 filin: ('Changes.st').
(dp0 file: 'changes.st') filout.
(dp0 file: 'xxx') edit.
dp0 pressfilin: ('xxx.press').
(dp0 filesMatching: '*.st') sort
dp0 list. dp0 freePages
dp0 delete: 'old'
dp0 rename: 'old' newName: 'new'

for reinitializing Sources and phylum
Sources release. phylum release. Sources reopen.

to make Smalltalk Sources local
 | s. s ← 'Smalltalk.Sources.'.
(phylum asFtpDirectory) retrieve: '<Smalltalk>' + s + user versionName as: s; close.
Sources on: (dp0 file: s).

to switch back to remote Sources
Sources close; on: (phylum file: '<Smalltalk>Smalltalk.Sources.' + user versionName).


to filin a remote Smalltalk file
phylum filin: ('<Small-goodies>NotifyChange.st').

to print a remote/local press file
(phylum pressfile: '<Smalltalk>xxx.press') toPrinter.
(dp0 pressfile: 'xxx.press') toPrinter: 'Lilac'.

File noChanges.
BitRect new fromuser; edit.
user schedule: (defaultBitRectEditor newframe).

DocumentEditor new defaultdocument: 'test'.
DocumentEditor new init: (Document new fromPress: 'test.document').


user releaseExternalViews.
E sleep. E kill. E ← nil.
E ← Etherworld new. E broadcastFilter: true. E wakeup.
Sources reopen.

for primary Smalltalk access to file servers and printers at other sites.
substitute yourserver for phylum above, compile this workspace
PrinterName ← 'name-of-your-printer'.
Smalltalk declare: yourserver.
yourserver ← ILFileDirectory new directory: 'name-of-your-server'.
yourserver name: 'Smalltalk-User' password: 'Smalltalk'.
Sources on: (yourserver file: '<Smalltalk>Smalltalk.Sources.' + user versionName).
Changes init.

user Swat.
"].
"65" UserView$'Misc System Stuff'
[purgealittle | |<primitive: 0>
	].
"97" UserView$'Mouse, Cursor, Keys'
[waitnokey | |
	[self keyset = 0] whileFalseDo:  [self rawkbck]].
"66" UserView$'Time'
[totalsecs | |
	↑self totalsecs: self timewords].
"209" UserView$'Dialog Window'
[newdisploc: origin and: corner | |
	 "for moving disp"
	(disp text "user newdisploc: 80 and: 15096" frame inset: 2  2) clear.
	disp text frame← origin rect: corner.
	disp show].
"560" UserView$'Misc System Stuff'
[systemStartup | |
	 "To do after system flush and installation of new core image"
	Top top.
	Window classInit "The following screen extent seems to really fill the screen in x,
	the Alto Hardware Manual to the contrary notwithstanding.".
	self screenextent: 640  580 tab: 0  50.
	Sources release.
	dp0 release.
	dp1 release.
	self releaseExternalViews.
	E  nil
	  ifFalse: [ "ignore broadcasts"
		E broadcastFilter: true].
	NoteTaker
	  ifTrue: [self afterBirth]
	  ifFalse:
		[VirtualMemory new thisvmem.
		Vmem afterBirth]].
"155" UserView$'Window Scheduling'
[schedule: window | |
	sched  nil
	  ifTrue: [sched ← window inVector]
	  ifFalse: [sched ← window inVector concat: sched]].
"154" UserView$'Mouse, Cursor, Keys'
[keyset | |
	NoteTaker
	  ifTrue: [↑(self primMouseKeys lshift: 3) land: 31].
	↑31 - ((mem  488 lshift: 3) land: 31)].
"83" UserView$'Mouse, Cursor, Keys'
[waitclickbug | |
	self waitnobug.
	↑self waitbug].
"60" UserView$'Screen Views'
[reconfigure | |<primitive: 75>
	].
"159" UserView$'System quit/resume'
[backup | |
	 "back up smalltalk on ivy and resume"
	ivy open.
	ivy delete: 'small.boot'.
	ivy store: 'small.boot'.
	ivy close].
"157" UserView$'Misc System Stuff'
[growSmalltalk: numberofdiskpages | |
	 "for preemptive growth of Small.boot on disk"
	dp0 growSmalltalkBy: numberofdiskpages].
"68" UserView$'Mouse, Cursor, Keys'
[tabletrelative | |
	mem  86 ← 1].
"72" UserView$'Time'
[rawtotalsecs | |
	↑self rawtotalsecs: self timewords].
"405" UserView$'Misc System Stuff'
[reclaim | c cl cv |
	 " Should only be called from bugScreenMenu !! "
	user cr.
	user show: 'Reclaiming... '.
	cl ← {CodePane , ScrollBar , PanedWindow , ListPane , Generator , Parser}.
	cv ← Context allInstances.
	user print: cv length.
	cv do:
		[:c | (cl has: c mclass)
		  ifTrue: [c release]].
	cv all← nil.
	user show: ' reduced to ' + Context howMany asString + '.'].
"83" UserView$'Time'
[timeWordsInto: s | |<primitive: 81>
	 "s length=4!"
	user croak].
"443" SymbolTable$'Searching'
[allCallsOn: selector from: classNames | className s w cl sel |
	(selector is: Vector)
	  ifFalse: [selector ← selector inVector].
	s ← Stream default.
	user displayoffwhile [(classNames do:
			[:className | cl ← self  className.
			selector do:
				[:sel | w ← cl whosends: sel.
				w length = 0
				  ifFalse:
					[s append: className.
					s append: ''.
					s append: w asString.
					s cr]]])].
	↑s contents].
"89" SymbolTable$'Insertion'
[define: name as: x | |
	 "synonym"
	↑self declare: name as: x].
"87" SymbolTable$'Insertion'
[insert: name withref: ref | |
	super insert: name with: ref].
"162" SymbolTable$'Searching'
[allRefs | |
	 "what methods reference my variables (I am probably 'Undeclared')"
	↑self allRefsTo: self contents from: user classNames].
"309" SymbolTable$'Searching'
[allRefsTo: symbol from: classNames | s |
	(symbol is: Vector)
	  ifFalse: [symbol ← symbol inVector].
	↑Smalltalk allCallsOn: (symbol transform [:s | s] to [(self ref: s)]) from: classNames "
Smalltalk allRefsTo: ST80 from: (SystemOrganization superclassOrder: 'S80-Compiler')
"].
"70" ObjectReference$'Indirection'
[value← t1 | |
	object ← t1.
	↑object].
"64" ObjectReference$'Initialization'
[object: t1 | |
	object ← t1].
"51" ObjectReference$'Indirection'
[eval | |
	↑object].
"90" ObjectReference$'Conversion'
[printon: strm | |
	strm append: '->'.
	strm print: object].
"52" ObjectReference$'Indirection'
[value | |
	↑object].
"147" SymbolTable$'Insertion'
[insert: name with: x | |
	(self has: name)
	  ifFalse: [super insert: name with: ObjectReference new].
	self  name ← x].
"68" SymbolTable$'Searching'
[lookupRef: name | |
	↑super lookup: name].
"277" SymbolTable$'Growing and shrinking'
[rehash | i copy |
	copy ← SymbolTable new init: self size "create a copy".
	(1 to: objects length) "hash each entry into it" do:
		[:i | objects  i  nil
		  ifFalse: [copy insert: objects  i withref: values  i]].
	self copyfrom: copy].
"389" SymbolTable$'Insertion'
[declare: name from: symTab | a |
	 "take name(s), ref(s) and value(s) from symTab"
	(name is: Vector)
	  ifTrue: [name do: [:a | self declare: a from: symTab]]
	  ifFalse:
		[(self has: name)
		  ifFalse:
			[(symTab has: name)
			  ifTrue:
				[super insert: name with: (symTab ref: name).
				symTab delete: name]
			  ifFalse: [self insert: name with: nil]]]].
"103" SymbolTable$'Searching'
[lookup: name | r |
	(r ← super lookup: name)
	  ifTrue: [↑r value].
	↑false].
"180" SymbolTable$'Searching'
[invert: obj | i |
	(1 to: values length) do:
		[:i | nil  (values  i)
		  ifFalse:
			[obj  (values  i) value
			  ifTrue: [↑objects  i]]].
	↑false].
"373" SymbolTable$'As yet unclassified'
[forEachClass class selector selector do action | name cl s |
	user cr.
	user show: 'anybug to interrupt.'.
	user cr.
	AllClassNames do:
		[:name | user anybug
		  ifFalse:
			[user show: name.
			user cr.
			class value← cl ← Smalltalk  name.
			user displayoffwhile [(cl md do:
					[:s | selector value← s.
					action eval])]]]].
"139" SymbolTable$'Searching'
[invertRef: obj | i |
	(1 to: values length) do:
		[:i | obj  (values  i)
		  ifTrue: [↑objects  i]].
	↑false].
"145" SymbolTable$'Insertion'
[declare: name | |
	 "Take ref(s) and value(s) from Undeclared, if name(s) there"
	self declare: name from: Undeclared].
"182" SymbolTable$'Growing and shrinking'
[clean | name |
	 "release unreferenced entries"
	self do:
		[:name |  "slick, huh"
		(super  name) refct = 1
		  ifTrue: [self delete: name]]].
"62" SymbolTable$'Access to parts'
[ref: name | |
	↑super  name].
"144" MethodDictionary$'As yet unclassified'
[has: key | probe |
	(probe ← super at: (self find: key))  nil
	  ifTrue: [↑false].
	↑probe key = key].
"101" MethodDictionary$'As yet unclassified'
[methodorfalse: sel | |
	↑self at: sel ifAbsent [(↑false)]].
"118" MethodDictionary$'As yet unclassified'
[method: sel | |
	↑self at: sel ifAbsent [(self error: sel + ' not found')]].
"166" LADDictionary$'As yet unclassified'
[noCheckAdd: anAssociation | |
	self at: (self find: anAssociation key) put: anAssociation.
	tally ← tally + 1.
	↑anAssociation].
"147" LADDictionary$'As yet unclassified'
[at: key ifAbsent expr | val |
	val ← super at: (self find: key).
	val  nil
	  ifTrue: [↑expr eval].
	↑val].
"233" LADDictionary$'As yet unclassified'
[add: anAssociation | index |
	index ← self find: anAssociation key.
	(super at: index)  nil
	  ifTrue: [tally ← tally + 1].
	self at: index put: anAssociation.
	self fullCheck.
	↑anAssociation].
"320" LADDictionary$'As yet unclassified'
[find: key | index len probe pass |
	len ← self length.
	pass ← 1.
	index ← key hash \ len + 1.
	[(probe ← super at: index)  nil or: [probe key = key]] whileFalseDo: 
		[(index ← index + 1) > len
		  ifTrue:
			[index ← 1.
			(pass ← pass + 1) > 2
			  ifTrue: [↑index]]].
	↑index].
"204" LADDictionary$'As yet unclassified'
[contents | s i |
	s ← Stream new of: (Vector new: self length).
	(1 to: self length) do:
		[:i | self  i  nil
		  ifFalse: [s next← (self  i) key]].
	↑s contents].
"104" LADSet$'As yet unclassified'
[at: index | |
	NoteTaker
	  ifTrue: [↑self  index].
	↑contents  index].
"110" LADSet$'As yet unclassified'
[fullCheck | |
	self length - tally  (self length / 4)
	  ifTrue: [self grow]].
"52" LADSet$'As yet unclassified'
[init | |
	tally ← 0].
"49" LADSet$'As yet unclassified'
[size | |
	↑tally].
"179" LADSet$'As yet unclassified'
[at: index put: anAssociation | |
	 "should be primitive"
	NoteTaker
	  ifTrue: [↑self  index ← anAssociation].
	↑contents  index ← anAssociation].
"100" LADSet$'As yet unclassified'
[length | |
	NoteTaker
	  ifTrue: [↑super length].
	↑contents length].
"291" LADSet$'As yet unclassified'
[grow | oldContents newSelf oldTally i |
	NoteTaker
	  ifTrue:
		[newSelf ← self species new: self length * 2.
		newSelf init "tally ← 0".
		(1 to: self length) do:
			[:i | self  i  nil
			  ifFalse: [newSelf noCheckAdd: self  i]].
		self become: newSelf]].
"107" UniqueString$'Reading and Writing'
[ x ← val | |
	user notify: 'UniqueStrings are not for writing into'].
"110" UniqueString$'Selectors'
[isinfix | x |
	self length  1
	  ifTrue: [↑false].
	↑(self  1) isletter  false].
"46" UniqueString$'Initialization'
[unique | |
	].
"50" UniqueString$'Compatibility'
[recopy | |
	↑self].
"55" UniqueString$'Conversion'
[asString | |
	↑super copy].
"262" UniqueString$'Initialization'
[rehash | old s i |
	 " a rehash. "
	old ← USTable.
	USTable ← Vector new: old length.
	(1 to: old length) do:
		[:i | USTable  i ← Vector new: 0.
		old  i do:
			[:s | s  nil
			  ifFalse: [self intern: s]].
		old  i ← nil]].
"48" UniqueString$'Comparison'
[= x | |
	↑self  x].
"101" UniqueString$'Initialization'
[str: s | j |
	(1 to: s length) do: [:j | super  j ← s  j].
	↑self].
"66" UniqueString$'Conversion'
[printon: strm | |
	strm append: self].
"393" UniqueString$'Initialization'
[hasInterned: s | i v |
	 "false if String s hasnt been interned, else s unique"
	s length = 1
	  ifTrue:
		[s  1 < 128
		  ifTrue: [↑UST1  (s  1 + 1)]].
	v ← USTable  (s stringhash \ USTable length + 1).
	(1 to: v length) do:
		[:i | v  i  nil
		  ifFalse:
			[s length = (v  i) length
			  ifTrue:
				[s = (v  i)
				  ifTrue: [↑v  i]]]].
	↑false].
"219" UniqueString$'Selectors'
[mustTake: nargs | |
	 "fatal error if I am not a selector that takes nargs arguments"
	self numArgs  nargs
	  ifTrue: [user notify: self + ' does not take ' + nargs asString + ' arguments']].
"341" UniqueString$'Initialization'
[intern: s | ustr h |
	(ustr ← self hasInterned: s)
	  ifTrue: [↑ustr].
	 "check if already exists"
	ustr ← ((s is: UniqueString)
			  ifTrue: [s]
			  ifFalse: [ "create a new one"
				(UniqueString new: s length) str: s]).
	h ← s stringhash \ USTable length + 1.
	USTable  h ← {USTable  h , ustr}.
	↑ustr].
"481" UniqueString$'Selectors'
[numArgs | len n i t4 |
	 "the number of arguments I take when I am a selector"
	len ← self length.
	len = 1
	  ifTrue: [↑(self  1) isletter
		  ifTrue: [0]
		  ifFalse: [1]].
	n ← 0 "count colons, dots, and arrows".
	(1 to: len) do:
		[:i | (t4 ← self  i) = 58
		  ifTrue: [n ← n + 1]
		  ifFalse:
			[t4 = 3
			  ifTrue: [n ← n + 1]
			  ifFalse:
				[t4 = 95
				  ifTrue: [n ← n + 1]
				  ifFalse:
					[t4 = 7
					  ifTrue: [n ← n + 1]]]]].
	↑n].
"497" UniqueString$'Selectors'
[keywords | result strm i l char colon ocolon |
	 "return a vector of the keywords that compose me"
	'←' = self
	  ifTrue: [↑#('' '←' )].
	result ← (Vector new: 10) asStream.
	strm ← Stream default.
	colon ← ':'  1.
	ocolon ← ''  1.
	i ← 1.
	l ← self length.
	[i  l] whileTrueDo:
		[char ← self  i.
		strm append: char.
		((char = colon or: [char = ocolon]) or: [i = l])
		  ifTrue:
			[result next← strm contents.
			strm reset].
		i ← i + 1].
	↑result contents].
"200" UniqueString$'Initialization'
[classInit | i a v |
	 "make up table of 1-char atoms"
	v ← Vector new: 128.
	a ← String new: 1.
	(1 to: 128) do:
		[:i | a  1 ← i - 1.
		v  i ← a unique].
	UST1 ← v].
"57" UniqueString$'Comparison'
[stringhash | |
	↑super hash].
"55" UniqueString$'Comparison'
[hash | |<primitive: 39>
	].
"163" UniqueString$'Selectors'
[iskeyword | x |
	 "ends with colon"
	self length  1
	  ifTrue: [↑false].
	x ← self  self length.
	x = 58
	  ifTrue: [↑true].
	↑x = 3].
"120" UniqueString$'Selectors'
[isarrow | |
	 "ends with ←"
	self length  1
	  ifTrue: [↑false].
	↑self  self length = 95].
"48" UniqueString$'Compatibility'
[copy | |
	↑self].
"93" UniqueString$'Selectors'
[isuneval | x |
	 "ends with open colon"
	↑self  self length = 3].
"53" UniqueString$'Compatibility'
[species | |
	↑String].
"311" Object$'System Primitives'
[error | sender op n args i |
	 "after compiling execute: nil installError.  "
	sender ← thisContext sender.
	op ← sender thisop.
	n ← op numArgs.
	args ← Vector new: n.
	(n to: 1 by: 1) do: [:i | args  i ← sender pop].
	↑self messageNotUnderstood: op withArgs: args from: sender].
"315" MethodContext$'Initialization'
[goBaby | height |
	NoteTaker ← true.
	MethodKeeper ← (Vector new: 10) asStream.
	externalViews ← Set new vector: 10.
	height ← 760 " 480 376 ".
	user currentDisplay: (Form new extent: 640  height bits: (Bitmap new: 640 / 16 * height) offset: nil).
	[true] whileTrueDo: [self run]].
"619" Class$'Message access'
[install: name method: method literals: literals code: code backpointers: backpointers | c |
	NoteTaker
	  ifFalse:
		[literals length > 60
		  ifTrue:
			[user show: literals length asString + ' literals **'.
			user cr]].
	NoteTaker
	  ifTrue: [messagedict add: method]
	  ifFalse: [messagedict ← messagedict insert: name method: method literals: literals code: code asParagraph makeBoldPattern backpointers: backpointers].
	lastClass ← self.
	lastSelector ← name.
	lastParagraph ← code.
	Changes insert: (c ← title + ' ' + name).
	(Changes has: (c ← '~' + c))
	  ifTrue: [Changes delete: c]].
"99" Class$'Access to parts'
[isVariable | |
	NoteTaker
	  ifTrue: [↑instsize allmask: 4096].
	↑false].
"76" Class$'Instance access'
[printon: strm | |
	strm append: 'Class ' + title].
"58" Class$'Instance access'
[default | |
	↑self new default].
"91" Class$'System Organization'
[category | |
	↑SystemOrganization invert: self title unique].
"116" Class$'Message access'
[space | a s |
	s ← 0.
	messagedict do: [:a | s ← s + (messagedict method: a) length].
	↑s].
"101" Class$'Instance access'
[init | |
	 "init and default get propagated to instances"
	↑self new init].
"55" Class$'Filin and Filout'
[endCategoryOn: pstrm | |
	].
"204" Class$'Instance access'
[new: length | |
	 "To allow fixed-length classes to simulate variable-length ones"
	self isVariable
	  ifTrue: [user croak]
	  ifFalse: [↑self new init: length] "By convention"].
"146" Class$'Instance access'
[recopy: inst | t i |
	t ← self new.
	(1 to: self instsize) do: [:i | t instfield: i ← (inst instfield: i) recopy].
	↑t].
"135" Class$'Instance access'
[copy: inst | t i |
	t ← self new.
	(1 to: self instsize) do: [:i | t instfield: i ← inst instfield: i].
	↑t].
"82" Class$'Filin and Filout'
[endChangesOn: pstrm | |
	pstrm print: '' asParagraph].
"90" Class$'Filin and Filout'
[printMethod: sel on: pstrm | |
	pstrm print: (self code: sel)].
"153" Class$'Filin and Filout'
[startChangesOn: pstrm | |
	pstrm print: (('
' + title + ' asFollows') asParagraph maskrunsunder: 241 to: 81) "Font 5, Bold"].
"941" Class$'Filin and Filout'
[paraprinton: strm | para frame s heading org |
	 "Strm is actually a ParagraphPrinter"
	para ← ('"' + title + '"') asParagraph.
	para maskrunsunder: 241 to: 81 "Font ← 5, Bold".
	frame ← strm defaultframe "defeat ST76 optimization".
	.
	strm frame← 15000  frame origin y rect: 20000  frame corner y.
	strm print: para.
	strm frame← frame.
	strm print: ((self definition + ';
	asFollows') asParagraph maskrunsunder: 241 to: 81).
	org ← self organization.
	strm print: ('
' + org globalComment) asParagraph allItalic.
	org categories do: [:heading | self printCategory: heading on: strm].
	self endChangesOn: strm.
	strm print: ('SystemOrganization classify: ' + title + ' under: ''' + (SystemOrganization invert: title unique) + '''.') asParagraph.
	(self  Class or: [self  VariableLengthClass])
	  ifFalse:
		[(self canunderstand: #classInit)
		  ifTrue: [strm print: (title + ' classInit') asParagraph]]].
"206" Class$'Filin and Filout'
[noChanges | s t |
	t ← title + ' *'.
	Changes contents do:
		[:s | ((s  1 = 126 "~" and: [(t match: s  (2 to: s length))]) or: [(t match: s)])
		  ifTrue: [Changes delete: s]]].
"135" Class$'Filin and Filout'
[filoutCategory: cat | |
	(dp0 file: (title + '-' + cat + '.st') asFileName) filout: (self changelist: cat)].
"177" Class$'Instance access'
[instfield: i | |
	 "prevent user from getting freelist"
	i > Class instsize
	  ifTrue: [user notify: 'arg too big']
	  ifFalse: [↑super instfield: i]].
"82" Class$'Message access'
[canunderstand: selector | |
	↑messagedict has: selector].
"118" Class$'Filin and Filout'
[printout | |
	user displayoffwhile [((dp0 file: title + '.press.') printoutclass: self)]].
"135" Class$'Message access'
[notify: errorString at: position in: stream | |
	↑self notify: errorString at: position in: stream for: self].
"211" Class$'Message access'
[whosends: selector | s l a |
	s ← Stream default.
	messagedict do: [:a | (messagedict literals: a) do:
			[:l | selector  l
			  ifTrue:
				[s append: a.
				s space]]].
	↑s contents].
"75" Class$'Message access'
[method: sel | |
	↑messagedict methodorfalse: sel].
"45" Class$'Access to parts'
[title | |
	↑title].
"50" Class$'Organization'
[classvars | |
	↑classvars].
"210" Class$'Initialization'
[subclassof: t1 | |
	superclass ← t1.
	((superclass isnt: Class) and: [(superclass isnt: VariableLengthClass)])
	  ifTrue: [user notify: 'Superclass is not yet defined or not a Class']].
"538" Class$'Message access'
[code: sel | |
	 "last paragraph returned is cached (mainly for NotifyWindows)"
	lastParagraph ← ((sel  lastSelector and: [self  lastClass])
			  ifTrue: [lastParagraph]
			  ifFalse:
				[sel = #ClassOrganization
				  ifTrue: [self organization]
				  ifFalse:
					[user leftShiftKey
					  ifTrue: [self decompile: sel]
					  ifFalse:
						[NoteTaker
						  ifTrue: [self getSource80: sel]
						  ifFalse: [messagedict code: sel]]]]) asParagraph.
	lastClass ← self.
	lastSelector ← sel.
	↑lastParagraph].
"54" Class$'Organization'
[environment | |
	↑environment].
"338" Class$'Initialization'
[bytesize: n | |
	 "non-pointer declaration"
	self  self realself
	  ifTrue: [self realself bytesize: n]
	  ifFalse:
		[NoteTaker
		  ifTrue: [instsize ← (instsize land: 8191) + (n = 8
					  ifTrue: [0]
					  ifFalse: [16384])]
		  ifFalse: [fieldtype ← 32 + (n = 8
					  ifTrue: [8]
					  ifFalse: [16])]]].
"106" Class$'Initialization'
[veryspecial: n | |
	 "inaccessible fields"
	instsize ← self instvars length + n].
"139" Class$'Message access'
[understands: code | selector old |
	 "install method"
	↑self understands: code classified: 'As yet unclassified'].
"768" Class$'Initialization'
[declare: v | var recom |
	self  self realself
	  ifTrue: [self realself declare: v]
	  ifFalse:
		[classvars  nil
		  ifTrue: [classvars ← SymbolTable init].
		(v is: String)
		  ifTrue: [self declare: v asVector]
		  ifFalse:
			[recom ← false.
			(v is: Vector)
			  ifTrue: [v do:
					[:var | ((Smalltalk has: var) or: [(Undeclared has: var)])
					  ifTrue: [recom ← true]]]
			  ifFalse:
				[((Smalltalk has: v) or: [(Undeclared has: v)])
				  ifTrue: [recom ← true]].
			recom
			  ifTrue: [user notify: 'Methods recompile if you proceed, global became local'].
			(v is: Vector)
			  ifTrue: [v do: [:var | classvars insert: var with: nil]]
			  ifFalse: [classvars insert: v with: nil].
			recom
			  ifTrue: [self compileall]]]].
"55" Class$'Access to parts'
[superclass | |
	↑superclass].
"372" Class$'Message access'
[compileall | s c |
	 "does not modify code, just compiles it"
	messagedict do: [:s | self recompile: s].
	self  Object
	  ifTrue: [nil installError] "to recompile the whole system (check out big changes) execute:
	| n [for n from: AllClassNames do
		[user show: n; cr. (Smalltalkn) compileall.
		Changes init. MessageDict new freeMethods]] "].
"299" Class$'Organization'
[organization | o |
	classvars  nil
	  ifTrue: [self declare: #ClassOrganization].
	o ← classvars lookup: #ClassOrganization.
	(o is: ClassOrganizer)
	  ifTrue: [↑o].
	o ← ClassOrganizer new init: messagedict contents sort.
	classvars insert: #ClassOrganization with: o.
	↑o].
"81" Class$'Filin and Filout'
[readfrom: strm | |
	↑self readfrom: strm format: nil].
"290" Class$'Instance access'
[print: inst on: strm | ivars i |
	ivars ← self instvars.
	strm append: '('.
	strm append: title.
	strm append: ' new '.
	(1 to: instsize) do:
		[:i | strm append: ivars  i.
		strm append: ': '.
		strm print: (inst instfield: i).
		strm space].
	strm append: ')'].
"443" Class$'Initialization'
[title: name insystem: system | cl |
	superclass ← Object.
	(system has: name)
	  ifTrue:
		[cl ← (system  name) class.
		cl  self class
		  ifTrue: [↑self].
		user notify: name + ' will change from a ' + cl title + ' to a ' + self class title + ' if you proceed...'].
	system declare: name as: self.
	AllClassNames ← AllClassNames insertSorted: name.
	SystemOrganization classify: name under: 'As yet unclassified'].
"491" Class$'Message access'
[derstands: selector | c |
	 "overstands?  undersits? - forget it"
	(selector is: Vector)
	  ifTrue: [selector do: [:c | self derstands: c]]
	  ifFalse:
		[(messagedict has: selector)  false
		  ifFalse:
			[messagedict ← messagedict delete: selector.
			self organization delete: selector.
			lastClass ← lastSelector ← lastParagraph ← nil.
			(Changes has: (c ← title + ' ' + selector))
			  ifTrue: [Changes delete: c].
			Changes insert: (c ← '~' + c).
			↑c]]].
"776" Class$'Filin and Filout'
[asFollows | s heading selector p t5 |
	self  self realself
	  ifTrue: [self realself asFollows]
	  ifFalse:
		[heading ← 'As yet unclassified' "handles Bravo or Press (Smalltalk generated) files".
		[(p ← FilinSource nextParagraph) and: [(s ← p text)  '']] whileTrueDo:
			[s  1 = 13
			  ifTrue: [s ← s copy: 2 to: s length "throw away initial cr before comment and headings"].
			(t5 ← p runs  2) = 2 "italic"
			  ifTrue: [self organization globalComment← s]
			  ifFalse:
				[t5 = 81 "5, bold"
				  ifTrue: [heading ← s]
				  ifFalse:
					[(self canunderstand: (selector ← self understands: p classified: heading))
					  ifTrue:
						[user show: selector.
						user space]
					  ifFalse: [user show: '(an uncompiled method) ']]]]]].
"93" Class$'Filin and Filout'
[readfrom: strm format: f | |
	↑self new readfrom: strm format: f].
"296" Class$'Message access'
[describe: method on: strm | sel cls |
	 "append mclass and selector"
	cls ← self.
	[cls  nil
	  ifTrue:
		[cls ← self.
		sel ← #?]
	  ifFalse: [sel ← cls md invert: method]] whileFalseDo:  [cls ← cls superclass].
	strm append: cls title.
	strm space.
	strm append: sel].
"62" Class$'Initialization'
[myinstvars← t1 | |
	myinstvars ← t1].
"62" Reader$'Internal readers'
[step | |
	nextchar ← source next].
"650" Reader$'Initialization'
[classInit | strm type first last i |
	 "Initialize the type and mask tables"
	typetable ← String new: 256.
	strm ← Stream new of: #(5 0 255 1 65 90 1 97 122 2 48 57 3 58 58 3 3 3 4 9 10 4 12 13 4 32 32 6 34 34 6 25 25 7 39 39 8 21 21 9 26 26 10 30 30 11 40 41 ) "(initialize)" "upper and lower case letters" "digits" "colon, open colon" "TAB, LF, FF, CR, blank" "5 is one-char tokens" "comment quote and " "string quote" "high-minus" "↑Z (format trailer)" "DOIT" "open and close paren".
	[type ← strm next] whileTrueDo:
		[first ← strm next.
		last ← strm next.
		(first + 1 to: last + 1) do: [:i | typetable  i ← type]]].
"117" Reader$'Initialization'
[of: s | |
	typetbl ← typetable.
	token ← Stream default.
	source ← s asStream.
	self step].
"83" TokenCollector$'Finalization'
[notify: errorString | |
	user notify: errorString].
"148" TokenCollector$'Finalization'
[contents | |
	 "Close all parentheses first"
	[parenstack empty] whileFalseDo:  [self rightparen].
	↑sink contents].
"50" TokenCollector$'Constructors'
[comment: s | |
	].
"50" TokenCollector$'Constructors'
[trailer: s | |
	].
"103" TokenCollector$'Constructors'
[onechar: c | x |
	x ← String new: 1.
	x  1 ← c.
	self next← x unique].
"69" TokenCollector$'Constructors'
[keyword: s | |
	self next← s unique].
"72" TokenCollector$'Constructors'
[integer: s | |
	self next← s asInteger].
"74" TokenCollector$'Initialization'
[default | |
	self to: (Vector new: 20)].
"105" TokenCollector$'Constructors'
[leftparen | |
	parenstack next← sink.
	sink ← (Vector new: 10) asStream].
"179" TokenCollector$'Constructors'
[rightparen | |
	parenstack empty
	  ifFalse:
		[ "Error will be caught elsewhere"
		parenstack last next← sink contents.
		sink ← parenstack pop]].
"71" TokenCollector$'Constructors'
[otheratom: s | |
	self next← s unique].
"61" TokenCollector$'Constructors'
[string: s | |
	self next← s].
"96" TokenCollector$'Finalization'
[next← obj | |
	sink next← obj "subclasses can override easily"].
"119" TokenCollector$'Initialization'
[to: v | |
	 "Initialize"
	sink ← v asStream.
	parenstack ← (Vector new: 5) asStream].
"109" TokenCollector$'Constructors'
[float: i fraction: f exp: e | |
	self next← (i + '.' + f + 'e' + e) asFloat].
"72" TokenCollector$'Constructors'
[identifier: s | |
	self next← s unique].
"52" TokenCollector$'Constructors'
[separator: c | |
	].
"73" Reader$'Main reader'
[read | |
	↑self readInto: TokenCollector default].
"538" Reader$'Main reader'
[readnum | val d e |
	val ← self rdint: 21.
	nextchar = 46
	  ifTrue:
		[ "check for decimal point"
		self step.
		(nextchar  false or: [nextchar isdigit  false])
		  ifTrue:
			[collector integer: val.
			collector onechar: 46]
		  ifFalse:
			[ "was <Integer> .  "
			d ← self rdint: 1 "fraction part".
			nextchar = 101
			  ifTrue:
				[ "check for e<exponent> "
				self step.
				e ← self rdint: 21]
			  ifFalse: [e ← ''].
			collector float: val fraction: d exp: e]]
	  ifFalse: [collector integer: val]].
"539" Reader$'Internal readers'
[rdint: char | |
	 "Read an integer, allow char as first char"
	token reset.
	nextchar = char
	  ifTrue:
		[token next← char.
		self step].
	[nextchar] whileTrueDo:
		[nextchar < 48
		  ifTrue: [↑token contents].
		nextchar > 57
		  ifTrue:
			[ "allow ABCDEFGH for hex"
			nextchar > 72
			  ifTrue: [↑token contents].
			nextchar < 65
			  ifTrue: [↑token contents].
			token next← nextchar.
			nextchar ← source next]
		  ifFalse:
			[.
			token next← nextchar.
			nextchar ← source next]].
	↑token contents].
"388" Reader$'Internal readers'
[upto: char | start |
	 "Knows about doubled ' in strings"
	start ← source position.
	token reset.
	[nextchar ← source next] whileTrueDo:
		[nextchar = char
		  ifTrue:
			[self step.
			char  39
			  ifTrue: [↑false].
			nextchar  39
			  ifTrue: [↑false]].
		token next← nextchar "Ran off end, back up."].
	source skip: start - 1 - source position.
	↑true].
"1489" Reader$'Main reader'
[readInto: t1 | x |
	collector ← t1.
	[nextchar] whileTrueDo:
		[x ← typetbl  (nextchar + 1) "See classInit for the meanings of the type codes".
		x = 4
		  ifTrue:
			[collector separator: nextchar.
			nextchar ← source next]
		  ifFalse:
			[x = 1
			  ifTrue: [self readatom: 0]
			  ifFalse:
				[x = 5
				  ifTrue:
					[collector onechar: nextchar.
					nextchar ← source next]
				  ifFalse:
					[x = 6
					  ifTrue:
						[(self upto: nextchar)
						  ifTrue: [collector notify: 'Unmatched comment quote']
						  ifFalse: [collector comment: token contents]]
					  ifFalse:
						[x = 2
						  ifTrue: [self readnum]
						  ifFalse:
							[x = 11
							  ifTrue:
								[nextchar = 40
								  ifTrue: [collector leftparen]
								  ifFalse: [collector rightparen].
								nextchar ← source next]
							  ifFalse:
								[x = 7
								  ifTrue:
									[(self upto: nextchar)
									  ifTrue: [collector notify: 'Unmatched string quote']
									  ifFalse: [collector string: token contents]]
								  ifFalse:
									[x = 8
									  ifTrue: [self readnum]
									  ifFalse:
										[x = 9
										  ifTrue:
											[(self upto: 13)
											  ifTrue: [collector notify: '↑Z without CR']
											  ifFalse: [collector trailer: token contents]]
										  ifFalse:
											[x = 10
											  ifTrue: [↑collector contents].
											x = 3
											  ifTrue: [self readatom: 1]]]]]]]]]]].
	↑collector contents].
"719" Reader$'Main reader'
[readatom: ncolons | type s t4 |
	token reset.
	[token next← nextchar.
	(nextchar ← source next)
	  ifTrue: [(type ← typetbl  (nextchar + 1))  3]
	  ifFalse: [false]] whileTrueDo:
		[type = 3
		  ifTrue: [ncolons ← ncolons + 1]].
	s ← token contents.
	ncolons = 0
	  ifTrue: [collector identifier: s]
	  ifFalse:
		[ncolons > 1
		  ifTrue: [collector otheratom: s]
		  ifFalse:
			[.
			s length = 1
			  ifTrue: [collector otheratom: s]
			  ifFalse:
				[ ": or  alone"
				(t4 ← s  s length) = 58
				  ifTrue: [collector keyword: s]
				  ifFalse:
					[t4 = 3
					  ifTrue: [collector keyword: s]
					  ifFalse:
						[.
						collector otheratom: s "Colon wasn't last character"]]]]]].
"177" Class$'Access to parts'
[fieldNamesInto: collector | |
	superclass  nil
	  ifFalse: [superclass fieldNamesInto: collector].
	↑(Reader new of: myinstvars) readInto: collector].
"166" Class$'Access to parts'
[Isa: x | |
	 "is x on my superclass chain?"
	superclass  x
	  ifTrue: [↑true].
	superclass  nil
	  ifTrue: [↑false].
	↑superclass Isa: x].
"106" Class$'Initialization'
[environment← t1 | |
	environment ← t1 "for resetting to reread sharing clauses"].
"100" Class$'Initialization'
[classInit | |
	 "gets propagated to a dummy instance"
	self new classInit].
"156" Class$'Instance access'
[allInstances | |
	NoteTaker
	  ifTrue: [user notify: 'use allInstancesdo in ST80']
	  ifFalse: [↑self allInstancesEver notNil]].
"97" Class$'Message access'
[selectors | |
	 "Return a Vector of all my selectors."
	↑self messages].
"182" Class$'Filin and Filout'
[definition | strm |
	 "return a string that defines me (Class new title etc.)"
	strm ← (String new: 50) asStream.
	self printdefon: strm.
	↑strm contents].
"1124" Class$'Filin and Filout'
[printdefon: strm | s |
	 "print my definition on strm"
	strm append: self class title.
	strm append: ' new title: '.
	strm append: title unique.
	strm cr.
	strm tab.
	strm append: 'subclassof: ' + (superclass  nil
	  ifTrue: ['nil']
	  ifFalse: [superclass title]).
	strm cr.
	strm tab.
	strm append: 'fields: ' + myinstvars asString.
	strm cr.
	strm tab.
	strm append: 'declare: '''.
	classvars contents do:
		[:s | s = #ClassOrganization
		  ifFalse:
			[strm append: s.
			strm space]].
	strm append: ''''.
	NoteTaker
	  ifTrue:
		[(instsize nomask: 16384)
		  ifTrue:
			[strm semicrtab.
			strm append: 'bytesize: '.
			(strm print: (instsize anymask: 8192))
			  ifTrue: []
			  ifFalse: []]]
	  ifFalse:
		[fieldtype  16
		  ifTrue:
			[strm semicrtab.
			strm append: 'bytesize: '.
			strm print: fieldtype - 32].
		instsize  (s ← self instvars) length
		  ifTrue:
			[strm semicrtab.
			strm append: 'veryspecial: '.
			strm print: instsize - s length]].
	environment  nil
	  ifFalse: [environment do:
			[:s | strm semicrtab.
			strm append: 'sharing: ' + (Smalltalk invert: s)]]].
"101" Class$'Filin and Filout'
[changelist: cat | |
	↑{title unique , (self organization category: cat)}].
"205" Class$'Organization'
[clean | name |
	 "release unreferenced classvars"
	classvars do:
		[:name | (name  #ClassOrganization and: [(classvars ref: name) refct = 1])
		  ifTrue: [classvars delete: name]]].
"158" Class$'Instance access'
[init: n | |
	 "init and default get propagated to instances"
	self isVariable
	  ifTrue: [↑(self new: n) init].
	↑self new init: n].
"168" Class$'Initialization'
[sharing: table | |
	self  self realself
	  ifTrue: [self realself sharing: table]
	  ifFalse: [environment ← {environment asVector , table}]].
"321" Class$'Initialization'
[obsolete | |
	 "invalidate further communication"
	title ← 'AnObsolete' + title.
	classvars ← nil "recycle class variables".
	messagedict close "invalidate and recycle local messages".
	environment ← self "keep me around for old instances".
	superclass ← Object "invalidate superclass messages"].
"330" Class$'Access to parts'
[instsize | |
	 "Return the number of user accessable instance fields"
	NoteTaker
	  ifTrue: [↑instsize land: 2047].
	↑fieldtype  32
	  ifTrue: [0]
	  ifFalse:
		[self  Class
		  ifTrue: [instsize - 1]
		  ifFalse:
			[self  VariableLengthClass
			  ifTrue: [instsize - 20]
			  ifFalse: [instsize]]]].
"79" Class$'Message access'
[bytesof: sel | |
	↑(messagedict method: sel) asBytes].
"85" Class$'Message access'
[messages | |
	↑{messagedict contents , #ClassOrganization}].
"94" FieldNameCollector$'Invalid fields'
[leftparen | |
	self next← '(' "just for error message"].
"95" FieldNameCollector$'Invalid fields'
[rightparen | |
	self next← ')' "just for error message"].
"109" FieldNameCollector$'Invalid fields'
[next← value | |
	user notify: 'Invalid field name: ' + value asString].
"69" FieldNameCollector$'Valid fields'
[identifier: s | |
	sink next← s].
"248" Class$'Access to parts'
[instvars | |
	self  lastInstvarClass
	  ifTrue: [↑lastInstvars copy].
	 "cache last computation of instvars"
	lastInstvarClass ← self.
	lastInstvars ← self fieldNamesInto: FieldNameCollector default.
	↑lastInstvars copy].
"64" Class$'Initialization'
[abstract | |
	self fields: nullString].
"119" Class$'Editing'
[execute: code | |
	 "disposable methods"
	self understands: 'doit [' + code + ']'.
	↑self new doit].
"305" Class$'Editing'
[edit: selector | para s v |
	para ← (selector = #ClassOrganization
			  ifTrue: [self organization asParagraph]
			  ifFalse:
				[(messagedict has: selector)
				  ifTrue: [self code: selector]
				  ifFalse: [nullString asParagraph]]).
	self edit: selector para: para formerly: false].
"103" Class$'Initialization'
[realself | |
	↑Smalltalk  title unique "as opposed to possible filin ghost"].
"841" Class$'Access to parts'
[invertRef: refs | cl env source ref inv sym t |
	 "Refs may be a vector (to allow batching)"
	(refs isnt: Vector)
	  ifTrue: [↑(self invert: refs inVector)  1].
	env ← (self wholeEnvironment concat: {Undeclared , Smalltalk}) asStream.
	source ← Dictionary init.
	↑refs transform [:ref | ref] to [
		(cl ← self.
		env reset.
		[(sym ← env next)  false
		  ifTrue: [inv ← 'unknown ' concat: ref asOop base8]
		  ifFalse:
			[(cl  nil and: [sym  cl classvars])
			  ifTrue:
				[t ← cl title.
				cl ← cl superclass]
			  ifFalse: [t ← false].
			(inv ← sym invertRef: ref)  false
			  ifTrue: [false]
			  ifFalse:
				[t
				  ifFalse:
					[(t ← source lookup: sym)
					  ifFalse: [source insert: sym with: (t ← Smalltalk invert: sym)]].
				inv ← (t concat: ' ') concat: inv]]] whileFalseDo:  [].
		inv)]].
"628" Class$'Initialization'
[rename: newtitle | name newname oldclass category |
	name ← title unique.
	newname ← newtitle unique.
	(Smalltalk has: newname)
	  ifTrue:
		[oldclass ← Smalltalk  newname.
		user notify: 'All ' + newtitle + 's will become obsolete if you proceed'.
		oldclass obsolete]
	  ifFalse:
		[category ← SystemOrganization invert: name.
		AllClassNames ← AllClassNames insertSorted: newname.
		SystemOrganization classify: newname under: category].
	Smalltalk delete: name.
	AllClassNames ← AllClassNames delete: name.
	SystemOrganization delete: name.
	title ← newtitle.
	Smalltalk declare: newname as: self].
"1031" Class$'Initialization'
[fields: t1 | r a b s h |
	 "list of instance variables"
	myinstvars ← t1.
	messagedict ← (NoteTaker
			  ifTrue: [MethodDictionary init: 4]
			  ifFalse: [MessageDict init]).
	r ← self realself.
	a ← self instvars.
	h ← HashSet init.
	a do:
		[:s | (h has: s)
		  ifTrue: [user notify: s + ' is used already (maybe in superclass)']
		  ifFalse: [h insert: s]].
	self = r
	  ifTrue: [self initClass]
	  ifFalse:
		[a = (b ← r instvars)
		  ifTrue:
			[r environment← nil.
			r myinstvars← myinstvars.
			r subclassof: superclass]
		  ifFalse:
			[r howMany > 0
			  ifTrue: [user notify: 'All ' + title + 's become obsolete if you proceed...'].
			classvars ← r classvars.
			messagedict ← r md copy.
			(a length  b length or: [a  (1 to: b length)  b])
			  ifTrue:
				[ "just adding new inst fields"
				user notify: title + ' methods recompile if you proceed...'.
				self compileall].
			r md init.
			self fixSubClassesOf: r.
			r obsolete.
			Smalltalk  title unique ← self.
			self initClass]]].
"262" Class$'Instance access'
[howMany | v n |
	 "how many instances of this class are in use now?"
	NoteTaker
	  ifTrue:
		[n ← 0.
		self allInstances: v do [(n ← n + 1)].
		↑n].
	v ← self allInstancesEver.
	thisContext destroyAndReturn: v length - (v count: nil)].
"96" Class$'Message access'
[copy: sel from: class | |
	self copy: sel from: class classified: nil].
"179" Class$'Message access'
[canUnderstand: selector | |
	(messagedict has: selector)
	  ifTrue: [↑self].
	superclass  nil
	  ifTrue: [↑false].
	↑superclass canUnderstand: selector].
"587" Class$'Instance access'
[allInstancesEver | indx vec PCLs i |
	 "returns a vector containing all instances of this class mixed with nils"
	NoteTaker
	  ifTrue: [user notify: 'not implemented']
	  ifFalse:
		[ "Works for all classes.  Some additional instances may be created after the
	vector is filled but before you get to use it."
		PCLs ← Vmem pclassesOf: self "vector of PCLs".
		vec ← Vector new: 128 * PCLs length.
		(1 to: PCLs length) do: [:i | vec  (i - 1 * 128 + 1 to: i * 128) all← PCLs  i].
		thisContext destroyAndReturn: (self fromFreelist: Class instsize fill: vec)]].
"183" Class$'Organization'
[wholeEnvironment | |
	↑(classvars asVector concat: environment asVector) concat: (superclass  nil
	  ifTrue: [#()]
	  ifFalse: [superclass wholeEnvironment])].
"55" Class$'Access to parts'
[myinstvars | |
	↑myinstvars].
"245" Class$'Initialization'
[copyof: oldClass subclassof: newSubClass | |
	title ← oldClass title.
	self subclassof: newSubClass.
	classvars ← oldClass classvars.
	environment ← oldClass environment.
	self newFieldsForSubClass: oldClass myinstvars].
"214" Class$'Initialization'
[fixSubClassesOf: oldClass | n subClass |
	user classNames do:
		[:n | subClass ← Smalltalk  n.
		subClass superclass  oldClass
		  ifTrue: [Class new copyof: subClass subclassof: self]]].
"260" Class$'Initialization'
[initClass | |
	fieldtype ← 16.
	instsize ← self instvars length.
	instsize > 256
	  ifTrue: [user notify: 'too many instance variables']
	  ifFalse:
		[NoteTaker
		  ifTrue: [instsize ← instsize + 1 * 2 + 8192].
		self organization]].
"1082" Class$'Initialization'
[newFieldsForSubClass: t1 | r a b |
	 "list of instance variables"
	myinstvars ← t1.
	messagedict ← MessageDict init.
	r ← self realself.
	self = r
	  ifTrue: [user notify: 'problem in class redefinition. See coment at end of method']
	  ifFalse:
		[(a ← self instvars) = (b ← r instvars)
		  ifTrue: [user notify: 'problem in class redefinition. See coment at end of method']
		  ifFalse:
			[r howMany > 0
			  ifTrue: [user cr show: 'All ' + title + 's are obsolete.'].
			classvars ← r classvars.
			messagedict ← r md copy.
			r md init.
			(a length  b length or: [a  (1 to: b length)  b])
			  ifTrue:
				[ "changing inst fields"
				user cr show: title + ' recompiled.'.
				self compileall].
			self fixSubClassesOf: r.
			r obsolete.
			Smalltalk  title unique ← self.
			self initClass]] "Regarding the notifys in this method: It is my understanding
		 that this method will only be invoked when the conditions
		 leading to the notifys are false. If I'm available, I'd like to see
		 any case that results in notification.
				Dave Robson"].
"1034" Class$'Message access'
[archiveOn: file changesOnly: ch | org m |
	user cr "this should be called only by the system releaser
	(via UserView file:classes:changesOnly:) !!!

	if you want to archive your own classes (useful only if you have stable code
	and intend to clean up afterwards with a vmem write), see Steve.

	write comment and method text on a FileStream for some file.
	ch [write only changes (non-remote String/Paraagraphs)] write everything".
	user show: title.
	org ← self organization.
	(ch and: [(org globalCommentItself "org globalComment always yields a String, so a small kludge is in order" is: RemoteParagraph)])
	  ifFalse: [org globalComment← (RemoteParagraph new on: file) fromString: org globalComment] "archive in category&alphabetical rather than hash order (messagedict)".
	org do:
		[:m | (ch and: [((messagedict code: m) is: RemoteParagraph)])
		  ifFalse:
			[messagedict code: m ← (RemoteParagraph new on: file) fromParagraph: (self code: m).
			ch
			  ifTrue:
				[user space.
				user show: m]]]].
"365" Class$'As yet unclassified'
[regenerate: sel | old new tree |
	sel  nil
	  ifTrue: [messagedict do: [:sel | user displayoffwhile [(self regenerate: sel)]]]
	  ifFalse:
		[ "user show: title; space; show: sel; cr."
		.
		tree ← self decompile: sel.
		new ← tree generate.
		old ← self method: sel "user print: old length; space; print: new length; cr.".
		↑new]].
"251" Class$'Instance access'
[allInstances each do expr | inst |
	inst ← self someInstance.
	inst  false
	  ifFalse:
		[each value← inst.
		expr eval.
		[inst ← inst nextInstance] whileTrueDo:
			[each value← inst.
			expr eval].
		each value← false]].
"136" Class$'Instance access'
[someInstance | |<primitive: 84>
	 "return first instance of this class, false if there are none"
	user croak].
"1050" Class$'Message access'
[getSource80: sel | meth loc file pos char len str |
	 "get source text from file, or decompile"
	(meth ← messagedict methodorfalse: sel)
	  ifFalse: [↑self decompile: sel].
	loc ← meth length.
	file ← meth  loc.
	pos ← file land: 63 "high order 6 bits of pos".
	file ← file / 64 "top 2 bits are file index".
	pos ← pos * 256 + (meth  (loc - 1)).
	pos ← pos * 256 + (meth  (loc - 2)).
	pos = 0
	  ifTrue: [↑self decompile: sel].
	file ← SourceFiles  (file + 1) "get to correct file (should be readonly)".
	file position← pos "read source text, this should be merged with filin stuff.
		For now, it does not check matching selectors!!".
	char ← file next.
	char  34
	  ifTrue: [user notify: 'not pointing at length comment']
	  ifFalse:
		[len ← file integerScan.
		[(char ← file next) = 91] whileFalseDo:  [ "skip class and category"
			len ← len - 1 "and decrease len of code"].
		len ← len - 2 "subtract for ].<cr> after code".
		str ← String new: len.
		file into: str "get code".
		↑str asParagraph makeBoldPattern]].
"63" Class$'Access to parts'
[ x ← val | |
	↑classvars  x ← val].
"48" Class$'Access to parts'
[md | |
	↑messagedict].
"51" Class$'Access to parts'
[ x | |
	↑classvars  x].
"244" Class$'System Organization'
[moveFromCat: cat1 to: cat2 | |
	((cat1 is: String) and: [(cat2 is: String)])
	  ifTrue: [SystemOrganization move: self title unique from: cat1 to: cat2]
	  ifFalse: [user notify: 'Category name must be a String']].
"62" Class$'Instance access'
[new | |<primitive: 29>
	user croak].
"226" Class$'Editing'
[ed: selector | c s |
	c ← self code: selector.
	user clearshow: c.
	[s ← user request: 'substitute: '] whileTrueDo:
		[c ← c subst: s for: (user request: 'for: ').
		user clearshow: c].
	self understands: c].
"1157" LADDecompiler$'Initialization'
[decompile: selOrFalse in: class method: method | i primitive nTemps lits |
	instVars ← class instvars.
	(1 to: instVars length) do: [:i | instVars  i ← LADVariableNode new name: instVars  i index: i - 1 type: LdInstType].
	method isQuick
	  ifTrue: [↑self quickMethod: method selector: selOrFalse].
	 "parse the header"
	nLits ← method numLiterals.
	nTemps ← method numTemps.
	nArgs ← method numArgs.
	primitive ← method primitive "create symbol tables".
	tempVars ← Vector new: nTemps.
	(1 to: nTemps) do: [:i | tempVars  i ← LADVariableNode new name: 't' + i asString index: i - 1 type: LdTempType].
	literals ← Vector new: nLits.
	lits ← method literals.
	(1 to: nLits) do: [:i | literals  i ← LADLiteralNode new key: lits  i index: i - 1 type: LdLitType].
	postfixStream ← method asStream.
	postfixStream skip: nLits * 2 + 4.
	NoteTaker
	  ifTrue:
		[postfixStream limit: postfixStream limit - 3 "three on end for file pos"].
	symbolTables ← {class wholeEnvironment , Smalltalk , Undeclared}.
	self reverse "reverse the bytes".
	↑(self method: selOrFalse primitive: primitive literals: lits class: class) simplify].
"684" LADDecompiler$'Decompiler'
[quickMethod: method selector: selOrFalse | block flags |
	flags ← method  3 / 32.
	block ← (flags = 5
			  ifTrue: [LADBlockNode new default mustReturn]
			  ifFalse:
				[flags = 6
				  ifTrue: [LADBlockNode new statements: (instVars  (method  3 \ 32 + 1)) inVector returns: true]
				  ifFalse: [user notify: 'improper short method']]).
	↑LADMethodNode new selector: (selOrFalse
	  ifTrue: [LADSelectorNode new key: selOrFalse code: nil]
	  ifFalse: [false]) arguments: #() precedence: (selOrFalse isinfix
	  ifTrue: [2]
	  ifFalse:
		[selOrFalse iskeyword
		  ifTrue: [3]
		  ifFalse: [1]]) temporaries: #() block: block encoder: nil primitive: 0].
"608" LADDecompiler$'Decompiler'
[method: selOrFalse primitive: primitive literals: lits class: class | method |
	 "pattern block"
	method ← LADMethodNode new selector: (selOrFalse
			  ifTrue: [LADSelectorNode new key: selOrFalse code: nil]
			  ifFalse: [selOrFalse]) arguments: self arguments precedence: (selOrFalse isinfix
			  ifTrue: [2]
			  ifFalse:
				[selOrFalse iskeyword
				  ifTrue: [3]
				  ifFalse: [1]]) temporaries: self temporaries block: self statements encoder: (LADEncoder new initScopeAndLiteralTables nTemps: tempVars length literals: lits class: class) primitive: primitive.
	↑method].
"135" LADDecompiler$'Reverser Performs'
[goto: nibble | |
	nibble < 8
	  ifTrue: [self jmp: nibble + 1]
	  ifFalse: [self bfp: nibble - 7]].
"87" LADDecompiler$'Decoding'
[decodeInstanceVariable: which | |
	↑instVars  (which + 1)].
"324" LADDecompiler$'Decoding'
[decodePoolVariable: which | global ref name |
	ref ← (literals  (which + 1)) key.
	symbolTables do:
		[:global | (name ← global invertRef: ref)
		  ifTrue: [↑LADVariableNode new name: name key: ref index: which type: LdLitIndType]].
	self error: 'Obsolete global/class/pool variable referenced'].
"109" LADDecompiler$'Reverser Performs'
[send: lowbits | |
	prefixStream next← self decodeSelector: lowbits \ 16].
"108" LADDecompiler$'Reverser Performs'
[ldLitInd: which | |
	prefixStream next← self decodePoolVariable: which].
"166" LADDecompiler$'Reverser Performs'
[gotoLong: nibble | |
	nibble < 8
	  ifTrue: [self jmp: (self long: nibble - 4)]
	  ifFalse: [self bfp: (self long: nibble - 12)]].
"106" LADDecompiler$'Reverser Performs'
[sendSpecial: which | |
	prefixStream next← self decodeSpecial: which].
"100" LADDecompiler$'Reverser Performs'
[ldLit: which | |
	prefixStream next← self decodeLiteral: which].
"88" LADDecompiler$'Decoding'
[decodeTemporaryVariable: which | |
	↑tempVars  (which + 1)].
"80" LADDecompiler$'Reverser Performs'
[pop: lowbits | |
	prefixStream next← #:pop].
"402" LADDecompiler$'Decompiler'
[while: truth | if then |
	 "if whileTrue: [then]"
	then ← self block.
	self require: #:come.
	truth  false
	  ifTrue: [self require: #:come].
	if ← self block.
	self require: #:begin.
	↑LADMessageNode new receiver: if selector: (LADSelectorNode new key: (truth
	  ifTrue: [#whileTrueDo:]
	  ifFalse: [#whileFalseDo:]) code: #macro) arguments: then inVector precedence: 3].
"625" LADDecompiler$'Decompiler'
[remote | block args sel |
	 "[{:x} | ...]"
	hereType  #:endMethod
	  ifFalse: [ "endRemote elided"
		self require: #:endRemote].
	block ← self block.
	self match: #:begin "st76 back-jump".
	self require: #:come.
	args ← (Vector new: 2) asStream.
	(self match: #:arguments)
	  ifTrue: [[self match: #:pop] whileTrueDo:
			[args next← self require: LADVariableNode.
			self require: #:store]].
	sel ← self advance.
	sel key = #blockCopy:
	  ifTrue: [self advance].
	self exactly: NodeThisContext.
	block transformRemoteVariable
	  ifTrue: [↑block].
	 "ST76 only"
	↑block arguments: args contents].
"130" LADDecompiler$'Reverser Subroutines'
[come: dist | |
	prefixStream next← #:come.
	self reverseTo: postfixStream position + dist].
"91" LADDecompiler$'Reverser Subroutines'
[long: octal | |
	↑octal * 256 + postfixStream next].
"664" LADDecompiler$'Initialization'
[decompile: sel in: class | old newBytes tree |
	NoteTaker
	  ifTrue:
		[ST80  false
		  ifTrue: [self classInit].
		↑self decompile: sel in: class method: (class method: sel)].
	ST80
	  ifTrue: [self ST76Init].
	true
	  ifTrue:
		[tree ← self decompile76: sel in: class method: (class method: sel) "user notify: '*'.".
		↑tree].
	 "special version to check out ST80 decompiling
Convert old bytes to new then decompile new bytes"
	tree ← self decompile76: sel in: class method: (class method: sel) "user notify: '*'. ".
	newBytes ← tree generate asCompiledMethod.
	self classInit.
	↑self decompile: sel in: class method: newBytes].
"339" LADDecompiler$'Decompiler'
[expression | e |
	 "assignment | message | variable | literal | control"
	aheadType  #:store
	  ifTrue: [↑self assignment].
	(e ← self match: LADVariableNode)
	  ifTrue: [↑e].
	(e ← self match: LADSelectorNode)
	  ifTrue: [↑self message: e].
	(e ← self match: LADLiteralNode)
	  ifTrue: [↑e].
	↑self control].
"155" LADDecompiler$'Decompiler'
[assignment | var |
	var ← self advance.
	self require: #:store.
	↑LADAssignmentNode new variable: var value: self expression].
"445" LADDecompiler$'Decompiler'
[statements | stmts e returns |
	returns ← self match: #:endMethod.
	stmts ← (Vector new: 10) asStream.
	e ← self expression.
	(self match: #:endMethod)
	  ifTrue: [e ← self expression "last return was inaccessible"].
	[e] whileTrueDo:
		[stmts next← e.
		e ← ((self match: #:pop)
				  ifTrue: [self expression]
				  ifFalse: [self control])].
	↑LADBlockNode new statements: stmts reverseContents returns: returns].
"409" LADDecompiler$'Decompiler'
[conditional: withElse | if then else |
	 "if ifTrue: then ifFalse: else"
	withElse
	  ifTrue:
		[else ← self block.
		self require: #:come]
	  ifFalse: [else ← LADBlockNode default].
	then ← self block.
	self require: #:come.
	↑LADMessageNode new receiver: self expression selector: (LADSelectorNode new key: #ifTrue:ifFalse: code: #macro) arguments: {then , else} precedence: 3].
"88" LADDecompiler$'Reverser Subroutines'
[abguments | |
	↑(tempVars  (1 to: nArgs)) copy].
"77" LADDecompiler$'Errors'
[confused | |
	self error: 'unexpected object code'].
"431" LADDecompiler$'ST76'
[decodeConstant76: which | |
	which = 1
	  ifTrue: [↑NodeSelf].
	which > 12
	  ifTrue:
		[which = 13
		  ifTrue: [↑NodeNil].
		which = 14
		  ifTrue: [↑NodeFalse].
		↑NodeTrue]
	  ifFalse:
		[which = 12
		  ifTrue: [↑LADLiteralNode new key: 10 code: 3].
		which < 8
		  ifTrue: [user notify: 'Cant decode context-rel loads']
		  ifFalse: [↑LADLiteralNode new key: which - 8 - 1 code: LdMinus1 + which - 8]]].
"1108" LADDecompiler$'ST76'
[decompile76: selOrFalse in: class method: string | i primitive nTemps lits |
	instVars ← class instvars.
	(1 to: instVars length) do: [:i | instVars  i ← LADVariableNode new name: instVars  i index: i - 1 type: LdInstType].
	string length  6
	  ifTrue: [↑self quickMethod76: string selector: selOrFalse].
	 "parse the header"
	postfixStream ← string asStream.
	postfixStream skip: 1.
	primitive ← postfixStream next.
	postfixStream skip: 1.
	nArgs ← postfixStream next.
	nTemps ← postfixStream next.
	nLits ← postfixStream next - 6 / 2 "create symbol tables".
	tempVars ← Vector new: nTemps.
	(1 to: nTemps) do: [:i | tempVars  i ← LADVariableNode new name: 't' + i asString index: i - 1 type: LdTempType].
	literals ← Vector new: nLits.
	lits ← Vector new: nLits.
	(1 to: nLits) do: [:i | literals  i ← LADLiteralNode new key: lits  i ← postfixStream nextword asObject index: i - 1 type: LdLitType].
	symbolTables ← {class wholeEnvironment , Smalltalk , Undeclared}.
	self reverse "reverse the bytes".
	↑self method: selOrFalse primitive: primitive literals: lits class: class].
"96" LADDecompiler$'Scanner'
[match: type | |
	hereType  type
	  ifTrue: [↑self advance].
	↑false].
"105" LADDecompiler$'Decompiler'
[block | |
	 "ignores for-effect pop"
	self match: #:pop.
	↑self statements].
"117" LADDecompiler$'Reverser'
[reverseTo: limit | |
	[postfixStream position  limit] whileFalseDo:  [self reverseNext]].
"713" LADDecompiler$'Reverser'
[reverseNext | byte group sel thisLoc |
	byte ← postfixStream next "Mark loop beginnings: ".
	[nextBegin and: [postfixStream position = nextBegin]] whileTrueDo:
		[prefixStream last "ST80false and"  #:store
		  ifTrue:
			[ "handle for-loop optimization"
			nextBegin ← false "store var test -> store var pop begin var test".
			thisLoc ← postfixStream position.
			postfixStream skip: 1.
			self reverseNext.
			prefixStream next← #:pop.
			postfixStream position← thisLoc].
		prefixStream next← #:begin.
		nextBegin ← beginStream next].
	group ← byte / 16 + 1.
	sel ← typeTable  group.
	self performDangerously: sel with: byte - (baseTable  group) "checked in classInit".
	↑sel].
"326" LADDecompiler$'Decoding'
[decodeConstant: lowbits | |
	lowbits  4
	  ifTrue: [↑LADLiteralNode new key: 1 + lowbits - 4 code: LdMinus1 + lowbits - 4].
	lowbits = 0
	  ifTrue: [↑NodeSelf].
	lowbits = 1
	  ifTrue: [↑NodeTrue].
	lowbits = 2
	  ifTrue: [↑NodeFalse].
	lowbits = 3
	  ifTrue: [↑NodeNil].
	self confused: lowbits].
"78" LADDecompiler$'Decoding'
[decodeLiteral: which | |
	↑literals  (which + 1)].
"138" LADDecompiler$'Decoding'
[decodeSelector: which | |
	↑LADSelectorNode new key: (literals  (which + 1)) key index: which type: SendType].
"130" LADDecompiler$'Decoding'
[decodeSpecial: which | |
	↑LADSelectorNode new key: specialTable  (which + 1) code: SendPlus + which].
"687" LADDecompiler$'ST76'
[quickMethod76: method selector: selOrFalse | block node |
	block ← (method  2 = 1
			  ifTrue: [LADBlockNode new default mustReturn]
			  ifFalse:
				[method  2 = 40
				  ifTrue: [LADBlockNode new statements: (instVars  (method  5 + 1)) inVector returns: true]
				  ifFalse: [user notify: 'improper short method']]).
	node ← LADMethodNode new selector: (selOrFalse
			  ifTrue: [LADSelectorNode new key: selOrFalse code: nil]
			  ifFalse: [false]) arguments: #() precedence: (selOrFalse isinfix
			  ifTrue: [2]
			  ifFalse:
				[selOrFalse iskeyword
				  ifTrue: [3]
				  ifFalse: [1]]) temporaries: #() block: block encoder: nil primitive: 0.
	↑node].
"853" LADDecompiler$'Initialization'
[classInit | x |
	 "LADDecompiler classInit."
	typeTable ← #(ldInst: ldTemp: ldLit: ldLit: ldLitInd: ldLitInd: shortStoP: constAndRet: sundry: goto: gotoLong: sendSpecial: sendSpecial: send: send: send: ) "16 groups of 16 byte codes each" "typeTable transform x to [x mustTake: 1]. check for performDangerously".
	baseTable ← #(0 16 32 32 64 64 96 112 128 144 160 176 176 208 208 208 ) "subtract base of group to get low bits".
	sundryTable ← #(longLoad: longSto: longStoPop: longSend: longSend: longSuper: longSuper: pop: dup: ldThisContext: ldHome: confused: confused: confused: confused: confused: ) "sundryTable transform x to [x mustTake: 1]. check for performDangerously".
	specialTable ← (SpecialOops  (10 ~ 41)) copy.
	specialTable  (19 ~ 23) ← {#length , #next , 'next←' unique , #end , #}.
	ST80 ← true].
"341" LADDecompiler$'Reverser'
[reverse | |
	self backScan "Check for backward jumps".
	nextBegin ← beginStream next.
	prefixStream ← (Vector new: postfixStream limit * 2) asStream.
	self reverseTo: postfixStream limit "Reverse the method".
	prefixStream ← prefixStream reverseContents asStream.
	self advance.
	self advance "Start the scanner"].
"445" LADDecompiler$'Reverser Performs'
[constAndRet: lowbits | |
	lowbits < 8
	  ifTrue: [prefixStream next← self decodeConstant: lowbits]
	  ifFalse:
		[lowbits < 12
		  ifTrue:
			[prefixStream next← self decodeConstant: lowbits - 8.
			self endMethod: lowbits]
		  ifFalse:
			[lowbits = 12
			  ifTrue: [self endMethod: lowbits]
			  ifFalse:
				[lowbits = 13
				  ifTrue: [self endRemote: lowbits]
				  ifFalse: [self confused: lowbits]]]]].
"256" LADDecompiler$'Reverser Performs'
[shortStoP: lowbits | |
	prefixStream next← #:store.
	prefixStream next← (lowbits < 8
	  ifTrue: [self decodeInstanceVariable: lowbits]
	  ifFalse: [self decodeTemporaryVariable: lowbits - 8]).
	prefixStream next← #:pop].
"527" LADDecompiler$'Reverser Subroutines'
[jmp: dist | nargs argLoc p |
	dist < 0
	  ifTrue: [prefixStream next← #:while]
	  ifFalse:
		[argLoc ← postfixStream position.
		ST80
		  ifTrue:
			[nargs ← 0 "collect arguments to block".
			[(p ← postfixStream peek) = StorePop or: [(p between: ShortStoP and: [ShortStoP + 15])]] whileTrueDo:
				[self reverseNext.
				nargs ← nargs + 1].
			nargs > 0
			  ifTrue: [prefixStream next← #:arguments]].
		self come: dist - (postfixStream position - argLoc).
		prefixStream next← #:else]].
"99" LADDecompiler$'Reverser Subroutines'
[bfp: dist | |
	self come: dist.
	prefixStream next← #:then].
"100" LADDecompiler$'Reverser Performs'
[ldThisContext: lowbits | |
	prefixStream next← NodeThisContext].
"110" LADDecompiler$'Reverser Performs'
[ldInst: which | |
	prefixStream next← self decodeInstanceVariable: which].
"111" LADDecompiler$'Reverser Performs'
[ldTemp: which | |
	prefixStream next← self decodeTemporaryVariable: which].
"205" LADDecompiler$'Reverser Performs'
[sundry: nibble | sel |
	sel ← sundryTable  (nibble + 1).
	sel  1 = 58 ":"
	  ifTrue: [prefixStream next← sel]
	  ifFalse: [self performDangerously: sel with: nibble]].
"92" LADDecompiler$'Reverser Performs'
[endMethod: lowbits | |
	prefixStream next← #:endMethod].
"232" LADDecompiler$'Reverser Performs'
[endRemote: lowbits | |
	prefixStream next← #:endRemote.
	(postfixStream peek between: JmpLong and: [JmpLong + 3])
	  ifTrue: [postfixStream skip: 2] "skip ST76 back-jmp so it wont make a :while"].
"400" LADDecompiler$'Decompiler'
[control | |
	 "conditional | loop"
	(self match: #:then)
	  ifTrue:
		[(self match: #:else)
		  ifTrue:
			[(self match: #:while)
			  ifTrue: [↑self while: false].
			↑self conditional: true]
		  ifFalse:
			[(self match: #:while)
			  ifTrue: [↑self while: true].
			↑self conditional: false]]
	  ifFalse:
		[(self match: #:else)
		  ifTrue: [↑self remote].
		↑false]].
"86" LADDecompiler$'Errors'
[confused: lowbits | |
	self error: 'unexpected object code'].
"80" LADDecompiler$'Reverser Performs'
[dup: lowbits | |
	prefixStream next← #:dup].
"81" LADDecompiler$'ST76'
[sendLong76: lowbits | |
	self send76: postfixStream next].
"122" LADDecompiler$'ST76'
[storePop76: lowbits | |
	prefixStream next← #:store.
	self reverseNext.
	prefixStream next← #:pop].
"75" LADDecompiler$'ST76'
[ldSuper76: lowbits | |
	prefixStream next← #:super].
"86" LADDecompiler$'Reverser Performs'
[ldSelf: lowbits | |
	prefixStream next← #:ldSelf].
"89" LADDecompiler$'ST76'
[send76: which | |
	prefixStream next← self decodeSelector: which].
"83" LADDecompiler$'ST76'
[ldInstLong76: lowbits | |
	self ldInst: postfixStream next].
"87" LADDecompiler$'ST76'
[ldLitIndLong76: lowbits | |
	self ldLitInd: postfixStream next].
"98" LADDecompiler$'ST76'
[ldConst76: lowbits | |
	prefixStream next← self decodeConstant76: lowbits].
"321" LADDecompiler$'Scanner'
[advance | old |
	old ← here.
	here ← ahead.
	hereType ← aheadType.
	ahead ← prefixStream next.
	aheadType ← ((ahead is: UniqueString)
			  ifTrue:
				[ahead  1 = 58
				  ifTrue: [ ":"
					ahead]
				  ifFalse: [#:selector]]
			  ifFalse: [ahead class "VariableNode or LiteralNode"]).
	↑old].
"81" LADDecompiler$'ST76'
[ldLitLong76: lowbits | |
	self ldLit: postfixStream next].
"83" LADDecompiler$'ST76'
[ldTempLong76: lowbits | |
	self ldTemp: postfixStream next].
"460" LADDecompiler$'Reverser Performs'
[longLoad: lowbits | extension type index |
	extension ← postfixStream next.
	type ← extension / 64.
	index ← extension \ 64.
	prefixStream next← (type = 0
	  ifTrue: [self decodeInstanceVariable: index]
	  ifFalse:
		[type = 1
		  ifTrue: [self decodeTemporaryVariable: index]
		  ifFalse:
			[type = 2
			  ifTrue: [self decodeLiteral: index]
			  ifFalse:
				[type = 3
				  ifTrue: [self decodePoolVariable: index]]]])].
"127" LADDecompiler$'Reverser Performs'
[longStoPop: lowbits | |
	self store: lowbits.
	self longLoad: lowbits.
	self pop: lowbits].
"84" LADDecompiler$'Reverser Performs'
[store: lowbits | |
	prefixStream next← #:store].
"105" LADDecompiler$'Scanner'
[require: type | |
	hereType  type
	  ifTrue: [↑self advance].
	self confused].
"878" LADDecompiler$'Decompiler'
[message: selector | sel prec rcvr n args i supered |
	 "receiver selector arguments"
	ST80  false
	  ifTrue: [↑self message76: selector].
	supered ← self match: #:super.
	sel ← selector key.
	n ← sel numArgs.
	args ← Vector new: n.
	(n to: 1 by: 1) do: [:i | args  i ← self expression].
	prec ← (sel isinfix
			  ifTrue: [2]
			  ifFalse:
				[sel iskeyword
				  ifTrue: [3]
				  ifFalse: [1]]).
	hereType  #:pop
	  ifTrue: [↑self cascade: (LADMessageNode new "last msg of cascade" receiver: false selector: selector arguments: args precedence: prec)].
	rcvr ← (supered
			  ifTrue:
				[self exactly: NodeSelf.
				NodeSuper]
			  ifFalse:
				[(self match: #:dup)
				  ifTrue: [false]
				  ifFalse: [ "prior msgs of cascade"
					self expression]]).
	↑LADMessageNode new receiver: rcvr selector: selector arguments: args precedence: prec].
"105" LADDecompiler$'Scanner'
[exactly: symbol | |
	here  symbol
	  ifTrue: [↑self advance].
	self confused].
"915" LADDecompiler$'Reverser'
[backScan | byte dist start |
	 "quickly locates destinations (begins) of back jumps
		to handle old for-loops, and while loops with multi-stmt conditions"
	start ← postfixStream position.
	beginStream ← (Vector new: 2) asStream.
	postfixStream do:
		[:byte | byte < JmpLong
		  ifTrue:
			[ST80
			  ifTrue:
				[byte < 128
				  ifFalse:
					[byte  134
					  ifTrue:
						[postfixStream next "extension bytes".
						(byte = 132 or: [byte = 134])
						  ifTrue: [postfixStream next]]]]
			  ifFalse:
				[byte < 136
				  ifFalse:
					[byte  140
					  ifTrue: [postfixStream next "ST76"]]]]
		  ifFalse:
			[byte  SendPlus
			  ifFalse:
				[dist ← byte \ 8 - 4 * 256 + postfixStream next.
				dist  0 "byte>(JmpLong+3)"
				  ifFalse: [beginStream next← postfixStream position + 1 + dist]]]].
	beginStream ← beginStream contents sort asStream.
	postfixStream position← start].
"246" LADDecompiler$'Reverser Performs'
[longSend: lowbits | |
	prefixStream next← ((lowbits allmask: 1)
	  ifTrue: [self decodeSelector: postfixStream next \ 32]
	  ifFalse:
		[postfixStream next "nargs".
		self decodeSelector: postfixStream next])].
"514" LADDecompiler$'ST76'
[message76: selector | sel rcvr n args i |
	 "receiver selector arguments"
	sel ← selector key.
	rcvr ← ((self match: #:super)
			  ifTrue:
				[self exactly: NodeSelf.
				NodeSuper]
			  ifFalse: [self expression]).
	n ← sel numArgs.
	args ← Vector new: n.
	(n to: 1 by: 1) do: [:i | args  i ← self expression].
	↑LADMessageNode new receiver: rcvr selector: selector arguments: args precedence: (sel isinfix
	  ifTrue: [2]
	  ifFalse:
		[sel iskeyword
		  ifTrue: [3]
		  ifFalse: [1]])].
"980" LADDecompiler$'ST76'
[ST76Init | x |
	 "LADDecompiler new ST76Init."
	typeTable ← #(ldInst: ldTemp: ldLit: ldLit: ldLitInd: ldLitInd: ldLitInd: ldConst76: sundry: goto: gotoLong: sendSpecial76: sendSpecial76: send76: send76: send76: ) "16 groups of 16 byte codes each" "typeTable transform x to [x mustTake: 1]. check for performDangerously".
	baseTable ← #(0 16 32 32 64 64 64 112 128 144 160 176 176 208 208 208 ) "subtract base of group to get low bits".
	sundryTable ← #(storePop76: store: pop: endMethod: endRemote: ldThisContext: ldSuper76: ldSelf: ldInstLong76: ldTempLong76: ldLitLong76: ldLitIndLong76: sendLong76: confused: confused: confused: ) "colon marks self-explanatory codes; rest get performed" "sundryTable transform x to [x mustTake: 1]. check for performDangerously".
	constantTable ← (SpecialOops  (2 ~ 9)) copy.
	specialTable ← (SpecialOops  (10 ~ 41)) copy.
	specialTable  (19 ~ 23) ← {#length , #next , 'next←' unique , #end , #}.
	ST80 ← false].
"183" LADDecompiler$'ST76'
[sendSpecial76: which | |
	(which  18 and: [which  22])
	  ifTrue: [which ← #(19 20 18 22 21 )  (which - 17)].
	prefixStream next← self decodeSpecial: which].
"276" LADDecompiler$'Reverser Performs'
[longSuper: lowbits | |
	prefixStream next← #:super.
	prefixStream next← ((lowbits allmask: 1)
	  ifTrue: [self decodeSelector: postfixStream next \ 32]
	  ifFalse:
		[postfixStream next "nargs".
		self decodeSelector: postfixStream next])].
"104" LADDecompiler$'Reverser Performs'
[longSto: lowbits | |
	self store: lowbits.
	self longLoad: lowbits].
"296" LADDecompiler$'Decompiler'
[cascade: lastMessage | messages |
	messages ← lastMessage inVector asStream settoend.
	[self match: #:pop] whileTrueDo: [messages next← self message: (self require: LADSelectorNode)].
	↑LADCascadeNode new receiver: self expression messages: messages reverseContents].
"108" LADDecompiler$'Reverser Subroutines'
[temporaries | |
	↑(tempVars  (nArgs + 1 to: tempVars length)) copy].
"115" Class$'Message access'
[decompile: sel | |
	↑user displayoffwhile [(LADDecompiler new decompile: sel in: self)]].
"681" Class$'Message access'
[copy: sel from: class classified: cat | s code |
	 "Useful when modifying an existing class"
	(sel is: Vector)
	  ifTrue: [sel do: [:s | self copy: s from: class classified: cat]]
	  ifFalse:
		[(sel is: String)
		  ifTrue: [self copy: (class organization category: sel) from: class classified: cat]
		  ifFalse:
			[code ← class code: sel.
			code  nil
			  ifFalse:
				[cat  nil
				  ifTrue: [cat ← class organization invert: sel].
				(messagedict has: sel)
				  ifTrue:
					[code text = (self code: sel) text
					  ifFalse: [user notify: title + ' ' + sel + ' will be redefined if you proceed.']].
				self understands: code classified: cat]]]].
"232" Class$'Message access'
[understands: code classified: heading | |
	 "compile and install method"
	↑(NoteTaker
	  ifTrue: [LADCompiler]
	  ifFalse: [Generator]) new compile: code asParagraph in: self under: heading notifying: self].
"351" Class$'Filin and Filout'
[filoutOrganization | t1 |
	 "So we can merge separate work on organization"
	user show: title.
	user cr.
	user displayoffwhile [
		((t1 ← dp0 file: title + '.org.') append: title + ' organization fromParagraph:'.
		t1 cr.
		t1 append: self organization asParagraph text asString.
		t1 append: 'asParagraph'.
		t1 close)]].
"309" Class$'Editing'
[edit: selector para: para formerly: oldpara | |
	NoteTaker
	  ifTrue: [user schedule: (CodeWindow new class: self selector: selector para: para formerly: oldpara)]
	  ifFalse:
		[user leaveTop.
		user restartup: (CodeWindow new class: self selector: selector para: para formerly: oldpara)]].
"193" Class$'Instance access'
[fromFreelist: i fill: vec | |<primitive: 75>
	 "i = zero order index of freelist in class instance.
	vec = vector in pclasses of all possible instances."
	user croak].
"203" Class$'Filin and Filout'
[printCategory: s on: pstrm | sel |
	self startCategory: s on: pstrm.
	(self organization category: s) do: [:sel | self printMethod: sel on: pstrm].
	self endCategoryOn: pstrm].
"138" Class$'Filin and Filout'
[startCategory: s on: pstrm | |
	pstrm print: (('
' + s) asParagraph maskrunsunder: 241 to: 81) "Font 5, Bold"].
"264" Class$'Initialization'
[title: t subclassof: s fields: f declare: d | |
	t  1  (t  1) asUppercase
	  ifTrue:
		[user notify: 'Please capitalize each word in class title: ' + t.
		↑false].
	self title: t.
	self subclassof: s.
	self fields: f.
	self declare: d].
"142" Class$'Filin and Filout'
[printoutCategory: cat | |
	(dp0 file: (title + '-' + cat + '.press') asFileName) printout: (self changelist: cat)].
"71" Class$'Message access'
[shrink | |
	messagedict ← messagedict shrink].
"132" Class$'Filin and Filout'
[filout | |
	user displayoffwhile [
		((dp0 file: title + '.st.') filoutclass: self.
		self noChanges)]].
"109" Class$'Initialization'
[title: t1 | |
	title ← t1.
	self title: (title ← title unique) insystem: Smalltalk].
"194" Class$'Message access'
[textLocal | s |
	s ← self organization "makes comment and methods local".
	s globalComment← s globalComment.
	messagedict do: [:s | messagedict code: s ← self code: s]].
"231" Class$'As yet unclassified'
[recompile: selector | c |
	 "does not modify code, just compiles it"
	c ← messagedict code: selector.
	self understands: c asParagraph.
	messagedict code: selector ← c "leave remote paragraphs alone"].
"153" Class$'As yet unclassified'
[usesNewSyntax | |
	self  LADObject
	  ifTrue: [↑true].
	superclass  nil
	  ifTrue: [↑false].
	↑superclass usesNewSyntax].
"193" Class$'System Organization'
[category: cat | |
	(cat is: String)
	  ifTrue: [SystemOrganization add: self title unique under: cat]
	  ifFalse: [user notify: 'Category name must be a String']].
"528" Class$'Message access'
[code80: sel | |
	 "last paragraph returned is cached (mainly for NotifyWindows)" "return this paragraph xlated to st80 syntax"
	(sel  lastSelector and: [self  lastClass])
	  ifFalse:
		[lastParagraph ← (sel = #ClassOrganization
				  ifTrue: [self organization]
				  ifFalse: [ "Paragraph or RemoteParagraph"
					messagedict code: sel]) asParagraph.
		lastClass ← self.
		lastSelector ← sel].
	↑(Generator80 new make80: lastParagraph in: self under: nil notifying: nil) asParagraph makeBoldPattern].
"399" Integer$'LargeInteger Compatability'
[ n | t |
	n = 1 "behave like a Natural"
	  ifTrue:
		[self < 0
		  ifTrue: [↑((self land: 255) lxor: 255) + 1 land: 255].
		↑self land: 255]
	  ifFalse:
		[n = 2
		  ifTrue:
			[self < 0
			  ifTrue:
				[t ← (self lshift: 8) lxor: 255.
				(self land: 255) = 0
				  ifTrue: [↑t + 1 land: 255].
				↑t]
			  ifFalse: [↑self lshift: 8]]
		  ifFalse: [↑0]]].
"165" Integer$'Arithmetic'
[+ arg | t |
	(arg is: Integer)
	  ifTrue: [↑self asLarge + arg].
	t ← arg asInteger.
	t isLarge
	  ifTrue: [↑self asLarge + arg].
	↑self + t].
"99" Integer$'Arithmetic'
[> arg | t |
	t ← arg asInteger.
	t isLarge
	  ifTrue: [↑t neg].
	↑self > t].
"118" Integer$'Arithmetic'
[< arg | t |
	t ← arg asInteger.
	t isLarge
	  ifTrue: [t neg  false]
	  ifFalse: [↑self < t]].
"165" Integer$'Arithmetic'
[- arg | t |
	(arg is: Integer)
	  ifTrue: [↑self asLarge - arg].
	t ← arg asInteger.
	t isLarge
	  ifTrue: [↑self asLarge - arg].
	↑self - t].
"84" Integer$'As yet unclassified'
[maxVal | |
	NoteTaker
	  ifTrue: [↑16383].
	↑32767].
"151" Integer$'Arithmetic'
[= arg | t |
	arg isNumber
	  ifTrue:
		[t ← arg asInteger.
		t isLarge
		  ifTrue: [↑false].
		↑self = t]
	  ifFalse: [↑false]].
"107" Integer$'Arithmetic'
[ arg | t |
	t ← arg asInteger.
	t isLarge
	  ifTrue: [↑t neg  false].
	↑self  t].
"86" Integer$'As yet unclassified'
[minVal | |
	NoteTaker
	  ifTrue: [↑16384].
	↑32768].
"99" Integer$'Arithmetic'
[ arg | t |
	t ← arg asInteger.
	t isLarge
	  ifTrue: [↑t neg].
	↑self  t].
"149" Integer$'Arithmetic'
[ arg | t |
	arg isNumber
	  ifTrue:
		[t ← arg asInteger.
		t isLarge
		  ifTrue: [↑true].
		↑self  t]
	  ifFalse: [↑true]].
"285" Integer$'Printing'
[printon: strm | |
	self < 0
	  ifTrue:
		[self = self minVal
		  ifTrue: [strm append: (NoteTaker
			  ifTrue: ['16384']
			  ifFalse: ['32768'])]
		  ifFalse:
			[strm append: ''.
			0 - self printon: strm base: 10]]
	  ifFalse: [self printon: strm base: 10]].
"168" Integer$'Bit Manipulation'
[lshift: arg | |<primitive: 13>
	(NoteTaker and: [arg class  Integer])
	  ifTrue: [↑self asLarge lshift: arg].
	↑self lshift: arg asSmall].
"179" Integer$'Arithmetic'
[* arg | t |<primitive: 9>
	(arg is: Integer)
	  ifTrue: [↑self asLarge * arg].
	t ← arg asInteger.
	t isLarge
	  ifTrue: [↑self asLarge * arg].
	↑self * t].
"196" Integer$'Arithmetic'
[/ arg | |<primitive: 10>
	0 = arg
	  ifTrue: [user notify: 'Attempt to divide by 0']
	  ifFalse:
		[arg isLarge
		  ifTrue: [↑self asLarge / arg].
		↑self / arg asInteger]].
"66" Integer$'Arithmetic'
[| arg | |
	 "truncate"
	↑self / arg * arg].
"204" Integer$'Arithmetic'
[\ arg | |<primitive: 11>
	 "mod"
	0 = arg
	  ifTrue: [user notify: 'Attempt to divide by 0']
	  ifFalse:
		[arg isLarge
		  ifTrue: [↑self asLarge \ arg].
		↑self \ arg asInteger]].
"90" Integer$'As yet unclassified'
[between: min and: max | |
	↑self  min and: [self  max]].
"270" Integer$'Compiler Bytecodes'
[emitBfp: code on: stack | |
	stack pop: 1.
	0 = self
	  ifTrue: [code next← toPop]
	  ifFalse:
		[(1  self and: [self  8])
		  ifTrue: [code next← self + toShortBfp - 1]
		  ifFalse: [ "short bfp"
			code emitLong: toLongBfp by: self]]].
"225" Integer$'Compiler Bytecodes'
[emitJmp: code on: stack | |
	0 = self
	  ifFalse:
		[(1  self and: [self  8])
		  ifTrue: [code next← self + toShortJmp - 1]
		  ifFalse: [ "short jmp"
			code emitLong: toLongJmp by: self]]].
"94" Integer$'Bit Manipulation'
[hash | |
	 "used to find large integers in dictionaries"
	↑self].
"472" Integer$'Printing'
[printon: strm base: b | i j x |
	(x ← self) < 0
	  ifTrue:
		[i ← 1.
		digitbuffer  1 ← 16384 \ b * 2 + self - 32768 \ b "Im trying to print 16-bit nos.".
		x ← 16384 / b * 2 + (self - 32768 / b)]
	  ifFalse: [i ← 0].
	[x  b] whileTrueDo:
		[digitbuffer  (i ← i + 1) ← x \ b.
		x ← x / b].
	digitbuffer  (i ← i + 1) ← x.
	(1 to: i) do:
		[:j | x ← digitbuffer  i.
		strm next← (x < 10
		  ifTrue: [48 + x]
		  ifFalse: [55 + x]).
		i ← i - 1]].
"108" Integer$'Characters'
[isalphanumeric | |
	self isletter
	  ifTrue: [↑true].
	 "lower-case"
	↑self isdigit].
"49" Integer$'Copying and Purging'
[copy | |
	↑self].
"128" Integer$'Subscripts'
[instfield: i | |
	 "small integer gives trouble"
	i = 1
	  ifTrue: [↑self].
	user notify: 'arg too big'].
"137" Integer$'Printing'
[absprinton: strm | rem |
	rem ← self \ 10.
	self > 9
	  ifTrue: [self / 10 absprinton: strm].
	strm next← rem + 48].
"101" Integer$'Characters'
[asLowercase | |
	65  self
	  ifTrue:
		[self  90
		  ifTrue: [↑self + 32]]].
"291" Integer$'Characters'
[compareChar: c | a |
	a ← self "self asLowercase compare: c asLowercase" "written in-line for speed".
	65  a
	  ifTrue:
		[a  90
		  ifTrue: [a ← a + 32]].
	65  c
	  ifTrue:
		[c  90
		  ifTrue: [c ← c + 32]].
	a < c
	  ifTrue: [↑1].
	a = c
	  ifTrue: [↑2].
	↑3].
"121" Integer$'Conversion'
[oneToMeAsStream | |
	 "used by for-loops"
	↑Stream new of: (Interval new from: 1 to: self by: 1)].
"63" Integer$'Conversion'
[asFloat | |<primitive: 62>
	user croak].
"248" Integer$'Conversion'
[asLarge | me digits |
	 "convert to LargeInteger"
	me ← self bytes.
	digits ← Natural new: me length.
	digits  1 ← me  1.
	digits length = 2
	  ifTrue: [digits  2 ← me  2].
	↑LargeInteger new bytes: digits neg: self neg].
"78" Integer$'Subscripts'
[cansubscript: a | |
	↑self  1 and: [self  a length]].
"307" Integer$'Compiler Bytecodes'
[emitBytes: code | c t |
	self < 256
	  ifTrue: [code next← self]
	  ifFalse:
		[c ← self lshift: 8.
		t ← self land: 255.
		#(16 16 32 48 48 )  c > t
		  ifTrue: [code next← #(0 16 32 64 208 )  c + t]
		  ifFalse:
			[code next← toLoadFieldLong + c - 1.
			code next← t]]].
"51" Integer$'Copying and Purging'
[recopy | |
	↑self].
"54" Integer$'Arithmetic'
[even | |
	↑(self land: 1) = 0].
"74" Integer$'Bit Manipulation'
[lor: arg | |<primitive: 16>
	↑arg lor: self].
"148" Integer$'Subscripts'
[subscripts: a | |
	(self cansubscript: a)
	  ifTrue: [↑a  self].
	user notify: 'Subscript out of bounds: ' + self asString].
"350" Integer$'Subscripts'
[subscripts: a ← val | t |
	(self cansubscript: a)
	  ifTrue:
		[t ← val asInteger.
		((a Is: String) and: [((t isnt: Integer) or: [(t between: 0 and: [255])  false])])
		  ifTrue: [user notify: 'Improper store into String']
		  ifFalse: [↑a  self ← t]]
	  ifFalse: [user notify: 'Subscript out of bounds: ' + self asString]].
"97" Integer$'Arithmetic'
[sameAs: arg | |
	 "arg assumed to be of same class as self"
	↑self = arg].
"217" Integer$'Arithmetic'
[compare: arg | |
	(arg is: Integer)
	  ifTrue:
		[self < arg
		  ifTrue: [↑1].
		self = arg
		  ifTrue: [↑2].
		↑3]
	  ifFalse: [↑self natcompare: arg bytes "4 - (arg bytes natcompare: self)"]].
"94" Integer$'Compiler Bytecodes'
[isField | |
	↑self  codeLoadField and: [self < codeLoadTemp]].
"70" Integer$'LargeInteger Compatability'
[last | |
	↑self  self length].
"128" Integer$'LargeInteger Compatability'
[length | |
	(self  256 "behave like a Natural" or: [self  256])
	  ifTrue: [↑2].
	↑1].
"175" Integer$'Bit Manipulation'
[field: spec | right |
	 "spec=width*16 + right (15=left, 0=right)"
	right ← 15 - (spec land: 15).
	↑self bits: right - (spec / 16) + 1 to: right].
"115" Integer$'LargeInteger Compatability'
[neg | |
	self < 0 "behave like a LargeInteger"
	  ifTrue: [↑true].
	↑false].
"558" Integer$'Compiler Bytecodes'
[asCompilerCode | |
	 "I am a byte code.  Return the corresponding compiler code"
	self < 16
	  ifTrue: [↑self + codeLoadField "inst field"].
	self < 32
	  ifTrue: [↑self - 16 + codeLoadTemp "temp"].
	self < 64
	  ifTrue: [↑self - 32 + codeLoadLit "literal"].
	self < 111
	  ifTrue: [↑self - 64 + codeLoadLitInd "indirect literal"].
	self < 208
	  ifTrue: [↑self].
	 "context relative or constant ... not all values here are legal"
	self < 256
	  ifTrue: [↑self - 208 + codeSendLit "selector"].
	user notify: 'unexpected byte'].
"46" Integer$'Arithmetic'
[negate | |
	↑0 - self].
"189" Integer$'Bit Manipulation'
[field: spec ← val | right |
	 "spec=width*16 + right (15=left, 0=right)"
	right ← 15 - (spec land: 15).
	↑self bits: (right - (spec / 16) + 1) to: right ← val].
"96" Integer$'Conversion'
[asObject | |<primitive: 40>
	user notify: 'This object does not exist!'].
"78" Integer$'Conversion'
[inString | t |
	t ← String new: 1.
	t  1 ← self.
	↑t].
"176" Integer$'Characters'
[tokenish | |
	 "test for token-chars"
	self isletter
	  ifTrue: [↑true].
	 "lower-case"
	self isdigit
	  ifTrue: [↑true].
	 "digits"
	↑'.:' has: self].
"152" Integer$'Characters'
[isletter | |
	self  97
	  ifTrue: [ " a "
		↑self  122].
	 " z "
	self  65
	  ifTrue: [ " A "
		↑self  90].
	 " Z "
	↑false].
"76" Integer$'Bit Manipulation'
[land: arg | |<primitive: 15>
	↑arg land: self].
"69" Integer$'Copying and Purging'
[purge | |<primitive: 0>
	user croak].
"97" Integer$'Characters'
[isdigit | |
	self  48
	  ifTrue: [ " 0 "
		↑self  57].
	 " 9 "
	↑false].
"100" Integer$'Conversion'
[unsigned | |
	self < 0
	  ifTrue: [↑65536.0 + self asFloat].
	↑self asFloat].
"66" Integer$'Bit Manipulation'
[allmask: b | |
	↑b = (self land: b)].
"66" Integer$'Bit Manipulation'
[anymask: b | |
	↑0  (self land: b)].
"38" Integer$'Conversion'
[asSmall | |
	].
"128" Integer$'Bit Manipulation'
[hibit | i |
	(1 to: 16) do:
		[:i | (self land: biton  (17 - i))  0
		  ifTrue: [↑17 - i]].
	↑0].
"45" Integer$'Conversion'
[asInteger | |
	↑self].
"76" Integer$'Bit Manipulation'
[lxor: arg | |<primitive: 14>
	↑arg lxor: self].
"173" Integer$'Compiler Bytecodes'
[jmpSize | |
	↑self = 0
	  ifTrue: [0]
	  ifFalse:
		[self < 0
		  ifTrue: [2]
		  ifFalse:
			[self > 8
			  ifTrue: [2]
			  ifFalse: [1]]]].
"128" Integer$'Compiler Bytecodes'
[bfpSize | |
	↑self < 0
	  ifTrue: [2]
	  ifFalse:
		[self > 8
		  ifTrue: [2]
		  ifFalse: [1]]].
"104" Integer$'Initialization'
[classInit | |
	 "Initialize the digit buffer"
	digitbuffer ← String new: 16].
"65" Integer$'Bit Manipulation'
[nomask: b | |
	↑0 = (self land: b)].
"75" Integer$'As yet unclassified'
[asInt32 | |
	↑Int32 new high: 0 low: self].
"102" Integer$'Characters'
[asUppercase | |
	97  self
	  ifTrue:
		[self  122
		  ifTrue: [↑self - 32]]].
"47" Integer$'Arithmetic'
[negated | |
	↑0 - self].
"139" Integer$'Conversion'
[asNatural | t |
	t ← Natural new: self length.
	t  1 ← self  1.
	t length > 1
	  ifTrue: [t  2 ← self  2].
	↑t].
"136" Integer$'LargeInteger Compatability'
[bytes | |
	↑self "behave like a LargeInteger - negative integers behave like positive naturals"].
"110" Integer$'Arithmetic'
[unsignedadd: y | |
	↑self + y "treat numbers as unsigned 8-bit quantities." land: 255].
"105" Integer$'Arithmetic'
[unsignedlessthan: y | |
	↑self < y "treat numbers as unsigned 8-bit quantities."].
"1406" Integer$'Compiler Bytecodes'
[printon: strm indent: level precedence: p forValue: v decompiler: decompiler | lit |
	v  false
	  ifFalse:
		[self < 112
		  ifTrue: [user notify: 'unknown code']
		  ifFalse:
			[self < 128
			  ifTrue: [strm append: #('sender' 'self' '?' '?' '?' '?' '?' '?' '1' '0' '1' '2' '10' 'nil' 'false' 'true' )  (self - 111)]
			  ifFalse:
				[self = 133
				  ifTrue: [strm append: 'thisContext']
				  ifFalse:
					[self = 134
					  ifTrue: [strm append: 'super']
					  ifFalse:
						[self < 167
						  ifTrue: [user notify: 'unknown code']
						  ifFalse:
							[self < 208
							  ifTrue: [strm append: SpecialOops  (self - 166)]
							  ifFalse:
								[self < 256
								  ifTrue: [user notify: 'unknown code']
								  ifFalse:
									[self < 512
									  ifTrue: [strm append: (decompiler instvar: self)]
									  ifFalse:
										[self < 768
										  ifTrue: [strm append: (decompiler temp: self)]
										  ifFalse:
											[self < 1024
											  ifTrue:
												[lit ← decompiler literalDirect: self.
												((lit is: UniqueString) or: [(lit is: Vector)])
												  ifTrue: [strm append: '#'].
												lit printon: strm]
											  ifFalse:
												[self < 1280
												  ifTrue: [strm append: (decompiler literalIndirect: self)]
												  ifFalse: [strm append: (decompiler selector: self)]]]]]]]]]]]]].
"47" Integer$'As yet unclassified'
[asInt16 | |
	].
"310" Integer$'As yet unclassified'
[bits: left to: right | width mask |
	 "  0 is leftmost bit, 15 is rightmost"
	width ← right - left + 1.
	mask ← (width < 15
			  ifTrue: [biton  (width + 1) - 1]
			  ifFalse:
				[width = 15
				  ifTrue: [32767]
				  ifFalse: [1]]).
	↑(self lshift: right - 15) land: mask].
"279" Integer$'LargeInteger Compatability'
[natcompare: arg | i len t4 t5 |
	len ← self length.
	(t4 ← arg length) < len
	  ifTrue: [↑3].
	t4 > len
	  ifTrue: [↑1].
	(len to: 1 by: 1) do:
		[:i | (t5 ← self  i) > (arg  i)
		  ifTrue: [↑3].
		t5 < (arg  i)
		  ifTrue: [↑1]].
	↑2].
"380" Integer$'LargeInteger Compatability'
[natnormalize: n | x i r f digit |
	r ← Natural new: self length "n is the number of bits to shift by. The Natural number returned will be written over repeatedly, so we must make a new one." + 1.
	x ← 0.
	f ← n - 8.
	(1 to: r length) do:
		[:i | digit ← self  i.
		r  i ← ((digit lshift: n) lor: x) land: 255.
		x ← digit lshift: f].
	↑r].
"58" Integer$'As yet unclassified'
[hex4 | |
	↑self base: 16].
"212" Integer$'As yet unclassified'
[asOop | |
	NoteTaker
	  ifTrue:
		[self  0
		  ifTrue: [↑32768 + self].
		 "0...16K-1 --> 32K...48K-1"
		↑65536 + self]
	  ifFalse: [ "-16K...-1 --> 48K...64K-1"
		↑super asOop]].
"392" Integer$'Initialization'
[fromString: str radix: radix | maxdigit c val i |
	maxdigit ← radix + (radix > 10
			  ifTrue: [55 - 1]
			  ifFalse: [48 - 1]).
	val ← 0.
	(1 to: str length) do:
		[:i | c ← str  i.
		(c < 48 or: [c > maxdigit])
		  ifTrue: [↑false].
		val ← val * radix + (c  57
				  ifTrue: [c - 48]
				  ifFalse:
					[c < 65
					  ifTrue: [↑false].
					c - 55])].
	↑val].
"192" Integer$'Arithmetic'
[intdiv: arg | |
	(arg is: Integer)
	  ifTrue: [↑{self / arg , (self \ arg)}].
	(arg is: LargeInteger)
	  ifTrue: [↑self asLarge intdiv: arg].
	user notify: 'I give up'].
"52" Integer$'LargeInteger Compatability'
[isInt | |
	].
"153" Integer$'As yet unclassified'
[asRemoteCode: generator | |
	↑super asRemoteCode: generator "Defeat generation of FieldReferences for remote variables"].
"112" Integer$'Compiler Bytecodes'
[emitsLoad | |
	self < 256
	  ifTrue: [↑self < toSmashPop].
	↑self < codeSendLit].
"148" Integer$'Compiler Bytecodes'
[emittedVariable | |
	(self < 256
	  ifTrue: [self  toSuper]
	  ifFalse: [self < codeSendLit])
	  ifFalse: [↑false]].
"53" Integer$'Arithmetic'
[odd | |
	↑(self land: 1) = 1].
"372" Integer$'As yet unclassified'
[bits: left to: right ← val | width mask |
	 "  0 is leftmost bit, 15 is rightmost"
	width ← right - left + 1.
	mask ← (width < 15
			  ifTrue: [biton  (width + 1) - 1]
			  ifFalse:
				[width = 15
				  ifTrue: [32767]
				  ifFalse: [1]]).
	↑(self land: ((mask lshift: 15 - right) lxor: 1)) lor: ((val land: mask) lshift: 15 - right)].
"87" Integer$'As yet unclassified'
[elementStream | |
	↑Stream new of: (Vector new: self)].
"120" Integer$'As yet unclassified'
[inUniqueString | |
	self < 128
	  ifTrue: [↑UST1  (self + 1)].
	↑self inString unique].
"723" Integer$'Compiler Bytecodes'
[findMacros: macros compilerTemps: compilerTemps | i j assignment |
	(self < codeLoadTemp or: [self > (codeLoadTemp + 255)])
	  ifFalse:
		[ "this temp is not compiler-generated"
		j ← self - codeLoadTemp + 1.
		compilerTemps  j  false
		  ifFalse:
			[compilerTemps  j  nil
			  ifTrue: [compilerTemps  j ← false]
			  ifFalse:
				[ "The temp isn't compiler-generated after all!!  Nil out the macro"
				(macros position to: 2 by: 2) do:
					[:i | assignment ← macros  (i - 1)  (macros  i).
					assignment var = self
					  ifTrue:
						[macros  i ← nil.
						macros  (i - 1) ← nil.
						compilerTemps  j ← false.
						↑nil]].
				user notify: 'couldnt find bad macro']]]].
"148" Integer$'Compiler Bytecodes'
[sizeForValue | |
	(self < 256 or: [#(16 16 32 48 48 )  (self lshift: 8) > (self land: 127)])
	  ifTrue: [↑1].
	↑2].
"167" Integer$'Compiler Bytecodes'
[emitForValue: code on: stack | |
	self = toSuper
	  ifTrue: [code next← toLoadSelf]
	  ifFalse: [self emitBytes: code].
	stack push: 1].
"48" Integer$'Compiler Bytecodes'
[firstPush | |
	].
"614" String$'Comparison'
[systemRehash | dicts d left loop |
	String understands: 'hash | l m
	[[(l← m← self length)2
		[l=2←3]; =1[((self1) land: 0177)*0152] 052525]].
	 (self1)*060+(self(m-1)+l)]' "change the meaning of hash for Strings" "rehash the atom table".
	#a rehash "rehash all dictionaries which have strings in them".
	dicts ← HashSet allInstances + Dictionary allInstances + SymbolTable allInstances.
	dicts do:
		[:d | left ← d objects asStream.
		loop ← left next.
		[loop] whileTrueDo:
			[(loop is: String)
			  ifTrue:
				[d rehash.
				loop ← false]
			  ifFalse: [loop ← left next]]]].
"201" String$'Copying and Altering'
[replace: a to: b by: s | |
	(s Is: String)
	  ifTrue: [↑self replace: a to: b by: s from: 1 to: s length].
	↑self replace: a to: b by: s asArray from: 1 to: s position].
"156" String$'Comparison'
[> s | |
	↑(self compare: s) "Return true iff I collate after s.  The collation sequence is ascii with case differences ignored." = 3].
"157" String$'Comparison'
[< s | |
	↑(self compare: s) "Return true iff I collate before s.  The collation sequence is ascii with case differences ignored." = 1].
"379" String$'Comparison'
[- s | i c ldiff |
	(1 to:  "Return a negative, zero, or positive integer as I compare < = or > s" "The collation sequence is ascii with case differences ignored."
	((ldiff ← self length - s length) < 0
	  ifTrue: [self length]
	  ifFalse: [s length])) do:
		[:i | (c ← UpperCase  (self  i + 1) - (UpperCase  (s  i + 1)))  0
		  ifTrue: [↑c]].
	↑ldiff].
"79" String$'Conversion'
[asParagraph | |
	↑Paragraph new text: self alignment: 0].
"123" String$'Conversion'
[asUppercase | s c |
	s ← Stream default.
	self do: [:c | s next← UpperCase  (c + 1)].
	↑s contents].
"418" String$'Conversion'
[asDecimalDigits | strm sign c val |
	 "Not asInteger, because the result may be a Float if it's too big"
	strm ← Stream new of: self.
	sign ← strm  21.
	val ← (self length > 4
			  ifTrue: [0.0]
			  ifFalse: [0]).
	strm do:
		[:c | (c < 48 or: [c > 57])
		  ifTrue: [user notify: self + ' isn''t a valid integer']
		  ifFalse: [val ← val * 10 + (c - 48)]].
	sign
	  ifTrue: [↑val * 1].
	↑val].
"65" String$'Conversion'
[hasBeenUniqued | |
	↑#a hasInterned: self].
"205" String$'Conversion'
[printon: strm | x |
	 "print inside string quotes"
	strm next← 39.
	self do:
		[:x | strm next← x.
		x = 39
		  ifTrue: [strm next← x]].
	strm next← 39 "imbedded quotes get doubled"].
"61" String$'Conversion'
[asVector | |
	↑self asStream asVector].
"130" String$'Copying and Altering'
[copy: a to: b | |
	↑(self species new: 1 + b - a) copy: 1 to: 1 + b - a with: self from: a to: b].
"253" String$'Copying and Altering'
[concat: s | len |
	((len ← self length) + s length > 20 and: [(s Is: String)])
	  ifTrue: [↑self replace: len + 1 "this concatenates more quickly if BitBlt is used" to: len by: s from: 1 to: s length].
	↑super concat: s].
"102" String$'As yet unclassified'
[asCompiledMethod | |
	↑self copyto: (CompiledMethod new: self length)].
"95" String$'Reading and Writing'
[length | |
	↑self length "In case this is reached by perform:"].
"222" String$'Comparison'
[hash | l m |
	(l ← m ← self length)  2
	  ifTrue:
		[l = 2
		  ifTrue: [m ← 3]
		  ifFalse:
			[l = 1
			  ifTrue: [↑(self  1 land: 127) * 106].
			↑21845]].
	↑self  1 * 48 + (self  (m - 1) + l)].
"56" String$'System primitives'
[lock | |<primitive: 75>
	].
"270" String$'Copying and Altering'
[findString: str startingAt: start | i t |
	str length = 0
	  ifTrue: [↑0].
	t ← str  1.
	(start to: self length - str length + 1) do:
		[:i | self  i = t
		  ifTrue:
			[self  (i to: i + str length - 1) = str
			  ifTrue: [↑i]]].
	↑0].
"346" String$'Conversion'
[asLarge | neg i large large10 |
	 "convert to a LargeInteger"
	self  1 = 21
	  ifTrue: [neg ← true]
	  ifFalse: [neg ← false].
	large ← 0 asLarge.
	large10 ← 10 asLarge.
	((neg
	  ifTrue: [2]
	  ifFalse: [1]) to: self length) do: [:i | large ← large * large10 + (self  i - 48)].
	neg
	  ifTrue: [↑large negated].
	↑large].
"47" String$'Compatibility'
[species | |
	↑String].
"118" String$'Reading and Writing'
[word: x | |
	 "read word in String"
	↑self  (x + x) + (self  (x + x - 1) lshift: 8)].
"122" String$'Conversion'
[asBytes | s c |
	s ← Stream default.
	self do:
		[:c | s append: c base8.
		s space].
	↑s contents].
"328" String$'Conversion'
[asFloat | strm int frac exp |
	strm ← Stream new of: self.
	int ← strm upto: 46.
	frac ← strm upto: 101.
	exp ← strm rest asInteger - frac length.
	int ← (int concat: frac) asDecimalDigits asFloat.
	exp = 0
	  ifTrue: [↑int].
	exp > 0
	  ifTrue: [↑int * (10.0 ipow: exp)].
	.
	↑int / (10.0 ipow: 0 - exp)].
"58" String$'System primitives'
[unlock | |<primitive: 75>
	].
"94" String$'Conversion'
[base8: i | |
	 "word: i  in base 8 as a String"
	↑(self word: i) base8].
"56" String$'Copying and Altering'
[recopy | |
	↑self copy].
"74" String$'Conversion'
[unique | u |
	 "copy and intern"
	↑#a intern: self].
"144" String$'Reading and Writing'
[word: x ← y | |
	 "write word in String"
	self  (x + x - 1) ← y lshift: 8.
	self  (x + x) ← y land: 255.
	↑y].
"792" String$'Comparison'
[match: text | star pound pattern scanning p t back |
	star ← 42 "*".
	pound ← 35 "#".
	pattern ← self asStream.
	text ← text asStream.
	scanning ← false.
	[true] whileTrueDo:
		[(p ← pattern next) = star
		  ifTrue:
			[pattern end
			  ifTrue: [↑true].
			scanning ← pattern position]
		  ifFalse:
			[(t ← text next)  false
			  ifTrue: [↑t  p].
			p  false
			  ifTrue:
				[scanning
				  ifTrue:
					[back ← scanning - pattern position.
					pattern skip: back.
					text skip: back]
				  ifFalse: [↑false]]
			  ifFalse:
				[(UpperCase  (t + 1) = (UpperCase  (p + 1)) or: [p = pound])
				  ifFalse:
					[scanning
					  ifTrue:
						[back ← scanning - pattern position.
						pattern skip: back.
						text skip: back + 1]
					  ifFalse: [↑false]]]]]].
"372" String$'Comparison'
[compare: s | i len lcomp u1 u2 t7 |
	lcomp ← ((t7 ← self length) < (len ← s length)
			  ifTrue:
				[len ← self length.
				1]
			  ifFalse:
				[t7 = len
				  ifTrue: [2]
				  ifFalse: [3]]).
	(1 to: len) do:
		[:i | (u1 ← UpperCase  (self  i + 1)) = (u2 ← UpperCase  (s  i + 1))
		  ifFalse:
			[u1 < u2
			  ifTrue: [↑1].
			↑3]].
	↑lcomp].
"166" String$'Copying and Altering'
[growto: n | len |
	(len ← self length)  n
	  ifFalse: [len ← n].
	↑(self species new: n) copy: 1 to: len with: self from: 1 to: len].
"127" String$'Reading and Writing'
[fill: a to: b with: val | i |
	(a to: b) do: [:i |  "eventually use BitBlt?"
		self  i ← val]].
"85" String$'Reading and Writing'
[all← val | |
	self fill: 1 to: self length with: val].
"459" String$'Copying and Altering'
[replace: a to: b by: r from: c to: d | s t |
	s ← self species new: self length + (d - c) - (b - a) "use BitBlt unless StringBlterfalse or index/sizes too large".
	(StringBlter and: [(BitBlt new stringReplace: s with: self from: a to: b and: [r] from: c to: d)])
	  ifTrue: [↑s].
	 "see Array concat:"
	t ← Stream new of: s.
	self copy: 1 to: a - 1 to: t.
	r copy: c to: d to: t.
	self copy: b + 1 to: self length to: t.
	↑s].
"659" String$'Copying and Altering'
[copy: a to: b with: s from: c to: d | i |
	((b - a "like replace, except in place. self(a to: b) ← s(c to: d).
	use BitBlt unless size too small, StringBlterfalse, or index/sizes too large" > 12 and: [StringBlter]) and: [(BitBlt new stringCopy: self from: a to: b with: s from: c to: d)])
	  ifFalse:
		[(self  s and: [(c < a and: [d  a])])
		  ifTrue: [(b - a "overlap of second range with below first in same string.
		copy in reverse order: self(b to: a by: 1) ← self(d to: c by: 1)" to: 0 by: 1) do: [:i | self  (a + i) ← self  (c + i)]]
		  ifFalse: [s copy: c to: d to: (Stream new of: self from: a to: b)]]].
"424" String$'As yet unclassified'
[inBase: b | neg i j large large10 |
	 "convert to a LargeInteger"
	self  1 = 21
	  ifTrue: [neg ← true]
	  ifFalse: [neg ← false].
	large ← 0 asLarge.
	large10 ← b asLarge.
	((neg
	  ifTrue: [2]
	  ifFalse: [1]) to: self length) do: [:i | large ← large * large10 + ((j ← self  i)  65 "A"
				  ifTrue: [j - 65 + 10]
				  ifFalse: [j - 48 "0"])].
	neg
	  ifTrue: [↑large negated].
	↑large].
"69" String$'As yet unclassified'
[alignForDisplay | |<primitive: 84>
	].
"84" String$'As yet unclassified'
[run: rcvr in: mclass | |<primitive: 75>
	user croak].
"409" String$'As yet unclassified'
[setSourcePosition: pos inFile: f | loc p1 |
	 "set last three bytes to be pos in file (0-3)"
	f > 3
	  ifTrue: [user notify: 'invalid file number']
	  ifFalse:
		[loc ← self length - 2.
		self  (loc + 2) ← f * 64 + (p1 ← pos / 65536).
		pos ← pos - (p1 * 65536) "into two bytes".
		self  (loc + 1) ← p1 ← pos / 256.
		pos ← pos land: 255 "into one byte".
		self  loc ← pos]].
"93" String$'Conversion'
[asBitmap | t |
	t ← Bitmap new: self length / 2.
	↑t fromString: self].
"59" String$'As yet unclassified'
[stringhash | |
	↑self hash].
"528" String$'Copying and Altering'
[subst: repl for: key | key1 i nskip result |
	nskip ← 0.
	key1 ← key  1.
	result ← Stream default.
	(1 to: self length) do:
		[:i |  " the Boyer Slow string replacement "
		nskip > 0
		  ifTrue: [nskip ← nskip - 1]
		  ifFalse:
			[self  i = key1
			  ifTrue:
				[self  (i to: (self length min: i + key length - 1)) = key
				  ifTrue:
					[result append: repl.
					nskip ← key length - 1]
				  ifFalse: [result next← self  i]]
			  ifFalse: [result next← self  i]]].
	↑result contents].
"999" String$'Conversion'
[asInteger | sign base maxdigit c val i i1 i2 |
	self length = 0
	  ifTrue: [↑0].
	i1 ← 1.
	i2 ← self length.
	sign ← (self  1 = 21
			  ifTrue:
				[i1 ← 2.
				1]
			  ifFalse: [1]).
	base ← (self  self length = 72
			  ifTrue:
				[i2 ← i2 - 1.
				16]
			  ifFalse:
				[self  i1 = 48
				  ifTrue: [8]
				  ifFalse: [10]]).
	maxdigit ← (base = 16
			  ifTrue: [70]
			  ifFalse: [47 + base]).
	val ← (self length > 4
			  ifTrue: [0.0]
			  ifFalse: [0]).
	(i1 to: i2) "octal and hex packed into 16-bit Integers" do:
		[:i | c ← self  i.
		(c < 48 or: [c > maxdigit])
		  ifTrue: [user notify: self + ' isn''t a valid Integer']
		  ifFalse: [val ← val * base + (c  57
					  ifTrue: [c - 48]
					  ifFalse: [c - 55])]].
	val > 32767
	  ifTrue:
		[(base = 8 or: [base = 16])
		  ifTrue:
			[sign = 1
			  ifTrue:
				[val < 65536
				  ifTrue: [↑(val - 65536) asInteger].
				user notify: 'Warning: Octal or Hex number exceeds 16 bits']]].
	↑(val * sign) asInteger].
"73" String$'Conversion'
[asFileName | |
	↑dp0 checkName: self fixing: true].
"115" Vector$'Copying and Altering'
[, x | v |
	v ← self growby: 1 "use a stream if youre in a hurry".
	v last← x.
	↑v].
"193" Vector$'Searching'
[max | biggest i |
	biggest ← self  1 "return largest value in a vector".
	(1 to: self length) do:
		[:i | self  i > biggest
		  ifTrue: [biggest ← self  i]].
	↑biggest].
"150" Vector$'Conversion'
[printon: strm | i |
	strm append: '('.
	(1 to: self length) do:
		[:i | strm print: self  i.
		strm space].
	strm append: ')'].
"38" Vector$'Conversion'
[asVector | |
	].
"78" Vector$'Compiler argument list'
[argsOff: stack | |
	stack pop: self length].
"111" Vector$'System primitives'
[nail | |<primitive: 75>
	user croak "Nail me in core and return my core address"].
"96" Vector$'Compiler argument list'
[remote: generator | x |
	self do: [:x | x remote: generator]].
"136" Vector$'As yet unclassified'
[hex | s y |
	s ← (String new: 4 * self length) asStream.
	self do: [:y | s append: y hex].
	↑s contents].
"118" Vector$'Reading and Writing'
[length | |
	 "This is actually done in microcode"
	↑self length "perform: needs this"].
"99" Vector$'System primitives'
[unNail | |<primitive: 75>
	user croak "Release me from being nailed"].
"124" Vector$'Compiler argument list'
[sizeForValue | size x |
	size ← 0.
	self do: [:x | size ← size + x sizeForValue].
	↑size].
"118" Vector$'Compiler argument list'
[emitForValue: code on: stack | x |
	self do: [:x | x emitForValue: code on: stack]].
"72" Vector$'Compiler argument list'
[firstPush | |
	↑(self  1) firstPush].
"212" Vector$'As yet unclassified'
[base: b | strm i |
	 "convert vector of numbers to a base"
	strm ← Stream default.
	(1 to: self length) do:
		[:i | strm append: (self  i base: b).
		strm space].
	↑strm contents].
"71" Stream$'Static reading and writing'
[ x ← val | |
	↑array  x ← val].
"516" Stream$'Sequential reading and writing'
[nextNumber: n ← v | vlen |
	v ← v bytes "write a positive Integer or LargeInteger as n characters".
	vlen ← v length.
	n < vlen
	  ifTrue: [user notify: 'number too big']
	  ifFalse:
		[n > vlen
		  ifTrue: [self next: (n - vlen) "pad beginning with 0's" ← 0]].
	vlen = 1
	  ifTrue: [self next← v]
	  ifFalse:
		[(vlen = 2 and: [(v is: Integer)])
		  ifTrue: [self nextword← v]
		  ifFalse: [ "LargeInteger (assume pos, no negative convention)"
			self append: v reverse]]].
"53" Stream$'Character printing'
[cr | |
	self next← 13].
"59" Stream$'Static reading and writing'
[ x | |
	↑array  x].
"663" Stream$'Sequential reading and writing'
[nextNumber: n | i s t |
	s ← false "return next n characters s as a positive Integer or LargeInteger" "scan for first non-zero byte, then collect rest appropriately".
	(1 to: n) do:
		[:i | t ← self next.
		s
		  ifTrue: [s  (n + 1 "more LargeInteger: reverse order of significance" - i) ← t]
		  ifFalse:
			[i = n
			  ifTrue: [↑t].
			t = 0
			  ifFalse:
				[(i  (n - 2) or: [(t land: 128) "i=n-1"  0])
				  ifTrue:
					[s ← Natural new: n + 1 "LargeInteger of 2 or more bytes" - i.
					s last← t]
				  ifFalse: [ "positive Integer"
					↑(t lshift: 8) + self next]]]].
	↑LargeInteger new bytes: s neg: false].
"78" Stream$'Test and alter position'
[wordposition← w | |
	self position← w * 2].
"244" Stream$'Sequential reading and writing'
[nextString | len |
	↑self into: (String new: ((len ← self next) < 192
	  ifTrue: [len]
	  ifFalse: [ "up to 191 chars (BCPL compat)"
		len - 192 * 256 + self next])) endError: true "up to 16383 chars"].
"53" Stream$'Character printing'
[tab | |
	self next← 9].
"206" Stream$'Sequential reading and writing'
[nextString← s | len |
	(len ← s length) < 192
	  ifTrue: [self next← len]
	  ifFalse:
		[self next← len / 256 + 192.
		self next← len \ 256].
	self append: s.
	↑s].
"68" Stream$'Test and alter position'
[position← t1 | |
	position ← t1].
"214" Stream$'Initialization'
[of: t1 from: pos to: lim | len |
	array ← t1.
	limit ← (lim > (len ← array length)
			  ifTrue: [len]
			  ifFalse: [lim]).
	position ← (pos  1
			  ifTrue: [0]
			  ifFalse: [pos - 1])].
"65" Stream$'Character printing'
[semicrtab | |
	self append: ';
	'].
"66" Stream$'Initialization'
[default | |
	self of: (String new: 16)].
"107" Stream$'Coercions'
[asVector | |
	 "Convert a string to a vector of tokens"
	↑(Reader new of: self) read].
"221" Stream$'Sequential reading and writing'
[ x | y |
	(y ← self next)
	  ifTrue:
		[ "peek for matching element"
		x = y
		  ifTrue: [↑y].
		 "gobble it if found"
		position ← position - 1.
		↑false]
	  ifFalse: [↑false]].
"56" Stream$'Character printing'
[space | |
	self next← 32].
"140" Stream$'Sequential reading and writing'
[pop: n | t |
	position < n
	  ifTrue: [↑false].
	t ← self last: n.
	position ← position - n.
	↑t].
"63" Stream$'Test and alter position'
[end | |
	↑position  limit].
"88" Stream$'Initialization'
[of: t1 | |
	array ← t1.
	position ← 0.
	limit ← array length].
"80" Stream$'Test and alter position'
[loc | |
	 "synonym for compiler"
	↑position].
"158" Stream$'Sequential reading and writing'
[pop | |
	 "use it as a LIFO"
	position < 1
	  ifTrue: [↑false].
	position ← position - 1.
	↑array  (position + 1)].
"105" Stream$'Sequential reading and writing'
[append: x | i |
	 "Array arg"
	x do: [:i | self next← i].
	↑x].
"355" Stream$'Compiler object code'
[emitLong: jmpOrBfp by: dist | |
	dist < 0
	  ifTrue: [dist ← dist + 1024]
	  ifFalse:
		[dist > 1023
		  ifTrue: [dist ← 1]
		  ifFalse: [jmpOrBfp ← jmpOrBfp + 4]].
	dist < 0
	  ifTrue: [user notify: 'A block compiles more than 1K bytes of code']
	  ifFalse:
		[self next← dist / 256 + jmpOrBfp.
		self next← dist \ 256]].
"65" Stream$'Character printing'
[print: obj | |
	obj printon: self].
"122" Stream$'Sequential reading and writing'
[nextword← val | |
	self next← val lshift: 8.
	self next← val land: 255.
	↑val].
"109" Stream$'Sequential reading and writing'
[next: n from: strm | |
	(1 to: n) do: [:n | self next← strm next]].
"109" Stream$'Sequential reading and writing'
[padNext← c | |
	position even
	  ifTrue: [↑false].
	↑self next← c].
"328" Stream$'Static reading and writing'
[insert: x | i |
	 "treat as LIFO queue, insert in front"
	 "grow array if necessary"
	position = limit
	  ifTrue:
		[array ← array grow.
		limit ← array length].
	(1 to: position) do: [:i | array  (position - i + 2) ← array  (position - i + 1)].
	array  1 ← x.
	position ← position + 1].
"580" Stream$'Sequential reading and writing'
[integerScan | sign base maxdigit c val |
	sign ←  "get the next Integer or LargeInteger (Float?) from a Stream.
	copied from String asInteger"
			(self  21
			  ifTrue: [1]
			  ifFalse: [1]).
	base ← (self  48
			  ifTrue: [8]
			  ifFalse: [10]).
	maxdigit ← 48 + base.
	val ← 0.
	[(c ← self next) and: [(c  48 and: [c < maxdigit])]] whileTrueDo: [val ← val * base + (c - 48)].
	c
	  ifTrue: [self skip: 1].
	(base = 8 and: [(val > 32767 and: [(sign = 1 and: [val < 65536])])])
	  ifTrue: [↑val asSmall].
	↑(val * sign) asInteger].
"106" Stream$'Test and alter position'
[skipTo: x | y |
	self do:
		[:y | y = x
		  ifTrue: [↑true]].
	↑false].
"161" Stream$'Sequential reading and writing'
[next | |<primitive: 20>
	 "simple result"
	self myend
	  ifTrue: [↑self pastend].
	↑array  (position ← position + 1)].
"85" Stream$'Static reading and writing'
[rest | |
	↑array copy: position + 1 to: limit].
"93" Stream$'Static reading and writing'
[last | |
	position  0
	  ifTrue: [↑array  position]].
"150" Stream$'Sequential reading and writing'
[peek | x |
	(x ← self next)
	  ifTrue:
		[position ← position - 1.
		↑x].
	 "peek at next element"
	↑false].
"81" Stream$'Static reading and writing'
[contents | |
	↑array copy: 1 to: position].
"37" Stream$'Coercions'
[asStream | |
	].
"168" Stream$'As yet unclassified'
[reverseContents | a s i |
	a ← array species new: position.
	s ← a asStream.
	(position to: 1 by: 1) do: [:i | s next← array  i].
	↑a].
"62" Stream$'Test and alter position'
[limit: t1 | |
	limit ← t1].
"151" Stream$'Sequential reading and writing'
[into: x | |
	↑self into: x endError: true "generate an error if the Stream is exhausted before x is filled"].
"73" Stream$'Test and alter position'
[skip: x | |
	position ← position + x].
"100" Stream$'Static reading and writing'
[last: n | |
	↑(array  (position - n + 1 to: position)) copy].
"170" Stream$'Sequential reading and writing'
[upto: x | y s |
	s ← (String new: 250) asStream.
	self do:
		[:y | y = x
		  ifTrue: [↑s contents].
		s next← y].
	↑s contents].
"65" Stream$'Test and alter position'
[myend | |
	↑position  limit].
"42" Stream$'Coercions'
[asArray | |
	↑array].
"67" Stream$'Test and alter position'
[settoend | |
	position ← limit].
"178" Stream$'Sequential reading and writing'
[nextword | hi lo |
	(hi ← self next)
	  ifTrue:
		[(lo ← self next)
		  ifTrue: [↑(hi lshift: 8) + lo].
		↑false]
	  ifFalse: [↑false]].
"110" Stream$'Test and alter position'
[pastend← x | |
	array ← array grow.
	limit ← array length.
	↑self next← x].
"218" Stream$'Sequential reading and writing'
[dequeue: n | t |
	position < n
	  ifTrue: [↑false].
	t ← (array  (1 to: n)) copy.
	array  (1 to: position - n) ← array  (n + 1 to: position).
	position ← position - n.
	↑t].
"87" Stream$'Static reading and writing'
[first | |
	position  0
	  ifTrue: [↑array  1]].
"60" Stream$'Test and alter position'
[reset | |
	position ← 0].
"56" Stream$'Test and alter position'
[pastend | |
	↑false].
"94" Stream$'Sequential reading and writing'
[dequeue | |
	 "use it as a FIFO"
	↑self dequeue: 1].
"69" Stream$'Test and alter position'
[empty | |
	 "for"
	↑position = 0].
"168" Stream$'Sequential reading and writing'
[next← x | |<primitive: 21>
	 "simple arg"
	self myend
	  ifTrue: [↑self pastend← x].
	↑array  (position ← position + 1) ← x].
"60" Stream$'Test and alter position'
[position | |
	↑position].
"54" Stream$'Test and alter position'
[limit | |
	↑limit].
"80" Stream$'Coercions'
[viewer | |
	↑SetReader new of: array from: 1 to: position].
"70" Stream$'Initialization'
[close | |
	limit ← position.
	position ← 0].
"106" Stream$'Sequential reading and writing'
[next: n | |
	↑self into: (array species new: n) endError: true].
"94" Stream$'Sequential reading and writing'
[next: n ← v | |
	(1 to: n) do: [:n | self next← v]].
"367" Stream$'Sequential reading and writing'
[into: x endError: err | i t len |
	i ← 0 "Array result".
	len ← x length "read until count or stream is exhausted".
	[i < len and: [(t ← self next)]] whileTrueDo: [x  (i ← i + 1) ← t].
	err
	  ifTrue:
		[t
		  ifTrue: [↑x].
		user notify: 'only read first ' + i asString]
	  ifFalse: [ "return number that were read"
		↑i]].
"178" Stream$'Coercions'
[asReadStream | |
	↑Stream new "an alternative to Set/SetReader.
	create another Stream which reads the contents of this one" of: array from: 1 to: position].
"88" Stream$'Sequential reading and writing'
[nextElement: element | |
	self next← element].
"97" Stream$'Character printing'
[crtab: n | i |
	self next← 13.
	(1 to: n) do: [:i | self next← 9]].
"52" Stream$'Initialization'
[release | |
	array ← nil].
"107" Stream$'As yet unclassified'
[do: aBlock | |
	[self end] whileFalseDo:  [aBlock value: self next].
	↑nil].
"179" Stream$'Sequential reading and writing'
[padNext | |
	position even "make position even (on word boundary), returning padding character if any"
	  ifTrue: [↑false].
	↑self next].
"113" Stream$'Sequential reading and writing'
[nextPoint | x |
	x ← self nextword.
	↑Point new x: x y: self nextword].
"101" Stream$'Sequential reading and writing'
[nextPoint← p | |
	self nextword← p x.
	self nextword← p y].
"71" Stream$'Test and alter position'
[skipwords: w | |
	self skip: 2 * w].
"73" Stream$'Test and alter position'
[wordposition | |
	↑self position / 2].
"59" Float$'Conversion'
[fpart | |<primitive: 59>
	user croak].
"100" Float$'Conversion'
[round | |
	↑(self + (self < 0
	  ifTrue: [0.5]
	  ifFalse: [0.5])) asInteger].
"152" Float$'Conversion'
[asInteger | |<primitive: 60>
	 "Return an Integer = self ipart"
	↑(self / 10000.0) asInteger * 10000 + (self \ 10000.0) asInteger].
"68" Float$'Arithmetic'
[+ arg | |<primitive: 49>
	↑self + arg asFloat].
"68" Float$'Arithmetic'
[> arg | |<primitive: 52>
	↑self > arg asFloat].
"68" Float$'Arithmetic'
[< arg | |<primitive: 51>
	↑self < arg asFloat].
"68" Float$'Arithmetic'
[- arg | |<primitive: 50>
	↑self - arg asFloat].
"600" Float$'Math functions'
[ln | a x x2 n P |
	self  0.0 "see Computer Approximations, pp. 105-111, p. 227 (LOGE 2663)"
	  ifTrue: [user notify: 'ln not valid for ' + self asString]
	  ifFalse:
		[x ← self + 0.0 "exponent".
		n ← ln2 * (((x instfield: 1) / 2) asFloat - 0.5) "mantissa between 0.5 and 1.0".
		.
		x instfield: 1 ← 0.
		x ← x * sqrt2.
		x ← x - 1.0 / (x + 1.0).
		x2 ← x * x.
		P ← 0.0 "(0.2000000000046727e1 0.666666635059382 0.4000059794795
		0.28525381498 0.2376245609) reverse copy".
		#(0.23762456 0.28525381 0.40000598 0.66666664 2.0 ) do: [:a | P ← P * x2 + a].
		↑n + (x * P)]].
"103" Float$'Arithmetic'
[= arg | |<primitive: 55>
	arg isNumber
	  ifTrue: [↑self = arg asFloat].
	↑false].
"68" Float$'Arithmetic'
[ arg | |<primitive: 53>
	↑self  arg asFloat].
"68" Float$'Arithmetic'
[ arg | |<primitive: 54>
	↑self  arg asFloat].
"68" Float$'Printing'
[printon: strm | |
	self printon: strm digits: 8].
"68" Float$'Arithmetic'
[ arg | |<primitive: 56>
	↑self  arg asFloat].
"68" Float$'Arithmetic'
[* arg | |<primitive: 57>
	↑self * arg asFloat].
"145" Float$'Arithmetic'
[/ arg | |<primitive: 58>
	0.0 = arg
	  ifTrue: [user notify: 'Attempt to divide by 0.0']
	  ifFalse: [↑self / arg asFloat]].
"88" Float$'Arithmetic'
[| arg | |
	 "By analogy with integers"
	↑(self / arg) ipart * arg].
"162" Float$'Arithmetic'
[\ arg | |
	 "By analogy with integers"
	self < 0.0
	  ifTrue: [↑(self / arg) ipart + 1.0 * arg + self].
	↑self - ((self / arg) ipart * arg)].
"504" Float$'Math functions'
[tan | x x2 sum const |
	 "for angles in radians"
	self < 0.0
	  ifTrue: [↑self negated tan negated].
	 " normalize to 0self(pi/4) "
	self > pi
	  ifTrue: [↑(self \ pi) tan].
	self > halfpi
	  ifTrue: [↑(self - halfpi) tan negated].
	self > fourthpi
	  ifTrue: [↑1.0 / (halfpi - self) tan].
	sum ← x ← self.
	x2 ← x * x.
	#(0.3333314 0.1333924 0.05337406 0.024565089 0.002900525 0.0095168091 ) do: [:const |  "Now compute the series"
		sum ← const * (x ← x * x2) + sum].
	↑sum].
"712" Float$'Math functions'
[exp | a n1 x x2 P Q |
	self abs "see Computer Approximations, pp. 96-104, p. 205 (EXPB 1065)" > 9212.0 "1.0e4001 ln"
	  ifTrue: [user notify: 'exp overflow']
	  ifFalse:
		[x ← self / ln2.
		(n1 ← Float new "2.0 ipow: x asInteger") instfield: 1 ← x asInteger * 2.
		(x ← x fpart)  0.5
		  ifTrue:
			[n1 ← n1 * sqrt2.
			x ← x - 0.5].
		x2 ← x * x "compute 2.0 power: x".
		P ← Q ← 0.0 "(0.25250428525576241933744e4 0.28875563776168927289e2) reverse copy".
		#(28.875564 2525.0429 ) do: [:a | P ← P * x2 + a "(0.72857336028361108885189e4 0.375021654220866600213e3 0.1e1) reverse copy"].
		#(1.0 375.02165 7285.7336 ) do: [:a | Q ← Q * x2 + a].
		↑n1 * (Q + (x * P) / (Q - (x * P)))]].
"110" Float$'Math functions'
[neg | |
	 "Obsolete - use negated, which is uniform for all Numbers"
	↑self negated].
"478" Float$'Math functions'
[sin | x x2 sum const |
	 "for angles in radians"
	self < 0.0
	  ifTrue: [↑self negated sin negated].
	 " normalize to 0self(pi/4) "
	self > twopi
	  ifTrue: [↑(self \ twopi) sin].
	self > pi
	  ifTrue: [↑(self - pi) sin negated].
	self > halfpi
	  ifTrue: [↑(pi - self) sin].
	sum ← x ← self.
	x2 ← x * x.
	#(0.16666667 0.0083333315 1.98409e4 2.7526e6 2.39e8 ) do: [:const |  "Now compute the series"
		sum ← const * (x ← x * x2) + sum].
	↑sum].
"38" Float$'Conversion'
[copy | |
	↑self].
"129" Float$'Math functions'
[cos | |
	 "for angles in radians"
	self < 0.0
	  ifTrue: [↑(self + halfpi) sin].
	↑(halfpi - self) sin].
"557" Float$'Math functions'
[arctan | theta term y eps i |
	 "return angle in degrees good to .02 degrees."
	self = 1.0
	  ifTrue: [↑45.0].
	.
	self = 1.0
	  ifTrue: [↑45.0].
	.
	self * self > 1.0
	  ifTrue:
		[theta ← halfpi.
		y ← 1.0 / (self * self).
		term ← 1.0 / self abs]
	  ifFalse:
		[theta ← 0.0.
		y ← 0.0 - (self * self).
		term ← self abs].
	i ← 1.
	eps ← 1.0e4.
	[term abs > eps] whileTrueDo:
		[theta ← theta + term.
		term ← term * y * i asFloat / (i + 2) asFloat.
		i ← i + 2].
	theta ← self sign asFloat * theta * 360.0 / twopi.
	↑theta].
"476" Float$'Conversion'
[asLarge | me digits nat i |
	 "convert to LargeInteger"
	self < 0
	  ifTrue: [↑(0.0 - self) asLarge negated].
	digits ← Stream default.
	self = 0.0
	  ifTrue: [digits next← 0]
	  ifFalse:
		[me ← self ipart.
		[me  1] whileTrueDo:
			[digits next← (me \ 256.0) asInteger.
			me ← me / 256.0]].
	digits ← digits contents.
	nat ← Natural new: digits length.
	(1 to: digits length) do: [:i | nat  i ← digits  i].
	↑LargeInteger new bytes: nat neg: false].
"89" Float$'Arithmetic'
[hash | |
	↑(self fpart * 100) asInteger lxor: self ipart asInteger].
"121" Float$'Arithmetic'
[near: n within: eps | |
	↑(self - n) "for testing near equality, e.g. error convergence" abs  eps].
"36" Float$'Conversion'
[asFloat | |
	].
"303" Float$'Printing'
[printon: strm digits: digits | |
	 "print me using digits significant figures"
	self > 0.0
	  ifTrue: [self absprinton: strm digits: digits]
	  ifFalse:
		[self = 0.0
		  ifTrue: [strm append: '0.0']
		  ifFalse:
			[strm append: ''.
			0.0 - self absprinton: strm digits: digits]]].
"96" Float$'Conversion'
[asDegrees | |
	 "self assumed to be in radians"
	↑self / radiansPerDegree].
"60" Float$'Conversion'
[asDirection | |
	↑self cos  self sin].
"40" Float$'Conversion'
[recopy | |
	↑self].
"96" Float$'Conversion'
[asRadians | |
	 "self assumed to be in degrees"
	↑self * radiansPerDegree].
"359" Float$'Math functions'
[sqrt | guess i |
	self  0.0
	  ifTrue:
		[self = 0.0
		  ifTrue: [↑0.0].
		user notify: 'sqrt invalid for x<0.']
	  ifFalse:
		[guess ← self + 0.0 "copy x".
		guess instfield: 1 ← (guess instfield: 1) / 4 * 2 "and halve expt for first guess".
		(1 to: 5) do: [:i | guess ← self - (guess * guess) / (guess * 2.0) + guess].
		↑guess]].
"68" Float$'Math functions'
[log: base | |
	↑self ln / base asFloat ln].
"95" Float$'Arithmetic'
[sameAs: arg | |
	 "arg assumed to be of same class as self"
	↑self = arg].
"270" Float$'Printing'
[epart: base | x |
	 "gives floor log.base self"
	self < base
	  ifTrue: [↑0].
	 "self assumed positive"
	self < (base * base)
	  ifTrue: [↑1].
	x ← 2 * (self epart: base * base) "binary recursion like ipow".
	↑x + (self / (base ipow: x) epart: base)].
"602" Float$'Initialization'
[classInit | |
	pi ← 3.1415927 "constants from Computer Approximations, pp. 182-183
	pi = 3.14159265358979323846264338327950288
	pi/2 = 1.57079632679489661923132169163975144
	pi/4 = 0.78539816339744830961566084581987572
	pi*2 = 6.28318530717958647692528676655900576
	pi/180 = 0.01745329251994329576923690768488612
	2.0 ln = 0.69314718055994530941723212145817657
	2.0 sqrt = 1.41421356237309504880168872420969808".
	halfpi ← pi / 2.0.
	fourthpi ← pi / 4.0.
	twopi ← pi * 2.0.
	radiansPerDegree ← pi / 180.0.
	degreesPerRadian ← 180.0 / pi.
	ln2 ← 0.69314718.
	sqrt2 ← 1.4142136].
"1050" Float$'Printing'
[absprinton: strm digits: digits | fuzz x exp q i |
	 "print me using digits significant figures"
	exp ←  "x is myself normalized to [1.0, 10.0), exp is my exponent"
			(self < 1.0
			  ifTrue: [0 - (10.0 / self epart: 10.0)]
			  ifFalse: [self epart: 10.0]).
	x ← self / (10.0 ipow: exp) "round the last digit to be printed".
	fuzz ← 10.0 ipow: 1 - digits.
	x ← 0.5 * fuzz + x "check if rounding has unnormalized x".
	x  10.0
	  ifTrue:
		[x ← x / 10.0.
		exp ← exp + 1].
	(exp < 6 and: [exp > 4])
	  ifTrue:
		[q ← 0 "decimal notation".
		exp < 0
		  ifTrue: [strm append: '0.0000'  (1 to: 1 - exp)]]
	  ifFalse:
		[.
		q ← exp.
		exp ← 0] "scientific notation" "use fuzz to track significance".
	[x  fuzz] whileTrueDo:
		[i ← x asInteger.
		strm next← 48 + i.
		x ← x - i * 10.0.
		fuzz ← fuzz * 10.0.
		exp ← exp - 1.
		exp = 1
		  ifTrue: [strm append: '.']].
	[exp  1] whileTrueDo:
		[strm next← 48.
		exp ← exp - 1.
		exp = 1
		  ifTrue: [strm append: '.']].
	q  0
	  ifTrue:
		[strm append: 'e'.
		strm print: q]].
"109" Float$'Printing'
[roundTo: d | |
	↑(self / d + (self < 0.0
	  ifTrue: [0.5]
	  ifFalse: [0.5])) ipart * d].
"47" Float$'Arithmetic'
[negated | |
	↑0.0 - self].
"64" Float$'Arithmetic'
[near: n | |
	↑self near: n within: 1.0e4].
"219" Float$'Math functions'
[ipow: x | |
	 "fixed powers in log n steps"
	x = 0
	  ifTrue: [↑1.0].
	x = 1
	  ifTrue: [↑self].
	x > 1
	  ifTrue: [↑(self * self ipow: x / 2) * (self ipow: x \ 2)].
	↑1.0 / (self ipow: 0 - x)].
"98" Float$'Conversion'
[ipart | |
	 "Returns a Float with zero fractional part"
	↑self - self fpart].
"75" MethodContext$'Initialization'
[setRestart code | |
	RestartCode ← code].
"68" MethodContext$'Access to Parts'
[tempAt: index | |
	↑self  index].
"70" MethodContext$'Initialization'
[systemRestart | |
	RestartCode eval].
"61" MethodContext$'Blocks'
[remoteCopy | |
	↑self blockCopy: 0].
"113" MethodContext$'Initialization'
[restart | |
	pc ← method initialPC.
	stackp ← method numArgs + method numTemps].
"70" MethodContext$'Debugger'
[erase | |
	receiver ← nil.
	super release].
"132" MethodContext$'Initialization'
[sender: t1 receiver: t2 mclass: ignored method: t4 | |
	sender ← t1.
	receiver ← t2.
	method ← t4].
"59" MethodContext$'Access to Parts'
[receiver | |
	↑receiver].
"55" MethodContext$'Access to Parts'
[method | |
	↑method].
"95" MethodContext$'Initialization'
[run | |
	self setRestart [(↑nil)].
	user restore.
	user run].
"716" MethodContext$'Initialization'
[send: selector to: rcvr | nargs i mcl context |
	mcl ← rcvr class.
	[mcl md has: selector] whileFalseDo: 
		[mcl ← mcl superclass.
		mcl  nil
		  ifTrue: [user notify: 'Message not understood: ' + selector]].
	method ← (NoteTaker
			  ifTrue: [mcl method: selector]
			  ifFalse: [(mcl regenerate: selector) asCompiledMethod]).
	context ← MethodContext new: method frameSize.
	context sender: self receiver: rcvr mclass: mcl method: method.
	nargs ← method numArgs.
	(1 to: nargs) do: [:i | context temp: (nargs - i + 1) ← self pop].
	context pc: method initialPC stackp: nargs + method numTemps.
	↑context "
 | NTP. NTP← MethodContext new.  (NTP send: goBaby to: NTP) inspect.
"].
"83" MethodContext$'Initialization'
[init: size | |
	tempsAndStack ← Vector new: size].
"315" MethodContext$'Initialization'
[goBaby | height |
	NoteTaker ← true.
	MethodKeeper ← (Vector new: 10) asStream.
	externalViews ← Set new vector: 10.
	height ← 760 " 480 376 ".
	user currentDisplay: (Form new extent: 640  height bits: (Bitmap new: 640 / 16 * height) offset: nil).
	[true] whileTrueDo: [self run]].
"87" MethodContext$'Access to Parts'
[tempAt: index put: value | |
	↑self  index ← value].
"79" MethodContext$'Initialization'
[pc: t1 stackp: t2 | |
	pc ← t1.
	stackp ← t2].
"121" MethodContext$'Blocks'
[blockCopy: nargs | |
	↑(BlockContext new: self length) home: self startpc: pc + 2 nargs: nargs].
"182" ContextPart$'As yet unclassified'
[stack | a strm |
	strm ← (Vector new: 20) asStream.
	strm next← a ← self.
	[(a ← a sender)  nil] whileFalseDo:  [strm next← a].
	↑strm contents].
"142" ContextPart$'As yet unclassified'
[variableNamesInto: dest with: block | n |
	self tempNames transform [:n | n] to [(dest identifier: n)]].
"126" ContextPart$'As yet unclassified'
[erase | i |
	 "release frames to break cycles"
	(1 to: stackp) do: [:i | self  i ← nil]].
"75" ContextPart$'As yet unclassified'
[sender← t1 | |
	sender ← t1.
	↑sender].
"294" ContextPart$'As yet unclassified'
[printon: strm | mclass |
	strm append: self receiver class title.
	mclass ← self mclass.
	mclass  self receiver class
	  ifFalse:
		[strm append: '('.
		strm append: mclass title.
		strm append: ')'].
	strm append: '>>'.
	strm append: self method selector].
"115" ContextPart$'As yet unclassified'
[tempframe | i |
	↑1 ~ self method numTemps transform [:i | i] to [self  i]].
"216" ContextPart$'As yet unclassified'
[mclass | mclass sel |
	mclass ← self receiver class.
	sel ← self selector.
	[mclass  nil or: [(mclass canunderstand: sel)]] whileFalseDo:  [mclass ← mclass superclass].
	↑mclass].
"99" ContextPart$'As yet unclassified'
[pop | val |
	val ← self  stackp.
	stackp ← stackp - 1.
	↑val].
"57" ContextPart$'As yet unclassified'
[sender | |
	↑sender].
"156" ContextPart$'As yet unclassified'
[releaseFully | c |
	 "release frames to break cycles"
	c ← self.
	[c  nil] whileFalseDo: 
		[c ← c sender.
		c erase]].
"73" ContextPart$'As yet unclassified'
[selector | |
	↑self method selector].
"125" ContextPart$'As yet unclassified'
[tempNames | i |
	↑1 ~ self method numTemps transform [:i | i] to [('t' + i asString)]].
"88" ContextPart$'As yet unclassified'
[push: val | |
	↑self  (stackp ← stackp + 1) ← val].
"68" ContextPart$'As yet unclassified'
[release | |
	self releaseFully].
"127" ContextPart$'As yet unclassified'
[swapSender: coroutine | oldSender |
	oldSender ← sender.
	sender ← coroutine.
	↑oldSender].
"179" BlockContext$'As yet unclassified'
[sender: t1 pc: t2 stackp: t3 home: t4 startpc: t5 nargs: t6 | |
	sender ← t1.
	pc ← t2.
	stackp ← t3.
	home ← t4.
	startpc ← t5.
	nargs ← t6].
"71" BlockContext$'As yet unclassified'
[tempAt: index | |
	↑home  index].
"85" BlockContext$'As yet unclassified'
[value: arg | |<primitive: 75>
	self valueError].
"112" BlockContext$'As yet unclassified'
[home: t1 startpc: t2 nargs: t3 | |
	home ← t1.
	startpc ← t2.
	nargs ← t3].
"110" BlockContext$'As yet unclassified'
[value: arg1 value: arg2 value: arg3 | |<primitive: 75>
	self valueError].
"120" BlockContext$'As yet unclassified'
[value← val | |
	 "for compatibility with ST76 remote variables"
	↑self value: val].
"76" BlockContext$'As yet unclassified'
[erase | |
	home ← nil.
	super release].
"331" BlockContext$'As yet unclassified'
[valueWithArgs: vec | t2 |
	(t2 ← vec length) = 0
	  ifTrue: [↑self value].
	t2 = 1
	  ifTrue: [↑self value: vec  1].
	t2 = 2
	  ifTrue: [↑self value: vec  1 value: vec  2].
	t2 = 3
	  ifTrue: [↑self value: vec  1 value: vec  2 value: vec  3].
	user notify: 'More than 3 args for value:'].
"67" BlockContext$'As yet unclassified'
[receiver | |
	↑home receiver].
"80" BlockContext$'As yet unclassified'
[value | |<primitive: 75>
	self valueError].
"63" BlockContext$'As yet unclassified'
[method | |
	↑home method].
"97" BlockContext$'As yet unclassified'
[valueError | |
	user notify: 'Incompatible number of args'].
"98" BlockContext$'As yet unclassified'
[value: arg1 value: arg2 | |<primitive: 75>
	self valueError].
"363" BlockContext$'As yet unclassified'
[eval | save val |
	nargs = 0
	  ifTrue: [↑self value].
	nargs = 1
	  ifTrue:
		[save ← startpc "amazing crock for reading ST76 remote variable".
		startpc ← startpc + (self method  startpc < 112
				  ifTrue: [1]
				  ifFalse: [2]).
		nargs ← 0.
		val ← self value.
		startpc ← save.
		nargs ← 1.
		↑val].
	self valueError].
"90" BlockContext$'As yet unclassified'
[tempAt: index put: value | |
	↑home  index ← value].
"143" BlockContext$'As yet unclassified'
[blockCopy: t1 | |
	nargs ← t1.
	↑(BlockContext new: self length) home: home startpc: pc + 2 nargs: nargs].
"162" Point$'Arithmetic'
[+ delta | |
	↑Point new "Return a Point that is the sum of me and delta (which is a Point or Number)" x: x + delta asPtX y: y + delta asPtY].
"45" Point$'Access to parts'
[y← t1 | |
	y ← t1].
"58" Point$'Arithmetic'
[< pt | |
	↑x < pt x and: [y < pt y]].
"169" Point$'Arithmetic'
[- delta | |
	↑Point new "Return a Point that is the difference of me and delta (which is a Point or Number)" x: x - delta asPtX y: y - delta asPtY].
"45" Point$'Access to parts'
[x← t1 | |
	x ← t1].
"58" Point$'Arithmetic'
[= pt | |
	↑x = pt x and: [y = pt y]].
"58" Point$'Arithmetic'
[ pt | |
	↑x  pt x and: [y  pt y]].
"58" Point$'Arithmetic'
[> pt | |
	↑x > pt x and: [y > pt y]].
"90" Point$'Conversion'
[printon: strm | |
	strm print: x.
	strm append: ''.
	strm print: y].
"58" Point$'Arithmetic'
[ pt | |
	↑x  pt x and: [y  pt y]].
"36" Point$'Conversion'
[asPtX | |
	↑x].
"106" Point$'Conversion'
[rect: p | |
	 "infix creation of rectangles"
	↑Rectangle new origin: self corner: p].
"166" Point$'Arithmetic'
[* scale | |
	↑Point new "Return a Point that is the product of me and scale (which is a Point or Number)" x: x * scale asPtX y: y * scale asPtY].
"167" Point$'Arithmetic'
[/ scale | |
	↑Point new "Return a Point that is the quotient of me and scale (which is a Point or Number)" x: x / scale asPtX y: y / scale asPtY].
"69" Point$'Arithmetic'
[| grid | |
	↑Point new x: x | grid y: y | grid].
"121" Point$'Arithmetic'
[dist: pt | t |
	 "distance (Manhattan norm) between pt and self"
	t ← (pt - self) abs.
	↑t x + t y].
"36" Point$'Conversion'
[asPtY | |
	↑y].
"37" Point$'Access to parts'
[x | |
	↑x].
"37" Point$'Access to parts'
[y | |
	↑y].
"90" Point$'Arithmetic'
[length | |
	↑(x asFloat * x asFloat + (y asFloat * y asFloat)) sqrt].
"36" Point$'Conversion'
[width | |
	↑1].
"78" Point$'Arithmetic'
[normalize | |
	self x← 0 "set selt to zero".
	self y← 0].
"43" Point$'Initialization'
[copy | |
	↑x  y].
"90" Point$'Arithmetic'
[abs | |
	 "absolute value of a point"
	↑Point new x: x abs y: y abs].
"115" Point$'SYSTEM'
[hideData: complete | s t3 |
	(t3 ← Stream new) of: (s ← String new: 4).
	t3 nextPoint← self.
	↑s].
"36" Point$'SYSTEM'
[pressCode | |
	↑7].
"108" Point$'SYSTEM'
[hidePress: press complete: c | |
	press skipcode: self pressCode data: (self hideData: c)].
"60" Point$'Access to parts'
[hash | |
	↑(x lshift: 2) lxor: y].
"361" Point$'Access to parts'
[theta | tan theta |
	 "return the angle the point makes with origin.  right is 0; down is 90."
	x = 0
	  ifTrue:
		[y  0
		  ifTrue: [↑90.0].
		↑270.0]
	  ifFalse:
		[.
		tan ← y asFloat / x asFloat.
		theta ← tan arctan.
		x  0
		  ifTrue:
			[y  0
			  ifTrue: [↑theta].
			↑360.0 + theta]
		  ifFalse:
			[.
			↑180.0 + theta]]].
"112" Point$'Conversion'
[asRectangle | |
	↑self rect: self "Return a Rectangle with me as both origin and corner."].
"88" Point$'Conversion'
[asRectCorner | |
	 "pretend to be a Rectangle for Rectangle +-*/"].
"88" Point$'Conversion'
[asRectOrigin | |
	 "pretend to be a Rectangle for Rectangle +-*/"].
"77" Point$'Arithmetic'
[max: t | |
	↑Point new x: (x max: t x) y: (y max: t y)].
"104" Point$'Arithmetic'
[translate: delta | |
	x ← x + delta x "increment self by delta".
	y ← y + delta y].
"77" Point$'Arithmetic'
[min: t | |
	↑Point new x: (x min: t x) y: (y min: t y)].
"59" Point$'Initialization'
[x: t1 y: t2 | |
	x ← t1.
	y ← t2].
"41" Point$'Conversion'
[extent | |
	↑1  1].
"40" Point$'Conversion'
[origin | |
	↑self].
"50" Point$'Conversion'
[corner | |
	↑self + (1  1)].
"37" Point$'Conversion'
[height | |
	↑1].
"123" Point$'Arithmetic'
[normal | n |
	 "unit vector rotated 90 deg clockwise"
	n ← y asFloat neg  x asFloat.
	↑n / n length].
"108" Point$'Conversion'
[extent: p | |
	 "infix creation of rectangles"
	↑Rectangle new origin: self extent: p].
"51" Point$'Conversion'
[asPoint | |
	 "Return self."].
"81" Point$'SYSTEM'
[fromPress: press value: s | |
	x ← s nextword.
	y ← s nextword].
"88" Natural$'As yet unclassified'
[ n | |
	super length < n
	  ifTrue: [↑0].
	↑super  n].
"427" Natural$'Arithmetic'
[natunnormalize: n lookfirst: a | x i r f digit |
	n ← 0 - n.
	x ← 0.
	f ← n + 8.
	i ← a.
	digit ← self  i.
	[((digit lshift: n) lor: x) = 0 and: [i  1]] whileTrueDo:
		[x ← digit lshift: f.
		i ← i - 1.
		digit ← self  i].
	r ← Natural new: i.
	a ← i.
	x ← self  1 lshift: n.
	(1 to: a) do:
		[:i | digit ← self  (i + 1).
		r  i ← ((digit lshift: f) lor: x) land: 255.
		x ← digit lshift: n].
	↑r].
"476" Natural$'Arithmetic'
[natdivideandCarry: arg extra: pair | i len z |
	z ← pair  2 "arg is an integer < 256 - returns remainder, smashes self to quotient - pair is a 2-vector of len (index of high order non-zero word in self) and a MachineDouble - be careful!!!".
	z high← 0.
	len ← pair  1.
	(len to: 1 by: 1) do:
		[:i | z low← self  i.
		self  i ← z mdiv: arg].
	self  len = 0
	  ifTrue:
		[len ← len - 1.
		len = 0
		  ifTrue: [len ← 1]].
	pair  1 ← len.
	↑z high].
"80" Natural$'As yet unclassified'
[printon: strm | |
	self printon: strm base: 10].
"340" Natural$'Arithmetic'
[natcompare: arg | i len t4 t5 |
	 "speeded up for Integer args, same speed for LargeInteger (Natural) args"
	len ← self length.
	(t4 ← arg length) < len
	  ifTrue: [↑3].
	t4 > len
	  ifTrue: [↑1].
	(len to: 1 by: 1) do:
		[:i | (t5 ← arg  i) < (self  i)
		  ifTrue: [↑3].
		t5 > (self  i)
		  ifTrue: [↑1]].
	↑2].
"364" Natural$'Arithmetic'
[natnormalize: n | x i r f digit |
	r ← Natural new: self length "n is the number of bits to shift by. The Natural number returned will be written over repeatedly, so we must make a new one." + 1.
	x ← 0.
	f ← n - 8.
	(1 to: r length) do:
		[:i | digit ← self  i.
		r  i ← ((digit lshift: n) lor: x) land: 255.
		x ← digit lshift: f].
	↑r].
"104" MachineDouble$'Arithmetic'
[< arg | |
	high = arg high
	  ifTrue: [↑low < arg low].
	↑high < arg high].
"186" MachineDouble$'As yet unclassified'
[printon: strm | |
	strm append: '[MachineDouble 0'.
	high printon: strm base: 8.
	strm append: ' 0'.
	low printon: strm base: 8.
	strm append: ']'].
"114" MachineDouble$'As yet unclassified'
[asInt | n i |
	 "may return a negative number"
	↑(high lshift: 8) lor: low].
"227" MachineDouble$'As yet unclassified'
[classInit | |
	low4 ← 64 "low4 is a field description for the low order 4 bits of an Integer
      high4 is a field description for the high order 4 bits of an 8-bit Integer".
	high4 ← 68].
"187" MachineDouble$'Access'
[extract | x |
	x ← low "returns low, moves high down and propagates sign.".
	low ← high.
	high ← ((low land: 128) = 0
			  ifTrue: [0]
			  ifFalse: [255]).
	↑x].
"171" MachineDouble$'Arithmetic'
[decreaseby: y | x |
	 "y is a positive <256 integer"
	x ← low - y.
	x < 0
	  ifTrue: [high ← high - 1 land: 255].
	low ← x land: 255.
	↑self].
"486" MachineDouble$'Arithmetic'
[gets: x mtimes: y | xh xl yh yl p1 p2 |
	xh ← x lshift: 4 "x and y are 8-bit positive #'s.
      Does single precision unsigned multiplication
      returning a double precision result.".
	xl ← x land: 15.
	yh ← y lshift: 4.
	yl ← y land: 15.
	low ← yl * xl.
	high ← yh * xh.
	p2 ← yh * xl.
	p1 ← p2 + (yl * xh).
	high ← high + (p1 lshift: 4).
	low ← ((p1 land: 15) lshift: 4) + low.
	low  256
	  ifTrue:
		[high ← high + 1.
		low ← low - 256].
	↑self].
"58" MachineDouble$'Access'
[high← t1 | |
	high ← t1.
	↑self].
"173" MachineDouble$'Arithmetic'
[increaseby: y | x |
	 "y is a positive <256 integer"
	x ← low + y.
	x > 255
	  ifTrue: [high ← high + 1 land: 255].
	low ← x land: 255.
	↑self].
"76" MachineDouble$'As yet unclassified'
[init | |
	low ← 0.
	high ← 0.
	↑self].
"56" MachineDouble$'Access'
[low← t1 | |
	low ← t1.
	↑self].
"794" MachineDouble$'Arithmetic'
[mdiv: y | x |
	high > y "Ignores y high (assumes it to be zero. Also assumes that y > high.
      This does a single precision unsigned divide into a double precision dividend
      that results in a single precision quotient (returned) and
      a single precision remainder(placed in self high).
		Fixed for NT 15-bit Integers - Dan I."
	  ifTrue: [user notify: 'illegal MachineDouble division']
	  ifFalse:
		[high < 64
		  ifTrue:
			[x ← high * 256 + low.
			high ← x \ y.
			↑x / y].
		high < 128
		  ifTrue:
			[x ← (high lshift: 2) + (low lshift: 6) - y.
			high ← x lshift: 2.
			low ← low field: 38 ← x.
			↑(self mdiv: y) + 64].
		x ← (high lshift: 1) + (low lshift: 7) - y.
		high ← x lshift: 1.
		low ← low field: 23 ← x.
		↑(self mdiv: y) + 128]].
"42" MachineDouble$'Access'
[high | |
	↑high].
"40" MachineDouble$'Access'
[low | |
	↑low].
"411" Natural$'As yet unclassified'
[printon: strm base: b | p z n b2 x |
	 "only works if b10"
	p ← Stream default.
	z ← {self length , MachineDouble new}.
	n ← Natural new: super length.
	b2 ← b * b.
	self copyto: n.
	[z  1 = 1 and: [n  1 < b2]] whileFalseDo: 
		[x ← n natdivideandCarry: b2 extra: z.
		p next← x \ b + 48.
		p next← x / b + 48].
	n  1 printon: strm base: b.
	strm append: p contents reverse].
"107" Natural$'As yet unclassified'
[classInit | |
	Naturalzero ← Natural new: 1.
	Naturalzero  1 ← 0.
	↑self].
"1007" Natural$'Arithmetic'
[natsubtract: arg | shorter longer i z sum sl al ng lastdigit |
	sl ← self length "returns an Integer that is created by this operation".
	al ← arg length.
	z ← MachineDouble init.
	sl = al
	  ifTrue:
		[i ← sl.
		[self  i = (arg  i) and: [i > 1]] whileTrueDo: [i ← i - 1].
		sl ← i.
		(self  i unsignedlessthan: arg  i)
		  ifTrue:
			[longer ← arg.
			ng ← true.
			shorter ← self]
		  ifFalse:
			[longer ← self.
			shorter ← arg.
			ng ← false]]
	  ifFalse:
		[sl < al
		  ifTrue:
			[longer ← arg.
			shorter ← self.
			ng ← true.
			sl ← al]
		  ifFalse:
			[longer ← self.
			shorter ← arg.
			ng ← false]].
	sum ← Natural new: longer length.
	lastdigit ← 1.
	(1 to: longer length) do:
		[:i | z increaseby: longer  i.
		z decreaseby: shorter  i.
		sum  i ← z extract  0
		  ifTrue: [lastdigit ← i]].
	lastdigit = longer length
	  ifFalse:
		[z ← Natural new: lastdigit.
		(1 to: lastdigit) do: [:i | z  i ← sum  i].
		sum ← z].
	↑LargeInteger new bytes: sum neg: ng].
"626" Natural$'Arithmetic'
[nattimes: arg | prod z pl carry digit i j k |
	(self length = 1 and: [self  1 = 0])
	  ifTrue: [↑Naturalzero].
	pl ← self length + arg length.
	prod ← Natural new: pl.
	z ← MachineDouble new.
	(1 to: pl) do: [:i | prod  i ← 0].
	(1 to: self length) do:
		[:i | k ← i - 1.
		carry ← 0.
		digit ← self  i.
		digit  0
		  ifTrue:
			[(1 to: arg length) do:
				[:j | z gets: digit mtimes: arg  j.
				z increaseby: carry.
				k ← k + 1.
				z increaseby: prod  k "k=i+j-1".
				prod  k ← z low.
				carry ← z high].
			prod  (k + 1) ← carry]].
	prod  pl = 0
	  ifTrue: [↑prod growby: 1].
	↑prod].
"456" Natural$'Arithmetic'
[natadd: arg | shorter longer i z sum |
	z ← MachineDouble init "returns a Natural number".
	self length < arg length
	  ifTrue:
		[longer ← arg.
		shorter ← self]
	  ifFalse:
		[longer ← self.
		shorter ← arg].
	sum ← Natural new: longer length.
	(1 to: longer length) do:
		[:i | z increaseby: longer  i.
		z increaseby: shorter  i.
		sum  i ← z extract].
	z low  0
	  ifTrue:
		[sum ← sum growby: 1.
		sum last← z low].
	↑sum].
"1664" Natural$'Arithmetic'
[natdiv: arg | quo rem ql d div dh dnh z z2 dl q i j k l carry digit flag |
	l ← self length "returns a vector of (quotient, remainder)" - arg length + 1.
	l  0
	  ifTrue: [↑{Naturalzero , self}].
	d ← 8 - arg last hibit.
	rem ← self natnormalize: d "makes a copy and shifts".
	div ← arg natnormalize: d "shifts so high order word is >127".
	quo ← Natural new: l.
	dl ← div length - 1.
	ql ← l.
	dh ← div  dl.
	dnh ← (dl = 1
			  ifTrue: [0]
			  ifFalse: [div  (dl - 1)]).
	z ← MachineDouble init.
	z2 ← MachineDouble new.
	(1 to: ql) do:
		[:k |  "maintain quo*arg+rem=self"
		j ← rem length + 1 - k.
		z high← rem  j.
		z high = dh
		  ifTrue: [q ← 1]
		  ifFalse:
			[z low← rem  (j - 1).
			q ← z mdiv: dh.
			z low← (j < 3
			  ifTrue: [0]
			  ifFalse: [rem  (j - 2)]).
			z2 gets: q mtimes: dnh.
			flag ← true.
			[z < z2 and: [flag]] whileTrueDo:
				[q ← q unsignedadd: 1.
				z2 decreaseby: dnh.
				z2 high < dh
				  ifTrue: [flag ← false]
				  ifFalse: [z2 high← z2 high - dh]]].
		l ← j - dl.
		z2 init.
		carry ← 0.
		(1 to: div length) do:
			[:i | z gets: q mtimes: div  i.
			z2 increaseby: rem  l.
			z2 decreaseby: carry "subtract q * div from rem".
			z2 decreaseby: z low.
			carry ← z high.
			rem  l ← z2 extract.
			l ← l + 1].
		z2 low = 255
		  ifTrue:
			[q ← q unsignedadd: 1.
			l ← j - dl.
			z init.
			(1 to: div length) do:
				[:i | z increaseby: rem  l.
				z increaseby: div  i.
				rem  l ← z extract.
				l ← l + 1]].
		quo  (quo length + 1 - k) ← q].
	rem ← rem natunnormalize: d lookfirst: dl.
	quo last = 0
	  ifTrue:
		[ql < 2
		  ifFalse: [quo ← quo growby: 1]].
	↑{quo , rem}].
"53" Natural$'As yet unclassified'
[isLarge | |
	↑false].
"55" Natural$'As yet unclassified'
[species | |
	↑Natural].
"130" Natural$'As yet unclassified'
[asInteger | |
	self length = 1
	  ifTrue: [↑self  1].
	↑LargeInteger new bytes: self neg: false].
"315" LargeInteger$'As yet unclassified'
[bits: left to: right | width mask |
	 "  0 is leftmost bit, 15 is rightmost"
	width ← right - left + 1.
	mask ← (width < 15
			  ifTrue: [biton  (width + 1) - 1]
			  ifFalse:
				[width = 15
				  ifTrue: [32767]
				  ifFalse: [1]]).
	↑(self lshift: right - 15) land: mask].
"333" LargeInteger$'As yet unclassified'
[logicArg | b a i |
	 "convert to two byte twos complement number"
	neg
	  ifTrue:
		[b ← Natural new: 2.
		b  1 ← (a ← (bytes  1 lxor: 255) + 1) land: 255.
		a ← a lshift: 8.
		b  2 ← (bytes  2 lxor: 255) + a land: 255.
		↑LargeInteger new bytes: b neg: false] "if positive, just leave it"].
"43" LargeInteger$'Access'
[bytes | |
	↑bytes].
"334" LargeInteger$'Arithmetic'
[+ arg | as r |
	as ← arg neg "take care of sign. Arithmetic is done in Natural numbers. 
			if arg is Small, it behaves as a LargeInteger.".
	neg  as
	  ifTrue:
		[r ← bytes natadd: arg bytes.
		↑LargeInteger new bytes: r neg: neg].
	r ← bytes natsubtract: arg bytes.
	neg
	  ifTrue: [↑r negate].
	.
	↑r].
"92" LargeInteger$'Arithmetic'
[> arg | |
	(self compare: arg) = 3
	  ifTrue: [↑self].
	↑false].
"92" LargeInteger$'Arithmetic'
[< arg | |
	(self compare: arg) = 1
	  ifTrue: [↑self].
	↑false].
"364" LargeInteger$'Arithmetic'
[- arg | as r |
	as ← arg neg "take care of sign. Arithmetic is done in Natural numbers. 
			if arg is Small, it behaves as a LargeInteger.".
	neg  as
	  ifTrue:
		[r ← bytes natsubtract: arg bytes.
		neg
		  ifTrue: [↑r neg← r neg  false].
		.
		↑r]
	  ifFalse:
		[r ← bytes natadd: arg bytes.
		↑LargeInteger new bytes: r neg: neg]].
"143" LargeInteger$'Arithmetic'
[= arg | |
	arg isNumber
	  ifTrue:
		[(self compare: arg) = 2
		  ifTrue: [↑self].
		↑false]
	  ifFalse: [↑false]].
"92" LargeInteger$'Arithmetic'
[ arg | |
	(self compare: arg) < 3
	  ifTrue: [↑self].
	↑false].
"92" LargeInteger$'Arithmetic'
[ arg | |
	(self compare: arg) > 1
	  ifTrue: [↑self].
	↑false].
"557" LargeInteger$'Bit Manipulation'
[lshift: n | a c s1 s2 h |
	NoteTaker
	  ifTrue:
		[a ← self logicArg.
		c ← Natural new: 2.
		c  1 ← a bytes  1.
		c  2 ← a bytes  2.
		a bytes: c neg: false.
		(h ← n abs)  16
		  ifTrue: [↑0].
		s1 ← h / 2.
		s2 ← h - s1.
		s1 ← 1 lshift: s1.
		s2 ← 1 lshift: s2.
		h ← s1 asLarge * s2 asLarge.
		a ← (n < 0
				  ifTrue: [a / h]
				  ifFalse: [a * h]).
		c ← Natural new: 2.
		c  1 ← a bytes  1.
		c  2 ← a bytes  2.
		↑(LargeInteger new bytes: c neg: false) logicUnArg]
	  ifFalse: [↑self asSmall lshift: n]].
"252" LargeInteger$'Arithmetic'
[* arg | as r |
	as ← arg neg "take care of sign. Arithmetic is done in Natural numbers. 
			if arg is Small, it behaves as a LargeInteger.".
	r ← bytes nattimes: arg bytes.
	↑LargeInteger new bytes: r neg: neg  as  false].
"76" LargeInteger$'Arithmetic'
[/ arg | |
	↑((self intdiv: arg)  1) asInteger].
"118" LargeInteger$'Printing'
[printon: strm base: b | |
	neg
	  ifTrue: [strm append: ''].
	bytes printon: strm base: b].
"64" LargeInteger$'Arithmetic'
[\ arg | |
	↑(self intdiv: arg)  2].
"418" LargeInteger$'Arithmetic'
[intdiv: arg | quo rem ng qr z |
	qr ← bytes natdiv: arg bytes "returns a vector of (quotient, remainder)".
	quo ← qr  1.
	rem ← (qr  2) asInteger.
	ng ← neg  arg neg  false.
	quo last = 0
	  ifTrue:
		[quo length < 2
		  ifFalse: [quo ← quo growby: 1]].
	qr  1 ← LargeInteger new bytes: quo neg: ng.
	qr  2 ← ((ng and: [0  rem])
	  ifTrue: [arg abs - rem]
	  ifFalse: [rem]).
	↑qr].
"78" LargeInteger$'Access'
[neg← t1 | |
	 "Smashes sign - be careful!"
	neg ← t1].
"57" LargeInteger$'Bit Manipulation'
[hash | |
	↑bytes hash].
"39" LargeInteger$'Access'
[neg | |
	↑neg].
"152" LargeInteger$'Arithmetic'
[abs | |
	 "Return the positive magnitude (absolute value) of this LargeInteger"
	↑LargeInteger new bytes: bytes neg: false].
"43" LargeInteger$'Conversion'
[asLarge | |
	].
"102" LargeInteger$'Conversion'
[asFloat | |
	 "Built for comfort, not for speed"
	↑self asString asFloat].
"315" LargeInteger$'Arithmetic'
[compare: arg | i a |
	(((bytes length = 1 and: [bytes  1 = 0]) and: [arg bytes length = 1]) and: [arg bytes  1 = 0])
	  ifTrue: [↑2].
	neg
	  ifTrue:
		[arg neg
		  ifTrue: [↑arg bytes natcompare: bytes].
		↑1]
	  ifFalse:
		[arg neg
		  ifTrue: [↑3].
		↑bytes natcompare: arg bytes]].
"123" LargeInteger$'Access'
[bytes: t1 neg: t2 | |
	bytes ← t1.
	neg ← t2.
	[bytes isLarge] whileTrueDo: [bytes ← bytes bytes]].
"64" LargeInteger$'Arithmetic'
[even | |
	↑(bytes  1 land: 1) = 0].
"377" LargeInteger$'As yet unclassified'
[bits: left to: right ← val | width mask |
	 "  0 is leftmost bit, 15 is rightmost"
	width ← right - left + 1.
	mask ← (width < 15
			  ifTrue: [biton  (width + 1) - 1]
			  ifFalse:
				[width = 15
				  ifTrue: [32767]
				  ifFalse: [1]]).
	↑(self land: ((mask lshift: 15 - right) lxor: 1)) lor: ((val land: mask) lshift: 15 - right)].
"219" LargeInteger$'Conversion'
[canBeSmall | i |
	bytes length > 2
	  ifTrue: [(3 to: bytes length) do:
			[:i | bytes  i  0
			  ifTrue: [↑false]]].
	(self  1 maxVal and: [self  1 minVal])
	  ifTrue: [↑true].
	↑false].
"319" LargeInteger$'As yet unclassified'
[lor: n | a b c |
	 "simulated 16 bit logic"
	NoteTaker
	  ifTrue:
		[a ← self logicArg bytes.
		b ← n asLarge logicArg bytes.
		c ← Natural new: 2.
		c  1 ← a  1 lor: b  1.
		c  2 ← a  2 lor: b  2.
		↑(LargeInteger new bytes: c neg: false) logicUnArg].
	↑self asSmall lor: n].
"241" LargeInteger$'As yet unclassified'
[logicUnArg | |
	 "convert 2's complement to signed"
	bytes length  2
	  ifTrue: [user notify: 'not logic arg']
	  ifFalse:
		[bytes  2  128
		  ifTrue: [↑(self - 65536) asInteger].
		↑self asInteger]].
"232" LargeInteger$'Access'
[bit: index | byte |
	 "Return bit number i in the binary representation of this number. Bit number 1 is the low order bit"
	byte ← bytes  (1 + (index - 1 / 8)).
	↑(byte lshift: 0 - (index - 1 \ 8)) land: 1].
"180" LargeInteger$'Bit Manipulation'
[field: spec | right |
	 "spec=width*16 + right (15=left, 0=right)"
	right ← 15 - (spec land: 15).
	↑self bits: right - (spec / 16) + 1 to: right].
"89" LargeInteger$'Arithmetic'
[negate | |
	↑LargeInteger new bytes: bytes neg: neg  false].
"194" LargeInteger$'Bit Manipulation'
[field: spec ← val | right |
	 "spec=width*16 + right (15=left, 0=right)"
	right ← 15 - (spec land: 15).
	↑self bits: (right - (spec / 16) + 1) to: right ← val].
"397" LargeInteger$'Conversion'
[asObject | |
	NoteTaker
	  ifTrue:
		[self canBeSmall
		  ifTrue: [↑self asSmall asObject].
		self < 49152
		  ifTrue:
			[self < 32768
			  ifTrue: [self error: 'invalid oop']
			  ifFalse: [↑(self - 32768) asSmall]]
		  ifFalse:
			[self  65536
			  ifTrue: [self error: 'invalid oop']
			  ifFalse: [↑(self - 65536) asSmall]]]
	  ifFalse: [↑self asSmall asObject]].
"330" LargeInteger$'Conversion'
[asSmall | t u |
	 "Truncate high bits to make small integer."
	t ← bytes  1.
	bytes length > 1
	  ifTrue:
		[u ← bytes  2.
		t ← ((NoteTaker
				  ifTrue: [(u land: 63) - (u land: 64)]
				  ifFalse: [u]) lshift: 8) + t].
	neg
	  ifTrue:
		[t = 0 minVal
		  ifTrue: [↑t].
		↑0 - t]
	  ifFalse: [↑t]].
"70" LargeInteger$'Bit Manipulation'
[nomask: b | |
	↑0 = (self land: b)].
"71" LargeInteger$'Bit Manipulation'
[allmask: b | |
	↑b = (self land: b)].
"43" LargeInteger$'Conversion'
[isLarge | |
	].
"71" LargeInteger$'Bit Manipulation'
[anymask: b | |
	↑0  (self land: b)].
"90" LargeInteger$'Arithmetic'
[negated | |
	↑LargeInteger new bytes: bytes neg: neg  false].
"320" LargeInteger$'Bit Manipulation'
[land: n | a b c |
	 "simulated 16 bit logic"
	NoteTaker
	  ifTrue:
		[a ← self logicArg bytes.
		b ← n asLarge logicArg bytes.
		c ← Natural new: 2.
		c  1 ← a  1 land: b  1.
		c  2 ← a  2 land: b  2.
		↑(LargeInteger new bytes: c neg: false) logicUnArg].
	↑self asSmall land: n].
"168" LargeInteger$'Access'
[hibit | |
	 "Return the index of the high order bit of the binary representation of this number"
	↑bytes last hibit + (8 * (bytes length - 1))].
"323" LargeInteger$'As yet unclassified'
[lxor: n | a b c |
	 "simulated 16 bit logic"
	NoteTaker
	  ifTrue:
		[a ← self logicArg bytes.
		b ← n asLarge logicArg bytes.
		c ← Natural new: 2.
		c  1 ← a  1 lxor: b  1.
		c  2 ← a  2 lxor: b  2.
		↑(LargeInteger new bytes: c neg: false) logicUnArg].
	↑self asSmall lxor: n].
"95" LargeInteger$'Conversion'
[asInteger | |
	self canBeSmall
	  ifTrue: [↑self asSmall].
	↑self].
"250" LargeInteger$'As yet unclassified'
[inFourBytes | four i |
	bytes length > 4
	  ifTrue: [user notify: 'wont fit in 4 bytes']
	  ifFalse:
		[four ← String new: 4.
		four all← 0.
		(1 to: bytes length) do: [:i | four  (5 - i) ← bytes  i].
		↑four]].
"57" Message$'As yet unclassified'
[selector | |
	↑selector].
"220" Message$'As yet unclassified'
[selector: sel args: vec | i |
	self length  vec length
	  ifTrue: [user notify: '# args doesnt match']
	  ifFalse:
		[selector ← sel.
		(1 to: vec length) do: [:i | self  i ← vec  i]]].
"145" Message$'As yet unclassified'
[selector: sel | |
	self length  0
	  ifTrue: [user notify: '# args doesnt match']
	  ifFalse: [selector ← sel]].
"174" Message$'As yet unclassified'
[selector: sel arg: arg | |
	self length  1
	  ifTrue: [user notify: '# args doesnt match']
	  ifFalse:
		[selector ← sel.
		self  1 ← arg]].
"59" CompiledMethod$'Header'
[flags | |
	↑self  3 lshift: 5].
"99" CompiledMethod$'Header'
[initialPC | |
	self isQuick
	  ifTrue: [↑0].
	↑self numLiterals * 2 + 5].
"96" CompiledMethod$'Header'
[frameSize | |
	self  4 < 128
	  ifTrue: [↑smallFrame].
	↑largeFrame].
"73" CompiledMethod$'Association'
[key: key | |
	↑self objectAt: 1 put: key].
"98" CompiledMethod$'Header'
[numLiterals | |
	self isQuick
	  ifTrue: [↑0].
	↑self  4 / 2 land: 63].
"146" CompiledMethod$'Header'
[isReturnField | |
	 "Return field # if code is quick, else false"
	self flags = 6
	  ifTrue: [↑self numTemps].
	↑false].
"100" CompiledMethod$'Header'
[isReturnSelf | |
	 "Return true if code is quick self"
	↑self flags = 5].
"188" CompiledMethod$'Header'
[primitive | |
	self flags < 7
	  ifTrue: [↑0].
	 "no prim, or quick prim"
	↑(self literalAt: self numLiterals - 1) land: 255 "Prim # is in next-to-last literal"].
"49" CompiledMethod$'Association'
[value | |
	↑self].
"131" CompiledMethod$'Header'
[isQuick | |
	 "Return non-false iff quick primitive (self or field)"
	↑self flags between: 5 and: [6]].
"59" CompiledMethod$'Association'
[key | |
	↑self objectAt: 1].
"69" CompiledMethod$'Literals'
[literalAt: i | |
	↑self objectAt: i + 2].
"87" CompiledMethod$'Literals'
[literalAt: i put: val | |
	↑self objectAt: i + 2 put: val].
"119" CompiledMethod$'Header'
[endPC | |
	(self last between: 120 and: [124])
	  ifTrue: [↑self length].
	↑self length - 3].
"179" CompiledMethod$'Header'
[numArgs | t1 |
	(t1 ← self flags)  4
	  ifTrue: [↑self flags].
	t1 < 7
	  ifTrue: [↑0].
	↑((self literalAt: self numLiterals - 1) lshift: 8) land: 31].
"134" CompiledMethod$'Literals'
[objectAt: i | |<primitive: 73>
	NoteTaker
	  ifTrue: [user croak]
	  ifFalse: [↑(self word: i) asObject]].
"144" CompiledMethod$'Literals'
[objectAt: i put: val | |<primitive: 74>
	NoteTaker
	  ifTrue: [user croak]
	  ifFalse: [↑self word: i ← val asOop]].
"1973" CompiledMethod$'Initialization'
[classInit | |
	 "CompiledMethod classInit."
	smallFrame ← 12.
	largeFrame ← 32 "Context range for temps+stack".
	byteNames ← #('in0' 'in1' 'in2' 'in3' 'in4' 'in5' 'in6' 'in7' 'in8' 'in9' 'in10' 'in11' 'in12' 'in13' 'in14' 'in15' 'tp0' 'tp1' 'tp2' 'tp3' 'tp4' 'tp5' 'tp6' 'tp7' 'tp8' 'tp9' 'tp10' 'tp11' 'tp12' 'tp13' 'tp14' 'tp15' 'lt0' 'lt1' 'lt2' 'lt3' 'lt4' 'lt5' 'lt6' 'lt7' 'lt8' 'lt9' 'lt10' 'lt11' 'lt12' 'lt13' 'lt14' 'lt15' 'lt16' 'lt17' 'lt18' 'lt19' 'lt20' 'lt21' 'lt22' 'lt23' 'lt24' 'lt25' 'lt26' 'lt27' 'lt28' 'lt29' 'lt30' 'lt31' 'gl0' 'gl1' 'gl2' 'gl3' 'gl4' 'gl5' 'gl6' 'gl7' 'gl8' 'gl9' 'gl10' 'gl11' 'gl12' 'gl13' 'gl14' 'gl15' 'gl16' 'gl17' 'gl18' 'gl19' 'gl20' 'gl21' 'gl22' 'gl23' 'gl24' 'gl25' 'gl26' 'gl27' 'gl28' 'gl29' 'gl30' 'gl31' 'si0' 'si1' 'si2' 'si3' 'si4' 'si5' 'si6' 'si7' 'st0' 'st1' 'st2' 'st3' 'st4' 'st5' 'st6' 'st7' 'self' 'true' 'false' 'nil' 'cNeg1' 'c0' 'c1' 'c2' 'retSelf' 'retTrue' 'retFalse' 'retNil' 'ret' 'blockRet' 'bad' 'bad' 'xLoad1' 'xSto' 'xPopSto' 'xSend' 'xxSend' 'xSuper' 'xxSuper' 'pop' 'dup' 'current' 'bad' 'bad' 'bad' 'bad' 'bad' 'bad' 'j1' 'j2' 'j3' 'j4' 'j5' 'j6' 'j7' 'j8' 'b1' 'b2' 'b3' 'b4' 'b5' 'b6' 'b7' 'b8' 'jB' 'jB' 'jB' 'jB' 'jF' 'jF' 'jF' 'jF' 'bT' 'bT' 'bT' 'bT' 'bF' 'bF' 'bF' 'bF' 'sPlus' 'sMinus' 'sLss' 'sGtr' 'sLeq' 'sGeq' 'sEqu' 'sNeq' 'sTimes' 'sOver' 'sRem' 'sMakePt' 'sLshift' 'sLxor' 'sLand' 'sLor' 'sSub' 'sSubGets' 'sLength' 'sNext' 'sNextGets' 'sEnd' 'sEq' 'sClass' 'sBCopy' 'sValue' 'sValue:' 'bad' 'sNew' 'sNew:' 'sX' 'sY' 's0.0' 's0.1' 's0.2' 's0.3' 's0.4' 's0.5' 's0.6' 's0.7' 's0.8' 's0.9' 's0.10' 's0.11' 's0.12' 's0.13' 's0.14' 's0.15' 's1.0' 's1.1' 's1.2' 's1.3' 's1.4' 's1.5' 's1.6' 's1.7' 's1.8' 's1.9' 's1.10' 's1.11' 's1.12' 's1.13' 's1.14' 's1.15' 's2.0' 's2.1' 's2.2' 's2.3' 's2.4' 's2.5' 's2.6' 's2.7' 's2.8' 's2.9' 's2.10' 's2.11' 's2.12' 's2.13' 's2.14' 's2.15' ).
	byteNames length  256
	  ifTrue: [user notify: 'not 256 byte codes']].
"492" CompiledMethod$'Source Code'
[setSourcePosition: pos inFile: f | loc p1 |
	 "set last three bytes to be pos in file (0-3)"
	f > 3
	  ifTrue: [user notify: 'invalid file number']
	  ifFalse:
		[loc ← self length - 2.
		self  (loc + 2) ← f * 64 + (p1 ← pos / 65536).
		p1 > 62
		  ifTrue:
			[user show: 'Source file is getting full!!'.
			user cr].
		pos ← pos - (p1 * 65536) "into two bytes".
		self  (loc + 1) ← p1 ← pos / 256.
		pos ← pos land: 255 "into one byte".
		self  loc ← pos]].
"154" CompiledMethod$'Literals'
[literals | lit |
	 "Return vector of literals"
	↑1 ~ self numLiterals transform [:lit | lit] to [(self objectAt: lit + 2)]].
"141" CompiledMethod$'Header'
[numStack | |
	self isQuick
	  ifTrue: [↑0].
	 "self or instvar"
	↑self frameSize - self numTemps - self numArgs].
"93" CompiledMethod$'Header'
[numTemps | t |
	self isQuick
	  ifTrue: [↑0].
	↑self  3 land: 31].
"56" CompiledMethod$'Association'
[selector | |
	↑self key].
"1632" CompiledMethod$'ByteCodes'
[symbolic | s d byte i nlits |
	self isQuick
	  ifTrue:
		[self isReturnSelf
		  ifTrue: [↑'quick ↑self'].
		↑'quick ↑field: ' + self isReturnField asString]
	  ifFalse:
		[d ← Stream default.
		d cr.
		d append: ' numArgs: '.
		d print: self numArgs.
		d cr.
		d append: ' numTemps: '.
		d print: self numTemps.
		d cr.
		d append: ' numLiterals: '.
		d print: (nlits ← self numLiterals).
		d cr.
		self frameSize > smallFrame
		  ifTrue:
			[d append: 'large frame'.
			d cr].
		self primitive > 0
		  ifTrue:
			[d append: 'primitive: '.
			d print: self primitive.
			d cr].
		d print: self literals.
		d cr.
		s ← Stream new of: self from: self initialPC to: self endPC.
		s do:
			[:byte | d append: byteNames  (byte + 1).
			d append: '('.
			d append: byte base8.
			d append: ')'.
			d space.
			byte < 128
			  ifFalse:
				[byte  176
				  ifFalse:
					[byte  130
					  ifTrue:
						[ "long loads, stores"
						i ← s next.
						d append: #('inst' 'temp' 'lit' 'glob' )  (i / 64 + 1).
						d print: i \ 64.
						d space]
					  ifFalse:
						[byte  134
						  ifTrue:
							[ "long sends"
							byte even  false
							  ifTrue:
								[i ← s next.
								d append: '('.
								d print: i / 32.
								d append: ')'.
								d print: i \ 32.
								d space]
							  ifFalse:
								[d append: '('.
								d print: s next.
								d append: ')'.
								d print: s next.
								d space]]
						  ifFalse:
							[(160  byte and: [byte  175])
							  ifTrue:
								[ "long jumps"
								d print: byte \ 8 - 4 * 256 + s next.
								d space]]]]]].
		↑d contents]].
"99" Interval$'Reading and Writing'
[ x ← val | |
	user notify: 'Intervals are not for writing into'].
"176" Interval$'Reading and Writing'
[ x | |
	(x is: Integer)
	  ifTrue:
		[x < 1
		  ifFalse:
			[x > length
			  ifFalse: [↑start + (step * (x - 1))]]]
	  ifFalse: [↑super  x]].
"54" Interval$'Reading and Writing'
[length | |
	↑length].
"144" Interval$'Compatibility'
[cansubscript: a | |
	↑length  0 or: [((start cansubscript: a) and: [(length - 1 * step + start cansubscript: a)])]].
"50" Interval$'Reading and Writing'
[stop | |
	↑stop].
"110" Interval$'Compatibility'
[= int | |
	↑start = int start and: [(stop = int stop and: [length = int length])]].
"95" Interval$'Compatibility'
[hash | |
	↑(((start lshift: 2) lxor: stop) lshift: 1) lxor: length].
"72" Interval$'Random Numbers'
[randomInit | |
	self randomInit: mem  280].
"247" Interval$'Initialization'
[from: t1 to: t2 by: t3 | |
	start ← t1.
	stop ← t2.
	step ← t3.
	length ← 1 + (stop - start / step).
	step < 0
	  ifTrue:
		[start < stop
		  ifTrue: [length ← 0]]
	  ifFalse:
		[stop < start
		  ifTrue: [length ← 0]]].
"57" Interval$'Compatibility'
[isIntervalBy1 | |
	↑step = 1].
"212" Interval$'Random Numbers'
[randomInit: x | |
	 "Call with const to get repeatable sequence"
	step ← x "step holds the current state".
	(start is: Float)
	  ifTrue: [length ← stop - start] "for Float intervals"].
"289" Interval$'Random Numbers'
[random | |
	 "See Lehmers linear congruential method, Knuth Vol. 1:
	modulus m=2↑16
	a=27181 odd, and 5 = a mod 8
	c=13849 odd, and c/m around 0.21132"
	step ← (13849 + (27181 * step)) asInt16.
	↑(start + (length asFloat * (32768.0 + step) / 65536.0)) asSmall].
"52" Interval$'Reading and Writing'
[start | |
	↑start].
"74" Substring$'Reading and Writing'
[ x ← val | |
	↑data  (map  x) ← val].
"62" Substring$'Reading and Writing'
[ x | |
	↑data  (map  x)].
"208" Substring$'Conversion'
[asStream | |
	map isIntervalBy1
	  ifTrue: [ "direct stream for simple substrings"
		↑Stream new of: data from: map start to: map stop].
	↑Stream new of: self from: 1 to: map length].
"59" Substring$'Reading and Writing'
[length | |
	↑map length].
"170" Substring$'Copying and Altering'
[swap: i with: j | t |
	t ← map  i "By permuting my map (a writable Array), swap elements i and j.".
	map  i ← map  j.
	map  j ← t].
"56" Substring$'Compatability'
[species | |
	↑data species].
"73" Substring$'Initialization'
[data: t1 map: t2 | |
	data ← t1.
	map ← t2].
"66" Substring$'Reading and Writing'
[map | |
	↑map "Return my map."].
"84" BitRect$'Rectangle Protocol'
[height← h | |
	self growby: 0  (h - self extent y)].
"71" BitRect$'Rectangle Protocol'
[corner← x | |
	self growby: x - corner].
"76" BitRect$'Rectangle Protocol'
[extent← x | |
	self growby: x - self extent].
"132" BitRect$'Showing'
[show | strips i |
	strips ← self strips.
	(1 to: strips length) do: [:i | strips  i bitsFromString: data  i]].
"51" BitRect$'Rectangle Protocol'
[= x | |
	↑self  x].
"160" BitRect$'Initialization'
[origin: t1 corner: t2 title: t3 stripheight: t4 data: t5 | |
	origin ← t1.
	corner ← t2.
	title ← t3.
	stripheight ← t4.
	data ← t5].
"45" BitRect$'Access to parts'
[data | |
	↑data].
"76" BitRect$'Rectangle Protocol'
[printon: strm | |
	strm append: 'a BitRect'].
"60" BitRect$'Initialization'
[default | |
	↑defaultpic recopy].
"233" BitRect$'Rectangle Protocol'
[growby: change | old |
	old ← BitRect new origin: origin corner: corner title: title stripheight: stripheight data: data.
	self title: title in: (origin rect: corner + change).
	self copyBitsFrom: old].
"54" BitRect$'Press'
[length | |
	↑self bitmapLength * 2].
"74" BitRectEditor$'Window protocol'
[redbug | |
	dirty ← true.
	tool redbug].
"139" RadioButtons$'Pushing a Button'
[setvalue: v | i |
	i ← (vec find: v) "if value has been lost, set self to 1" max: 1.
	self push: i.
	↑i].
"139" RadioButtons$'Init and State'
[vec: t1 at: r height: t3 | |
	vec ← t1.
	size ← t3.
	rect ← r rect: r + (vec length  1 * size).
	cur ← 0].
"138" RadioButtons$'Init and State'
[vec: t1 at: r width: t3 | |
	vec ← t1.
	size ← t3.
	rect ← r rect: r + (1  vec length * size).
	cur ← 0].
"126" RadioButtons$'Pushing a Button'
[bug: pt | r a |
	r ← pt - rect origin - (1  1) / size.
	a ← r x + r y + 1.
	↑self push: a].
"108" RadioButtons$'Init and State'
[moveto: pt | |
	rect moveto: pt.
	cur ← 0.
	↑rect corner x  rect origin y].
"55" RadioButtons$'Init and State'
[value | |
	↑vec  cur].
"52" RadioButtons$'Init and State'
[reset | |
	cur ← 0].
"60" RadioButtons$'Init and State'
[has: pt | |
	↑rect has: pt].
"47" RadioButtons$'Init and State'
[vec | |
	↑vec].
"97" RadioButtons$'Pushing a Button'
[push: a | |
	self release: cur thenPush: a.
	↑vec  (cur ← a)].
"492" RadioButtons$'Private'
[release: a thenPush: b | boxer offset |
	a = b
	  ifFalse:
		[offset ← (size = rect extent y
				  ifTrue: [size  0]
				  ifFalse: [0  size]).
		a  0
		  ifTrue:
			[boxer ← Rectangle new origin: offset * (a - 1) + rect origin + 1 extent: size  size - 1.
			boxer comp.
			(boxer inset: 1  1) comp].
		b  0
		  ifTrue:
			[boxer ← Rectangle new origin: offset * (b - 1) + rect origin + 1 extent: size  size - 1.
			boxer comp.
			(boxer inset: 1  1) comp]]].
"1623" BitRectTool$'Tool action'
[brush: sourceRect | minpt maxpt pt offset |
	 "use the bits in the BitRect sourceRect as a brush"
	sourceRect moveto: brushpt "The inner painting loop should be fast - all the extra foliage below
		is to move tests outside of the inner loop".
	sourceRect show.
	minpt ← self frame origin.
	maxpt ← self frame corner - sourceRect extent.
	offset ← sourceRect extent / 2 "If mode is storing or oring, use brush command, otherwise blt.
		Use the unclipped form of brushing  and grid=1 when possible".
	(mode < xoring and: [grid = 1])
	  ifTrue: [[user redbug] whileTrueDo:
			[(minpt  (pt ← user mp - offset) and: [pt  maxpt])
			  ifTrue: [sourceRect brush: pt mode: mode color: tone]
			  ifFalse: [sourceRect brush: pt mode: mode color: tone clippedBy: self frame]]]
	  ifFalse:
		[(mode  xoring and: [grid = 1])
		  ifTrue: [[user redbug] whileTrueDo:
				[(minpt  (pt ← user mp - offset) and: [pt  maxpt])
				  ifTrue: [sourceRect blt: pt mode: mode]
				  ifFalse: [sourceRect blt: pt mode: mode clippedBy: self frame]]]
		  ifFalse:
			[mode < xoring
			  ifTrue: [ "grid is > 1"
				[user redbug] whileTrueDo:
					[(minpt  (pt ← self mpOnGrid - offset) and: [pt  maxpt])
					  ifTrue: [sourceRect brush: pt mode: mode color: tone]
					  ifFalse: [sourceRect brush: pt mode: mode color: tone clippedBy: self frame]]]
			  ifFalse: [ "grid is > 1 and modexoring"
				[user redbug] whileTrueDo:
					[(minpt  (pt ← self mpOnGrid - offset) and: [pt  maxpt])
					  ifTrue: [sourceRect blt: pt mode: mode]
					  ifFalse: [sourceRect blt: pt mode: mode clippedBy: self frame]]]]]].
"62" BitRectTool$'Tool action'
[redbug | |
	self perform: action].
"47" BitRectTool$'Tool action'
[brush | |
	↑brush].
"316" BitRectTool$'Tool action'
[setbrush | rect |
	rect ← self getRectangle.
	(rect empty or: [50  50 < rect extent])
	  ifTrue: [pencil frame flash]
	  ifFalse:
		[.
		brush color: white mode: storing.
		brush title: 'brush' in: rect.
		brush saveScreenBits.
		brush moveto: brushpt.
		brush show.
		action ← #paint]].
"121" BitRectTool$'Tool selection'
[brushpt: pt | |
	 "set the point at which the current brush will be shown"
	brushpt ← pt].
"111" BitRectTool$'Tool action'
[mpOnGrid | |
	 "return mouse point rounded to grid"
	↑user mp + (grid / 2) | grid].
"542" BitRectTool$'Tool selection'
[setfrom: butvec | pt |
	(butvec  1 has: (pt ← user mp))
	  ifTrue: [action ← butvec  1 bug: pt]
	  ifFalse:
		[(butvec  2 has: pt)
		  ifTrue:
			[tone ← butvec  2 bug: pt.
			tone = white
			  ifTrue: [pencil white]
			  ifFalse: [pencil black]]
		  ifFalse:
			[(butvec  3 has: pt)
			  ifTrue: [mode ← butvec  3 bug: pt]
			  ifFalse:
				[(butvec  4 has: pt)
				  ifTrue: [pencil width: (butvec  4 bug: pt)]
				  ifFalse:
					[(butvec  5 has: pt)
					  ifTrue: [grid ← butvec  5 bug: pt]]]]]].
"81" BitRectTool$'Tool action'
[block | |
	self getRectangle color: tone mode: mode].
"57" BitRectTool$'Tool selection'
[frame | |
	↑pencil frame].
"58" BitRectTool$'Tool action'
[paint | |
	self brush: brush].
"45" BitRectTool$'Tool action'
[tone | |
	↑tone].
"813" BitRectTool$'Tool action'
[shade | p1 p2 a b t p r vs |
	 "down on redbug is black place.
	up on redbug is white place.  Subsequent redbugs
	paint a shade of gray depending on position between
	black and white (and beyond white to black again).
	Yellow or blue bug terminates."
	[user redbug] whileFalseDo:  [p1 ← user mp "black"].
	[user nobug] whileFalseDo:  [p2 ← user mp "white"].
	vs ← #(1 1025 1089 585 4681 6731 22058 27031 26986 31191 32108 5160 5128 8321 1025 1 0 ).
	r ← 0  0 rect: 10  10.
	b ← p1 - p2.
	b ← b x asFloat  b y asFloat.
	a ← b x * b x + (b y * b y) / 16.0.
	[user yellowbug or: [user bluebug]] whileFalseDo: 
		[user redbug
		  ifTrue:
			[p ← user mp.
			t ← b * (p - p2).
			t ← (t x + t y / a) asInteger abs min: 16.
			brush brush: p mode: mode color: vs  (17 - t)]]].
"62" BitRectTool$'Tool selection'
[frame: f | |
	pencil frame: f].
"45" BitRectTool$'Tool action'
[mode | |
	↑mode].
"428" BitRectTool$'Class initialization'
[classInit | rect saveBits t i |
	blowupScale ← 4 "make a vector of gray pens".
	rect ← 0  0 rect: 9  9.
	saveBits ← rect bitsIntoString.
	t ← Turtle init.
	graypens ← Vector new: 8.
	(1 to: 8) do:
		[:i | t width: i.
		rect clear: white.
		t place: 4  4.
		t go: 0.
		graypens  i ← BitRect new title: 'graypen' in: rect.
		(graypens  i) saveScreenBits].
	rect bitsFromString: saveBits].
"234" BitRectTool$'Class initialization'
[init | |
	(pencil ← Turtle new) init.
	pencil color: black.
	pencil width: 2.
	(brush ← BitRect new) title: 'brush' in: (0  0 rect: 16  16).
	tone ← black.
	mode ← 0.
	grid ← 1.
	action ← #draw].
"600" BitRectTool$'Tool action'
[getRectangle | rect newrect start t |
	 "rect must be in my frame"
	start ← self mpOnGrid "the rect-newrect stuff is so that the complementing stays
		on for a while".
	rect ← newrect ← (Rectangle new origin: start corner: start) intersect: self frame "move the cursor slightly so that the user will notice the rectangle
		being complemented".
	user cursorloc← start + 4.
	[user anybug] whileTrueDo:
		[rect ← newrect.
		rect comp.
		t ← self mpOnGrid.
		newrect ← (Rectangle new origin: (start min: t) corner: (start max: t)) intersect: self frame.
		rect comp].
	↑rect].
"1060" BitRectTool$'Tool action'
[blowup: smallRect to: bigRectFrame | bigRect box pt i turt flag bits |
	bits ← bigRectFrame bitsIntoString.
	bigRect ← bigRectFrame inset: 2  2.
	smallRect blowup: bigRect origin by: blowupScale.
	turt ← Turtle init.
	box ← 0  0 rect: blowupScale - 1  (blowupScale - 1) "keep editing in blowup mode until the user presses a button
		outside the big rect".
	[flag] whileTrueDo:
		[(bigRect has: (pt ← user mp))
		  ifTrue:
			[box moveto: bigRect origin + (i ← pt - bigRect origin | blowupScale).
			turt place: smallRect origin + (i / blowupScale).
			user redbug
			  ifTrue:
				[box color: black mode: storing.
				turt black.
				turt go: 0]
			  ifFalse:
				[user yellowbug
				  ifTrue:
					[box color: white mode: storing.
					turt white.
					turt go: 0]
				  ifFalse:
					[user bluebug
					  ifTrue: [bigRect flash]]]]
		  ifFalse:
			[user anybug
			  ifTrue:
				[((bigRect inset: 5  5) has: pt)
				  ifTrue: [bigRect flash]
				  ifFalse: [ "quit"
					flag ← false]]]].
	bigRectFrame bitsFromString: bits].
"200" BitRectTool$'Tool selection'
[showon: butvec | |
	butvec  1 setvalue: action.
	butvec  2 setvalue: tone.
	butvec  3 setvalue: mode.
	butvec  4 setvalue: pencil width.
	butvec  5 setvalue: grid].
"415" BitRectTool$'Tool action'
[draw | |
	(tone = white or: [tone = black])
	  ifTrue:
		[pencil place: self mpOnGrid - pencil frame origin.
		grid = 1
		  ifTrue: [ "make drawing with grid 1 fast"
			[user redbug] whileTrueDo: [pencil goto: user mp - pencil frame origin]]
		  ifFalse: [[user redbug] whileTrueDo: [pencil goto: self mpOnGrid - pencil frame origin]]]
	  ifFalse: [self brush: graypens  pencil width]].
"465" BitRectTool$'Tool action'
[line | start end width |
	start ← end ← self mpOnGrid - pencil frame origin.
	width ← pencil width.
	pencil xor.
	pencil width: 1.
	[user redbug] whileTrueDo:
		[end ← self mpOnGrid - pencil frame origin.
		pencil xor.
		pencil place: start.
		pencil goto: end.
		pencil place: start.
		pencil goto: end].
	tone = white
	  ifTrue: [pencil white]
	  ifFalse: [pencil black].
	pencil width: width.
	pencil place: start.
	pencil goto: end].
"605" BitRectTool$'Tool action'
[blowup | smallRect bigRectFrame |
	smallRect ← self getRectangle.
	bigRectFrame ← Rectangle new origin: smallRect corner extent: 4  4 + (smallRect extent * blowupScale).
	(smallRect empty or: [bigRectFrame bitStringLength > 4000])
	  ifTrue:
		[pencil frame flash.
		↑nil].
	.
	(user screenrect has: bigRectFrame corner)
	  ifFalse:
		[bigRectFrame moveto: smallRect origin - bigRectFrame extent.
		(user screenrect has: bigRectFrame origin)
		  ifFalse:
			[ "can't find a space for blown up image"
			pencil frame flash.
			↑nil]].
	self blowup: smallRect to: bigRectFrame].
"139" BitRectEditor$'Initialization'
[picture: t1 | |
	picture ← t1.
	tool ← tools push: 1.
	self frame: (picture origin rect: picture corner)].
"62" BitRectEditor$'Initialization'
[toolpic: a | |
	toolpic ← a].
"332" BitRectEditor$'Window protocol'
[leave | |
	nil  saveActionPic
	  ifFalse:
		[actionpic bitsFromString: saveActionPic.
		saveActionPic ← nil].
	nil  saveToolPic
	  ifFalse:
		[toolpic bitsFromString: saveToolPic.
		saveToolPic ← nil].
	dirty
	  ifTrue:
		[picture saveScreenBits.
		dirty ← false].
	frame border: 3 color: white].
"51" BitRectEditor$'Window protocol'
[tool | |
	↑tool].
"109" BitRectEditor$'Window protocol'
[fixframe: r | |
	picture moveto: r origin.
	r corner← picture corner.
	↑r].
"1205" BitRectEditor$'Window protocol'
[enter | start pt b t4 |
	super show "Periodically check if the mouse is still in the frame.
		If not, stop showing the picture".
	self lostMouse
	  ifTrue: [↑false].
	picture show.
	dirty ← false.
	self lostMouse
	  ifTrue: [↑false].
	actionbuttons do: [:b | b reset "show action menu above the picture"].
	start ← frame origin - 1.
	pt ← start - (0  actionpic extent y).
	actionpic moveto: pt.
	saveActionPic ← actionpic bitsIntoString.
	self lostMouse
	  ifTrue: [↑false].
	 "last point I can return before having to restore bits under menus"
	actionpic show.
	pt ← actionbuttons  1 moveto: pt "action".
	pt ← actionbuttons  3 moveto: pt "mode".
	pt ← actionbuttons  4 moveto: pt "width" "show the next bank of action buttons".
	pt ← start - (0  (actionpic extent y + 1 / 2)).
	pt ← actionbuttons  2 moveto: pt "tone".
	pt ← actionbuttons  5 moveto: pt "grid".
	tool brushpt: (pt ← pt + (7  7)).
	(t4 ← tool brush) moveto: pt.
	t4 show "show the tool pic".
	pt ← start - (toolpic extent x  0).
	toolpic moveto: pt.
	saveToolPic ← toolpic bitsIntoString.
	toolpic show.
	tools moveto: pt.
	tools setvalue: tool.
	tool frame: frame.
	tool showon: actionbuttons].
"539" BitRectEditor$'Initialization'
[initmenu1 | s z |
	s ← Vector new: 5.
	z ← 20.
	s  1 ← RadioButtons new vec: #(setbrush paint block draw line blowup ) at: 0  0 height: z "action".
	s  2 ← RadioButtons new vec: {black , dkgray , gray , ltgray , white} at: 0  0 height: z "tone".
	s  3 ← RadioButtons new vec: {0 , 1 , 2 , 3} at: 0  0 height: z "mode".
	s  4 ← RadioButtons new vec: {1 , 2 , 4 , 8} at: 0  0 height: z "width".
	s  5 ← RadioButtons new vec: {1 , 2 , 4 , 8 , 16 , 32} at: 0  0 height: z "grid".
	actionbuttons ← s].
"66" BitRectEditor$'Initialization'
[actionpic: a | |
	actionpic ← a].
"80" BitRectEditor$'Window protocol'
[lostMouse | |
	↑(frame has: user mp)  false].
"357" BitRectEditor$'Initialization'
[classInit | t i |
	t ← Vector new: 6.
	(1 to: t length) do: [:i | t  i ← BitRectTool new init].
	tools ← RadioButtons new vec: t at: 0  0 width: 20.
	windowmenu ← Menu new string: 'under
move
grow
close
filout
printbits' "actionpic←BitRect new filin: 'actionpic'.
	toolpic←BitRect new filin: 'toolpic'.".
	self initmenu1].
"329" BitRectEditor$'Window protocol'
[outside | pt |
	(toolpic has: (pt ← user mp))
	  ifTrue:
		[user redbug
		  ifTrue:
			[tool ← tools bug: pt.
			tool frame: frame.
			tool showon: actionbuttons]]
	  ifFalse:
		[(actionpic has: pt)
		  ifTrue:
			[user redbug
			  ifTrue: [tool setfrom: actionbuttons]]
		  ifFalse: [↑false]]].
"1087" BitImage$'EDITING'
[grayEdit | a b c i d p r v bits |
	 "edit up a gray pattern and return it"
	r ← Rectangle new "first a rectangle for it.  Then redbug is black, yellow is white,
	blue terminates" fromuser.
	bits ← 0.
	a ← r extent.
	a ← (a x max: a y) | 4.
	a ← a  a.
	b ← r origin.
	r extent← a.
	r color: white mode: storing.
	r moveby: 0  (0 - a y).
	c ← a / 4.
	d ← b rect: b + c.
	[user bluebug] whileFalseDo: 
		[user redbug
		  ifTrue:
			[p ← user mp - b / c.
			i ← p y * 4 + p x + 1.
			(i < 1 or: [i > 16])
			  ifTrue: [r flash]
			  ifFalse:
				[d moveto: b + (c * p).
				d color: black mode: storing.
				bits ← bits lor: (1 lshift: 16 - i).
				r color: bits mode: storing.
				user waitnobug]]
		  ifFalse:
			[user yellowbug
			  ifTrue:
				[p ← user mp - b / c.
				i ← p y * 4 + p x + 1.
				(i < 1 or: [i > 16])
				  ifTrue: [r flash]
				  ifFalse:
					[d moveto: b + (c * p).
					d color: white mode: storing.
					bits ← (1 lxor: (1 lshift: 16 - i)) land: bits.
					r color: bits mode: storing.
					user waitnobug]]]].
	↑bits "aa grayEdit base8 ."].
"92" BitImage$'DISPLAY'
[show | |
	super displayat: 0  0 effect: 0 clippedBy: user screenrect].
"65" BitImage$'MODULE ACCESS'
[moveto: pt | |
	self translateto: pt].
"768" BitImage$'EDITING'
[arc | pt1 pt2 pt3 p pt |
	BlankCursor topage1 "arc tool for forms.".
	user clear.
	user print: 'Redbug 3 points'.
	user cr.
	user print: 'Paints using current brush.'.
	user waitnobug.
	[user redbug] whileFalseDo:  [pt1 ← self blinkbrush].
	brush displayat: pt1 effect: color clippedBy: user screenrect.
	user waitnobug.
	[user redbug] whileFalseDo:  [pt2 ← self blinkbrush].
	brush displayat: pt2 effect: color clippedBy: user screenrect.
	user waitnobug.
	[user redbug] whileFalseDo:  [pt3 ← self blinkbrush].
	brush displayat: pt3 effect: color clippedBy: user screenrect.
	XeqCursor show.
	p ← Path new init.
	p addarcfrom: pt1 via: pt2 to: pt3.
	p do: [:pt | brush displayat: pt effect: color clippedBy: user screenrect].
	NormalCursor show].
"145" BitImage$'DISPLAY'
[displayat: t1 effect: effect clippedBy: cliprect | |
	path ← t1.
	super displayat: path effect: effect clippedBy: cliprect].
"385" BitImage$'EDITING'
[resize: t1 | pt f |
	superimage ← t1.
	dotsetter leave.
	CornerCursor topage1.
	user waitbug.
	[user nobug] whileFalseDo: 
		[self reverse.
		self reverse.
		pt ← superimage mp + superimage rectangle origin.
		self corner← pt max: self origin + (16  16)].
	self fromrectangle: rectangle.
	self white.
	self display.
	NormalCursor topage1.
	self edit: superimage].
"69" BitImage$'SYSTEM'
[printon: strm | t |
	strm append: 'a Bitmage: '].
"854" BitImage$'EDITING'
[yellowbug | t1 |
	(t1 ← bitimagemenu bug) = 1
	  ifTrue: [self resize: superimage]
	  ifFalse:
		[ "change size"
		t1 = 2
		  ifTrue: [self setfigure]
		  ifFalse:
			[t1 = 3
			  ifTrue: [self setground]
			  ifFalse:
				[t1 = 4
				  ifTrue: [self newbrush]
				  ifFalse:
					[t1 = 5
					  ifTrue: [self pastebrush]
					  ifFalse:
						[t1 = 6
						  ifTrue: [self arc]
						  ifFalse:
							[t1 = 7
							  ifTrue: [Rectangle new fromuser fillin: dotsetter tool tone mode: dotsetter tool mode]
							  ifFalse:
								[t1 = 8
								  ifTrue: [dotsetter tool shade]
								  ifFalse:
									[t1 = 9
									  ifTrue: [self verticalsymmetry]
									  ifFalse:
										[t1 = 10
										  ifTrue: [self horizontalsymmetry]
										  ifFalse:
											[t1 = 11
											  ifTrue: [self rotate]]]]]]]]]]]].
"57" BitImage$'PATTERN ACCESS'
[strips: t1 | |
	strips ← t1].
"39" BitImage$'SYSTEM'
[pressCode | |
	↑3].
"36" BitImage$'SYSTEM'
[title | |
	↑''].
"333" BitImage$'EDITING'
[rotate | r f i j |
	r ← Rectangle new "90 degree rotation tool" fromuser.
	(1 to: r width) do: [:i | (1 to: r height) do:
			[:j | f ← Form new fromrectangle: (Rectangle new origin: r origin x + i  (r top + j) extent: 1  1).
			f displayat: r corner x + j  (r top + i) effect: 0 clippedBy: user screenrect]]].
"184" BitImage$'SYSTEM'
[copy | t i |
	t ← BitImage new "return a copy of myself" origin: origin copy extent: self extent copy.
	(1 to: self length) do: [:i | t add: (self  i) copy].
	↑t].
"480" BitImage$'EDITING'
[edit: t1 | bits |
	superimage ← t1.
	XeqCursor show "uses the BitRect toolbox editor".
	dotsetter ← BitRectEditor new picture: self.
	dotsetter firsttime.
	NormalCursor show.
	[true] whileTrueDo:
		[ "forever"
		(dotsetter lostMouse and: [user anybug])
		  ifTrue:
			[dotsetter outside
			  ifFalse:
				[XeqCursor show.
				dotsetter lasttime.
				bits ← self fromrectangle: rectangle.
				NormalCursor show.
				↑bits]]
		  ifFalse: [dotsetter eachtime]]].
"171" BitImage$'EDITING'
[setfigure | t |
	figure ← figure + 1 "for now just increment the figure color by 1 \ 12" \ 12.
	self do: [:t | t form figure: figure].
	self display].
"184" BitImage$'INIT'
[fromImage: image | |
	self fromrectangle: image rectangle "creates a virtual bit map with width = (image width) and height = (image height) with the bits in image."].
"111" Image$'MODULE ACCESS'
[superimage | |
	↑superimage "return the superimage (Image containing) of this Image."].
"236" Image$'BUILDING IMAGES'
[addimage: i | r |
	rectangle ← rectangle include: (Rectangle new "add the Image i (as a subimage) and expand the
		 bounding rectangle of this image." origin: i origin + origin extent: i extent).
	self add: i].
"144" Image$'CHANGING IMAGES'
[findbyrect: image | i |
	(1 to: position) do:
		[:i | (array  i) rectangle = image rectangle
		  ifTrue: [↑i]].
	↑0].
"271" Image$'CHANGING IMAGES'
[deleteimage: i | subimage |
	subimage ← self  i "delete the i th subimage and recompute the bounding rectangle of the Image".
	self deleteI: i.
	(subimage rectangle isWithin: rectangle)
	  ifFalse: [self resize "recompute bounding rectangle"]].
"87" Image$'PATTERN ACCESS'
[black | |
	self color: black effect: 0 "black out the image"].
"43" BorderedText$'SYSTEM'
[pressCode | |
	↑6].
"171" BorderedText$'SYSTEM'
[copy | t |
	t ← BorderedText new paragraph: para copy frame: frame copy style: style copy.
	t c1← c1.
	t c2← c2.
	t begintypein← begintypein.
	↑t].
"665" BorderedText$'SYSTEM'
[presson: press in: r | scale |
	scale ← press scale.
	press setp: r origin x - scale  (r corner y - (3 * scale)).
	press showrectwidth: scale * (2 + self width) height: scale.
	press setp: r origin x - scale  (r corner y - (self height + 5 * scale)).
	press showrectwidth: scale * (2 + self width) height: scale.
	press setp: r origin x - scale  (r corner y - (scale * (self height + 4))).
	press showrectwidth: scale height: scale * (self height + 2).
	press setp: r origin x + (scale * self width)  (r corner y - (scale * (self height + 4))).
	press showrectwidth: scale height: scale * (self height + 2).
	↑para presson: press in: r].
"530" BorderedText$'DISPLAY'
[displayat: pt effect: effect clippedBy: cliprect | origin corner t6 |
	super displayat: pt effect: effect clippedBy: cliprect "display text and border around it ".
	origin ← frame origin.
	corner ← frame corner.
	(t6 ← Rectangle new origin: origin - (1  1) corner: corner x + 1  origin y) color: 1 mode: effect.
	t6 moveto: origin x - 1  corner y.
	t6 color: 1 mode: effect.
	t6 origin← corner x  (origin y - 1).
	t6 color: 1 mode: effect.
	t6 moveto: origin - (1  1).
	t6 color: 1 mode: effect].
"194" Image$'PATTERN ACCESS'
[white | |
	(form is: BorderedText) "white out the image"
	  ifTrue: [(rectangle inset: 1  1 and: [1  1]) clear: 0]
	  ifFalse:
		[self color: white effect: over]].
"67" Image$'MODULE ACCESS'
[= image | |
	↑rectangle = image rectangle].
"124" Image$'MODULE ACCESS'
[rightside | |
	↑rectangle corner "return the rightmost x of the bounding rectangle of theImage." x].
"131" Image$'MODULE ACCESS'
[contains: pt | |
	↑rectangle has: pt "return true if the  bounding rectangle for the Image contains pt.."].
"90" Image$'PATTERN ACCESS'
[gray | |
	self color: gray effect: storing "gray out the image"].
"270" Image$'TRANSFORMATIONS'
[normalize | delta i |
	 "recompute origin, rectangle and path so that: path origin = 00."
	nil  path
	  ifFalse:
		[delta ← path origin copy.
		path normalize.
		origin translate: delta].
	(1 to: self length) do: [:i | (self  i) normalize]].
"178" Image$'SYSTEM'
[mp | p |
	p ← user mp " returns a gridded point relative to my rectangle.".
	p x← p x - rectangle origin x | xgrid.
	p y← p y - rectangle origin y | ygrid.
	↑p].
"173" Image$'SYSTEM'
[printon: strm | t |
	strm append: 'an Image: '.
	(array is: String)
	  ifTrue: [strm space append: self]
	  ifFalse: [self do: [:t | strm space print: t]]].
"76" Image$'ACCESS TO PARTS'
[form | |
	↑form "return the form for this Image"].
"76" Image$'ACCESS TO PARTS'
[path | |
	↑path "return the path for this Image"].
"63" Image$'ACCESS TO PARTS'
[superimage: t1 | |
	superimage ← t1].
"97" Image$'CHANGING IMAGES'
[deletesubimage: i | |
	self deleteindex: i "delete the ith subimage."].
"175" Image$'CHANGING IMAGES'
[subimage: i | sub s |
	sub ← self  i "return the ith subimage." s← Image new at: self origin + (sub  1) origin.
	s add: 0  0 and: [sub  2].
	↑s].
"209" Image$'CHANGING IMAGES'
[subimageat: pt | i |
	i ← self indexofsubimageat: pt "return the  subimage which contains pt (relative to self origin)
		otherwise return false.".
	i
	  ifTrue: [↑self  i].
	↑false].
"204" Image$'CHANGING IMAGES'
[substitute: form1 for: form2 | i |
	(1 to: self length "everywhere in the imagesubstitute form1 for form2") do:
		[:i | self  i  2  form2
		  ifTrue: [self  i  2 ← form1]]].
"270" Image$'INIT'
[origin: t1 rectangle: t2 path: t3 form: t4 figure: t5 ground: t6 xgrid: t7 ygrid: t8 | |
	origin ← t1.
	rectangle ← t2.
	path ← t3.
	form ← t4.
	figure ← t5.
	ground ← t6.
	xgrid ← t7.
	ygrid ← t8.
	self default "basic message to create a new instance."].
"101" Image$'MODULE ACCESS'
[rectangle: r | |
	rectangle ← r "redefine rectangle that bounds the Image."].
"201" Image$'CHANGING IMAGES'
[highlite | r i |
	(1 to: position) do:
		[:i |  "reverse the ith subimage ."
		r ← Rectangle new origin: self origin + (self  i) origin extent: (self  i) extent.
		r comp]].
"173" Image$'BUILDING IMAGES'
[addform: f andpath: p | r |
	self addpath: p andform: f "add p (set or point) and f ( Form ) and expand the
		 bounding rectangle of this image."].
"429" Image$'BUILDING IMAGES'
[addpath: p andform: f | r |
	rectangle ← rectangle include: (r ← (Rectangle new "add p (set or point) and f ( Form ) and expand the
		 bounding rectangle of this image." origin: p origin extent: f extent "+ origin") include: (Rectangle new origin: p corner - (1  1) extent: f extent "+ origin")).
	self add: (Image new origin: 0  0 rectangle: r path: p form: f figure: 1 ground: 0 xgrid: 1 ygrid: 1)].
"951" Image$'CHANGING IMAGES'
[edit: t1 | blackdot pt indexofsubimage subimage |
	superimage ← t1.
	nil  form "eventually a general Image manipulator for now
			just passes control to its subimages."
	  ifTrue:
		[user waitnobug.
		[1 = 2] whileFalseDo: 
			[ "until bug occurs outside rectangle"
			(false = (rectangle has: user mp) and: [user anybug])
			  ifTrue: [↑self].
			user kbck
			  ifTrue: [self kbd]
			  ifFalse:
				[user redbug
				  ifTrue:
					[indexofsubimage ← self smallestsubimageat: user mp - self rectangle origin.
					indexofsubimage
					  ifTrue:
						[subimage ← self  indexofsubimage.
						subimage translate: self origin.
						subimage edit: self.
						subimage translate: 0  0 - self origin]]
				  ifFalse:
					[user yellowbug
					  ifTrue: [self yellowbug]]]]]
	  ifFalse:
		[.
		form ← form edit: self.
		(form is: Form)
		  ifFalse: [ "origin ←  (form origin) copy."
			rectangle ← form frame copy].
		↑self]].
"265" Image$'SYSTEM'
[copy | im i |
	im ← Image new origin: origin copy rectangle: rectangle copy path: path copy form: form copy figure: figure copy ground: ground copy xgrid: xgrid copy ygrid: ygrid copy.
	(1 to: self length) do: [:i | im add: (self  i) copy].
	↑im].
"53" Image$'ACCESS TO PARTS'
[hash | |
	↑rectangle hash].
"98" Image$'SYSTEM'
[kbd | |
	user kbd " default response for Images.".
	self reverse.
	self reverse].
"262" Image$'INIT'
[origin: t1 rectangle: t2 path: t3 form: t4 | |
	origin ← t1.
	rectangle ← t2.
	path ← t3.
	form ← t4.
	self origin: origin rectangle: rectangle path: path form: form figure: 1 ground: 0 xgrid: 1 ygrid: 1 "basic message to create a new instance."].
"280" Image$'CHANGING IMAGES'
[indexofsubimageat: pt | i subimage |
	(1 to: self length "return the index of the subimage which contains pt(relative to self origin)
		otherwise return false.") do:
		[:i | subimage ← self  i.
		(subimage rectangle has: pt)
		  ifTrue: [↑i]].
	↑false].
"174" Image$'TRANSFORMATIONS'
[translate: delta | |
	rectangle ← rectangle translate: delta "translate the origin and bounding rectangle of the Image.".
	origin translate: delta].
"261" Image$'INIT'
[origin: t1 extent: extent | |
	origin ← t1.
	self origin: origin copy "create a new Image at origin with extent (widthheight). " rectangle: (Rectangle new origin: origin extent: extent) path: nil form: nil figure: 1 ground: 0 xgrid: 1 ygrid: 1].
"372" Image$'INIT'
[classInit | |
	black ← 0 - 1 "sets up black and white as colors and over ,under and reverse as modes
	also initializes the name screen as an image the size of the display".
	white ← 0.
	over ← 0.
	under ← 1.
	reverse ← 2.
	screen ← Image new origin: user screenrect origin extent: user screenrect extent.
	aurora ← nil "Aurora new".
	aurorarunning ← false].
"104" Image$'MODULE ACCESS'
[extent | |
	↑rectangle extent "return the extent (width,height) of the Image."].
"79" Image$'MODULE ACCESS'
[origin | |
	↑origin "return the origin of the image."].
"89" Image$'MODULE ACCESS'
[corner | |
	↑rectangle corner "return the corner of the Image."].
"91" Image$'MODULE ACCESS'
[height | |
	↑rectangle extent "return the height of the Image." y].
"146" Image$'DISPLAY'
[display | |
	self displayat: 0  0 "display all of the forms in the image on the screen " effect: 0 clippedBy: user screenrect].
"357" Image$'BUILDING IMAGES'
[add: p and: i | s |
	rectangle ← rectangle include: ((Rectangle new "add p (set or point) and i ( Image or Form ) and expand the
		 bounding rectangle of this image." origin: p origin + origin extent: i size) include: (Rectangle new origin: p corner + origin extent: i size)).
	s ← Set default.
	s add: p.
	s add: i.
	self add: s].
"118" Image$'MODULE ACCESS'
[bottom | |
	↑rectangle corner "return the bottom y of the bounding rectangle of theImage." y].
"87" Image$'MODULE ACCESS'
[origin: t1 | |
	origin ← t1 "change the origin of the image."].
"124" Image$'PATTERN ACCESS'
[reverse | |
	self color: black effect: 2 "reverse  the image (black to white and white to black)"].
"180" Image$'CHANGING IMAGES'
[appendimage: newimage after: image | i |
	i ← self findbyrect: image "append newimage into the image after image.".
	self insertI: i + 1 value: newimage].
"170" Image$'CHANGING IMAGES'
[replaceimage: image with: newimage | i |
	i ← self findbyrect: image "replace image with newimage in self.".
	self replaceI: i value: newimage].
"89" Image$'MODULE ACCESS'
[center | |
	↑rectangle center "return the center of the Image."].
"285" Image$'INIT'
[fromuser | |
	rectangle ← Rectangle new "create a new Image whose rectangle is specified by the user. " fromuser.
	self origin: rectangle origin rectangle: rectangle path: rectangle origin form: (Form new fromrectangle: rectangle) figure: 1 ground: 0 xgrid: 1 ygrid: 1].
"329" Image$'MODULE ACCESS'
[resize | i |
	 " Recompute the bounding rectangle of the Image"
	nil  form
	  ifTrue: [rectangle ← Rectangle new origin: origin extent: 1  1]
	  ifFalse: [rectangle ← Rectangle new origin: origin extent: form extent].
	(1 to: self length) do: [:i | rectangle ← rectangle include: (self  i) rectangle]].
"112" Image$'MODULE ACCESS'
[top | |
	↑rectangle origin "return the top y of the bounding rectangle of theImage." y].
"96" Image$'MODULE ACCESS'
[corner← pt | |
	rectangle corner← pt "modify the corner of the Image."].
"96" Image$'ACCESS TO PARTS'
[xgrid: t1 | |
	xgrid ← t1 "set the x gridding module for this Image"].
"100" Image$'TRANSFORMATIONS'
[translateto: pt | |
	self translate: pt - origin "move the Image to pt."].
"91" Image$'ACCESS TO PARTS'
[xgrid | |
	↑xgrid "return the x gridding module for this Image"].
"96" Image$'PATTERN ACCESS'
[boxcomp | |
	rectangle comp "border without disturbing the interior."].
"84" Image$'ACCESS TO PARTS'
[form: t1 | |
	form ← t1 "change the form for this Image"].
"84" Image$'ACCESS TO PARTS'
[path: t1 | |
	path ← t1 "change the path for this Image"].
"89" Image$'MODULE ACCESS'
[width | |
	↑rectangle extent "return the width of the Image." x].
"91" Image$'ACCESS TO PARTS'
[ygrid | |
	↑ygrid "return the y gridding module for this Image"].
"318" Image$'DISPLAY'
[displayat: pt effect: effect clippedBy: cliprect | i |
	 "display all of the subimages in this image "
	nil  form
	  ifFalse: [form displayat: path + pt + origin effect: effect clippedBy: cliprect].
	(1 to: self length) do: [:i | self  i displayat: pt + origin effect: effect clippedBy: cliprect]].
"96" Image$'ACCESS TO PARTS'
[ygrid: t1 | |
	ygrid ← t1 "set the y gridding module for this Image"].
"315" Image$'INIT'
[blink: t1 | pt |
	form ← t1.
	pt ← self mp "to show current gridded position of the form... returns abs position.".
	form displayat: rectangle origin + pt effect: 2 clippedBy: user screenrect.
	form displayat: rectangle origin + pt effect: 2 clippedBy: user screenrect.
	↑self rectangle origin + pt].
"233" Image$'CHANGING IMAGES'
[indexofsubimagebelow: yvalue | i subimage |
	(1 to: self length "return the index of the first subimage below yvalue otherwise return false.") do:
		[:i | (self  i) top  yvalue
		  ifTrue: [↑i]].
	↑false].
"395" Image$'INIT'
[rectanglefromuser | f pt r |
	r ← Rectangle new "create a  Rectangle  specified by the user and origin and corner are gridded. ".
	f ← Form new extent: xgrid  ygrid.
	f black.
	user waitnobug.
	[user anybug] whileFalseDo: 
		[r origin← self blink: f].
	[user nobug] whileFalseDo: 
		[r corner← self mp + rectangle origin max: r origin + f extent.
		r reverse.
		r reverse].
	↑r].
"118" Image$'ACCESS TO PARTS'
[figure | |
	↑figure "return the figure color (color associated with black) for this Image"].
"118" Image$'ACCESS TO PARTS'
[ground | |
	↑ground "return the ground color (color associated with white) for this Image"].
"155" Image$'Fist and last'
[close | im |
	array  nil
	  ifFalse: [self asArray notNil do: [:im | im close]].
	superimage ← nil.
	form ← nil.
	self vector: 0].
"122" Image$'MODULE ACCESS'
[leftside | |
	↑rectangle origin "return the leftmost x of the bounding rectangle of theImage." x].
"498" Image$'SYSTEM'
[hideData: complete | s t3 |
	(t3 ← Stream new "stores an instance of class Image on a press file. ignore complete") of: (s ← String new: 24).
	t3 nextword← self length "number of subimages".
	t3 nextPoint← origin.
	t3 nextPoint← rectangle origin.
	t3 nextPoint← rectangle corner.
	t3 nextword← xgrid.
	t3 nextword← ygrid.
	t3 nextword← figure.
	t3 nextword← ground.
	t3 next← (form  nil
	  ifTrue: [0]
	  ifFalse: [1]).
	t3 next← (path  nil
	  ifTrue: [0]
	  ifFalse: [1]).
	↑s].
"36" Image$'SYSTEM'
[pressCode | |
	↑1].
"126" Image$'ACCESS TO PARTS'
[figure: t1 | |
	figure ← t1 "change the figure color (color associated with black) for this Image"].
"126" Image$'ACCESS TO PARTS'
[ground: t1 | |
	ground ← t1 "change the ground color (color associated with white) for this Image"].
"364" Image$'SYSTEM'
[hidePress: press complete: c | |
	c  0
	  ifTrue:
		[ "called from PressPrinter print:in:"
		form  nil
		  ifFalse: [ "already done"
			form hidePress: press complete: c].
		path  nil
		  ifFalse: [path hidePress: press complete: c]]
	  ifFalse: [ "1. called from Image presson:in:"
		press skipcode: self pressCode data: (self hideData: c)]].
"244" Image$'DISPLAY'
[display: effect | |
	self displayat: 0  0 "display all of the forms in the image on the screen 
	effect = 0  store
	effect = 1  or
	effect = 2  xor
	effect = 3  and complement
" effect: effect clippedBy: user screenrect].
"517" Image$'CHANGING IMAGES'
[smallestsubimageat: pt | i smallest slf sml |
	smallest ← false "return the index of the smallest subimage which contains pt(relative to self origin)
		otherwise return false.".
	(1 to: self length) do:
		[:i | ((self  i) rectangle has: pt)
		  ifTrue:
			[smallest
			  ifTrue:
				[slf ← (self  i) rectangle.
				sml ← (self  smallest) rectangle.
				slf area < sml area
				  ifTrue: [smallest ← i]]
			  ifFalse: [smallest ← i]]].
	smallest
	  ifTrue: [↑self  smallest].
	↑smallest].
"809" Image$'DISPLAY'
[quickDisplayAt: pt scale: scal offset: delta | i rect x1 y1 x2 y2 |
	x1 ← (scal * (rectangle minX "outline me and all of the subimages in this image in given scale" + pt x) + delta x) asInteger.
	y1 ← (scal * (rectangle minY + pt y) + delta y) asInteger.
	x2 ← (scal * (rectangle maxX + pt x) + delta x) asInteger.
	y2 ← (scal * (rectangle maxY + pt y) + delta y) asInteger.
	rect ← x1  y1 rect: x2  y2.
	rect outline.
	pt ← pt + origin.
	(1 to: self length) do:
		[:i | rect ← (self  i) rectangle.
		x1 ← (scal * (rect minX + pt x) + delta x) asInteger.
		y1 ← (scal * (rect minY + pt y) + delta y) asInteger.
		x2 ← (scal * (rect maxX + pt x) + delta x) asInteger.
		y2 ← (scal * (rect maxY + pt y) + delta y) asInteger.
		rect ← x1  y1 rect: x2  y2.
		rect color: gray mode: oring]].
"97" Image$'MODULE ACCESS'
[rectangle | |
	↑rectangle "return the rectangle that bounds the Image."].
"347" Image$'PATTERN ACCESS'
[color: color effect: effect | |
	rectangle color: color mode: effect "basic rectangle call to blt.".
	aurorarunning
	  ifTrue: [user displayoffwhile [
			(aurora destination: rectangle.
			aurora source: rectangle.
			aurora figure: figure.
			aurora ground: ground.
			aurora function: 1103 "AoverB".
			aurora doit)]]].
"82" Image$'DISPLAY'
[blink | |
	self display: 2 "blink the image".
	self display: 2].
"221" Image$'CHANGING IMAGES'
[outlinesubimage: i | r |
	r ← Rectangle new "draw an outline(reversed boarder 2 units thick) about the ith subimage ." origin: self origin + (self  i) origin extent: (self  i) extent.
	r comp].
"657" Image$'SYSTEM'
[presson: press in: r | yvalue t h rect |
	(self length > 0 and: [r height < (h ← press scale * self height)])
	  ifTrue: [↑self].
	 "try on next page"
	self hidePress: press complete: 1.
	self do:
		[:t | yvalue ← t presson: press in: r "if subimage didn't fit, print version will be clipped,
		but entire subimage will be stored".
		t hidePress: press complete: ((yvalue is: Integer)
		  ifTrue: [0]
		  ifFalse: [1])].
	form  nil
	  ifTrue: [↑r corner y - h].
	rect ← r copy.
	rect corner y← rect corner y - (path y * press scale) "form will be hidden by Image presson:in: or PressPrinter print:in:".
	.
	↑form presson: press in: rect].
"136" Image$'CHANGING IMAGES'
[comment | |
	 "see class Set for operations (deletion,replacement,insertion etc.) on subimages ( elements)."].
"80" Image$'TRANSFORMATIONS'
[griddedpoint: pt | |
	↑pt x | xgrid  (pt y | ygrid)].
"674" Image$'CHANGING IMAGES'
[subimageswithin: rect | image topleft fittedimage t |
	image ← Image new "return an image containing my subimages that are within rect, 		otherwise return false." origin: rect origin extent: rect extent.
	self do:
		[:t | (t rectangle isWithin: rect)
		  ifTrue: [image addimage: (t translate: 0  0 - rect origin)]].
	image length = 0
	  ifTrue: [↑false].
	topleft ← (image  1) rectangle origin.
	image do:
		[:t | t rectangle origin < topleft
		  ifTrue: [topleft ← t rectangle origin]].
	fittedimage ← Image new origin: topleft + rect origin extent: 1  1.
	image do: [:t | fittedimage addimage: (t translate: 0  0 - topleft)].
	↑fittedimage].
"1513" Image$'SYSTEM'
[fromPress: press value: s | numberofsubimages i code t |
	self default "retrieves and builds an instance of class Image from a press file".
	numberofsubimages ← s nextword.
	origin ← s nextPoint.
	i ← s nextPoint.
	rectangle ← i rect: s nextPoint.
	xgrid ← s nextword.
	ygrid ← s nextword.
	figure ← s nextword.
	ground ← s nextword.
	form ← s next.
	path ← s next.
	(1 to: numberofsubimages) do:
		[:i | s ← press nextControl asStream.
		code ← s next.
		t ← Image new.
		code = t pressCode
		  ifTrue: [self addimage: (t fromPress: press value: s)]
		  ifFalse: [user notify: 'subimage not Image']].
	form = 0
	  ifTrue: [form ← nil]
	  ifFalse:
		[s ← press nextControl asStream.
		code ← s next.
		form ← (code = 4
				  ifTrue: [TextImage new]
				  ifFalse:
					[code = 5
					  ifTrue: [Form new]
					  ifFalse:
						[code = 6
						  ifTrue: [BorderedText new]
						  ifFalse: [false]]]).
		(form and: [code = form pressCode])
		  ifTrue:
			[code = 4
			  ifTrue: [form frame← rectangle copy].
			code = 6
			  ifTrue: [form frame← rectangle copy].
			form fromPress: press value: s]
		  ifFalse: [user notify: 'illegal form']].
	path = 0
	  ifTrue: [path ← nil]
	  ifFalse:
		[s ← press nextControl asStream.
		code ← s next.
		path ← (code = 6
				  ifTrue: [Path new]
				  ifFalse:
					[code = 7
					  ifTrue: [Point new]
					  ifFalse: [false]]).
		(path and: [code = path pressCode])
		  ifTrue: [path fromPress: press value: s]
		  ifFalse: [user notify: 'illegal path']]].
"822" BitImage$'INIT'
[fromrectangle: rect | r i leftover image yposition |
	super origin: rect origin "creates a virtual bit map with width = (r width) , height = (r height)
	 and the bits in rect. The Image is  made up of forms that are stripheight high." extent: rect extent.
	nstrips ← rect height + (stripheight - 1) / stripheight.
	yposition ← 0.
	leftover ← rect height \ stripheight.
	leftover = 0
	  ifTrue: [leftover ← stripheight].
	r ← Rectangle new origin: rect origin extent: rect width  stripheight.
	(1 to: nstrips) do:
		[:i | i = nstrips
		  ifTrue: [r extent← rect width  leftover].
		image ← Image new origin: 0  0 extent: rect extent.
		image form: (Form new fromrectangle: r).
		image path: 0  yposition.
		self addimage: image.
		yposition ← yposition + stripheight.
		r translate: 0  stripheight]].
"474" BitImage$'EDITING'
[line | pt1 pt2 p pt |
	BlankCursor topage1 "line tool for forms.".
	[user redbug] whileFalseDo:  [pt1 ← self blinkbrush].
	brush displayat: pt1 effect: color clippedBy: user screenrect.
	[user nobug] whileFalseDo:  [pt2 ← self blinkbrush].
	brush displayat: pt2 effect: color clippedBy: user screenrect.
	p ← Path new init.
	p addlinefrom: pt1 to: pt2.
	p do: [:pt | brush displayat: pt effect: color clippedBy: user screenrect].
	NormalCursor topage1].
"171" BitImage$'EDITING'
[setground | t |
	ground ← ground + 1 "for now just increment the ground color by 1 \ 12" \ 12.
	self do: [:t | t form ground: ground].
	self display].
"354" BitImage$'EDITING'
[newbrush | pt rect |
	OriginCursor topage1.
	user waitbug.
	pt ← self mp + rectangle origin.
	rect ← pt rect: pt.
	CornerCursor topage1.
	[user nobug] whileFalseDo: 
		[rect reverse.
		rect reverse.
		pt ← self mp + rectangle origin.
		rect corner← rect origin max: pt].
	brush ← Form new fromrectangle: rect.
	NormalCursor topage1].
"59" BitImage$'PATTERN ACCESS'
[nstrips: t1 | |
	nstrips ← t1].
"287" BitImage$'EDITING'
[pastebrush | pt1 |
	user waitnobug "one-copy tool for forms.".
	OriginCursor show.
	user waitbug.
	[user redbug] whileTrueDo: [pt1 ← self blinkbrush].
	XeqCursor show.
	brush displayat: pt1 effect: dotsetter tool mode clippedBy: user screenrect.
	NormalCursor show].
"439" BitImage$'EDITING'
[horizontalsymmetry | r f i |
	user clear "horizontal symmetry tool".
	user show: 'Define rectangle. Reflection will be around lower edge'.
	r ← Rectangle new fromuser.
	XeqCursor show.
	(1 to: r height) do:
		[:i | f ← Form new fromrectangle: (Rectangle new origin: r origin x  (r bottom - i) extent: r width  1).
		f displayat: r origin x  (r bottom + i) effect: 0 clippedBy: user screenrect].
	NormalCursor show].
"330" BitImage$'FILING'
[write: filename | file subimage |
	file ← dp0 file: filename "Saves the Form in the format nstrips , Form(1) , Form(2) , Form(3) . . .
		Form(nstips). Where each Form is saved as width,height then bits.  ".
	file nextword← nstrips.
	self do:
		[:subimage | file append: subimage form asInstance].
	file close].
"250" BitImage$'EDITING'
[blinkbrush | pt |
	pt ← self mp "to show current position of brush in the BitImage." + rectangle origin.
	brush displayat: pt effect: 2 clippedBy: user screenrect.
	brush displayat: pt effect: 2 clippedBy: user screenrect.
	↑pt].
"144" BitImage$'PATTERN ACCESS'
[erase | i |
	(1 to: nstrips) do: [:i |  "sets all bits in the BitImage to white ( to zeros)"
		(strips  i) white]].
"50" BitImage$'MODULE ACCESS'
[frame | |
	↑rectangle].
"51" BitImage$'PATTERN ACCESS'
[nstrips | |
	↑nstrips].
"50" BitImage$'PATTERN ACCESS'
[saveScreenBits | |
	].
"440" BitImage$'EDITING'
[verticalsymmetry | r f i |
	user clear "vertical symmetry tool".
	user show: 'Define rectangle. Reflection will be around right-hand edge'.
	r ← Rectangle new fromuser.
	XeqCursor show.
	(1 to: r width) do:
		[:i | f ← Form new fromrectangle: (Rectangle new origin: r origin x + r width - i  r top extent: 1  r height).
		f displayat: r corner x + i  r top effect: 0 clippedBy: user screenrect].
	NormalCursor show].
"60" BitImage$'MODULE ACCESS'
[comment | |
	 "see class Image"].
"376" BitImage$'INIT'
[classInit | |
	black ← 0 - 1 "sets up colors and effects for BITBLT.".
	white ← 0.
	over ← 0.
	under ← 1.
	reverse ← 2.
	erase ← 3.
	brush ← Form new extent: 5  5.
	brush black.
	color ← 1.
	stripheight ← 20.
	bitimagemenu ← Menu new string: 'size
figure
ground
newform
pasteform
arc
areafill
shade
vertical
horizontal
rotate
'.
	aurora ← nil "Aurora new"].
"502" BitImage$'FILING'
[read: filename | file subimage strip yposition i |
	self origin: 0  0 "Reads the Image in the format nstrips , Form(1) , Form(2) , Form(3) . . .
		Form(nstips). Where each Form is saved as width,height then bits.  " extent: 1  1.
	yposition ← 0.
	file ← (dp0 oldFile: filename) readonly.
	nstrips ← file nextword.
	(1 to: nstrips) do:
		[:i | strip ← Form new fromInstance: file.
		self addform: strip andpath: 0  yposition.
		yposition ← yposition + strip height].
	file close].
"149" BitImage$'INIT'
[fromuser | r |
	r ← Rectangle new "create a new Form whose rectangle is specified by the user. " fromuser.
	self fromrectangle: r].
"230" BitImage$'INIT'
[fromuserevenword | r |
	r ← Rectangle new "create a new BitImage whose rectangle is specified by the user,
		truncated to nearest multiple of 16 (for Spruce printing). " fromuserevenword.
	self fromrectangle: r].
"100" BitImage$'PATTERN ACCESS'
[strips | |
	↑strips "return the set of Forms making up this BitImage)"].
"104" BitRectEditor$'Window protocol'
[yellowbug | |
	(picture is: BitImage)
	  ifTrue: [picture yellowbug]].
"620" BitRectEditor$'Window protocol'
[bluebug | t1 |
	(picture is: BitImage)
	  ifTrue: [↑picture fromrectangle: picture rectangle].
	(t1 ← windowmenu bug) = 1
	  ifTrue:
		[self leave.
		↑exitflag ← false].
	 "under"
	t1 = 2
	  ifTrue:
		[self leave.
		self newframe.
		self enter]
	  ifFalse:
		[ "move"
		t1 = 3
		  ifTrue: [self grow "grow"]
		  ifFalse:
			[t1 = 4
			  ifTrue:
				[self leave.
				self erase "close".
				user unschedule: self.
				↑false].
			t1 = 5
			  ifTrue:
				[self leave.
				picture filout.
				self enter]
			  ifFalse:
				[ "filout"
				t1 = 6
				  ifTrue: [self print] "press file"]]]].
"812" BitRectEditor$'Window protocol'
[grow | oldframe newframe pt r |
	self leave.
	newframe ← picture origin rect: picture corner.
	CornerCursor showwhile [
		(pt ← user mp + 16.
		[user nobug] whileTrueDo:
			[newframe corner← pt.
			newframe comp.
			pt ← user mp + 16.
			newframe comp].
		[user anybug] whileTrueDo:
			[newframe corner← pt.
			newframe comp.
			pt ← user mp + 16.
			newframe comp])] "clear unused areas from old picture to background,
		and clear new picture areas to white".
	oldframe ← picture inset: 2  2 "2 is for erasing old border".
	(oldframe minus: newframe) do: [:r | r clear: background].
	(newframe minus: picture) do: [:r | r clear: white].
	picture title: picture title in: newframe.
	picture saveScreenBits.
	self frame: newframe.
	self show.
	self takeCursor.
	self enter].
"61" BitRectEditor$'Window protocol'
[title | |
	↑picture title].
"110" BitRectEditor$'Window protocol'
[showtitle | |
	 "The BitRectEditor have a menu where the title used to be"].
"130" BitRect$'Editing'
[edit | a |
	user leaveTop.
	a ← BitRectEditor new picture: self.
	a takeCursor.
	a enter.
	user restartup: a].
"47" BitRect$'Access to parts'
[title | |
	↑title].
"68" BitRect$'Rectangle Protocol'
[hash | |<primitive: 39>
	user croak].
"233" BitRect$'Filin and filout'
[filout | f i |
	 "write bits on a file"
	f ← dp0 file: (title concat: '.pic.').
	f nextword← self extent x.
	f nextword← self extent y.
	f nextword← stripheight.
	data do: [:i | i toStream: f].
	f close].
"71" BitRect$'Rectangle Protocol'
[growto: x | |
	self growby: x - corner].
"789" BitRect$'Editing'
[copyBitsFrom: other | clippedStrip i j myStrips otherStrips myStrip otherStrip bb |
	myStrips ← self strips "copy all bits from other that are within my area".
	otherStrips ← other strips.
	(1 to: myStrips length) do: [:i | (1 to: otherStrips length) do:
			[:j | myStrip ← myStrips  i.
			otherStrip ← otherStrips  j.
			clippedStrip ← myStrip intersect: otherStrip.
			clippedStrip empty
			  ifFalse:
				[bb ← BitBlt init.
				bb function← 0.
				bb destbase← data  i.
				bb destraster← myStrip width + 15 / 16.
				bb dest← clippedStrip origin - myStrip origin.
				bb extent← clippedStrip extent.
				bb sourcebase← other data  j.
				bb sourceraster← otherStrip width + 15 / 16.
				bb source← clippedStrip origin - otherStrip origin.
				bb bb callBLT]]]].
"171" BitRect$'Showing'
[saveScreenBits | strips i |
	strips ← self strips.
	(1 to: strips length) do: [:i | strips  i bitsIntoString: data  i mode: storing clippedBy: nil]].
"417" BitRect$'Initialization'
[title: t1 in: rect | nStrips i strips |
	title ← t1.
	origin ← rect origin.
	corner ← rect corner "the strip height is chosen so that each bitstring is about 2048 bytes".
	stripheight ← 1023 / (self extent x + 15 / 16).
	nStrips ← self extent y + stripheight - 1 / stripheight.
	data ← Vector new: nStrips.
	strips ← self strips.
	(1 to: nStrips) do: [:i | data  i ← (strips  i) bitmap]].
"712" BitRect$'Press'
[presson: press in: r | w h hs scale w16 y |
	scale ← press scale.
	h ← self height.
	(hs ← scale * h) > r height
	  ifTrue: [↑self].
	 "not enough room left on current page.
		assume for now that it will at least fit on an entire page"
	w ← self width.
	w16 ← w + 15 | 16 "width to next word boundary" "with w, prints on viola but not on spruce.
	with w16, prints on spruce with garbage on end".
	press setp: 0  (y ← r corner y - hs).
	press dots [
		(press setcoding: 1 dots: w16 lines: h "bitmap".
		press setmode: 3 "to right and to bottom".
		press setsizewidth: scale * w16 height: hs.
		press setwindowwidth: w16 height: h.
		press dotsfollow.
		self bitsOntoStream: press data)].
	↑y].
"130" BitRect$'Initialization'
[classInit | |
	defaultpic ← BitRect new "the default picture is a gray rectangle" filin: 'defaultpic'].
"102" BitRect$'Rectangle Protocol'
[bitsOntoStream: strm | bits |
	data do: [:bits | bits toStream: strm]].
"81" BitRect$'Rectangle Protocol'
[width← w | |
	self growby: w - self extent x  0].
"113" BitRect$'Initialization'
[fromuser | |
	self title: 'BitRect' in: Rectangle new fromuser.
	self saveScreenBits].
"594" BitRect$'Filin and filout'
[filin: t1 | f i x y rect strips |
	 "read bits from a file"
	title ← t1.
	f ← dp0 oldFile: (title concat: '.pic.').
	f readonly.
	f end
	  ifTrue:
		[f close.
		user notify: 'no data']
	  ifFalse:
		[x ← f nextword.
		y ← f nextword.
		rect ← Rectangle new origin: ((origin is: Point)
				  ifTrue: [origin]
				  ifFalse: [0  0]) extent: x  y.
		self title: title in: rect.
		stripheight  f nextword
		  ifTrue: [user notify: 'strip heights dont match']
		  ifFalse:
			[strips ← self strips.
			(1 to: strips length) do: [:i | f into: data  i].
			f close]]].
"499" BitRect$'Showing'
[strips | nStrips strips stripOrigin stripExtent i |
	 "return a vector of strips (Rectangles)"
	(nStrips ← data length) = 1
	  ifTrue: [↑self inVector].
	strips ← Vector new: nStrips.
	stripOrigin ← origin.
	stripExtent ← self width  stripheight.
	(1 to: nStrips - 1) do:
		[:i | strips  i ← Rectangle new origin: stripOrigin extent: stripExtent.
		stripOrigin ← stripOrigin + (0  stripheight)].
	strips  nStrips ← Rectangle new origin: stripOrigin corner: corner.
	↑strips].
"140" FormSet$'PARTS'
[descent | |
	↑strike word: 7 "When form set treated as characters, describes distance from bottom of
	form to baseline."].
"1451" FormSet$'ACCESS'
[from: first to: last ascent: ascent descent: descent style: t5 styleindex: t6 name: name | |
	style ← t5.
	styleindex ← t6.
	self classInit "Make an empty formset.".
	offsettable ← String new: last - first + 3 * 2.
	offsettable all← 0.
	offsettable word: (last - first + 3) ← 4 "width of illegal form".
	strike ← String new: 9 + ascent "header" + descent "space for illegal form" * 2.
	strike all← 0.
	self type: 32768 "for the outside world".
	self first: first.
	self last: last.
	self wordwidth: 1 "only illegal form".
	self ascent: ascent.
	self descent: descent.
	self maxwidth: 4 "width of illegal form".
	strike ← strike concat: offsettable  (1 to: offsettable length) "mash in bits of illegal form" "leftside".
	bitmover destraster← self wordwidth.
	bitmover destx← 0.
	bitmover desty← 0.
	bitmover width← 1.
	bitmover height← self ascent + self descent.
	bitmover destbase← strike.
	bitmover dstrike← true.
	bitmover fill: storing color: black "rightside".
	bitmover destx← 3.
	bitmover dstrike← true.
	bitmover fill: storing color: black "top".
	bitmover width← 4.
	bitmover height← 1.
	bitmover destx← 0.
	bitmover dstrike← true.
	bitmover fill: storing color: black "bottom".
	bitmover desty← self ascent + self descent - 1.
	bitmover dstrike← true.
	bitmover fill: storing color: black.
	self install: strike.
	self updateseglength.
	style  nil
	  ifFalse: [style setfont: styleindex name: name fromstring: strike]].
"82" FormSet$'ACCESS'
[space | |
	↑space "return textframe that is space of formset"].
"118" FormSet$'INTERNAL'
[length | |
	↑self last "Return length of formset, i.e. number of forms in set" - self first + 1].
"400" FormSet$'INTERNAL'
[checkindex | |
	 "check formindex for legality and make into number if necessary"
	(formindex is: String)
	  ifTrue:
		[formindex length > 1
		  ifTrue: [user notify: 'formindex out of range for FormSet.']
		  ifFalse: [formindex ← formindex  1]].
	(formindex < self first or: [formindex > (self last + 1)])
	  ifTrue: [user notify: 'formindex out of range for this FormSet.']].
"437" FormSet$'PARTS'
[wordwidth | |
	↑strike word: 9 "Also know as the raster of the formset.
	The width in alto words of the bits of the formset.  When the display of a 
	form is desired, the word and bit address of the bits of the form must
	be discovered.  Adding the wordwidth to the word portion of that value,
	produces the word address of the second line of the bits of the form, and
	so on until the height of the form is spanned."].
"118" FormSet$'ACCESS'
[changeascentto: newascent | |
	self deltaascent: newascent - self ascent "new ascent for FormSet"].
"868" FormSet$'INTERNAL'
[deltaascent: delta | newstrike |
	 "ascent delta"
	self ascent + delta < 0
	  ifTrue: [delta ← 0 - self ascent].
	delta > 0
	  ifTrue:
		[newstrike ← String new: 2 * self wordwidth "grow" * delta.
		newstrike all← 0 "fill with white".
		newstrike ← strike  (1 to: 18) "add oldfont header and new space together" concat: newstrike  (1 to: newstrike length).
		newstrike ← newstrike concat: strike  (19 to: strike length "now add on rest of old font")]
	  ifFalse:
		[ "shrink"
		newstrike ← strike  (1 to: 18) concat: strike  (19 + (0 - (2 * self wordwidth * delta)) to: strike length)].
	newstrike word: 6 ← self ascent + delta "reset ascent word in font".
	self install: newstrike "newstrike now font of interest".
	self updateseglength.
	style  nil
	  ifFalse:
		[style maxascent < self ascent
		  ifTrue: [style maxascent: self ascent]]].
"122" FormSet$'PARTS'
[last | |
	↑strike word: 3 "Heritage from the world of fonts" "maximum formindex (ascii) in the strike"].
"123" FormSet$'ACCESS'
[changedescentto: newdescent | |
	self deltadescent: newdescent - self descent "new ascent for FormSet"].
"796" FormSet$'INTERNAL'
[deltadescent: delta | newstrike somespace |
	 "descent delta"
	self descent + delta < 0
	  ifTrue: [delta ← 0 - self descent].
	delta > 0
	  ifTrue:
		[somespace ← String new: 2 * self wordwidth * delta.
		somespace all← 0.
		newstrike ← strike  (1 to: offsettable - 1 * 2) concat: somespace]
	  ifFalse:
		[newstrike ← strike  (1 to: offsettable - 1 * 2 + (self wordwidth * delta * 2))] "copy the xtable".
	newstrike ← newstrike concat: strike  (offsettable * 2 - 1 to: strike length).
	newstrike word: 7 ← self descent + delta "reset descent word in font".
	self install: newstrike "updatedfont now font of interest".
	self updatemaxwidth.
	self updateseglength.
	style  nil
	  ifFalse:
		[style maxdescent < self descent
		  ifTrue: [style maxdescent: self descent]]].
"1946" FormSet$'INTERNAL'
[deltawidthof: index by: delta | newwordwidth newoffsettable newstrike normalizedindex normalizedlast i |
	 "change width of form at index"
	delta < 0
	  ifTrue:
		[delta abs > self width
		  ifTrue: [delta ← 0 - self width]].
	newwordwidth ← (self strikerightx + 15 / 16  (i ← self strikerightx + delta + 15 / 16)
			  ifTrue: [i]
			  ifFalse: [self wordwidth]).
	newoffsettable ← newwordwidth * (self ascent + self descent) "height" + 9 "header" + 1 "for 0 addressing".
	XeqCursor showwhile [
		(newstrike ← String new: 9 + (newwordwidth * (self ascent "header" + self descent)) "bits" * 2 "grow/shrink the bits".
		newstrike all← 0.
		(1 to: 8) "fill in header of new font" do: [:i | newstrike word: i ← strike word: i].
		newstrike word: 9 ← newwordwidth "set raster in new font" "copy the xtable".
		newstrike ← newstrike concat: strike  (offsettable * 2 - 1 to: strike length) "set up to copy up to old bits of form in formset".
		bitmover destraster← newwordwidth.
		bitmover destx← 0.
		bitmover desty← 0.
		bitmover sourcex← 0.
		bitmover sourcey← 0.
		bitmover width← self originx + self width.
		bitmover height← self ascent + self descent.
		bitmover sourceraster← self wordwidth.
		bitmover destbase← newstrike.
		bitmover sourcebase← strike.
		bitmover sstrike← true.
		bitmover dstrike← true.
		bitmover copy: storing "now copy remainder of font".
		bitmover destx← self originx + self width + delta.
		bitmover width← self strikerightx - self originx - self width.
		bitmover sourcex← self originx + self width.
		bitmover copy: storing "shift x-vals".
		normalizedindex ← formindex - self first.
		normalizedlast ← self last - self first.
		(normalizedindex + 1 to: normalizedlast + 2 "max") do: [:i | newstrike word: (newoffsettable + i) ← delta + (newstrike word: newoffsettable + i)].
		self install: newstrike "set up the updated copy of the formset".
		self updatemaxwidth.
		self updateseglength)]].
"575" FormSet$'ACCESS'
[copy: t1 to: pt effect: effect | f |
	formindex ← t1.
	self checkindex "copies the form indexed by formindex to pt." "f ← Image new size: (self width)  (self height) at: pt.".
	bitmover destraster← user screenrect width + 15 / 16.
	bitmover destx← pt x.
	bitmover desty← pt y.
	bitmover sourcex← self originx.
	bitmover sourcey← 0.
	bitmover width← self width.
	bitmover height← self ascent + self descent.
	bitmover sourceraster← self wordwidth.
	bitmover destbase← mem  54.
	bitmover sourcebase← strike.
	bitmover strike← true.
	bitmover copy: effect].
"2057" FormSet$'ACCESS'
[include: t1 with: form | newoffsettable newstrike i j |
	formindex ← t1.
	(formindex > self first "Put a form into the formset" and: [formindex < self last])
	  ifTrue: [self replace: formindex with: form]
	  ifFalse:
		[formindex < 0
		  ifTrue: [user notify: 'Formindex < 0 illegal for formset.']
		  ifFalse:
			[formindex > 255
			  ifTrue: [user notify: 'Formindex > 255 illegal for formset.']
			  ifFalse:
				[formindex < self first
				  ifTrue:
					[newoffsettable ← String new: self first - formindex + self abslength * 2.
					newoffsettable all← 0.
					j ← self first - formindex + 1.
					(j to: newoffsettable length / 2) do: [:i | newoffsettable word: i ← strike word: offsettable + (i - j)]]
				  ifFalse:
					[newoffsettable ← String new: self abslength + formindex - self last * 2.
					newoffsettable all← 0.
					(0 to: self length - 1) do: [:i | newoffsettable word: (i + 1) ← strike word: offsettable + i].
					(self length to: newoffsettable length / 2) do: [:i | newoffsettable word: i ← strike word: offsettable + self length].
					newoffsettable word: (newoffsettable length / 2) ← strike word: offsettable + self length + 1].
				newstrike ← String new: 9 + (self wordwidth "header" * (self ascent + self descent)) "bits" * 2 "new space for bits".
				(1 to: 9) "fill in header of new font" do: [:i | newstrike word: i ← strike word: i].
				bitmover destraster← self wordwidth.
				bitmover destx← 0.
				bitmover desty← 0.
				bitmover sourcex← 0.
				bitmover sourcey← 0.
				bitmover width← self strikerightx.
				bitmover height← self ascent + self descent.
				bitmover sourceraster← self wordwidth.
				bitmover destbase← newstrike.
				bitmover sourcebase← strike.
				bitmover strike← true.
				bitmover copy: storing "copy the xtable".
				newstrike ← newstrike concat: newoffsettable  (1 to: newoffsettable length).
				self install: newstrike.
				formindex < self first
				  ifTrue: [self first: formindex]
				  ifFalse: [self last: formindex].
				self replace: formindex with: form]]]].
"89" FormSet$'ACCESS'
[currentformindex | |
	↑formindex "return index of form last touched"].
"255" FormSet$'INTERNAL'
[updateseglength | |
	strike word: 5 ← 5 + (self wordwidth "compute new segment length for formset" "length, ascent, descent, kern, and raster" * (self ascent + self descent)) "bits" + (self last "max" - self first "min" + 2) "xtabl"].
"164" FormSet$'ACCESS'
[fromspace: pt to: dest | |
	formindex ← image  ((space charofpt: pt) "get form selected from space" min: 256).
	↑self copy: formindex to: dest].
"134" FormSet$'PARTS'
[last: last | |
	strike word: 3 ← last "Heritage from the world of fonts" "maximum formindex (ascii) in the strike"].
"109" FormSet$'PARTS'
[maxwidth: maxwidth | |
	strike word: 4 ← maxwidth "All forms in this set  to this value"].
"741" FormSet$'ACCESS'
[replace: t1 with: form | |
	formindex ← t1.
	self checkindex "Replace form in set.  Check incoming form for compatibility with formset,
	and insert form into formset.".
	form width  self width
	  ifTrue: [self changewidthof: formindex to: form width].
	form displayat: 0  0 effect: 0 clippedBy: user screenrect "copy bits of form into formset".
	bitmover destraster← self wordwidth.
	bitmover destx← self originx.
	bitmover desty← 0.
	bitmover sourcex← 0.
	bitmover sourcey← 0.
	bitmover width← self width.
	bitmover height← self ascent + self descent.
	bitmover sourceraster← user screenrect width + 15 / 16.
	bitmover destbase← strike.
	bitmover sourcebase← mem  54.
	bitmover dstrike← true.
	bitmover copy: storing].
"123" FormSet$'PARTS'
[first | |
	↑strike word: 2 "Heritage from the world of fonts" "minimum formindex (ascii) in the strike"].
"180" FormSet$'INTERNAL'
[abslength | |
	↑self last "Return absolute length of formset, i.e. number of forms in set
		plus space for illegal character and its rightx" - self first + 3].
"137" FormSet$'PARTS'
[first: first | |
	strike word: 2 ← first "Heritage from the world of fonts" "minimum formindex (ascii) in the strike"].
"99" FormSet$'PARTS'
[segmentlength | |
	↑strike word: 5 "Amount of space allocated for form set - 4"].
"170" FormSet$'ACCESS'
[changewidthof: t1 to: width | |
	formindex ← t1.
	self checkindex "new width for form at index".
	self deltawidthof: formindex by: width - self width].
"130" FormSet$'PARTS'
[strikerightx | |
	↑strike word: offsettable + (self last "Corner x of last form in form set" - self first) + 2].
"164" FormSet$'ACCESS'
[currentformorigin | imageindex |
	imageindex ← image find: formindex "return index in image of form last touched".
	↑space ptofchar: imageindex].
"98" FormSet$'ACCESS'
[classInit | |
	bitmover ← BitBlt init "Just initialize the bitmover for now."].
"748" FormSet$'ACCESS'
[copyrange: start to: stop from: sourceset startingat: deststart | savebackground savebits i f |
	user displayoffwhile [
		 "copy a range of forms from one set to another"
		((sourceset is: FormSet)
		  ifFalse:
			[(sourceset is: String)
			  ifTrue: [sourceset ← FormSet new from: sourceset]
			  ifFalse: [user notify: 'Illegal sourceset -- not String or Formset.']].
		savebackground ← Form new size: sourceset maxwidth by: sourceset height.
		savebackground translate: 0  0.
		savebackground scale: 1.
		savebits ← savebackground bitsIntoString.
		(start to: stop) do:
			[:i | f ← sourceset copy: i to: 0  0.
			self include: deststart with: f.
			deststart ← deststart + 1].
		savebackground bitsFromString: savebits)]].
"195" FormSet$'ACCESS'
[fromstyle: t1 styleindex: t2 | |
	style ← t1.
	styleindex ← t2.
	self classInit "Make a formset out of string in strike format".
	self install: style fonts  (styleindex + 1)].
"545" FormSet$'ACCESS'
[initspaceat: t1 | i run para |
	spaceorigin ← t1.
	image ← String new: 256 "make a space for formset viewing".
	image all← 0.
	(self first to: self last + 1) do: [:i | image  (i + 1) ← i].
	run ← String new: 2.
	run word: 1 ← 16 * styleindex + 256.
	para ← Paragraph new text: image runs: run alignment: 0.
	space  nil
	  ifFalse: [space erase].
	space ← Textframe new para: para frame: (Rectangle new origin: spaceorigin extent: self last - self first * self maxwidth / 8  (self ascent + self descent * 6)) style: style].
"87" FormSet$'ACCESS'
[height | |
	↑self ascent "return height of fromset" + self descent].
"1282" FormSet$'ACCESS'
[makecu: name scale: scale | f i iform bits drast srast |
	user displayoffwhile [
		 "Put out strike in Carnegie-Mellon format.
		A typical call might look like:
			yourset ←
				FormSet new style: DefaultTextStyle styleindex: 0.

				yourset makecu: 'cream12' scale: 1.			
			"
		(f ← dp0 file: name + '.cu.'.
		f nextword← self height * scale.
		f nextword← self maxwidth * scale + 15 / 16.
		bits ← String new: self height * scale * (self maxwidth * scale + 15 / 16) * 2.
		drast ← self maxwidth * scale + 15 / 16.
		srast ← user screenrect width + 15 / 16.
		(self first to: self last by: 1) do:
			[:i | iform ← self asForm: i "self copy: i to: 00".
			iform displayat: 0  0 effect: 0 clippedBy: user screenrect.
			scale > 1
			  ifTrue: [iform blowup: 0  0 by: scale].
			f nextword← i.
			f nextword← self width * scale.
			bitmover destbase← bits.
			bitmover destraster← drast.
			bitmover destx← 0.
			bitmover desty← 0.
			bitmover sourcebase← mem  54.
			bitmover sourceraster← srast.
			bitmover sourcex← 0.
			bitmover sourcey← 0.
			bitmover dstrike← false.
			bitmover sstrike← true.
			bitmover width← iform width * scale.
			bitmover height← iform height * scale.
			bits all← 0.
			bitmover copy: storing.
			f append: bits].
		f close)]].
"73" FormSet$'ACCESS'
[spaceframe | |
	↑space frame "return frame of space"].
"158" FormSet$'PARTS'
[descent: descent | |
	strike word: 7 ← descent "When form set treated as characters, describes distance from bottom of
	form to baseline."].
"89" FormSet$'PARTS'
[maxwidth | |
	↑strike word: 4 "All forms in this set  to this value"].
"141" FormSet$'ACCESS'
[spaceorigin: t1 | |
	spaceorigin ← t1.
	space erase "reposition the space".
	space frame origin← spaceorigin.
	self show].
"102" FormSet$'ACCESS'
[widthof: t1 | |
	formindex ← t1.
	↑self width "return width of from at formindex"].
"264" FormSet$'INTERNAL'
[install: t1 | |
	strike ← t1.
	 "set up a new or refreshed strike"
	style  nil
	  ifFalse: [style fonts  (styleindex + 1) ← strike].
	offsettable ← self wordwidth * (self ascent + self descent) + 9 "header" + 1 "for 0 addressing".
	↑strike].
"116" FormSet$'ACCESS'
[newspace | |
	space frame← Rectangle new "let user reshape/position space" fromuser.
	self show].
"89" FormSet$'ACCESS'
[show | |
	space outline "show all the forms in the set".
	space show].
"126" FormSet$'INTERNAL'
[originx | |
	↑strike word: offsettable + formindex "Return origin x  of form at formindex" - self first].
"265" FormSet$'INTERNAL'
[updatemaxwidth | newmaxwidth i |
	newmaxwidth ← 0 "update max width".
	(offsettable to: offsettable + (self last - self first + 1)) do: [:i | newmaxwidth ← newmaxwidth max: (strike word: i + 1) - (strike word: i)].
	self maxwidth: newmaxwidth].
"152" FormSet$'PARTS'
[ascent: ascent | |
	strike word: 6 ← ascent "When form set treated as characters, describes distance from top of form
	to baseline."].
"113" FormSet$'PARTS'
[type: type | |
	strike word: 1 ← type "**BEWARE -- outside world has ideas about this value."].
"459" FormSet$'PARTS'
[wordwidth: wordwidth | |
	strike word: 9 ← wordwidth "Also know as the raster of the formset.
	The width in alto words of the bits of the formset.  When the display of a 
	form is desired, the word and bit address of the bits of the form must
	be discovered.  Adding the wordwidth to the word portion of that value,
	produces the word address of the second line of the bits of the form, and
	so on until the height of the form is spanned."].
"586" FormSet$'ACCESS'
[copy: t1 to: pt | f |
	formindex ← t1.
	self checkindex "copies the form indexed by formindex to pt." "f ← Image new size: (self width)  (self height) at: pt.".
	bitmover destraster← user screenrect width + 15 / 16.
	bitmover destx← pt x.
	bitmover desty← pt y.
	bitmover sourcex← self originx.
	bitmover sourcey← 0.
	bitmover width← self width.
	bitmover height← self ascent + self descent.
	bitmover sourceraster← self wordwidth.
	bitmover destbase← mem  54.
	bitmover sourcebase← strike.
	bitmover strike← true.
	bitmover copy: oring.
	↑self widthof: formindex].
"184" FormSet$'INTERNAL'
[width | |
	↑(strike word: offsettable + (formindex - self first "Return width of form at formindex") + 1) - (strike word: offsettable + (formindex - self first))].
"551" FormSet$'ACCESS'
[asForm: t1 | f |
	formindex ← t1.
	self checkindex "returns the form indexed by formindex .".
	f ← Form new extent: self width  self height.
	bitmover destraster← f width + 15 / 16.
	bitmover destx← 0.
	bitmover desty← 0.
	bitmover sourcex← self originx.
	bitmover sourcey← 0.
	bitmover width← self width.
	bitmover height← self ascent + self descent.
	bitmover sourceraster← self wordwidth.
	bitmover destbase← f bits.
	bitmover sourcebase← strike.
	bitmover dstrike← false.
	bitmover sstrike← true.
	bitmover copy: storing.
	↑f].
"134" FormSet$'ACCESS'
[from: t1 | |
	strike ← t1.
	self classInit "Make a formset out of string in strike format".
	self install: strike].
"136" FormSet$'PARTS'
[ascent | |
	↑strike word: 6 "When form set treated as characters, describes distance from top of form
	to baseline."].
"101" FormSet$'PARTS'
[type | |
	↑strike word: 1 "**BEWARE -- outside world has ideas about this value."].
"163" FormSet$'PARTS'
[kern | |
	↑strike word: 8 "When form set treated as characters, describes distance this form is
	to intrude into space of preceding character."].
"97" ParsedNode$'As yet unclassified'
[printCommentOn: str | |
	str append: comment.
	comment ← nil].
"66" ParsedNode$'As yet unclassified'
[comment: t1 | |
	comment ← t1].
"58" ParsedNode$'As yet unclassified'
[comment | |
	↑comment].
"127" JuniperFileController$'MISC (internal)'
[interface | |
	 "...returns the JuniperInterface controlling the file."
	↑directory].
"194" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[allocatePage | |
	 "...returns a new packet (Pacbuf) to be used as the data buffer in a JuniperPageBuffer."
	↑self interface newPacket].
"574" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[length: pLength | tRequest |
	 "...sets the number of bytes in the file to the integer pLength (an Integer)."
	tRequest ← self newRequestParameterBlock "1".
	tRequest longInteger: 1 ← pLength "2".
	self doAction: sSetLength requestPrs: tRequest "3".
	lastpn ← self pageFrom: pLength "4" "
1. Create a new request parameter block.
2. Set the length parameter to pLength.
3. Issue a 'set length' command to Juniper.
4. Determine the number of the last page of the file and assign it to the superClass field lastpn.
"].
"434" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[endFile: pPageBuffer | |
	 "...adjusts the file length, writes pPageBuffer (a JuniperPageBuffer) on the file, and returns pPageBuffer."
	self length: pPageBuffer pageNumber - 1 * pPageBuffer dataLength + pPageBuffer length "1".
	self writePage: pPageBuffer "2".
	↑pPageBuffer "
1. Set the file length to the total number of bytes in the file.
2. Write the page on Juniper.
"].
"1234" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[Read: pPageBuffer | tRequest tResult pn |
	 "...returns false if the page number of pPageBuffer (a JuniperPageBuffer) is greater than the page number of the last page of the file; otherwise, the data for that page is read from the Juniper file system into the packet of pPageBuffer."
	(pn ← pPageBuffer pageNumber) > lastpn
	  ifTrue: [↑false].
	 "1"
	(lastpn = 1 and: [self empty])
	  ifTrue:
		[pPageBuffer length: 0 " self Get: pPageBuffer"]
	  ifFalse:
		[tRequest ← self newRequestParameterBlock "2".
		tRequest parameter: 1 ← pn - 1 "3".
		tResult ← self doAction: sReadPage requestPrs: tRequest "4".
		pPageBuffer page: tResult packet "5".
		pPageBuffer length: (tResult parameter: 1) "6"].
	↑pPageBuffer "7" "
1. Return false if the page number of pPageBuffer is greater than that of the last page of the file.
2. Create a new request parameter block.
3. Set the page number parameter to that of pPageBuffer less 1.  Juniper page numbers start at 0.
4. Issue a 'read page' request.
5. Set the pPageBuffer packet to that of the result parameter block.
6. Set the length of pPageBuffer to that returned in the result parameter block.
7. Return pPageBuffer modified.
"].
"124" JuniperPageBuffer$'FILE PAGE OPERATIONS'
[pageNumber | |
	 "...returns the page number of the page buffer."
	↑fPageNumber].
"130" JuniperPageBuffer$'FILE PAGE OPERATIONS'
[serialNumber | |
	 "...returns the serial number of the page buffer."
	↑fSerialNumber].
"157" JuniperPageBuffer$'FILE PAGE OPERATIONS'
[serialNumber: pSerialNumber | |
	 "...sets the serial number of the page buffer."
	fSerialNumber ← pSerialNumber].
"159" JuniperPageBuffer$'FILE PAGE OPERATIONS'
[length: pLength | |
	 "...sets the number of bytes in the page buffer."
	fLength ← pLength.
	super length: pLength].
"120" JuniperPageBuffer$'FILE PAGE OPERATIONS'
[length | |
	 "...returns the number of bytes in the page buffer."
	↑fLength].
"291" JuniperPageBuffer$'DOCUMENTATION'
[implementationNotes | |
	 "
FIELDS
fLength : an Integer specifiying the number of bytes in the page buffer.
fPageNumber : an Integer specifying the number of the page buffer.
fSerialNumber : an Integer specifying the serial number of the page buffer. 
"].
"147" JuniperPageBuffer$'FILE PAGE OPERATIONS'
[pageNumber: pPageNumber | |
	 "...sets the page number of the page buffer."
	fPageNumber ← pPageNumber].
"172" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[entryClass | |
	 "...returns the class of objects managed by JuniperFileController objects."
	↑JuniperPageBuffer].
"833" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[Get: pPageBuffer | tNextPageNumber tNewPageNumber i |
	 "...reads the data from the page whose number is that specified by pPageBuffer (a JuniperPageBuffer) if such a page exists.  Otherwise pPageBuffer should contains data to be written on the file at the appropriate place."
	tNewPageNumber ← pPageBuffer pageNumber.
	(tNewPageNumber  lastpn and: [(lastpn > 1 or: [self length > 0])])
	  ifTrue: [↑self Read: pPageBuffer].
	tNextPageNumber ← lastpn + 1.
	tNewPageNumber = tNextPageNumber
	  ifFalse:
		[self length: tNewPageNumber - 1 * pPageBuffer dataLength.
		(tNextPageNumber to: tNewPageNumber - 1) do:
			[:i | pPageBuffer pageNumber: i.
			pPageBuffer ← self writePage: pPageBuffer]].
	pPageBuffer pageNumber: tNewPageNumber.
	pPageBuffer length: 0.
	↑pPageBuffer].
"155" JuniperFileController$'MISC (internal)'
[longFileHandle: pLongFileHandle | |
	 "...sets the file's long file handle."
	fLongFileHandle ← pLongFileHandle].
"163" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[close | |
	 "...closes the file on the Juniper file system."
	self doAction: sCloseFile requestPrs: nil].
"330" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[length | tResult |
	 "...returns the number of bytes (an Integer) in the file."
	tResult ← self doAction: sReadLength requestPrs: nil "1".
	↑tResult longInteger: 1 "2" "
1. Issue a 'read length' command to Juniper.
2. Return the length from the result parameter block.
"].
"263" JuniperFileController$'DOCUMENTATION'
[implementationNotes | |
	 "
FIELDS
fLongFileHandle : a LongInteger representing the unique identifier for the file.
fShortFileHandle : an Integer representing the identifier for the file during a particular transaction.
"].
"879" JuniperFileController$'MISC (internal)'
[doAction: pAction requestPrs: pRequest | |
	 "...the specified request, pAction, (selected from gJuniperConstants) with its corresponding request parameter block, pRequest ( a JuniperRequestParameter Block), is issued to the Juniper file server (through the file interface).  If no errors are found, a JuniperResultParameterBlock is returned; otherwise, error handling is invoked.  If no request parameters are required, pRequest can be specified as nil."
	pRequest  nil
	  ifTrue:
		[pRequest ← self newRequestParameterBlock] "1".
	pRequest shortFileHandle← fShortFileHandle "2".
	↑self interface doAction: pAction requestPrs: pRequest "3" "
1. Create a new request parameter block if one is not specified.
2. Set the short file handle parameter.
3. Issue the request to the Juniper interface and return the result parameter block.
"].
"123" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[lastFullPage | |
	↑self length / self entryClass new dataLength].
"1011" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[Write: pPageBuffer | tPageNumber |
	 "...adjusts the length of the file if pPageBuffer is the last page, sends the data buffered in pPageBuffer (a JuniperPageBuffer) to the Juniper file system, and returns pPageBuffer."
	tPageNumber ← pPageBuffer pageNumber.
	tPageNumber < lastpn
	  ifFalse:
		[ "1"
		tPageNumber > (lastpn + 1)
		  ifTrue: [↑self error: 'invalid page number'].
		 "2"
		self length: tPageNumber - 1 * pPageBuffer dataLength + pPageBuffer length "3"].
	self writePage: pPageBuffer "4".
	↑pPageBuffer "5" "
1. If the page number of pPageBuffer is less than the last page number of the file, do not readjust the file length.
2. If the page number of pPageBuffer is greater than the next available page number for the file, invoke error handling.
3. If pPageBuffer is the last page of the file or will immediately follow the last page of the file, adjust the file length.
4. Send the data to Juniper.
5. Return pPageBuffer unmodified.
"].
"181" JuniperFileController$'MISC (internal)'
[newRequestParameterBlock | |
	 "...initializes and returns a new JuniperRequestParameterBlock."
	↑self interface newRequestParameterBlock].
"668" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[open | tRequest tResult |
	 "...opens the file on the Juniper file system."
	tRequest ← self newRequestParameterBlock "1".
	tRequest nextDataBlockString← fLongFileHandle "2".
	tResult ← self interface doAction: sOpenFile requestPrs: tRequest "3".
	fShortFileHandle ← tResult parameter: 1 "4".
	self findLastPage "5" "
1. Create a new request parameter block.
2. Set the long file handle parameter.
3. Issue an 'open file' command to Juniper.
4. Set the superClass field serialNumber to the short file handle returned by Juniper in the result parameter block.
5. Set the number of the last page of the file.
"].
"225" JuniperRequestParameterBlock$'OPERATIONS'
[parameter: pIndex ← pValue | |
	 "...sets pValue (an Integer) in the packet at the request parameter field specified by pIndex (an Integer)."
	fPacket word: (16 + pIndex) ← pValue].
"1164" JuniperRequestParameterBlock$'OPERATIONS'
[nextDataBlockString← pString | tDataBlock tString tLength tMaxLength |
	 "...sets pString (a String) in the data block at the current position and advances the position."
	fPacket pupLength← 554 "1".
	tDataBlock ← self dataBlockGet "2".
	tLength ← pString length "3".
	tMaxLength ← tLength + 1 land: 2 "4".
	tDataBlock nextword← tLength "5".
	tDataBlock nextword← tMaxLength "6".
	tDataBlock append: pString "7".
	tDataBlock next: (tMaxLength - tLength) ← 0 "8".
	self dataBlockAdvance: 4 + tMaxLength "9" "
1. Set the length of the packet to the maximum size.  The length of each string in the data block is specified in the data block itself.
2. Get the data block (as a Stream) from the current position to the end.
3. Get the length of pString.
4. Determine the length of pString including padding needed to make its length even.
5. Set the length of pString in the data block (2 bytes).
6. Set the length of pString with padding in the data block (2 bytes).
7. Set pString in the data block.
8. Add padding in the data block.
9. Advance the current data block position past length, maximum length, and pString.
"].
"216" JuniperRequestParameterBlock$'OPERATIONS'
[shortFileHandle← pShortFileHandle | |
	 "...sets the request short file handle field in the packet to pShortFileHandle (an Integer)."
	fPacket word: 15 ← pShortFileHandle].
"568" JuniperRequestParameterBlock$'OPERATIONS'
[longInteger: pPosition ← pValue | tString tPosition |
	 "...sets pValue (4 bytes of long integer) in the packet at the parameter position specified by pPosition (an Integer)."
	tString ← fPacket pupString.
	tPosition ← pPosition + 16 * 2 - 1.
	(Stream new of: tString from: tPosition to: tPosition + 3) nextNumber: 4 ← pValue.
	tString swap: tPosition with: tPosition + 2.
	tString swap: tPosition + 1 with: tPosition + 3 "
1. the two words of a Juniper long integers are stored in reverse order from those in Smalltalk.
"].
"169" JuniperRequestParameterBlock$'OPERATIONS'
[opcode← pOpcode | |
	 "...sets the request opcode field in the packet to pOpcode (an Integer)."
	fPacket word: 16 ← pOpcode].
"150" JuniperParameterBlock$'OPERATIONS'
[dataBlockLength | |
	 "...returns the number of bytes (an Integer) in the data block."
	↑fPacket pupLength - 42].
"203" JuniperParameterBlock$'OPERATIONS'
[leader: pIndex ← pValue | |
	 "...sets pValue (an Integer) in the packet at the leader word specified by pIndex (an Integer)."
	fPacket word: (12 + pIndex) ← pValue].
"175" JuniperParameterBlock$'OPERATIONS'
[dataBlockLength← pLength | |
	 "...sets the number of bytes in the data block to pLength (an Integer)."
	fPacket pupLength← pLength + 42].
"193" JuniperParameterBlock$'OPERATIONS'
[dataBlockAdvance: pIncrement | |
	 "...advances the data block position by pIncrement (an Integer)."
	fDataBlockPosition ← fDataBlockPosition + pIncrement].
"263" JuniperParameterBlock$'DOCUMENTATION'
[implementationNotes | |
	 "
FIELDS
fPacket : a Pacbuf for sending request commands and parameters to the Juniper file server.
fDataBlockPosition : an Integer specifying the current position in the data block of fPacket.
"].
"179" JuniperParameterBlock$'OPERATIONS'
[leader: pIndex | |
	 "...returns the leader word (an Integer) specified by pIndex (an Integer) from the packet."
	↑fPacket word: 12 + pIndex].
"124" JuniperParameterBlock$'OPERATIONS'
[pupType | |
	 "...returns the pup type (an Integer) of the packet."
	↑fPacket pupType].
"184" JuniperParameterBlock$'OPERATIONS'
[packet← pPacket | |
	 "...sets the packet to pPacket (a Pacbuf) and resets the data block position."
	fPacket ← pPacket.
	fDataBlockPosition ← 45].
"152" JuniperParameterBlock$'OPERATIONS'
[pupType← pPupType | |
	 "...sets the pup type of the packet to pPupType (an Integer)."
	fPacket pupType← pPupType].
"97" JuniperParameterBlock$'OPERATIONS'
[packet | |
	 "...returns the packet (a Pacbuf)."
	↑fPacket].
"196" JuniperParameterBlock$'OPERATIONS'
[dataBlockGet | |
	 "...returns the current data block as a Stream."
	↑Stream new of: fPacket pupString from: fDataBlockPosition to: 4 + fPacket pupLength - 2].
"909" JuniperFileController$'FILE REDEFINITIONS (restricted)'
[writePage: pPageBuffer | tRequest |
	 "...sends the data buffered in pPageBuffer (a JuniperPageBuffer) to the Juniper file system provided the buffer is not empty."
	pPageBuffer length = 0
	  ifFalse:
		[ "1"
		tRequest ← JuniperRequestParameterBlock new "2".
		tRequest packet← pPageBuffer page "3".
		tRequest leader: 1 ← 0.
		tRequest leader: 2 ← 0 "4".
		tRequest parameter: 1 ← pPageBuffer pageNumber - 1 "5".
		self doAction: sWritePage requestPrs: tRequest "6"] "
1. If there is no data in pPageBuffer do nothing.
2. Create a new request parameter block.
3. Set the packet to that of pPageBuffer.  This contains the data to be written on the Juniper file.
4. Set the authentication key and reserved word to 0.
5. Set the page number parameter to that of pPageBuffer less 1.  Juniper page numbers start at 0.
6. Issue a 'write page' request.
"].
"204" ParsedFieldReference$'Decompiling'
[printon: strm indent: level precedence: p forValue: v decompiler: decompiler | |
	var printon: strm indent: level precedence: p forValue: true decompiler: decompiler].
"154" ParsedFieldReference$'Code generation'
[sizeForValue | |
	↑2 + toLoadVar sizeForValue + toLoadFieldReference sizeForValue + toObjectOffset sizeForValue].
"336" ParsedFieldReference$'Code generation'
[emitForValue: code on: stack | |
	(var isField
	  ifTrue: [toLoadSelf]
	  ifFalse: [toLoadTempframe]) emitForValue: code on: stack.
	toLoadVar emitForValue: code on: stack.
	toLoadFieldReference emitForValue: code on: stack.
	code next← toNew.
	toObjectOffset emitBytes: code.
	.
	stack pop: 2].
"58" ParsedFieldReference$'Code generation'
[local | |
	↑var].
"63" ParsedFieldReference$'Initialization'
[var: t1 | |
	var ← t1].
"90" ParsedFieldReference$'Miscellaneous'
[printon: s | |
	s append: 'FLD=> '.
	s print: var].
"143" ParsedFieldReference$'Decompiling'
[findMacros: macros compilerTemps: compilerTemps | |
	var findMacros: macros compilerTemps: compilerTemps].
"231" ParsedFieldReference$'Code generation'
[remote: generator | |
	toLoadVar ← generator literal: (var land: 127) + 1.
	toLoadFieldReference ← generator literal: FieldReference.
	toObjectOffset ← generator encodeSel: #object:offset:].
"160" ParsedObjectReference$'Decompiling'
[printon: strm indent: level precedence: p forValue: v decompiler: decompiler | |
	strm append: (decompiler literal: var)].
"87" ParsedObjectReference$'Code generation'
[sizeForValue | |
	↑(var - 256) sizeForValue].
"162" ParsedObjectReference$'Code generation'
[emitForValue: code on: stack | |
	 "Turn literal indirect into literal direct"
	var - 256 emitForValue: code on: stack].
"59" ParsedObjectReference$'Code generation'
[local | |
	↑var].
"64" ParsedObjectReference$'Initialization'
[var: t1 | |
	var ← t1].
"91" ParsedObjectReference$'Miscellaneous'
[printon: s | |
	s append: 'OBJ=> '.
	s print: var].
"144" ParsedObjectReference$'Decompiling'
[findMacros: macros compilerTemps: compilerTemps | |
	var findMacros: macros compilerTemps: compilerTemps].
"67" ParsedObjectReference$'Code generation'
[remote: generator | |
	].
"105" DictionaryEntry$'Filing'
[storeOn: file | |
	self subError "store self as fileSize characters on file"].
"43" DictionaryEntry$'Initialize'
[init | |
	].
"85" DictionaryEntry$'Other'
[dictionary | |
	↑false "what dictionary did I come from?"].
"55" DictionaryEntry$'Initialize'
[dictionary: dict | |
	].
"107" DictionaryEntry$'Other'
[match: entry | |
	self subError "does self (some kind of pattern) match entry?"].
"84" DictionaryEntry$'Filing'
[readFrom: file | |
	self subError "inverse of storeOn:"].
"49" DictionaryEntry$'Initialize'
[name: name | |
	].
"88" DictionaryEntry$'Filing'
[fileSize | |
	self subError "size in characters for filing"].
"384" Document$'SYSTEM'
[fromPress: t1 | press s |
	displayorder ← t1.
	user displayoffwhile [
		 "retrieves an instance of class Document from a press file"
		(self default.
		press ← dp0 pressfile: displayorder.
		press open.
		s ← press nextControl asStream.
		s next = self pressCode
		  ifTrue: [self fromPress: press value: s]
		  ifFalse:
			[user notify: 'error in pressfile'])]].
"277" Heading$'EDIT'
[up | delta |
	self boxcomp "move the current character up one bit.".
	self  currentcharacter translate: 0  0 - (0  1).
	delta ← origin copy.
	self translate: 0  0 - delta.
	self resize.
	self translate: delta.
	self white.
	self display: 1.
	self boxcomp].
"67" Heading$'SYSTEM'
[printon: strm | t |
	strm append: 'a Heading '].
"346" Heading$'EDIT'
[right | i delta |
	self boxcomp "move the current character and all those to the right of it to the right one bit.".
	(currentcharacter to: self length) do: [:i | self  i translate: 1  0].
	delta ← origin copy.
	self translate: 0  0 - delta.
	self resize.
	self translate: delta.
	self white.
	self display: 1.
	self boxcomp].
"604" Heading$'SYSTEM'
[presson: press in: r | hs y t i pressscale |
	(hs ← press scale * self height) > r height
	  ifTrue: [↑self].
	 "not enough room left on current page.
		assume for now that it will at least fit on an entire page"
	self hidePress: press complete: 1.
	pressscale ← press scale.
	press selectfont: (press fontindex: 16 * index style: DefaultTextStyle) - 1.
	(1 to: self length) do:
		[:i | press setx: r leftside + ((self  i) leftside * pressscale).
		press sety: r bottom - ((self  i) top * pressscale).
		press showchar: charactercodes  i].
	↑r bottom - (self height * pressscale)].
"616" Heading$'INIT'
[origin: t1 index: t2 charactercodes: t3 currentcharacter: t4 | char w delta |
	origin ← t1.
	index ← t2.
	charactercodes ← t3.
	currentcharacter ← t4.
	formset ← FormSet new "initilization of a Heading (used in copy)" fromstyle: DefaultTextStyle styleindex: index.
	nil  charactercodes
	  ifTrue: [charactercodes ← Set new default].
	self origin: origin extent: 200  formset height.
	w ← 0.
	delta ← origin copy.
	self translate: 0  0 - delta.
	charactercodes do:
		[:char | char ← formset asForm: char.
		self addpath: w  0 andform: char.
		w ← w + char width].
	self translate: delta.
	↑self].
"271" Heading$'EDIT'
[down | delta |
	self boxcomp "move the current character down one bit.".
	self  currentcharacter translate: 0  1.
	delta ← origin copy.
	self translate: 0  0 - delta.
	self resize.
	self translate: delta.
	self white.
	self display: 1.
	self boxcomp].
"121" Heading$'INIT'
[classInit | |
	headingmenu ← Menu new "menu for the Heading edits." string: 'right
left
up
down
font
'].
"354" Heading$'EDIT'
[left | i delta |
	self boxcomp "move the current character and all those to the right of it to the left one bit.".
	(currentcharacter to: self length) do: [:i | self  i translate: 0  0 - (1  0)].
	delta ← origin copy.
	self translate: 0  0 - delta.
	self resize.
	self translate: delta.
	self white.
	self display: 1.
	self boxcomp].
"308" Heading$'SYSTEM'
[hideData: complete | s i |
	s ← Stream new "stores an instance of class Heading on a press file" of: (String new: 100).
	s nextword← self length "number of characters".
	s nextPoint← origin.
	s nextword← index.
	(1 to: self length) do: [:i | s nextword← charactercodes  i].
	↑s contents].
"38" Heading$'SYSTEM'
[pressCode | |
	↑2].
"260" Heading$'SYSTEM'
[copy | h i |
	h ← Heading new origin: rectangle origin copy index: index charactercodes: charactercodes copy currentcharacter: currentcharacter copy.
	h rectangle: rectangle copy.
	(1 to: self length) do: [:i | h add: (self  i) copy].
	↑h].
"1260" Heading$'EDIT'
[edit: parentimage | pt t3 |
	self display: 0 "Simple Heading (line) editor for now.".
	[1 = 2] whileFalseDo: 
		[ "forever for now"
		user kbck
		  ifTrue: [self typein]
		  ifFalse:
			[user yellowbug
			  ifTrue:
				[(t3 ← headingmenu bug) = 1
				  ifTrue: [self right]
				  ifFalse:
					[ "move current character right one bit"
					t3 = 2
					  ifTrue: [self left]
					  ifFalse:
						[ "move current character left one bit"
						t3 = 3
						  ifTrue: [self up]
						  ifFalse:
							[ "move current character up one bit"
							t3 = 4
							  ifTrue: [self down]
							  ifFalse:
								[ "move current character down one bit"
								t3 = 5
								  ifTrue: [self newfont] "change fonts"]]]]]
			  ifFalse:
				[user redbug
				  ifTrue:
					[(rectangle has: (pt ← user mp))
					  ifTrue:
						[pt ← pt - rectangle origin.
						currentcharacter ← self indexofsubimageat: pt.
						currentcharacter
						  ifTrue:
							[self  currentcharacter displayat: self origin effect: 2 clippedBy: user screenrect.
							self  currentcharacter displayat: self origin effect: 2 clippedBy: user screenrect]]
					  ifFalse: [↑self]]
				  ifFalse:
					[user bluebug
					  ifTrue: [↑self] "exit back to the parentimage"]]]]].
"812" Heading$'EDIT'
[typein | w char charcount delta i |
	self white.
	(1 to: position) do: [:i | self  i ← nil].
	position ← 0.
	w ← 0.
	charcount ← 0.
	charactercodes ← Set new default.
	delta ← origin copy.
	self translate: 0  0 - delta.
	[(char ← user kbd) = 13] whileFalseDo: 
		[char = 8
		  ifTrue:
			[ "back space"
			charcount  0
			  ifTrue:
				[w ← w - (self  charcount) width.
				(self  charcount) white.
				self deleteimage: charcount.
				charactercodes deleteI: charcount.
				charcount ← charcount - 1]]
		  ifFalse:
			[charactercodes add: char.
			char ← formset asForm: char.
			char displayat: delta + (w  0) effect: 0 clippedBy: user screenrect.
			self addpath: w  0 andform: char.
			w ← w + char width.
			charcount ← charcount + 1]].
	self resize.
	self translate: delta.
	↑self].
"324" Heading$'INIT'
[origin: t1 formset: t2 currentcharacter: t3 | |
	origin ← t1.
	formset ← t2.
	currentcharacter ← t3.
	 "initilization of a Heading (used in copy)"
	(formset is: Integer)
	  ifTrue:
		[formset ← FormSet new fromstyle: DefaultTextStyle styleindex: formset].
	self origin: origin extent: 200  formset height].
"411" Heading$'SYSTEM'
[fromPress: press value: s | numberofcharacters i |
	numberofcharacters ← s nextword "retrieves and builds an instance of class Heading from a press file".
	origin ← s nextPoint.
	index ← s nextword.
	charactercodes ← Set new default.
	(1 to: numberofcharacters) do: [:i | charactercodes add: s nextword].
	↑self origin: origin index: index charactercodes: charactercodes currentcharacter: 1].
"637" Heading$'EDIT'
[newfont | w char charcount delta i |
	index ← (user request: 'index of new font . .  ') asInteger.
	formset ← FormSet new fromstyle: DefaultTextStyle styleindex: index.
	self white.
	(1 to: position) do: [:i | self  i ← nil].
	position ← 0.
	w ← 0.
	charcount ← 0.
	delta ← origin copy.
	self translate: 0  0 - delta.
	charactercodes do:
		[:char | nil  char
		  ifFalse:
			[char ← formset asForm: char.
			char displayat: delta + (w  0) effect: 0 clippedBy: user screenrect.
			self addpath: w  0 andform: char.
			w ← w + char width.
			charcount ← charcount + 1]].
	self resize.
	self translate: delta.
	↑self].
"769" Document$'SYSTEM'
[fromPress: press value: s | numberofsubimages t t1 i code |
	numberofsubimages ← s nextword "builds an instance of class Document from a press file".
	origin ← s nextPoint.
	t ← s nextPoint.
	t1 ← s nextPoint.
	rectangle ← t rect: t1.
	xgrid ← s nextword.
	ygrid ← s nextword.
	displayorder ← s nextString.
	(1 to: numberofsubimages) do:
		[:i | s ← press nextControl asStream.
		code ← s next.
		t ← (code = 1
				  ifTrue: [Image new]
				  ifFalse:
					[code = 2
					  ifTrue: [Heading new]
					  ifFalse:
						[code = 3
						  ifTrue: [BitImage new]
						  ifFalse: [false]]]).
		(t and: [code = t pressCode])
		  ifTrue: [self addimage: (t fromPress: press value: s)]
		  ifFalse: [user notify: 'illegal code or code mismatch']].
	↑self].
"154" Document$'EDITING'
[delete: image | i |
	i ← self find: image "delete image from the document and leave its space. ".
	i
	  ifTrue:
		[self deleteI: i]].
"156" Document$'INIT'
[name: t1 | |
	displayorder ← t1 "sets the name of the document ( displayorder is currently used for name... note that name is a string."].
"69" Document$'SYSTEM'
[printon: strm | t |
	strm append: 'a Document '].
"54" Document$'INIT'
[classInit | |
	micasperinch ← 2540].
"358" Document$'SYSTEM'
[hideData: complete | s |
	s ← Stream new "stores an instance of class Document from a press file" of: (String new: 100).
	s nextword← self length "number of subimages".
	s nextPoint← origin.
	s nextPoint← rectangle origin.
	s nextPoint← rectangle corner.
	s nextword← xgrid.
	s nextword← ygrid.
	s nextString← displayorder.
	↑s contents].
"39" Document$'SYSTEM'
[pressCode | |
	↑0].
"418" DocumentEditor$'FRAMING'
[show | |
	XeqCursor show.
	self outline.
	growing
	  ifFalse:
		[titleframe put: (Paragraph new text: self title runs: titlerun alignment: 0) at: frame origin + titleloc.
		titleframe window outline.
		titleframe show.
		screenimage white.
		screenimage displayat: 0  0 effect: 1 clippedBy: self frame.
		selection
		  ifTrue: [selection boxcomp]
		  ifFalse:
			[.
			NormalCursor show]]].
"131" DocumentEditor$'EDITING'
[editTitle | |
	titlepara ← document name asParagraph.
	super editTitle.
	document name: titlepara text].
"171" DocumentEditor$'EDITING'
[deselect | t |
	selection
	  ifTrue:
		[selection translate: 0  0 - screenimage origin.
		selection do: [:t | t translate: selection origin]]].
"512" DocumentEditor$'EDITING'
[place | pt tempimage t |
	 "add the image in the scrap to the screenimage."
	selection
	  ifTrue: [selection highlite].
	self deselect.
	selection ← scrap copy.
	OriginCursor showwhile [
		(user waitbug.
		[user nobug] whileFalseDo: 
			[pt ← screenimage mp + screenimage rectangle origin.
			selection translateto: pt.
			selection blink])].
	selection displayat: 0  0 effect: 1 clippedBy: self frame.
	self deselect.
	selection do:
		[:t | screenimage add: t].
	selection ← false].
"551" DocumentEditor$'EDITING'
[move | pt t |
	selection
	  ifTrue:
		[ "used to place subimages (paragraphs) in the Image."
		user waitnobug.
		OriginCursor show.
		user waitbug.
		selection highlite.
		selection displayat: 0  0 effect: 3 clippedBy: frame.
		[user redbug] whileTrueDo:
			[pt ← screenimage mp + screenimage rectangle origin.
			selection translateto: pt.
			selection blink].
		XeqCursor show.
		selection displayat: 0  0 effect: 1 clippedBy: frame.
		self deselect.
		selection ← false.
		NormalCursor show]
	  ifFalse: [frame flash]].
"223" DocumentEditor$'EDITING'
[copyselection | |
	selection
	  ifTrue:
		[ "copy the selection and put it in scrap"
		XeqCursor show.
		self closeScrap.
		scrap ← selection copy.
		NormalCursor show]
	  ifFalse: [frame flash]].
"1254" DocumentEditor$'EDITING'
[jump | y deltay yprime deltayprime rect pt newY scal r |
	user waitnobug.
	XeqCursor show.
	self update.
	y ← document height.
	yprime ← frame height.
	deltay ← documentwindow origin y - document origin y.
	scal ← yprime asFloat / y.
	deltayprime ← (scal * deltay) asInteger.
	pt ← screenimage leftside + (1.0 - scal * frame width / 2)  (screenimage top + deltayprime).
	document quickDisplayAt: 0  0 scale: scal offset: frame minX + (1.0 - scal * frame width / 2)  frame minY.
	rect ← 0  0 rect: 1  1.
	rect origin← pt.
	rect corner x← pt x + (scal * frame width) asInteger.
	rect corner y← pt y + (scal * frame height) asInteger.
	user cursorloc← pt.
	OriginCursor show.
	user waitbug.
	user redbug
	  ifTrue:
		[rect comp.
		[user redbug] whileTrueDo:
			[r ← rect copy.
			newY ← user mp y.
			newY < (frame minY - rect height)
			  ifTrue: [newY ← frame minY - rect height].
			newY > frame maxY
			  ifTrue: [newY ← frame maxY].
			rect translateto: pt x  newY.
			r comp.
			rect comp].
		rect comp.
		XeqCursor show.
		deltayprime ← newY - frame origin y.
		deltay ← y * deltayprime / yprime.
		documentwindow translateto: 0  deltay.
		selection ← false].
	self buildscreenimage.
	self show.
	NormalCursor show].
"898" DocumentEditor$'DEFAULT EVENT RESPONSES'
[yellowbug | pt t2 |
	(t2 ← documentmenu bug) = 1
	  ifTrue: [self move]
	  ifFalse:
		[t2 = 2
		  ifTrue: [self delete]
		  ifFalse:
			[t2 = 3
			  ifTrue: [self place]
			  ifFalse:
				[t2 = 4
				  ifTrue: [self cut]
				  ifFalse:
					[t2 = 5
					  ifTrue: [self paste]
					  ifFalse:
						[t2 = 6
						  ifTrue: [self copyselection]
						  ifFalse:
							[t2 = 7
							  ifTrue: [self top]
							  ifFalse:
								[t2 = 8
								  ifTrue: [self bottom]
								  ifFalse:
									[t2 = 9
									  ifTrue: [self jump]
									  ifFalse:
										[t2 = 10
										  ifTrue: [self addspace]
										  ifFalse:
											[t2 = 11
											  ifTrue: [self deletespace]
											  ifFalse:
												[t2 = 12
												  ifTrue:
													[self deselect.
													selection ← false.
													self show]]]]]]]]]]]]].
"54" DocumentEditor$'FRAMING'
[title | |
	↑document name].
"406" DocumentEditor$'EDITING'
[addspace | image i k r delta |
	self update "add whitespace to the document  .".
	selection ← false.
	r ← document rectanglefromuser.
	i ← document indexofsubimagebelow: r top - screenimage top + documentwindow top.
	i
	  ifTrue:
		[delta ← r height.
		(i to: document length) do: [:k | document  k translate: 0  delta].
		document resize].
	self buildscreenimage.
	self show].
"386" DocumentEditor$'INIT'
[init: t1 | i |
	document ← t1.
	self fixedwidthfromuser: document width "This is the paragraph (subimage) level document editor.".
	documentwindow ← Rectangle new origin: document rectangle origin extent: document width  self frame height.
	self buildscreenimage.
	selection ← false.
	user topWindow leave.
	self takeCursor.
	self enter.
	user restartup: self].
"98" DocumentEditor$'EDITING'
[copy | |
	self copyselection "copy the selection and put it in scrap"].
"383" DocumentEditor$'EDITING'
[update | i |
	XeqCursor topage1 "update the document to reflect any changes in the subimages .".
	selection
	  ifTrue: [self deselect].
	document deleteI: firstindex to: lastindex "update document".
	(1 to: screenimage length) do:
		[:i | document insert: (screenimage  i translate: 0  documentwindow origin y)].
	document resize.
	NormalCursor topage1].
"148" DocumentEditor$'DEFAULT EVENT RESPONSES'
[hardcopy | |
	self leave "write a press file and hardcopy this document".
	self top.
	document hardcopy].
"121" DocumentEditor$'DEFAULT EVENT RESPONSES'
[print | |
	document hardcopy "write a press file and hardcopy this document"].
"468" DocumentEditor$'DEFAULT EVENT RESPONSES'
[kbd | c x y |
	c ← user kbd.
	c = 120
	  ifTrue:
		[user clearshow: 'x gridding is '.
		document xgrid print.
		user cr.
		document xgrid: (x ← (user request: 'x gridding . . . ') asInteger).
		screenimage xgrid: x]
	  ifFalse:
		[c = 121
		  ifTrue:
			[user clearshow: 'y gridding is '.
			document ygrid print.
			user cr.
			document ygrid: (y ← (user request: 'y gridding . . . ') asInteger).
			screenimage ygrid: y]]].
"939" DocumentEditor$'DEFAULT EVENT RESPONSES'
[redbug | pt rect newrect start t |
	pt ← user mp.
	start ← pt.
	rect ← newrect ← Rectangle new origin: start corner: start.
	selection
	  ifTrue:
		[selection highlite.
		self deselect.
		selection ← false].
	[user anybug] whileTrueDo:
		[rect ← newrect.
		rect comp.
		t ← user mp.
		newrect ← Rectangle new origin: (start min: t) corner: (start max: t).
		rect comp].
	rect width < 10
	  ifTrue:
		[selection ← screenimage smallestsubimageat: pt - screenimage origin.
		selection
		  ifTrue:
			[selection translate: screenimage origin.
			selection edit: screenimage.
			selection translate: 0  0 - screenimage origin.
			selection ← false]]
	  ifFalse:
		[rect origin← screenimage griddedpoint: rect origin.
		selection ← screenimage subimageswithin: (rect translate: 0  0 - screenimage origin).
		selection
		  ifTrue:
			[selection translate: screenimage origin.
			selection highlite]]].
"831" DocumentEditor$'INIT'
[buildscreenimage | i r delta |
	screenimage ← Image new "This function copies the subimages intersecting the document window
		into the screen image." origin: self frame origin extent: self frame extent.
	screenimage xgrid: document xgrid.
	screenimage ygrid: document ygrid.
	delta ← documentwindow origin y.
	firstindex ← 1 " find the index of the first subimage that intersects the document window.".
	[firstindex  document length or: [(document  firstindex) rectangle bottom > documentwindow top]] whileFalseDo:  [firstindex ← firstindex + 1].
	lastindex ← firstindex.
	(firstindex to: document length) do:
		[:i | (document  i) rectangle top < documentwindow bottom
		  ifTrue:
			[lastindex ← i.
			screenimage add: (document  i translate: 0  0 "copy" - (0  delta))]
		  ifFalse: [↑lastindex]]].
"79" DocumentEditor$'INIT'
[defaultdocument | |
	self defaultdocument: 'document'].
"1011" DocumentEditor$'INIT'
[defaultdocument: name | defaultdocument run r textimage f im dot heading head text char b image row |
	defaultdocument ← Document new " name is a string" origin: 0  0 extent: user screenrect extent.
	defaultdocument name: name.
	defaultdocument xgrid: DefaultTextStyle tab.
	defaultdocument ygrid: DefaultTextStyle lineheight.
	textimage ← BorderedText new.
	textimage text: 'Text that is bordered' width: 200.
	defaultdocument addform: textimage andpath: 0  0.
	textimage ← TextImage new.
	textimage text: 'This is a paragraph' width: 600.
	defaultdocument addform: textimage andpath: 0  0.
	b ← BitImage new fromrectangle: (Rectangle new origin: 0  200 extent: 100  100).
	defaultdocument insert: b.
	head ← Set new default.
	text ← 'HEADING'.
	text do: [:char | head add: char].
	heading ← Heading new origin: 0  400 index: 9 charactercodes: head currentcharacter: 0.
	defaultdocument insert: heading "defaultdocument insert: CurveIdiom new init.".
	self init: defaultdocument].
"190" DocumentEditor$'DEFAULT EVENT RESPONSES'
[leave | |
	document  nil
	  ifFalse:
		[selection
		  ifTrue: [selection highlite].
		self update.
		self buildscreenimage.
		selection ← false]].
"371" DocumentEditor$'EDITING'
[cut | t |
	selection
	  ifTrue:
		[ "delete subimage (paragraph) from the screenimage and save it in the scrap"
		XeqCursor show.
		self closeScrap.
		scrap ← selection.
		self update.
		selection do:
			[:t | document bubbledelete: t].
		selection ← false.
		self buildscreenimage.
		self show.
		NormalCursor show]
	  ifFalse: [frame flash]].
"132" DocumentEditor$'FRAMING'
[newframe | |
	self update.
	self fixedwidthfromuser: document width.
	self buildscreenimage.
	self show].
"85" DocumentEditor$'DEFAULT EVENT RESPONSES'
[enter | |
	selection ← false.
	self show].
"510" DocumentEditor$'INIT'
[classInit | |
	 "  DocumentEditor classInit.    "
	documentmenu ← Menu new string: 'move
erase
place
cut
paste
copy
top
bottom
jump
addspace
deletespace
show
'.
	jumpcursor ← Cursor new fromtext: '
1111111111111111
1111111111111111
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000001110000000
0000011111000000
0000011111000000
0000001110000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
1111111111111111
1111111111111111' offset: 2  1].
"593" DocumentEditor$'EDITING'
[paste | pt t |
	 "add the subimage (paragraph) in the scrap to the screenimage."
	selection
	  ifTrue: [selection highlite].
	self update.
	selection ← scrap copy.
	OriginCursor showwhile [
		(user waitbug.
		[user nobug] whileFalseDo: 
			[pt ← screenimage mp + screenimage rectangle origin.
			selection translateto: pt.
			selection blink].
		selection displayat: 0  0 effect: 1 clippedBy: self frame)].
	self deselect.
	selection do:
		[:t | document bubbleinsert: (t translate: documentwindow origin)].
	selection ← false.
	self buildscreenimage.
	self show].
"154" DocumentEditor$'DEFAULT EVENT RESPONSES'
[close | |
	XeqCursor show.
	document close.
	document ← nil.
	screenimage ← Vector new: 0.
	NormalCursor show].
"420" DocumentEditor$'EDITING'
[deletespace | image i k r delta |
	self update "delete whitespace from the document  .".
	selection ← false.
	r ← document rectanglefromuser.
	i ← document indexofsubimagebelow: r top - screenimage top + documentwindow top.
	i
	  ifTrue:
		[delta ← r height.
		(i to: document length) do: [:k | document  k translate: 0  (0 - delta)].
		document resize].
	self buildscreenimage.
	self show].
"361" DocumentEditor$'EDITING'
[delete | t |
	selection
	  ifTrue:
		[ "delete subimage (paragraph) from the screenimage and save it in the scrap"
		XeqCursor show.
		self closeScrap.
		scrap ← selection.
		selection highlite.
		selection display: 3.
		selection do: [:t | screenimage delete: t].
		selection ← false.
		NormalCursor show]
	  ifFalse: [frame flash]].
"726" DocumentEditor$'EDITING'
[bottom | i delta |
	selection
	  ifTrue:
		[ "translate the current selection to the bottom of the window and update the document to reflect any changes in the subimages which are scrolled out of the screenimage."
		delta ← selection rectangle corner - screenimage rectangle corner.
		self update.
		selection ← false.
		documentwindow translate: 0  delta y "move window on document".
		self buildscreenimage.
		self show "reconstruct screen image, including reestablishing  first and last indices"]
	  ifFalse:
		[self update.
		documentwindow ← Rectangle new origin: document rectangle corner - self frame height extent: document width  self frame height.
		self buildscreenimage.
		self show]].
"700" DocumentEditor$'EDITING'
[top | i delta |
	selection
	  ifTrue:
		[ "translate the current selection to the top of the window and update the document to reflect any changes in the subimages which are scrolled out of the screenimage."
		delta ← selection rectangle origin - screenimage rectangle origin.
		self update.
		selection ← false.
		documentwindow translate: 0  delta y "move window on document".
		self buildscreenimage.
		self show "reconstruct screen image, including reestablishing  first and last indices"]
	  ifFalse:
		[self update.
		documentwindow ← Rectangle new origin: document rectangle origin extent: document width  self frame height.
		self buildscreenimage.
		self show]].
"82" DocumentEditor$'EDITING'
[closeScrap | |
	scrap  nil
	  ifFalse: [scrap close]].
"107" Document$'EDITING'
[edit | |
	DocumentEditor new "Documents are edited with a DocumentEditor" init: self].
"276" Document$'EDITING'
[resize | delta t |
	 "make sure the document does not have subimages that have negative y values and resize the document"
	position  1
	  ifTrue:
		[(delta ← (self  1) top)  0
		  ifTrue: [self do: [:t | t translate: 0  (0 - delta)]]].
	super resize].
"151" Document$'INIT'
[name | |
	↑displayorder "returns the name of the document ( displayorder is currently used for name... note that name is a string."].
"297" Document$'SYSTEM'
[copy | im i |
	im ← Document new origin: origin copy rectangle: rectangle copy path: path copy form: form copy figure: figure copy ground: ground copy xgrid: xgrid copy ygrid: ygrid copy.
	(1 to: self length) do: [:i | im add: (self  i) copy].
	im name: self name copy.
	↑im].
"304" Document$'EDITING'
[bubbledelete: image | delta i k |
	i ← self find: image "delete image from the document  and subtracting images extent y from all subimages below it.".
	i
	  ifTrue:
		[self deleteI: i.
		delta ← image extent y.
		(i to: self length) do: [:k | self  k translate: 0  (0 - delta)]]].
"164" Document$'EDITING'
[insert: image | i |
	i ← self findindex: image "insert image into the document keeping the document y-sorted.".
	self insertI: i value: image].
"603" Document$'EDITING'
[findindex: image | y guess top bottom |
	position = 0 "binary search on the origins of the rectangles surrounding my subimages
		returns the index of the subimage just below image."
	  ifTrue: [↑1].
	top ← 1.
	bottom ← position.
	y ← image rectangle origin y.
	y  (self  1) rectangle origin y
	  ifTrue: [↑1].
	.
	y  (self  position) rectangle origin y
	  ifTrue: [↑position + 1].
	guess ← position / 2.
	[bottom = (top + 1)] whileFalseDo: 
		[(self  guess) rectangle origin y  y
		  ifTrue: [bottom ← guess]
		  ifFalse: [top ← guess].
		guess ← bottom + top / 2].
	↑bottom].
"1356" Document$'SYSTEM'
[hardcopy | p i press bottoms rect pressscale pageheight pagewidth lastrect currentrect oldytop oldybottom |
	oldytop ← 11 * micasperinch.
	pageheight ← 11 * micasperinch.
	pagewidth ← 8 * micasperinch.
	user displayoffwhile [
		(press ← dp0 pressfile: displayorder + '.doc'.
		pressscale ← press scale.
		self hidePress: press complete: 1.
		p ← PressPrinter init.
		p press: press.
		p frame← 1 * micasperinch "in micas"  (1 * micasperinch) rect: pagewidth - micasperinch  (pageheight - micasperinch).
		lastrect ← (self  1) rectangle * pressscale.
		rect ← lastrect leftside  (1 * micasperinch) rect: lastrect rightside  (pageheight - lastrect top).
		oldybottom ← p print: self  1 in: rect.
		(2 to: self length) do:
			[:i | oldybottom > oldytop
			  ifTrue:
				[oldytop ← pageheight - micasperinch "page break"].
			currentrect ← (self  i) rectangle * pressscale.
			currentrect top > lastrect bottom
			  ifTrue: [oldytop ← oldybottom + (lastrect bottom - currentrect top) "no overlap"]
			  ifFalse: [oldytop ← oldytop + (lastrect top - currentrect top) "overlap"].
			rect ← currentrect leftside  (1 * micasperinch) rect: currentrect rightside  oldytop.
			oldybottom ← p print: self  i in: rect.
			lastrect ← (self  i) rectangle * pressscale].
		press close.
		press toPrinter "send over ethernet to printer")]].
"323" Document$'EDITING'
[bubbleinsert: image | delta i k |
	i ← self findindex: image "insert image into the document keeping the document y-sorted and adding images extent y to all subimages below it.".
	self insertI: i value: image.
	delta ← image extent y.
	(i + 1 to: self length) do: [:k | self  k translate: 0  delta]].
"146" JuniperResultParameterBlock$'OPERATIONS'
[resultCode | |
	 "...returns the result code (an Integer) from the result packet."
	↑fPacket word: 15].
"501" JuniperResultParameterBlock$'OPERATIONS'
[longInteger: pPosition | tArray tPosition |
	 "...returns the 4 bytes of long integer in the packet at the parameter position specified by pPosition (an Integer)."
	tPosition ← pPosition + 15 * 2 - 1.
	tArray ← (Stream new of: fPacket pupString from: tPosition to: tPosition + 3) next: 4.
	tArray swap: 1 with: 3.
	tArray swap: 2 with: 4 "1".
	↑tArray asStream nextNumber: 4 "
1. Juniper long integers are stored in reverse order from those in Smalltalk.
"].
"735" JuniperResultParameterBlock$'OPERATIONS'
[nextDataBlockString | tDataBlock tString tLength tMaxLength |
	 "...returns the string in the data block at the current position and advances the position."
	tDataBlock ← self dataBlockGet "1".
	tLength ← tDataBlock nextword "2".
	tMaxLength ← tDataBlock nextword "3".
	tString ← tDataBlock next: tLength "4".
	self dataBlockAdvance: 4 + tMaxLength "5".
	↑tString "6" "
1. Get the data block (as a Stream) from the current position to the end.
2. Get the length of the next string.
3. Get the length of the string including possible padding.
4. Get the next string from the data block.
5. Position the data block past the length, maximum length, string, and padding.
6. Return the string.
"].
"193" JuniperResultParameterBlock$'OPERATIONS'
[parameter: pIndex | |
	 "...returns from the packet the result parameter (an Integer) specified by pIndex (an Integer)."
	↑fPacket word: 15 + pIndex].
"165" MessageTally$'Public Tallying'
[on remote | val |
	 "Spy on the specified evaluation"
	self from: remote.
	timer reset.
	val ← remote eval.
	timer disable.
	↑val].
"169" MessageTally$'Private Reporting'
[leaves: ldict | b mt |
	b ← self breakdown.
	b length = 0
	  ifTrue: [self into: ldict]
	  ifFalse: [b do: [:mt | mt leaves: ldict]]].
"89" MessageTally$'Public Reporting'
[report: filename | |
	self report: filename cutoff: 2].
"64" MessageTally$'Private Reporting'
[> mt | |
	↑tally < mt tally].
"64" MessageTally$'Private Reporting'
[< mt | |
	↑tally > mt tally].
"66" MessageTally$'Private Reporting'
[= mt | |
	↑mt method  method].
"134" MessageTally$'Public Reporting'
[printon: s | |
	class  nil
	  ifTrue: [super printon: s]
	  ifFalse: [self printon: s total: 100]].
"298" MessageTally$'Private Tallying'
[tallyPath: context | m path mt c |
	m ← context method.
	path ← false.
	rcvrs do:
		[:mt | mt method  m
		  ifTrue: [path ← mt]].
	path  false
	  ifTrue:
		[path ← MessageTally new class: context receiver class method: m.
		rcvrs ← {rcvrs , path}].
	↑path bump].
"338" MessageTally$'Private Reporting'
[printon: s total: total | i v |
	v ← (0.0 + tally / total * 1000.0 + 0.5) asInteger asString.
	i ← v length.
	s append: '  '  (i to: 2).
	s append: v  (1 to: i - 1).
	s append: '.'.
	s next← v  i.
	s space.
	rcvrs  nil
	  ifTrue: [s append: 'primitives']
	  ifFalse: [class describe: method on: s]].
"219" MessageTally$'Public Reporting'
[report: filename cutoff: pct | f |
	 "pct=(leaves,roots,tree) or one number for all"
	f ← dp0 file: filename.
	f append: filename.
	f space.
	self fullprinton: f cutoff: pct.
	f close].
"277" MessageTally$'Private Reporting'
[breakdown | n b mt t4 |
	b ← rcvrs.
	(b  nil or: [b length = 0])
	  ifTrue: [↑#()].
	n ← tally.
	b do: [:mt | n ← n - mt tally].
	n > 0
	  ifTrue: [b ← {b , ((t4 ← MessageTally new) class: class method: method.
				t4 primitives: n)}].
	↑b].
"81" MessageTally$'Private Reporting'
[primitives: t1 | |
	tally ← t1.
	rcvrs ← nil].
"53" MessageTally$'Private Common'
[method | |
	↑method].
"60" MessageTally$'Private Reporting'
[hash | |
	↑method asOop].
"120" MessageTally$'Private Common'
[class: t1 method: t2 | |
	class ← t1.
	method ← t2.
	tally ← 0.
	rcvrs ← Vector new: 0].
"345" MessageTally$'As yet unclassified'
[for: number every: sixtieths onClass: newClass andMethod: newMethod | |
	self abort.
	timer ← Timer new for: sixtieths action [
				((number ← number - 1)  0
				  ifTrue: [timer disable]
				  ifFalse:
					[self tally: Top  1.
					timer reset])].
	self class: newClass method: newMethod.
	timer reset].
"280" MessageTally$'Public Tallying'
[tally: context | root |
	 "Explicitly tally the specified context and its stack"
	context method  method
	  ifTrue: [↑self bump].
	(root ← context sender)  nil
	  ifTrue: [↑self bump tallyPath: context].
	↑(self tally: root) tallyPath: context].
"206" MessageTally$'Private Reporting'
[into: set | mt i |
	(i ← set find: self)
	  ifTrue: [mt ← set objects  i]
	  ifFalse: [set insert: (mt ← MessageTally new class: class method: method)].
	mt bump: tally].
"90" MessageTally$'Public Tallying'
[abort | |
	(timer is: Timer)
	  ifTrue: [timer disable]].
"63" MessageTally$'Private Tallying'
[bump | |
	tally ← tally + 1].
"212" MessageTally$'Public Tallying'
[every: sixtieths | |
	 "Create a spy that samples with the specified period"
	self abort.
	timer ← Timer new for: sixtieths action [
				(self tally: Top  1.
				timer reset)]].
"156" MessageTally$'Public Tallying'
[from: context | |
	 "Create a tallier from the specified root"
	self class: context receiver class method: context method].
"93" MessageTally$'Public Tallying'
[reset | |
	tally ← 0 "reset stats".
	rcvrs ← Vector new: 0].
"105" MessageTally$'Public Tallying'
[classInit | |
	Smalltalk define: #spy as: (MessageTally new every: 10)].
"224" MessageTally$'Private Reporting'
[cumprinton: s from: set total: total over: threshold | mt |
	set contents sort do:
		[:mt | mt tally > threshold
		  ifTrue:
			[mt printon: s total: total.
			s cr]
		  ifFalse: [↑self]]].
"102" MessageTally$'Public Tallying'
[close | |
	 "release storage"
	class ← method ← tally ← rcvrs ← nil].
"338" MessageTally$'Private Reporting'
[treeprinton: s tab: tab total: total over: threshold | i mt |
	tally  threshold
	  ifFalse:
		[tab > 0
		  ifTrue:
			[(1 to: tab - 1) do: [:i | s append: '  |'].
			self printon: s total: total.
			s cr].
		self breakdown sort do: [:mt | mt treeprinton: s tab: tab + 1 total: total over: threshold]]].
"735" MessageTally$'Public Reporting'
[fullprinton: s cutoff: pct | set mt i t |
	user displayoffwhile [
		(s print: tally.
		s append: ' tallies'.
		s cr.
		tally = 0
		  ifFalse:
			[s cr.
			s cr.
			(pct is: Vector)
			  ifFalse: [pct ← {pct , pct}].
			pct  1 < 100
			  ifTrue:
				[s append: '**Leaves**'.
				s cr.
				t ← (pct  1 * (tally - 1) / 100) asInteger.
				set ← HashSet new init: 128.
				self leaves: set.
				self cumprinton: s from: set total: tally over: t.
				s next← 12.
				s cr.
				set ← nil].
			pct  2 < 100
			  ifTrue:
				[s append: '**Tree**'.
				s cr.
				t ← (pct  2 * (tally - 1) / 100) asInteger.
				self treeprinton: s tab: 0 total: tally over: t.
				s next← 12.
				s cr].
			s skip: 2])]].
"305" MessageTally$'Public Tallying'
[moreon remote | val |
	 "Spy on the specified evaluation without resetting"
	class ← remote receiver "use as follows:
eachtime  
	[spy every: 10.
	spy moreon [super eachtime].
	]" class.
	method ← remote method.
	timer reset.
	val ← remote eval.
	timer disable.
	↑val].
"54" MessageTally$'Private Reporting'
[tally | |
	↑tally].
"67" MessageTally$'Private Reporting'
[bump: n | |
	tally ← tally + n].
"1202" FontWindow$'Scheduler'
[eachtime | t1 |
	 "while active"
	(clearframe has: user mp)
	  ifTrue:
		[user redbug
		  ifTrue: [self setbit: user mp color: black]
		  ifFalse:
			[ "make dot black"
			user yellowbug
			  ifTrue: [self setbit: user mp color: white]
			  ifFalse:
				[ "make dot white"
				user bluebug
				  ifTrue:
					[(t1 ← fontmenu bug) = 1
					  ifTrue: [self strike]
					  ifFalse:
						[ "put strike of font in dialogue window"
						t1 = 2
						  ifTrue: [self setwidth]
						  ifFalse:
							[ "grow character"
							t1 = 3
							  ifTrue:
								[self updateseglength: font raster: fontraster.
								self updatemaxwidth "clean things up".
								user notify: 'font debugging']
							  ifFalse:
								[t1 = 4
								  ifTrue: [self frame]
								  ifFalse:
									[ "move fontwindow"
									t1 = 5
									  ifTrue:
										[clearframe clear.
										self updateseglength: font raster: fontraster.
										self updatemaxwidth "clean things up".
										user unschedule: self.
										↑false]]]]]]
				  ifFalse:
					[user kbck
					  ifTrue:
						[char ← user kbd.
						self setchar: char]]]]]
	  ifFalse:
		[user anybug
		  ifTrue: [↑false]]].
"55" FontWindow$'Scheduler'
[lasttime | |
	 "upon exit"
	].
"320" FontWindow$'Editing'
[setfont: t1 | |
	font ← t1.
	altostyle fonts  fontnumber ← font.
	fontraster ← font word: 9.
	fontht ← (font word: 6) + (font word: 7) "ascent + descent".
	fontxtabl ← fontraster * fontht + 9 "header" + 1 "for 0 addressing".
	bitsetter width← 1.
	bitsetter height← 1.
	self setchar: charstr  1].
"585" FontWindow$'Editing'
[setchar: t1 | |
	char ← t1.
	charstr  1 ← char.
	char ← (font word: 3) - (font word: 2) + 1 "char out of range".
	(font word: 2)  char
	  ifTrue:
		[char  (font word: 3)
		  ifTrue: [char ← char - (font word: 2)]].
	charx ← font word: fontxtabl + char.
	charwid ← (font word: fontxtabl + char + 1) - charx.
	clearframe clear.
	frame extent← charwid  fontht.
	clearframe ← frame inset: 2  2 "for clearing everything including outline" and: [charwid - (charwid * scale + 2)  (fontht - (fontht * scale + 2))].
	self show "FontWindow regenerate: setchar:"].
"535" FontWindow$'Editing'
[setwidth | newextentx outlineframe |
	outlineframe ← clearframe inset: 1  1 "get new size" and: [0  1].
	OriginCursor showwhile [
		(user waitbug
		  ifTrue:
			[[user anybug] whileTrueDo:
				[outlineframe growto: clearframe origin x + 2 + (newextentx ← user mp x - clearframe origin x + 2 | scale)  outlineframe corner y.
				outlineframe border: 2 color: black.
				outlineframe border: 2 color: background]]
		  ifFalse:
			[])].
	outlineframe border: 2 color: black.
	self setwidth: newextentx / scale].
"188" FontWindow$'Strike format'
[cufixup | |
	 "Carnegie-Mellon fixup for scale compatibility"
	boxer extent← scale - 1  (scale - 1).
	frame extent← scale  0.
	clearframe extent← scale  0].
"348" FontWindow$'Image'
[show | tempframe showrun showpara |
	 "refresh window"
	showrun ← String new: 2.
	showrun word: 1 ← 16 * (fontnumber - 1) + 256.
	showpara ← Paragraph new text: charstr runs: showrun alignment: 0.
	tempframe ← Textframe new para: showpara frame: frame style: altostyle.
	tempframe show.
	frame blowup: frame origin by: scale].
"155" FontWindow$'Image'
[frame | |
	clearframe clear.
	frame moveto: (OriginCursor showwhile [
		(user waitbug
		  ifTrue: [user mp])]).
	self setchar: char].
"1154" FontWindow$'Strike format'
[newfont: t1 maxcharwidth: maxcharwidth min: min max: max ascent: ascent kern: kern | raster i x |
	fontht ← t1.
	XeqCursor showwhile [
		(raster ← 2 + max - min * maxcharwidth + 15 / 16.
		font ← String new: 3 + max - min + (fontht * raster) + 9 * 2.
		font word: 1 ← 32768 "format: strike, simple, varwidth".
		font word: 2 ← min "min ascii code".
		font word: 3 ← max "max ascii code".
		font word: 4 ← maxcharwidth "max char width".
		font word: 5 ← 2 + max - min + 5 + (fontht * raster) "segment length".
		font word: 6 ← ascent "bits above baseline".
		font word: 7 ← fontht - ascent "bits below baseline".
		font word: 8 ← kern "kerning offset".
		font word: 9 ← raster "#words per scan-line in bitmap".
		font  (18 + 1 to: 2 * raster * fontht + 18) all← 0 "chars all white".
		ascent ← ascent min: fontht - 1 "keep baseline within char".
		font  (2 * raster * ascent + 18 + 1 to: ascent + 1 * raster * 2 + 18) all← 255 "put in a black baseline".
		x ← 0.
		(raster * fontht + 9 + 1 to: raster * fontht + 9 + 3 + max - min by: 1) do:
			[:i | font word: i ← x.
			x ← x + maxcharwidth "table of left x"])].
	↑font].
"191" FontWindow$'Strike format'
[strike | i showstr |
	 "Put a strike of font into dialogue window"
	showstr ← String new: 128.
	(1 to: 128) do: [:i | showstr  i ← i].
	user clearshow: showstr].
"110" FontWindow$'Initialization'
[classInit | |
	fontmenu ← Menu new string: 'strike
set width
debug
move
close'].
"280" FontWindow$'Strike format'
[updatemaxwidth | newmaxwidth i |
	newmaxwidth ← 0 "update max width".
	(fontxtabl to: fontxtabl + ((font word: 3) - (font word: 2) + 1) by: 1) do: [:i | newmaxwidth ← newmaxwidth max: (font word: i + 1) - (font word: i)].
	font word: 4 ← newmaxwidth].
"1124" FontWindow$'Strike format'
[makecu: name scale: cuscale | f svscale svchar bitwidth i bitmover bits |
	 "Put out font in Carnegie-Mellon format"
	f ← dp0 file: name + '.cu.'.
	self updateseglength: font raster: fontraster.
	self updatemaxwidth.
	svscale ← scale.
	scale ← cuscale.
	svchar ← char.
	self cufixup.
	f nextword← fontht * scale.
	f nextword← (bitwidth ← font word: 4) * scale + 15 / 16.
	bits ← String new: fontht * scale * (bitwidth * scale + 15 / 16) * 2.
	bitmover ← BitBlt init.
	bitmover destbase← bits lock.
	bitmover destraster← bitwidth * scale + 15 / 16.
	bitmover destx← 0.
	bitmover desty← 0.
	bitmover sourcebase← mem  54.
	bitmover sourceraster← user screenrect extent x + 15 / 16.
	bitmover sourcex← frame origin x.
	bitmover sourcey← frame origin y.
	((font word: 2) to: (font word: 3) by: 1) do:
		[:i | self setchar: i.
		f nextword← i.
		f nextword← charwid * scale.
		bitmover width← frame extent x * scale.
		bitmover height← frame extent y * scale.
		bits all← 0.
		bitmover copy: storing.
		f append: bits].
	f close.
	scale ← svscale.
	self cufixup.
	bits unlock.
	self setchar: svchar].
"126" FontWindow$'Scheduler'
[firsttime | |
	 "upon entry"
	(clearframe has: user mp)
	  ifTrue: [self show]
	  ifFalse: [↑false]].
"503" FontWindow$'Initialization'
[altostyle: t1 fontnumber: t2 at: origin | |
	altostyle ← t1.
	fontnumber ← t2.
	 "set up an instance"
	fontmenu  nil
	  ifTrue: [self init].
	scale ← 9.
	charstr ← String new: 1.
	char ← 65.
	charstr  1 ← char.
	bitsetter ← BitBlt init.
	boxer ← Rectangle new origin: 0  0 extent: scale - 1  (scale - 1).
	frame ← Rectangle new origin: origin extent: scale  0.
	clearframe ← Rectangle new origin: origin extent: scale  0.
	self setfont: altostyle fonts  fontnumber].
"272" FontWindow$'Strike format'
[updateseglength: newfont raster: newraster | |
	newfont word: 5 ← 5 + (newraster * fontht) "compute new segment length for a font" "length, ascent, descent, kern, and raster" "bits" + ((font word: 3) "max" - (font word: 2) "min" + 2) "xtabl"].
"596" FontWindow$'Editing'
[setbit: bitpoint color: color | x y |
	 "turn bits on, off"
	bitpoint ← bitpoint - frame origin.
	x ← (0 max: charwid - 1) min: bitpoint x / scale.
	y ← (0 max: fontht - 1) min: bitpoint y / scale.
	boxer moveto: frame origin + (scale * x  (scale * y)).
	boxer color: color mode: storing "turn bit on/off in blowup".
	bitsetter destraster← fontraster "set up bitblt table.".
	bitsetter destx← charx + x.
	bitsetter desty← y.
	bitsetter destbase← font.
	bitsetter dstrike← true "lock font and get core ptr".
	bitsetter fill: storing color: color "turn bit on/off in font"].
"1937" FontWindow$'Editing'
[setwidth: delta | fontrightx newraster newxtabl newmaxwidth updatedfont i |
	delta ← delta - charwid "change in width".
	delta = 0
	  ifTrue:
		[self show.
		↑false].
	.
	fontrightx ← font word: fontxtabl + ((font word: 3) - (font word: 2)) + 2.
	newraster ← (fontrightx + 15 / 16  (i ← fontrightx + delta + 15 / 16)
			  ifTrue: [i]
			  ifFalse: [fontraster]).
	newxtabl ← newraster * fontht + 9 "header" + 1 "for 0 addressing".
	XeqCursor showwhile [
		(updatedfont ← String new: 9 + (newraster * fontht) "header" "bits" * 2 "grow/shrink the bits".
		(1 to: 8) "fill in header of new font" do: [:i | updatedfont word: i ← font word: i].
		updatedfont word: 9 ← newraster "set raster in new font" "copy the xtable".
		updatedfont ← self appendxtable: updatedfont "set up to copy up to old bits of char".
		bitsetter destraster← newraster.
		bitsetter destx← 0.
		bitsetter desty← 0.
		bitsetter sourcex← 0.
		bitsetter sourcey← 0.
		bitsetter width← charx + charwid.
		bitsetter height← fontht.
		bitsetter sourceraster← fontraster.
		bitsetter destbase← updatedfont.
		bitsetter sourcebase← font.
		bitsetter sstrike← true.
		bitsetter dstrike← true.
		bitsetter copy: storing.
		delta < 0 "if char grown, clean out right side of char"
		  ifFalse:
			[bitsetter destx← charx + charwid.
			bitsetter width← delta.
			bitsetter fill: storing color: 0] "now copy remainder of font".
		bitsetter destx← charx + charwid + delta.
		bitsetter width← fontrightx - charx - charwid.
		bitsetter sourcex← charx + charwid.
		bitsetter copy: storing "shift x-vals".
		(char + 1 to: 2 + (updatedfont word: 3) - (updatedfont word: 2) "max") do: [:i | updatedfont word: (newxtabl + i) ← delta + (updatedfont word: newxtabl + i)].
		clearframe clear "clear out old version of character".
		self setfont: updatedfont "set up the new copy of the font".
		self updateseglength: font raster: fontraster.
		self updatemaxwidth)]].
"847" FontWindow$'Editing'
[setascent: ascentdelta | updatedfont ascent |
	ascent ← font word: 6 "ascent delta".
	ascent + ascentdelta < 0
	  ifTrue: [ascentdelta ← 0 - ascent].
	ascentdelta > 0
	  ifTrue:
		[updatedfont ← String new: 2 * fontraster * ascentdelta "grow".
		updatedfont all← 0 "fill with white".
		updatedfont ← font  (1 to: 18) "add oldfont header and new space together" concat: updatedfont  (1 to: updatedfont length).
		updatedfont ← updatedfont concat: font  (19 to: font length "now add on rest of old font")]
	  ifFalse:
		[updatedfont ← font  (1 to: 18) concat: font  (19 + (0 - (2 * fontraster "shrink" * ascentdelta)) to: font length)].
	updatedfont word: 6 ← ascent + ascentdelta "reset ascent word in font".
	self setfont: updatedfont "updatedfont now font of interest".
	self updateseglength: font raster: fontraster].
"185" FontWindow$'Strike format'
[appendxtable: thefont | |
	thefont ← thefont concat: font  (fontxtabl * 2 "put fontxtable on end of a grown/shrunk font" - 1 to: font length).
	↑thefont].
"732" FontWindow$'Editing'
[setdescent: descentdelta | updatedfont descent space |
	descent ← font word: 7 "descent delta".
	descent + descentdelta < 0
	  ifTrue: [descentdelta ← 0 - descent].
	descentdelta > 0
	  ifTrue:
		[space ← String new: 2 * fontraster * descentdelta.
		space all← 0.
		updatedfont ← font  (1 to: fontxtabl - 1 * 2) concat: space.
		updatedfont ← self appendxtable: updatedfont]
	  ifFalse:
		[updatedfont ← font  (1 to: fontxtabl - 1 * 2 + (fontraster * descentdelta * 2)).
		updatedfont ← self appendxtable: updatedfont].
	updatedfont word: 7 ← descent + descentdelta "reset descent word in font".
	self setfont: updatedfont "updatedfont now font of interest".
	self updateseglength: font raster: fontraster].
"1100" FontWindow$'Help'
[help | |
	 "
**sysFontWindow is declared in the Smalltalk dictionary, and bound to the font window displayed on the screen of most system releases -- intended to provide an easy way to play around with the font editor.
**to create a window for editing default font 0 at middle-click:
	 user schedule: (sysFontWindow ← FontWindow new
		altostyle: DefaultTextStyle
		fontnumber: 1
		at: (OriginCursor showwhile
			[user waitbug ser mp]])).
**to create a new font
	yourfont ← FontWindow new newfont: 16 maxcharwidth: 16 min: 0
			max: 177 ascent: 12 kern: 0.

**to edit newly created font
	yourtextstyle setfont: n name: yourfont.	**insert it into a TextStyle
	**now create a window as above with yourtextstyle and appropriate
		fontnumber
	

**examples of manual manipulation of yourfontwindow:
	sysFontWindow setascent: 2.	**Deltas -- for entire font**
	sysFontWindow setascent: 3.
	sysFontWindow setdescent: 2.
	sysFontWindow setdescent: 2.
	sysFontWindow setchar: 046.
	sysFontWindow setwidth: 5.	**Absolute--for char in window. 
	Useful for characters of zero width.**
"].
"43" HalfToner$'Init/Access'
[npix | |
	↑npix].
"554" HalfToner$'AIS to Bits'
[intoPress: p file: f | outrect |
	 "Creates an external file reference"
	outrect ← p transrect: rect.
	p setp: outrect origin.
	p dots [
		(p setcoding: 8 dots: npix lines: nlines "byte samples".
		p setmode: 3 "to right and to bottom of page".
		p setwindowwidth: pixelsPerLine height: lines skipdots: inset x skiplines: inset y.
		p setsizewidth: outrect width height: outrect height.
		p dotsfromAIS: f)] "
	|p. p←dp0 pressfile: 'pix.press'.
	p pictureinit. (HalfToner new test) intoPress: p file: 'Rolfup.AIS'. p close.
"].
"51" HalfToner$'Init/Access'
[rect← t1 | |
	rect ← t1].
"47" HalfToner$'Init/Access'
[nlines | |
	↑nlines].
"964" HalfToner$'Init/Access'
[setup: t1 | inrect croprect |
	strm ← t1.
	strm readonly.
	((strm word: 2)  1024 or: [(strm word: 9)  8])
	  ifTrue: [user notify: 'bad file']
	  ifFalse:
		[nlines ← lines ← strm word: 4.
		npix ← pixelsPerLine ← strm nextword.
		black ← 0.
		white ← 255.
		inrect ← 0  0 rect: pixelsPerLine  lines.
		inrect moveto: rect origin.
		inrect usermove.
		inrect comp "show whole".
		croprect ← rect copy.
		croprect moveto: inrect origin copy.
		croprect maxstretch: inrect.
		croprect userstretch: inrect.
		inrect comp.
		inset ← croprect origin - inrect origin.
		pixelsPerLine ← croprect width.
		lines ← pixelsPerLine * rect height / rect width.
		rect width > pixelsPerLine
		  ifTrue:
			[inpix ← 32 "blowup".
			outpix ← 32 * rect width / pixelsPerLine]
		  ifFalse:
			[ "shrink"
			outpix ← 32.
			inpix ← 32 * pixelsPerLine / rect width].
		errorString ← String new: pixelsPerLine * outpix / inpix + 2.
		errorString all← 0]].
"43" HalfToner$'Init/Access'
[strm | |
	↑strm].
"340" HalfToner$'Init/Access'
[test | files |
	files ← (dp0 filesMatching: '*.ais.') sort.
	files empty
	  ifTrue: [user notify: 'no .ais files on disk']
	  ifFalse:
		[strm ← dp0 file: files  (Menu new stringFromVector: files) zbug.
		strm readonly.
		rect ← Rectangle new usersize.
		self setup: strm.
		self doFile] "
HalfToner new test.
"].
"43" HalfToner$'Init/Access'
[rect | |
	↑rect].
"913" HalfToner$'AIS to Bits'
[decode: str using: s | i j k x cascadeRight cascadeDiag val error r msk masks |<primitive: 75>
	masks ← #(128 64 32 16 8 4 2 1 ) "Change 8-bit grey from str filling s".
	cascadeRight ← 0.
	cascadeDiag ← errorString  1.
	i ← msk ← j ← k ← 1.
	x ← 0 - outpix.
	s  1 ← 0.
	(1 to: pixelsPerLine) do:
		[:i | [x < 0] whileTrueDo:
			[val ← str  i - black.
			(error ← cascadeRight - val)  0
			  ifTrue:
				[s  j ← masks  msk "print Black" + (s  j).
				error > white
				  ifTrue: [error ← white]]
			  ifFalse:
				[ "print White"
				(error ← error + white) < 0
				  ifTrue: [error ← 0]].
			error ← error / 2.
			val ← error / 2.
			errorString  k ← cascadeDiag + val.
			cascadeRight ← errorString  (k + 1) + error.
			cascadeDiag ← val.
			(msk ← msk + 1) > 8
			  ifTrue:
				[msk ← 1.
				j ← j + 1.
				s  j ← 0].
			x ← x + inpix.
			k ← k + 1].
		x ← x - outpix].
	↑s].
"980" HalfToner$'AIS to Bits'
[doFile | str i s2 r y skipsum |
	str ← String new: pixelsPerLine.
	r ← 0  0 rect: pixelsPerLine * outpix / inpix  1.
	r moveto: rect origin copy.
	s2 ← String new: 1 + (pixelsPerLine * outpix / (8 * inpix)).
	vect ← Vector new: lines.
	strm reset.
	strm position← 2048 + (inset y * npix) "crop top".
	i ← 1.
	y ← 0 - outpix.
	skipsum ← 0.
	[i  lines] whileTrueDo:
		[skipsum ← skipsum + inset x "inset left".
		strm skip: skipsum.
		skipsum ← 0 "do all tallied skips prior to next read".
		strm into: str endError: true.
		r bitsFromString: (self decode: str using: s2).
		skipsum ← skipsum + npix - (pixelsPerLine + inset x).
		r origin y← r origin y + 1.
		r corner y← r corner y + 1.
		(y ← y + inpix)  0
		  ifTrue:
			[ "next line?"
			i ← i + 1.
			y ← y - outpix.
			[y  0 and: [i  lines]] whileTrueDo:
				[i ← i + 1.
				y ← y - outpix.
				skipsum ← skipsum + npix]]
		  ifFalse: [skipsum ← skipsum - npix] "not next line"].
	strm close].
"2002" JuniperInterface$'CLASS INIT'
[juniperConstants | |
	 "...returns the set of constants used to specify requests to and to  interpret results from the Juniper file system."
	↑#(168 sRequest sResult sUnsolicited sCustodian sSync sPineAck sNoop 5 sReadPage sWritePage sSetLength sReadLength sCloseFile sDestroyAnonymousFile sReadData sWriteData sReadAttribute sWriteAttribute sSetWriteLock sSetReadLock sReleaseReadLock 32 sChangePassword sRoom sOpenFile sCreateAnonymousFile sFindFile sLockQuery sTransCompletionQuery 42 sLogout sCloseTransaction sAbortTransaction sLoginRequest 60 sLookupFile sCreateFile sDestroyFile sRenameFile sNextFile sNextFewFiles 1 sCommandNak sCommandAck sHeresData sHeresEntry sHeresFileList sHeresLFH sHeresFile sHeresLength sLoginResponse sLogoutResponse sTransactionClosed sTransCompletionInfo sResourceData sHeresRoom 0 sTransactionAborted sReadLockBroken 8 sLogin sAddServer sResourceLocation 42 sUnimplementedFeature sIllegalLoginAttempt sSoftwareVersionMismatch sNoSuchUser sPasswordMismatch sBytesPerPageUnacceptable sServerTooBusy sOutOfSpace sNoFilesHere sNoDirectoryHere sIllegalFileName sFileNotFound sFileAlreadyExists sTransactionAborting sNoSuchOpenFile sBigFilesNotImplemented sIllegalAttribute sReadAttributeProtectionError sUserAskedForIt sWriteAttributeProtectionError sPackNotOnDrive sTooManyOpenFiles sProtectionViolation sFileNotOnPack sPackFull sFileRefOutOfBounds sFileSizeExcessive sByteRangeExcessive sPackNotOnMachine sNoSuchTransaction sBrokenLock sInconvenientUnwind sSequenceNumberGap sRecoveryUnderWay sTransactionClosing sCongestion 120 sBlockTooLarge sNoRouteToServer sServerUnknown sBadBytesPerPage sInvalidRequest sPupGlitch sUnableToDecrypt sNoResponseToRequest sNewServerUnwilling sTransactionInUnknownState sBadTimeForRequests ) "PineMsgType (Pup types)" "DataRequest" "TransactionRequest" "ActivityRequest" "DirectoryRequest" "ResultCode" "Unsolicited Code" "CustodianCode" "PineErrorCode" "TransTroubleCode" "Retryable" "UserDetected"].
"647" JuniperInterface$'TIMER (internal)'
[timerOn | |
	 "...assigns fTimer to a new timer object that wakes up every 100 seconds (6000 1/60 seconds) and issues a 'noop' command to Juniper.  This  is used to prevent Juniper from timing out during periods of inactivity."
	self timerOff "1".
	fTimer ← Timer new "2".
	fTimer for: 6000 action [
		(self noOp.
		user show: '.'.
		fTimer reset)] "3".
	user cr.
	fTimer reset "4" "
1. Make sure that the current timer is released.
2. Create a new timer.
3. Set the timer interval to 100 seconds.  The action of the timer is to send a noop, show a dot in the dispFrame, and reset.
4. Activate the timer.
"].
"313" JuniperInterface$'USER CALLABLE'
[exceptionHandler: pExceptionHandler | |
	 "...specifies an exception handler to be invoked if any subsequent request discovers that the expected transaction has been closed.  If no exception handler is set, a notify window is displayed."
	fExceptionHandler ← pExceptionHandler].
"368" JuniperInterface$'FILE DIRECTORY (restricted)'
[Rename: oldFile from: newFile | tRequest newName |
	 "renames a file on Juniper"
	tRequest ← self newRequestParameterBlock.
	tRequest nextDataBlockString← oldFile name.
	tRequest nextDataBlockString← newName ← self checkDirectory: newFile name.
	self doAction: sRenameFile requestPrs: tRequest.
	oldFile name: newName].
"152" JuniperInterface$'FILE DIRECTORY (restricted)'
[entryClass | |
	 "...returns the file class handled by the JuniperInterface."
	↑JuniperFileController].
"781" JuniperInterface$'FILE DIRECTORY (restricted)'
[nextFile: pFile | tRequest tResult |
	 "same as LookupFile (Find:), but it pertains to the file whose name is lexically next after the fileName specified in the request.  If the file is found, its name and long file handle are set in pFile (a JuniperFileController). Otherwise (no next file) false is returned."
	fSpecialError ← sFileNotFound "1".
	tRequest ← self newRequestParameterBlock "2".
	tRequest nextDataBlockString← self checkDirectory: pFile name "3".
	tResult ← self doAction: sNextFile requestPrs: tRequest "4".
	fSpecialError  true
	  ifTrue:
		[fSpecialError ← nil.
		↑false].
	 "5"
	fSpecialError ← nil "6".
	pFile longFileHandle: tResult nextDataBlockString.
	pFile name: tResult nextDataBlockString "7".
	↑pFile].
"910" JuniperInterface$'FILE DIRECTORY (restricted)'
[Match: entries to: strm | entry pat ents name i p lastname |
	entries do:
		[:pat |  "search for Files matching patterns"
		name ← self checkDirectory: pat name.
		i ← name find: '*'  1.
		p ← name find: '#'  1.
		i ← (p = 0
				  ifTrue: [i]
				  ifFalse:
					[i = 0
					  ifTrue: [p]
					  ifFalse: [i min: p]]).
		i = 0
		  ifTrue:
			[(self Find: pat)
			  ifTrue: [strm next← pat "exact name found"]]
		  ifFalse:
			[ "pattern match over range of first to last possible matches"
			pat ← self makeEntry: name.
			entry ← self makeEntry: (name copy: 1 to: i - 1).
			lastname ← name copy: 1 to: i.
			lastname  i ← 255.
			[(entry ← self nextFile: entry) and: [entry name < lastname]] whileTrueDo:
				[(pat match: entry)
				  ifTrue:
					[strm next← entry "copy entry since nextFile smashes into it".
					entry ← self makeEntry: entry name]]]]].
"156" JuniperInterface$'TIMER (internal)'
[timerOff | |
	 "...disables fTimer and sets it to nil."
	fTimer  nil
	  ifFalse:
		[fTimer disable.
		fTimer ← nil]].
"792" JuniperInterface$'JUNIPER COMMAND INTERFACE (restricted)'
[doLogin: pRequest | tResult |
	 "...is sent by login:password: with pRequest (a JuniperRequestParameter Block) set.  doLogin: issues a login request, checks for errors, and retries if necessary.  If no error occurs, a JuniperResultParameterBlock is returned; otherwise, error handling is invoked."
	tResult ← JuniperResultParameterBlock new "1".
	tResult packet← fJuniperSocket sendLogin: pRequest packet "2".
	(self checkResult: tResult)
	  ifTrue: [↑tResult].
	 "3"
	↑self doLogin: pRequest "4" "
1. Create a new result parameter block.
2. Issue a login request and set the result packet in the result parameter block.
3. Check the result and return it if there is no error.
4. Retry the request if there is a retryable error.
"].
"952" JuniperInterface$'MISC (internal)'
[login: pName password: pPassword | tRequest |
	 "...sets the necessary request parameters and invokes doLogin to issue a login request.  pName (a String) specifies the name of an account on the Juniper file system.  pPassword (a String) specifies the password of the account."
	tRequest ← self newRequestParameterBlock "1".
	tRequest leader: 3 ← sLogin "2".
	tRequest leader: 4 ← 512 "3".
	tRequest leader: 5 ← 7 "4".
	tRequest leader: 6 ← self hash: pPassword "5".
	tRequest nextDataBlockString← pName "6".
	tRequest pupType← sCustodian "7".
	↑self doLogin: tRequest "8" "
1. Create a new request parameter block.
2. Set the command to Login.
3. Set the number of bytes per page to 512.
4. Set the Juniper version number to 7 (Nov 80).
5. Set the hashed account password to pPassword hashed.
6. Set the account name to pName.
7. Set the packet pup type to custodian.
8. Issue the request and return the result.
"].
"336" JuniperInterface$'TEST / DIAGNOSTIC'
[test | |
	 "
	dpj ← nil.
	dpj ← JuniperInterface new.
	dpj release.
	dpj open.
	dpj close.
	| f  [ dpj open.  f ← dpj file: 'test.test'.
until [ f end ] do [ user show: (f next) inString. ]. f close. dpj close. ]

JuniperSocket howMany 2 1 2 2 2  11 Timer howMany  33  NameUser howMany 1 1 1
"].
"72" JuniperInterface$'USER CALLABLE'
[obsolete | |
	↑fOpenIndicator  nil].
"440" JuniperSocket$'Socket'
[timerFired | |
	notWaiting "This piece of code only runs when a timer fires!
	Thus, there is mutual exclusion between this and other timer code.
	Runs below the ethernet input.   Don't do an active return
	Timer sometimes fires even though its been disabled!"
	  ifFalse:
		[self timerOn
		  ifTrue: [self completePup: outPac "go ahead and retransmit....."]
		  ifFalse:
			[notWaiting ← true.
			result ← false]]].
"396" JuniperSocket$'Initialization/Termination'
[net: pNet host: pHost | |
	 "start with the well known Juniper listener, leave filterInput false"
	super net: pNet host: pHost soc: 64 asInt32.
	self retransmit: 3 every: 500 "8 sec".
	outAck ← self freePacket "for the outgoing pineAck".
	outAck pupType← 173.
	outAck pupID1← 0.
	outAck dataString← '' "also sets length; need to set addresses later"].
"1434" JuniperSocket$'Socket'
[socProcess: Ipac | temp |
	loginPending
	  ifTrue:
		[ "Juniper has responded, we're running at a high level" "handle this special case"
		((frnNet  Ipac sourceNet "watch out, src has not been checked" or: [frnHost  Ipac sourceHost]) or: [(169  Ipac pupType or: [0  Ipac pupID0])])
		  ifFalse:
			[ "discard it" "Ipac ← self freePacket: Ipac" "this must be it!"
			frnSocNum high: Ipac sourceSoc0 low: Ipac sourceSoc1.
			self setOutAddBlock.
			self setAddresses: outAck "for later use" "generate an ack".
			outAck pupID0← 0.
			self completePup: outAck.
			loginPending ← false.
			notWaiting ← filterInput ← true.
			result ← Ipac]]
	  ifFalse:
		[ "src. and dest. should have been checked ??)"
		Ipac pupType = 169
		  ifTrue:
			[outAck pupID0← Ipac pupID0 "might be a retransmission of a previous Juniper response or what we want.
		acknowledge in either case then see whether we want to keep the result".
			self completePup: outAck.
			(notWaiting or: [seqNum  Ipac pupID0])
			  ifFalse:
				[ "Ipac ← self freePacket: Ipac"
				notWaiting ← true.
				result ← Ipac]]
		  ifFalse:
			[ "Ipac pupType = 0255  [Ipac←self freePacket: Ipac]" "discard pineack"
			(notWaiting  false and: [(Ipac pupType = 4 and: [(Ipac word: 23) = 2])])
			  ifTrue:
				[self timerOff "no socket at Juniper".
				notWaiting ← true.
				result ← Ipac]
			  ifFalse:
				[ "Ipac ← self freePacket: Ipac."
				]]]].
"341" JuniperSocket$'Socket'
[sendRequest: t1 | |
	outPac ← t1.
	notWaiting ← false "General routine to send request packets, wait for ack, retransmit.
	Will return the Juniper response packet, or else a false.".
	outPac pupID0← seqNum ← seqNum + 1.
	self setAddressesAndComplete: outPac.
	[notWaiting] whileFalseDo:  [ "all done"
		].
	↑result].
"491" JuniperSocket$'Socket'
[sendLogin: t1 | |
	outPac ← t1.
	frnSocNum high: 0 low: 64 "Special routine to send login, wait for ack, retransmit.
	Need to reset seqNum, and get new Juniper socket number.
	Will return the Juniper response packet, or else a false.".
	self setOutAddBlock.
	filterInput ← false.
	outPac pupID0← 0.
	outPac pupID1← seqNum ← 0.
	notWaiting ← false.
	loginPending ← true.
	self setAddressesAndComplete: outPac.
	[notWaiting] whileFalseDo:  [ "all done"
		].
	↑result].
"1074" JuniperInterface$'USER CALLABLE'
[open | tResult |
	 "...opens the interface allowing access to files on the Juniper file system.  A new transaction is started."
	fOpenIndicator  true
	  ifFalse:
		[ "1"
		E wakeup "2".
		self release "3".
		fJuniperSocket ← JuniperSocket new hostName: self server "4".
		tResult ← self login: self userName password: self userPassword "5".
		user cr.
		user show: tResult nextDataBlockString "6".
		self timerOn "7".
		super open "8".
		fOpenIndicator ← true "9"] "
1. If the interface is already open, do nothing.
2. Make sure that the EtherWorld mechanism is in a valid state.
3. Release the interface to insure a valid initial state.  (An invalid state can occur from  an error on some statement in a previous invocation of 'open').
4. Create and initialize a JuniperSocket (parameterize server name?).
5. Issue a login command.
6. Display the login message that is returned by Juniper.
7. Turn on a timer to issue periodic noop commands to prevent timeout.
8. Do predefined open operations.
9. Set the interface status to 'open'.
"].
"394" JuniperInterface$'USER CALLABLE'
[release | |
	 "...leaves the interface in a valid state after an error."
	fOpenIndicator ← nil "1".
	self timerOff "2".
	fJuniperSocket  nil
	  ifFalse:
		[fJuniperSocket close "3".
		fJuniperSocket ← nil "4"] "
1. Set the interface status to 'not open'.
2. Turn off the timer.
3. Close the JuniperSocket if it exists.
4. Release the JuniperSocket field.
"].
"159" JuniperInterface$'MISC (internal)'
[userName | |
	 "...returns the account name or a default (a String)."
	fName  nil
	  ifTrue: [↑super userName].
	↑fName].
"179" JuniperInterface$'MISC (internal)'
[userPassword | |
	 "...returns the account password or a default (a String)."
	fPassword  nil
	  ifTrue: [↑super userPassword].
	↑fPassword].
"1247" JuniperInterface$'FILE DIRECTORY (restricted)'
[Find: pFile | tRequest tResult |
	 "...sends a 'look up file' request to the Juniper file server.  If the file is found, its name and long file handle are set in pFile (a JuniperFileController). Otherwise false is returned."
	fSpecialError ← sFileNotFound "1".
	tRequest ← self newRequestParameterBlock "2".
	tRequest nextDataBlockString← self checkDirectory: pFile name "3".
	tResult ← self doAction: sLookupFile requestPrs: tRequest "4".
	fSpecialError  true
	  ifTrue:
		[fSpecialError ← nil.
		↑false].
	 "5"
	fSpecialError ← nil "6".
	pFile longFileHandle: tResult nextDataBlockString.
	pFile name: tResult nextDataBlockString "7" "
1. Set the error handling mechanism to ignore a 'file not found' error.
2. Create a new request parameter block.
3. Get the file name from pFile, add the default directory name to it if necessary, and write it in the request parameter block.
4. Issue a 'look up file' request and get the result parameter block.
5. If a 'file not found' error was encountered, reset the error handling mechanism and return false.
6. (no error encountered) Reset the error handling mechanism.
7. Set the long file handle and name (from the result parameter block) in pFile.
"].
"212" JuniperInterface$'JUNIPER COMMAND INTERFACE (restricted)'
[newPacket | |
	 "...returns a new packet (Pacbuf) from the JuniperSocket."
	fJuniperSocket  nil
	  ifTrue:
		[self open].
	↑fJuniperSocket freePacket].
"108" JuniperInterface$'FILE DIRECTORY (restricted)'
[server | |
	↑'Juniper1' "should be an instance variable?"].
"282" JuniperInterface$'MISC (internal)'
[directory | |
	 "...Returns a string specifying the default file name directory.  The default directory is fDefaultDirectory if it is not nil, otherwise it is self name"
	fDefaultDirectory  nil
	  ifTrue: [↑self userName].
	↑fDefaultDirectory].
"388" JuniperInterface$'MISC (internal)'
[hash: pString | tHash1 tHash2 i |
	 "...returns a hash value for pString (a String)."
	tHash1 ← 0.
	tHash2 ← 0.
	(1 to: pString length by: 2) do:
		[:i | tHash1 ← tHash1 lxor: UpperCase  (pString  i + 1).
		tHash2 ← tHash2 lxor: (i = pString length
				  ifTrue: [32]
				  ifFalse: [UpperCase  (pString  (i + 1) + 1)])].
	↑tHash1 * 256 + tHash2].
"250" JuniperInterface$'USER CALLABLE'
[closeTransaction | |
	 "...closes the current transaction leaving the user logged in with all open files still open, and all read and write locks still in effect."
	self doAction: sCloseTransaction requestPrs: nil].
"490" JuniperInterface$'CLASS INIT'
[classInit | tIndex tConstant |
	 "...initializes the constants in gJuniperConstants
(see [ivy] <Juniper>4.4> CommonPineDefs.mesa).
Do the following to initialize:
Smalltalk declare: gJuniperConstants as: (SymbolTable new init: 256).
JuniperInterface classInit."
	self juniperConstants do:
		[:tConstant | (tConstant is: Integer)
		  ifTrue:
			[tIndex ← tConstant]
		  ifFalse:
			[gJuniperConstants declare: tConstant as: tIndex.
			tIndex ← tIndex + 1]]].
"543" JuniperInterface$'MISC (internal)'
[checkDirectory: pFileName | ps |
	 "...returns a string that has the default directory name added to the beginning of pFileName (a String) unless pFileName already begins with a directory name in which case it is returned unchanged. max length of ~58"
	ps ← (String new: 60) asStream.
	(pFileName length > 0 and: [pFileName  1 = ('<'  1)])
	  ifFalse:
		[ps append: '<'.
		ps append: self directory.
		ps append: '>'].
	ps append: pFileName.
	ps last = ('.'  1)
	  ifTrue: [ps skip: 1].
	↑ps contents].
"573" JuniperInterface$'FILE DIRECTORY (restricted)'
[Delete: pFile | tRequest |
	 "...deletes from the Juniper file system the file whose file name is specified by pFile (a JuniperFileController)."
	tRequest ← self newRequestParameterBlock "1".
	tRequest nextDataBlockString← self checkDirectory: pFile name "2".
	self doAction: sDestroyFile requestPrs: tRequest "3" "
1. Create a new request parameter block.
2. Get the file name from pFile, add the default directory name to it if necessary, and write it in the request parameter block.
3. Issue a 'destroy file' request.
"].
"62" JuniperInterface$'USER CALLABLE'
[versionNumbers | |
	↑true].
"260" JuniperInterface$'USER CALLABLE'
[name: pName password: pPassword | |
	 "...specifies the name and password of an account on the Juniper file system.  This account will be logged into whenever the interface is opened."
	fName ← pName.
	fPassword ← pPassword].
"1071" JuniperInterface$'FILE DIRECTORY (restricted)'
[Insert: pFile | tRequest tResult |
	 "...issues a 'create file' request to the Juniper file server and sets the returned long file handle and name in pFile (a JuniperFileController)."
	tRequest ← self newRequestParameterBlock "1".
	tRequest longInteger: 2 ← 0 "user rawtotalsecs" "1.5".
	tRequest nextDataBlockString← self checkDirectory: pFile name "2".
	tRequest nextDataBlockString← '' "3".
	tResult ← self doAction: sCreateFile requestPrs: tRequest "4".
	pFile longFileHandle: tResult nextDataBlockString.
	pFile name: tResult nextDataBlockString "5" "
1. Create a new request parameter block.
1.5 Set creation date (to default (current) -- later some specific date&time?)
2. Get the file name from pFile, add the default directory name to it if necessary, and write it in the request parameter block.
3. Blank the file server field of the request parameter block.
4. Issue a 'create file' request and get the result parameter block.
5. Set the long file handle and name (from the result parameter block) in pFile.
"].
"684" JuniperInterface$'TIMER (internal)'
[noOp | tPacket |
	 "...sends a noop command to the Juniper file server.  It's only effect is to reset the timout mechanism of the server."
	tPacket ← fJuniperSocket freePacket "1".
	tPacket pupType← sNoop "2".
	tPacket dataString← '' "3".
	fJuniperSocket setAddressesAndComplete: tPacket.
	fJuniperSocket timerOff "4" "
1. Get a new packet (Pacbuf).
2. Set packet pup type to 'noop'.
3. Set the dataString to the empty string.  This has the necessary effect of setting the packet length to 0.
4. Send the packet.  It is necessary to bypass the normal JuniperSocket interface (sendRequest:) because no acknowledgement is returned for the noop.
"].
"481" JuniperInterface$'USER CALLABLE'
[close | tResult |
	 "...ends the current transaction and closes the interface."
	fOpenIndicator  nil
	  ifFalse:
		[ "1"
		tResult ← self doAction: sLogout requestPrs: nil "2".
		user cr.
		user show: tResult nextDataBlockString "3".
		super close "4"] "
1. If the interface is not open, do nothing.
2. Issue a logout command.
3. Display the logout message returned by Juniper.
4. delete self from externalViews, Release timers, fields, etc.
"].
"813" JuniperInterface$'JUNIPER COMMAND INTERFACE (restricted)'
[newRequestParameterBlock | tRequestParameterBlock |
	 "...initializes and returns a new JuniperRequestParameterBlock."
	fJuniperSocket  nil
	  ifTrue:
		[self open] "1".
	tRequestParameterBlock ← JuniperRequestParameterBlock new "2".
	tRequestParameterBlock packet← fJuniperSocket freePacket "3".
	tRequestParameterBlock dataBlockLength← 0 "4".
	tRequestParameterBlock leader: 1 ← 0.
	tRequestParameterBlock leader: 2 ← 0 "5".
	↑tRequestParameterBlock "6" "
1. Open the interface if it is not already.
2. Create a new request parameter block.
3. Create a new packet and set it in the request parameter block.
4. Set the data block length to 0.
5. Set the authentication key and reserved word to 0.
6. Return the initialized request parameter block.
"].
"400" JuniperInterface$'JUNIPER COMMAND INTERFACE (restricted)'
[checkRetry: pErrorCode | |
	 "...is sent by checkResult to test for a retryable error.  Returns true if so; false otherwise."
	pErrorCode = sSequenceNumberGap
	  ifTrue: [↑true].
	pErrorCode = sRecoveryUnderWay
	  ifTrue: [↑true].
	pErrorCode = sTransactionClosing
	  ifTrue: [↑true].
	pErrorCode = sCongestion
	  ifTrue: [↑true].
	↑false].
"202" JuniperInterface$'USER CALLABLE'
[directory: pDirectory | |
	 "...specifies the directory name to be added to any file name that does not begin with a directory name."
	fDefaultDirectory ← pDirectory].
"755" JuniperInterface$'DOCUMENTATION'
[implementationNotes | |
	 "
FIELDS
fName : a String representing the name of an account on the Juniper file system.
fPassword : a String representing the password of the same account.
fDefaultDirectory : a String representing the directory to be used as the default if one is not specified as part of a file name.
fJuniperSocket : a JuniperSocket used to interface to the etherWorld mechanism.
fTimer : a Timer used to periodically send noop commands when the interface is open to prevent timeout.
fExceptionHandler : an ExceptionHandler to invoke when a transaction is aborted.
fSpecialError : an error code to ignore on a command request.
fOpenIndicator : the interface status: true means open; nil means not open.
"].
"385" JuniperInterface$'JUNIPER COMMAND INTERFACE (restricted)'
[error: pMessage | tMessage |
	 "...is sent by checkResult if an error is encountered on a Juniper request.  (pMessage is a String containing an appropriate error message.)  The error message is formed and a notify window is displayed."
	tMessage ← Stream default.
	tMessage append: pMessage.
	super error: tMessage contents].
"1872" JuniperInterface$'JUNIPER COMMAND INTERFACE (restricted)'
[checkResult: pResult | t2 |
	 "...is sent by doAction and doLogin to check the result of a Juniper request.  pResult is a result parameter block (JuniperResultParameterBlock) containing the packet (Pacbuf) returned as a result of the request."
	((pResult packet  false or: [pResult pupType = 4]) or: [(pResult resultCode = sCommandNak and: [(pResult parameter: 1) = sTransactionAborting])])
	  ifTrue:
		[ "3"
		fExceptionHandler  nil
		  ifFalse:
			[fExceptionHandler trap "4"].
		self error: 'No Juniper Transaction' "5"].
	(t2 ← pResult resultCode) = sCommandAck
	  ifTrue: [↑true].
	 "6"
	t2 = sCommandNak
	  ifTrue:
		[ "7"
		(self checkRetry: (pResult parameter: 1))
		  ifTrue: [↑false].
		 "8"
		(pResult parameter: 1) = fSpecialError
		  ifTrue:
			[fSpecialError ← true.
			↑true].
		 "9"
		self error: pResult nextDataBlockString "10"]
	  ifFalse: [↑true] "11" "
1. JuniperSocket sendRequest: and sendLogin: return false if no response is received from Juniper.
2. Invoke error handling if there is no response from Juniper.
3. Juniper returns an error pup (packet pup type  = 4) if the transaction has been aborted.
4. If the transaction has been aborted and there is an exception handler, then trap to the handler.
5. Invoke error handling if control is returned or if there is no exception handler.
6. Return true if a 'command acknowledged' was returned (this means success with no result parameters).
7. If a 'command not acknowledged' was returned,  an error condition exists.
8. Check for a retryable error and return false if so.
9. If the error is the same as that specified in the special error indicator, then indicate it and return true.
10. If not, invoke error handling.
11. Return true if a 'command not acknowledged' was not returned (this means success with result parameters).
"].
"1778" JuniperInterface$'JUNIPER COMMAND INTERFACE (restricted)'
[doAction: pAction requestPrs: pRequest | tResult |
	 "...corresponds to the Pine Protocol function.  The specified request, pAction, (selected from gJuniperConstants) with its corresponding request parameter block, pRequest (a JuniperRequestParameterBlock), is issued to the Juniper file server (through JuniperSocket sendRequest:). A packet is returned and inserted into a result parameter block and checked for error conditions.  If no errors are found, the result parameter block (a JuniperResultParameterBlock) is returned; otherwise, error handling is invoked.  If no request parameters are required, pRequest can be specified as nil."
	fOpenIndicator  nil
	  ifTrue:
		[self open] "1".
	pRequest  nil
	  ifTrue:
		[pRequest ← self newRequestParameterBlock] "2".
	fTimer disable "3".
	pRequest opcode← pAction "4".
	pRequest pupType← sRequest "5".
	tResult ← JuniperResultParameterBlock new "6".
	tResult packet← fJuniperSocket sendRequest: pRequest packet "7".
	fTimer reset "8".
	(self checkResult: tResult)
	  ifTrue: [↑tResult].
	 "9"
	↑self doAction: pAction requestPrs: pRequest "10" "
1. Make sure the JuniperInterface is open.
2. Create a request parameter block if none was specified.
3. Disable the timer to insure that a noop command is not sent while the current request is in progress.
4. Set the command code in the packet.
5. Set the packet pup type to 'request'.
6. Create a result parameter block.
7. Send the request to the JuniperSocket with the packet from the request parameter block; set the result packet in the result parameter block.
8. Reset the timer.
9. Check the result; if valid, return it.
10. If false is returned, then a retryable error was encountered so retry the command.
"].
"92" ExceptionHandler$'MISC'
[result | |
	 "...returns the result set by 'result←'."
	↑fResult].
"125" ExceptionHandler$'MISC'
[result← pResult | |
	 "...sets the result value of 'doonTrapDo' to pResult."
	fResult ← pResult].
"2555" ExceptionHandler$'DOCUMENTATION'
[description | |
	 "
This class provides some exception handling capabilities that can be used in a variety of applications.  It is intended to be used in the following way:

1. An ExceptionHandler object is created to supervise the execution of a block of statements.
	EH ← ExceptionHandler new.
2. Each object that is capable of detecting an exception is informed of the existence of the ExceptionHandler object.
	dpj exceptionHandler: EH.
3. The ExceptionHandler object is then sent the message 'do pCode onTrapDo pTrapCode'.  The parameter pCode is a block of statements that is to be supervised by the ExceptionHandler object.  The parameter pTrapCode is a block of statements that is to be executed whenever an exception is detected.
	EH do [ ... ] onTrapDo [ ... ].
4. When an exception is detected during the execution of one of the statements in pCode the message 'trap' can be sent to the ExceptionHandler object which will then take control.  If information about the exception is available, it can be relayed by sending the message 'trap:' with the information specified as the parameter.
	EH trap.  (or)  EH trap: information.
5. When the ExceptionHandler object gets control it saves the parameter if one was sent, then executes pTrapCode.  The saved parameter can be retrieved by sending the message 'trapCondition'.  The statements in pTrapCode should take any actions necessary to handle the exception. Messages can be included in pTrapCode that tell the ExceptionHandler object what to do when pTrapCode completes.  The available messages are:
	5.1 'restart' which restarts the execution of pCode,
	5.2 'continue' which continues pCode at the point at which 'trap' was sent,
	5.3 'abort' which aborts the execution of pCode and returns control to the statement following 'do pCode onTrapDo pTrapCode'.
	EH restart.  (or)  EH continue.  (or)  EH abort.
6. The message 'doonTrapDo' returns a result which can be specified during the execution of either  pCode or pTrapCode by the message 'result ← pResult'.  This result value can be retrieved anytime after it has been specified by sending the message 'result'.
	EH result ← true.
	[ EH result  [ ... ] ].
7. If pCode is terminated abnormally from a user notify window, the message 'release' should be sent to return the ExceptionHandler object to its initial state.
	EH release.
8. Special error checking is included in the ExceptionHandler object to detect calls to pTrapCode during the execution of pTrapCode and other invalid conditions.
"].
"194" ExceptionHandler$'POST TRAP SPECIFICATION'
[restart | |
	 "...specifies that the code interrupted by 'trap' or 'trap:' will be restarted when the trap code completes."
	fPostTrapIndicator ← 0].
"503" ExceptionHandler$'EXAMPLES'
[juniperTest | e i max f |
	 "ExceptionHandler new juniperTest."
	e ← ExceptionHandler new.
	i ← 0.
	max ← 5.
	dpj exceptionHandler: e.
	dpj open.
	f ← dpj file: 'test.test'.
	e do [
		(f reset.
		[f end] whileFalseDo: 
			[user show: f next inString])] onTrapDo [
		(user cr.
		user show: 'Juniper not responding'.
		f release.
		dpj release.
		i ← i + 1.
		i < max
		  ifTrue:
			[e restart]
		  ifFalse: [e abort])].
	user cr.
	user show: 'done'.
	f close.
	dpj close].
"275" ExceptionHandler$'POST TRAP SPECIFICATION'
[abort | |
	 "...specifies that the code interrupted by 'trap' or 'trap:' will be aborted when the trap code completes.  Control will return to the statement that follows the invocation of 'doonTrapDo'."
	fPostTrapIndicator ← 1].
"162" ExceptionHandler$'TRAP HANDLER'
[trap | |
	 "...interrupts the execution of pCode and begins pTrapCode (from 'do pCode onTrapDo pTrapCode')."
	self trap: nil].
"1613" ExceptionHandler$'TRAP HANDLER'
[trap: pTrapCondition | tTrapCode i |
	 "...interrupts the execution of pCode and begins pTrapCode (from 'do pCode onTrapDo pTrapCode').  The trap condition is set to pTrapCondition."
	fStatusIndicator  nil
	  ifTrue: [user notify: 'ExceptionHandler is not active']
	  ifFalse:
		[ "1"
		fStatusIndicator = 0
		  ifTrue: [user notify: 'ExceptionHandler trap code is already active'] "2"].
	fStatusIndicator ← 0 "3".
	fTrapCondition ← pTrapCondition "4".
	fPostTrapIndicator ← 0 "5".
	tTrapCode ← fTrapCode cleancopy "6".
	tTrapCode eval "7".
	(1 to: tTrapCode totalPT) "8" do:
		[:i | fTrapCode setPT: i to: (tTrapCode getPT: i)].
	fStatusIndicator ← 1 "9".
	fPostTrapIndicator = 0 "10"
	  ifTrue:
		[self restartCode]
	  ifFalse:
		[fPostTrapIndicator = 1
		  ifTrue:
			[self abortCode]
		  ifFalse:
			[fPostTrapIndicator = 2]] "
1. If fStatusIndicator  nil, then 'doonTrapDo' has not been invoked and there is no trap code to execute.
2. if fStatusIndicator = 0, then fTrapCode is active.  This is an invalid state.
3. Set fStatusIndicator to indicate fTrapCode is active.
4. Set the trap condition to pTrapCondition.
5. Set the default post trap action to 'restart'.
6. Make a new copy of the context, fTrapCode.
7. Execute the new copy of fTrapCode.
8. Set the parameters and temporaries in the context, fTrapCode to those of the executed copy.  This is done so that fCode will see any changes made to these variables by fTrapCode.
9. Set fStatusIndicator to indicate fTrapCode is not active.
10. Select the terminating action from the value of fPostTrapIndicator.
"].
"1540" ExceptionHandler$'CONTROL STRUCTURE'
[do pCode onTrapDo pTrapCode | |
	 "...executes the set of statements in the block pCode and, conditionally, the set of statements in the block pTrapCode.  If 'trap' or 'trap:' is invoked during the execution of pCode, the execution is interrupted and pTrapCode is started.  When pTrapCode completes, pCode is either continued, restarted, or aborted, depending on which of 'continue', 'restart', and 'abort' is sent during the execution of pTrapCode.  A notify window is created if 'trap' or 'trap:' is sent when pCode is not active, or if 'doonTrapDo' is sent again before the first invocation completes."
	fStatusIndicator  nil
	  ifTrue:
		[user notify: 'ExceptionHandler is active'] "1".
	fStatusIndicator ← 1 "2".
	fCode ← pCode "3".
	fTrapCode ← pTrapCode "4".
	fDoContext ← thisContext "5".
	fTrapCondition ← nil "6".
	fResult ← true "7".
	fCode eval "8".
	self release "9".
	↑fResult "10" "
1. If fStatusIndicator  nil, then the previous invocation of 'doonTrapDo' has not completed properly.  Create a notify window in this case.
2. Set fStatusIndicator to indicate pCode is active.
3. Save pCode for execution and restart.
4. Save pTrapCode for later execution.
5. Save the context of 'doonTrapDo' for 'restart' and 'abort'.
6. Initialize the trap condition to nil.
7. Initialize the result of 'doonTrapDo ' to true.
8. Execute pCode.
9. Set fields to nil to release saved contexts.
10. Return fResult (which may have been modified during the execution of pCode or pTrapCode).
"].
"776" ExceptionHandler$'DOCUMENTATION'
[implementationNotes | |
	 "
FIELDS
fDoContext : a Context that controls the execution of the message 'doonTrapDo'.
fCode : a Context that controls the execution of the statements passed as the first parameter to 'doonTrapDo'.
fTrapCode : a Context that controls the execution of the statements passed as the second parameter to 'doonTrapDo'.
fTrapCondition : the object passed as the parameter to 'trap:'.
fResult : the object that is the result of 'doonTrapDo'.
fPostTrapIndicator : an Integer specifying the action to be taken after fTrapCode is executed.
fStatusIndicator : an Integer specifying the status of 'doonTrapDo'; nil means 'doonTrapDo' has not been invoked, 1 means fCode is active, 0 means fTrapCode is active.
"].
"136" ExceptionHandler$'MISC'
[trapCondition | |
	 "...returns the condition that was passed as the parameter to 'trap:'."
	↑fTrapCondition].
"195" ExceptionHandler$'POST TRAP SPECIFICATION'
[continue | |
	 "...specifies that the code interrupted by 'trap' or 'trap:' will be continued when the trap code completes."
	fPostTrapIndicator ← 2].
"363" ExceptionHandler$'TEST AND DIAGNOSTIC'
[test | guard i |
	 "ExceptionHandler new test."
	guard ← ExceptionHandler new.
	user clear.
	i ← 0.
	guard do [
		(user show: i asString.
		i ← i + 1.
		guard trap: i.
		user show: ' end')] onTrapDo [
		(i < 10
		  ifTrue: [guard restart]
		  ifFalse: [guard continue])].
	user show: ' done.'.
	user cr.
	↑guard result].
"522" ExceptionHandler$'TEST AND DIAGNOSTIC'
[testTransaction | e i max f |
	 "ExceptionHandler new testTransaction."
	e ← ExceptionHandler new.
	i ← 0.
	max ← 5.
	dpj exceptionHandler: e.
	dpj open.
	f ← dpj file: 'test.test'.
	e do [
		(f reset.
		[f end] whileFalseDo: 
			[user show: f next inString])] onTrapDo [
		(user cr.
		user show: 'Juniper not responding'.
		f release.
		dpj release.
		i ← i + 1.
		i < max
		  ifTrue:
			[e restart]
		  ifFalse: [e abort])].
	user cr.
	user show: 'done'.
	f close.
	dpj close].
"513" ExceptionHandler$'POST TRAP ACTION (internal)'
[restartCode | |
	 "...releases the context chain and restarts the block of statements passed as the first parameter to 'doonTrapDo'."
	thisContext caller releaseTo: fCode "1".
	fCode restart "2".
	fCode push: fDoContext "3".
	Top run: fCode at: Top currentPriority "4" "
1. Release the context chain from the caller of thisContext up to fCode.
2. Resets the pc and stack pointer of fCode.
3. Push the return context of fCode onto its tempframe.
4. Run fCode.
"].
"664" ExceptionHandler$'POST TRAP ACTION (internal)'
[abortCode | tDoContextCaller |
	 "...releases the context chain and returns fResult to the caller of 'doonTrapDo'."
	tDoContextCaller ← fDoContext caller "1".
	thisContext caller releaseTo: tDoContextCaller "2".
	self release "3".
	tDoContextCaller push: fResult "4".
	Top run: tDoContextCaller at: Top currentPriority "5" "
1. Get the caller of 'doonTrapDo'.
2. Release the context chain from the caller of thisContext up to the caller of 'doonTrapDo'.
3. Set fields to nil to clean up pointers to unwanted contexts.
4. Return fResult to the caller of 'doonTrapDo'.
5. Run the caller of 'doonTrapDo'.
"].
"199" ExceptionHandler$'POST TRAP ACTION (internal)'
[release | |
	 "...resets the exception handler to its initial condition."
	fCode ← nil.
	fTrapCode ← nil.
	fDoContext ← nil.
	fStatusIndicator ← nil].
"360" ExceptionHandler$'EXAMPLES'
[loopTest | guard i |
	 "ExceptionHandler new loopTest."
	guard ← ExceptionHandler new.
	user clear.
	i ← 0.
	guard do [
		(user show: i asString.
		i ← i + 1.
		guard trap: i.
		user show: ' end')] onTrapDo [
		(i < 10
		  ifTrue: [guard restart]
		  ifFalse: [guard continue])].
	user show: ' done.'.
	user cr.
	↑guard result].
"307" IDict$'As yet unclassified'
[findorinsert: obj | i |
	 "insert if not found, "
	i ← self findornil: obj.
	objects  i  obj
	  ifTrue: [↑i].
	 "found it"
	self sparse
	  ifTrue:
		[objects  i ← obj.
		↑i].
	 "insert if room"
	self growto: objects length * 2 "grow".
	↑self findorinsert: obj "and insert"].
"367" IDict$'As yet unclassified'
[findornil: obj | i loc |
	 "index if found or available slot"
	loc ← obj hash \ objects length.
	(1 to: objects length) do:
		[:i | loc ← (loc = objects length
				  ifTrue: [1]
				  ifFalse: [loc + 1]).
		objects  loc  nil
		  ifTrue: [↑loc].
		objects  loc  obj
		  ifTrue: [↑loc]].
	↑1 "table full - caller must check for hit"].