'From Cuis 1.0 of 28 November 2009 [latest update: #337] on 8 December 2009 at 9:26:09 am'!

!Compiler methodsFor: 'public access' stamp: 'jmv 12/8/2009 09:22'!
translate: aStream noPattern: noPattern ifFail: failBlock parser: aParser
	| tree |
	tree := aParser
			parse: aStream
			class: class
			noPattern: noPattern
			context: context
			notifying: requestor
			ifFail: [^ failBlock value].
	^ tree! !


!Encoder methodsFor: 'encoding' stamp: 'jmv 12/8/2009 09:23'!
encodeSelector: aSelector

	^self
		name: aSelector
		key: aSelector
		class: SelectorNode
		type: SendType
		set: selectorSet! !


!LeafNode methodsFor: 'code generation' stamp: 'jmv 12/8/2009 09:23'!
emitLong: mode on: aStream 
	"Emit extended variable access."
	| type idx |
	code < 256
		ifTrue:
			[code < 16
			ifTrue: [type := 0.
					idx := code]
			ifFalse: [code < 32
					ifTrue: [type := 1.
							idx := code - 16]
					ifFalse: [code < 96
							ifTrue: [type := code // 32 + 1.
									idx := code \\ 32]
							ifFalse: [self error: 
									'Sends should be handled in SelectorNode']]]]
		ifFalse: 
			[idx := code \\ 256.
			type := code // 256 - 1].
	idx <= 63 ifTrue:
		[aStream nextPut: mode.
		^ aStream nextPut: type * 64 + idx].
	"Compile for Double-exetended Do-anything instruction..."
	mode = LoadLong ifTrue:
		[aStream nextPut: DblExtDoAll.
		aStream nextPut: (#(64 0 96 128) at: type+1).  "Cant be temp (type=1)"
		^ aStream nextPut: idx].
	mode = Store ifTrue:
		[aStream nextPut: DblExtDoAll.
		aStream nextPut: (#(160 0 0 224) at: type+1).  "Cant be temp or const (type=1 or 2)"
		^ aStream nextPut: idx].
	mode = StorePop ifTrue:
		[aStream nextPut: DblExtDoAll.
		aStream nextPut: (#(192 0 0 0) at: type+1).  "Can only be inst"
		^ aStream nextPut: idx].
! !

!LeafNode methodsFor: 'private' stamp: 'jmv 12/8/2009 09:24'!
code: idx type: type

	idx isNil 
		ifTrue: [^type negated].
	(CodeLimits at: type) > idx 
		ifTrue: [^(CodeBases at: type) + idx].
	^type * 256 + idx! !


!SelectorNode methodsFor: 'code generation' stamp: 'jmv 12/8/2009 09:25'!
emit: stack args: nArgs on: aStream super: supered
	| idx |
	stack pop: nArgs.
	(supered not and: [code - Send < SendLimit and: [nArgs < 3]]) ifTrue:
		["short send"
		code < Send
			ifTrue: [^ aStream nextPut: code "special"]
			ifFalse: [^ aStream nextPut: nArgs * 16 + code]].
	idx := code < 256 ifTrue: [code - Send] ifFalse: [code \\ 256].
	(idx <= 31 and: [nArgs <= 7]) ifTrue: 
		["extended (2-byte) send [131 and 133]"
		aStream nextPut: SendLong + (supered ifTrue: [2] ifFalse: [0]).
		^ aStream nextPut: nArgs * 32 + idx].
	(supered not and: [idx <= 63 and: [nArgs <= 3]]) ifTrue:
		["new extended (2-byte) send [134]"
		aStream nextPut: SendLong2.
		^ aStream nextPut: nArgs * 64 + idx].
	"long (3-byte) send"
	aStream nextPut: DblExtDoAll.
	aStream nextPut: nArgs + (supered ifTrue: [32] ifFalse: [0]).
	aStream nextPut: idx! !

!SelectorNode methodsFor: 'code generation' stamp: 'jmv 12/8/2009 09:25'!
size: encoder args: nArgs super: supered
	| idx |
	self reserve: encoder.
	(supered not and: [code - Send < SendLimit and: [nArgs < 3]])
		ifTrue: [^1]. "short send"
	(supered and: [code < Send]) ifTrue: 
		["super special:"
		code := self code: (encoder sharableLitIndex: key) type: 5].
	idx := code < 256 ifTrue: [code - Send] ifFalse: [code \\ 256].
	(idx <= 31 and: [nArgs <= 7])
		ifTrue: [^ 2]. "medium send"
	(supered not and: [idx <= 63 and: [nArgs <= 3]])
		ifTrue: [^ 2]. "new medium send"
	^ 3 "long send"! !


!VariableNode methodsFor: 'tiles' stamp: 'jmv 12/8/2009 09:25'!
variableGetterBlockIn: aContext

	| temps idx ivars |

	(self type = 4 and: [self key isVariableBinding]) ifTrue: [
		^[self key value]
	].
	aContext ifNil: [^nil].
	self isSelfPseudoVariable ifTrue: [^[aContext receiver]].
	self type = 1 ifTrue: [
		ivars := aContext receiver class allInstVarNames.
		idx := ivars indexOf: self name ifAbsent: [^nil].
		^[aContext receiver instVarAt: idx]
	].
	self type = 2 ifTrue: [
		temps := aContext tempNames.
		idx := temps indexOf: self name ifAbsent: [^nil].
		^[aContext tempAt: idx]
	].
	^nil
! !


!LiteralVariableNode methodsFor: 'code generation' stamp: 'jmv 12/8/2009 09:25'!
sizeForStore: encoder
	| idx |
	(key isVariableBinding and:[key isSpecialWriteBinding]) 
		ifFalse:[^super sizeForStore: encoder].
	code < 0 ifTrue:[
		idx := self index.
		code := self code: idx type: LdLitType].
	writeNode := encoder encodeSelector: #value:.
	^(writeNode size: encoder args: 1 super: false) + (super sizeForValue: encoder)! !

!LiteralVariableNode methodsFor: 'code generation' stamp: 'jmv 12/8/2009 09:24'!
sizeForStorePop: encoder
	| idx |
	(key isVariableBinding and:[key isSpecialWriteBinding]) 
		ifFalse:[^super sizeForStorePop: encoder].
	code < 0 ifTrue:[
		idx := self index.
		code := self code: idx type: LdLitType].
	writeNode := encoder encodeSelector: #value:.
	^(writeNode size: encoder args: 1 super: false) + (super sizeForValue: encoder) + 1! !

!LiteralVariableNode methodsFor: 'code generation' stamp: 'jmv 12/8/2009 09:24'!
sizeForValue: encoder
	| idx |
	(key isVariableBinding and:[key isSpecialReadBinding]) 
		ifFalse:[^super sizeForValue: encoder].
	code < 0 ifTrue:[
		idx := self index.
		code := self code: idx type: LdLitType].
	readNode := encoder encodeSelector: #value.
	^(readNode size: encoder args: 0 super: false) + (super sizeForValue: encoder)! !

