nil subclass: #Object instanceVariableNames: '' category: 'Kernel'! !Object methodsFor: 'accessing'! yourself ^self ! class ! size self error: 'Object not indexable' ! instVarAt: aString ! instVarAt: aString put: anObject ! basicAt: aString ! basicAt: aString put: anObject ! basicDelete: aString ! ! !Object methodsFor: 'comparing'! = anObject ! ~= anObject ^(self = anObject) == false ! ! !Object methodsFor: 'converting'! -> anObject ^Association key: self value: anObject ! asString ^self printString ! asJavascript ^self asString ! asJSON ! asJSONObject | object | object := Object new. self class instanceVariableNames do: [:each | object basicAt: each put: (self instVarAt: each) asJSONObject]. ^object ! ! !Object methodsFor: 'copying'! copy ^self shallowCopy postCopy ! shallowCopy < var copy = self.klass._new(); for(var i in self) { if(/^@.+/.test(i)) { copy[i] = self[i]; } } return copy; > ! deepCopy < var copy = self.klass._new(); for(var i in self) { if(/^@.+/.test(i)) { copy[i] = self[i]._deepCopy(); } } return copy; > ! postCopy ! ! !Object methodsFor: 'error handling'! error: aString Error signal: aString ! subclassResponsibility self error: 'This method is a responsibility of a subclass' ! shouldNotImplement self error: 'This method should not be implemented in ', self class name ! try: aBlock catch: anotherBlock ! doesNotUnderstand: aMessage MessageNotUnderstood new receiver: self; message: aMessage; signal ! halt self error: 'Halt encountered' ! ! !Object methodsFor: 'initialization'! initialize ! ! !Object methodsFor: 'message handling'! perform: aSymbol ^self perform: aSymbol withArguments: #() ! perform: aSymbol withArguments: aCollection ^self basicPerform: aSymbol asSelector withArguments: aCollection ! basicPerform: aSymbol ^self basicPerform: aSymbol withArguments: #() ! basicPerform: aSymbol withArguments: aCollection ! ! !Object methodsFor: 'printing'! printString ^'a ', self class name ! printNl ! ! !Object methodsFor: 'testing'! isKindOf: aClass ^(self isMemberOf: aClass) ifTrue: [true] ifFalse: [self class inheritsFrom: aClass] ! isMemberOf: aClass ^self class = aClass ! ifNil: aBlock "inlined in the Compiler" ^self ! ifNil: aBlock ifNotNil: anotherBlock "inlined in the Compiler" ^anotherBlock value ! ifNotNil: aBlock "inlined in the Compiler" ^aBlock value ! ifNotNil: aBlock ifNil: anotherBlock "inlined in the Compiler" ^aBlock value ! isNil ^false ! notNil ^self isNil not ! isClass ^false ! isMetaclass ^false ! isNumber ^false ! isString ^false ! isParseFailure ^false ! ! !Object class methodsFor: 'initialization'! initialize "no op" ! ! Object subclass: #Smalltalk instanceVariableNames: '' category: 'Kernel'! !Smalltalk methodsFor: 'accessing'! classes ! readJSON: anObject ! at: aString ! removeClass: aClass aClass isMetaclass ifTrue: [self error: aClass asString, ' is a Metaclass and cannot be removed!!']. aClass methodDictionary values do: [:each | aClass removeCompiledMethod: each]. aClass class methodDictionary values do: [:each | aClass class removeCompiledMethod: each]. self basicDelete: aClass name ! ! Smalltalk class instanceVariableNames: 'current'! !Smalltalk class methodsFor: 'accessing'! current ! ! Object subclass: #Behavior instanceVariableNames: '' category: 'Kernel'! !Behavior methodsFor: 'accessing'! name ! superclass ! subclasses ! allSubclasses | result | result := self subclasses. self subclasses do: [:each | result addAll: each allSubclasses]. ^result ! withAllSubclasses ^(Array with: self) addAll: self allSubclasses; yourself ! prototype ! methodDictionary ! methodsFor: aString ^ClassCategoryReader new class: self category: aString; yourself ! addCompiledMethod: aMethod ! instanceVariableNames ! comment ^(self basicAt: 'comment') ifNil: [''] ! comment: aString self basicAt: 'comment' put: aString ! commentStamp ^ClassCommentReader new class: self; yourself ! removeCompiledMethod: aMethod ! protocols | protocols | protocols := Array new. self methodDictionary do: [:each | (protocols includes: each category) ifFalse: [ protocols add: each category]]. ^protocols sort ! protocolsDo: aBlock "Execute aBlock for each method category with its collection of methods in the sort order of category name." | methodsByCategory | methodsByCategory := Dictionary new. self methodDictionary values do: [:m | (methodsByCategory at: m category ifAbsentPut: [Array new]) add: m]. self protocols do: [:category | aBlock value: category value: (methodsByCategory at: category)] ! allInstanceVariableNames | result | result := self instanceVariableNames copy. self superclass ifNotNil: [ result addAll: self superclass allInstanceVariableNames]. ^result ! methodAt: aString ! methodsFor: aString stamp: aStamp "Added for compatibility, right now ignores stamp." ^self methodsFor: aString ! commentStamp: aStamp prior: prior "Ignored right now." ! ! !Behavior methodsFor: 'instance creation'! new ^self basicNew initialize ! basicNew ! inheritsFrom: aClass ^aClass allSubclasses includes: self ! ! Behavior subclass: #Class instanceVariableNames: '' category: 'Kernel'! !Class methodsFor: 'accessing'! category ! category: aString ! rename: aString < smalltalk[aString] = self; delete smalltalk[self.className]; self.className = aString; > ! ! !Class methodsFor: 'class creation'! subclass: aString instanceVariableNames: anotherString ^self subclass: aString instanceVariableNames: anotherString category: nil ! subclass: aString instanceVariableNames: aString2 category: aString3 ^ClassBuilder new superclass: self subclass: aString instanceVariableNames: aString2 category: aString3 ! subclass: aString instanceVariableNames: aString2 classVariableNames: classVars poolDictionaries: pools category: aString3 "Just ignore class variables and pools. Added for compatibility." ^self subclass: aString instanceVariableNames: aString2 category: aString3 ! ! !Class methodsFor: 'printing'! printString ^self name ! ! !Class methodsFor: 'testing'! isClass ^true ! ! Behavior subclass: #Metaclass instanceVariableNames: '' category: 'Kernel'! !Metaclass methodsFor: 'accessing'! instanceClass ! instanceVariableNames: aCollection ClassBuilder new class: self instanceVariableNames: aCollection ! ! !Metaclass methodsFor: 'printing'! printString ^self instanceClass name, ' class' ! ! !Metaclass methodsFor: 'testing'! isMetaclass ^true ! ! Object subclass: #CompiledMethod instanceVariableNames: '' category: 'Kernel'! !CompiledMethod methodsFor: 'accessing'! source ^(self basicAt: 'source') ifNil: [''] ! source: aString self basicAt: 'source' put: aString ! category ^(self basicAt: 'category') ifNil: [''] ! category: aString self basicAt: 'category' put: aString ! selector ^self basicAt: 'selector' ! selector: aString self basicAt: 'selector' put: aString ! fn ^self basicAt: 'fn' ! fn: aBlock self basicAt: 'fn' put: aBlock ! messageSends ^self basicAt: 'messageSends' ! methodClass ^self basicAt: 'methodClass' ! referencedClasses ^self basicAt: 'referencedClasses' ! ! Object subclass: #Number instanceVariableNames: '' category: 'Kernel'! !Number methodsFor: 'arithmetic'! + aNumber "Inlined in the Compiler" ! - aNumber "Inlined in the Compiler" ! * aNumber "Inlined in the Compiler" ! / aNumber "Inlined in the Compiler" ! max: aNumber ! min: aNumber ! modulo: aNumber ! ! !Number methodsFor: 'comparing'! = aNumber "Inlined in the Compiler" ! > aNumber "Inlined in the Compiler" > aNumber> ! < aNumber "Inlined in the Compiler" ! >= aNumber "Inlined in the Compiler" >= aNumber> ! <= aNumber "Inlined in the Compiler" ! ! !Number methodsFor: 'converting'! rounded ! truncated ! to: aNumber | array first last count | first := self truncated. last := aNumber truncated + 1. count := 1. (first <= last) ifFalse: [self error: 'Wrong interval']. array := Array new. (last - first) timesRepeat: [ array at: count put: first. count := count + 1. first := first + 1]. ^array ! asString ^self printString ! asJavascript ^'(', self printString, ')' ! atRandom ^(Random new next * self) truncated + 1 ! @ aNumber ^Point x: self y: aNumber ! asPoint ^Point x: self y: self ! asJSONObject ^self ! ! !Number methodsFor: 'enumerating'! timesRepeat: aBlock | integer count | integer := self truncated. count := 1. [count > self] whileFalse: [ aBlock value. count := count + 1] ! to: aNumber do: aBlock ^(self to: aNumber) do: aBlock ! ! !Number methodsFor: 'printing'! printString ! ! !Number methodsFor: 'testing'! isNumber ^true ! even ^ 0 = (self modulo: 2) ! odd ^ self even not ! ! !Number methodsFor: 'timeouts/intervals'! clearInterval ! clearTimeout ! ! !Number class methodsFor: 'instance creation'! pi ! ! Object subclass: #BlockClosure instanceVariableNames: '' category: 'Kernel'! !BlockClosure methodsFor: 'accessing'! compiledSource ! ! !BlockClosure methodsFor: 'controlling'! whileTrue: aBlock "inlined in the Compiler" ! whileFalse: aBlock "inlined in the Compiler" ! whileFalse "inlined in the Compiler" self whileFalse: [] ! whileTrue "inlined in the Compiler" self whileTrue: [] ! ! !BlockClosure methodsFor: 'error handling'! on: anErrorClass do: aBlock self try: self catch: [:error | (error isKindOf: anErrorClass) ifTrue: [aBlock value: error] ifFalse: [error signal]] ! ! !BlockClosure methodsFor: 'evaluating'! value "inlined in the Compiler" ! value: anArg "inlined in the Compiler" ! value: firstArg value: secondArg "inlined in the Compiler" ! value: firstArg value: secondArg value: thirdArg "inlined in the Compiler" ! valueWithPossibleArguments: aCollection ! new "Use the receiver as a JS constructor. *Do not* use this method to instanciate Smalltalk objects!!" ! ! !BlockClosure methodsFor: 'printing'! printString ^ String streamContents: [:aStream| aStream nextPutAll: super printString; nextPutAll: '('; nextPutAll: self compiledSource; nextPutAll: ')'; cr. ] ! ! !BlockClosure methodsFor: 'timeout/interval'! valueWithTimeout: aNumber ! valueWithInterval: aNumber ! ! Object subclass: #Boolean instanceVariableNames: '' category: 'Kernel'! !Boolean methodsFor: 'comparing'! = aBoolean ! asJSONObject ^self ! ! !Boolean methodsFor: 'controlling'! ifTrue: aBlock "inlined in the Compiler" ^self ifTrue: aBlock ifFalse: [] ! ifFalse: aBlock "inlined in the Compiler" ^self ifTrue: [] ifFalse: aBlock ! ifFalse: aBlock ifTrue: anotherBlock "inlined in the Compiler" ^self ifTrue: anotherBlock ifFalse: aBlock ! ifTrue: aBlock ifFalse: anotherBlock "inlined in the Compiler" < if(self == true) { return aBlock(); } else { return anotherBlock(); } > ! and: aBlock ^self = true ifTrue: aBlock ifFalse: [false] ! or: aBlock ^self = true ifTrue: [true] ifFalse: aBlock ! not ^self = false ! ! !Boolean methodsFor: 'copying'! shallowCopy ^self ! deepCopy ^self ! ! !Boolean methodsFor: 'printing'! printString ! ! Object subclass: #Date instanceVariableNames: '' category: 'Kernel'! !Date commentStamp! The Date class is used to work with dates and times.! !Date methodsFor: 'accessing'! year ! month ! month: aNumber ! day ^self dayOfWeek ! dayOfWeek ! dayOfWeek: aNumber ! day: aNumber self day: aNumber ! year: aNumber ! dayOfMonth ! dayOfMonth: aNumber ! time ! time: aNumber ! hours: aNumber ! minutes: aNumber ! seconds: aNumber ! milliseconds: aNumber ! hours ! minutes ! seconds ! milliseconds ! ! !Date methodsFor: 'arithmetic'! - aDate ! + aDate ! ! !Date methodsFor: 'comparing'! < aDate ! > aDate > aDate> ! <= aDate ! >= aDate >= aDate> ! ! !Date methodsFor: 'converting'! asString ! asMilliseconds ^self time ! asDateString ! asTimeString ! asLocaleString ! asNumber ^self asMilliseconds ! asJSONObject ^self ! ! !Date methodsFor: 'printing'! printString ^self asString ! ! !Date class methodsFor: 'instance creation'! new: anObject ! fromString: aString "Example: Date fromString('2011/04/15 00:00:00')" ^self new: aString ! fromSeconds: aNumber ^self fromMilliseconds: aNumber * 1000 ! fromMilliseconds: aNumber ^self new: aNumber ! today ^self new ! now ^self today ! millisecondsToRun: aBlock | t | t := Date now. aBlock value. ^Date now - t ! ! Object subclass: #UndefinedObject instanceVariableNames: '' category: 'Kernel'! !UndefinedObject methodsFor: 'class creation'! subclass: aString instanceVariableNames: anotherString ^self subclass: aString instanceVariableNames: anotherString category: nil ! subclass: aString instanceVariableNames: aString2 category: aString3 ^ClassBuilder new superclass: self subclass: aString instanceVariableNames: aString2 category: aString3 ! ! !UndefinedObject methodsFor: 'copying'! shallowCopy ^self ! deepCopy ^self ! ! !UndefinedObject methodsFor: 'printing'! printString ^'nil' ! ! !UndefinedObject methodsFor: 'testing'! ifNil: aBlock "inlined in the Compiler" ^self ifNil: aBlock ifNotNil: [] ! ifNotNil: aBlock "inlined in the Compiler" ^self ! ifNil: aBlock ifNotNil: anotherBlock "inlined in the Compiler" ^aBlock value ! ifNotNil: aBlock ifNil: anotherBlock "inlined in the Compiler" ^anotherBlock value ! isNil ^true ! notNil ^false ! ! !UndefinedObject class methodsFor: 'instance creation'! new self error: 'You cannot create new instances of UndefinedObject. Use nil' ! ! Object subclass: #Collection instanceVariableNames: '' category: 'Kernel'! !Collection methodsFor: 'accessing'! size self subclassResponsibility ! readStream ^self stream ! writeStream ^self stream ! stream ^self streamClass on: self ! streamClass ^self class streamClass ! ! !Collection methodsFor: 'adding/removing'! add: anObject self subclassResponsibility ! addAll: aCollection aCollection do: [:each | self add: each]. ^aCollection ! remove: anObject self subclassResponsibility ! ! !Collection methodsFor: 'converting'! asArray | array index | array := Array new. index := 0. self do: [:each | index := index + 1. array at: index put: each]. ^array ! ! !Collection methodsFor: 'copying'! , aCollection ^self copy addAll: aCollection; yourself ! copyWith: anObject ^self copy add: anObject; yourself ! copyWithAll: aCollection ^self copy addAll: aCollection; yourself ! ! !Collection methodsFor: 'enumerating'! do: aBlock ! collect: aBlock | newCollection | newCollection := self class new. self do: [:each | newCollection add: (aBlock value: each)]. ^newCollection ! detect: aBlock ^self detect: aBlock ifNone: [self errorNotFound] ! detect: aBlock ifNone: anotherBlock < for(var i = 0; i < self.length; i++) if(aBlock(self[i])) return self[i]; return anotherBlock(); > ! do: aBlock separatedBy: anotherBlock | first | first := true. self do: [:each | first ifTrue: [first := false] ifFalse: [anotherBlock value]. aBlock value: each] ! inject: anObject into: aBlock | result | result := anObject. self do: [:each | result := aBlock value: result value: each]. ^result ! reject: aBlock ^self select: [:each | (aBlock value: each) = false] ! select: aBlock | stream | stream := self class new writeStream. self do: [:each | (aBlock value: each) ifTrue: [ stream nextPut: each]]. ^stream contents ! ! !Collection methodsFor: 'error handling'! errorNotFound self error: 'Object is not in the collection' ! ! !Collection methodsFor: 'testing'! includes: anObject < var i = self.length; while (i--) { if (smalltalk.send(self[i], "__eq", [anObject])) {return true;} } return false > ! notEmpty ^self isEmpty not ! isEmpty ^self size = 0 ! ! !Collection class methodsFor: 'accessing'! streamClass ^Stream ! ! !Collection class methodsFor: 'instance creation'! with: anObject ^self new add: anObject; yourself ! with: anObject with: anotherObject ^self new add: anObject; add: anotherObject; yourself ! with: firstObject with: secondObject with: thirdObject ^self new add: firstObject; add: secondObject; add: thirdObject; yourself ! withAll: aCollection ^self new addAll: aCollection; yourself ! ! Collection subclass: #SequenceableCollection instanceVariableNames: '' category: 'Kernel'! !SequenceableCollection methodsFor: 'accessing'! at: anIndex ^self at: anIndex ifAbsent: [ self errorNotFound] ! at: anIndex ifAbsent: aBlock self subclassResponsibility ! at: anIndex put: anObject self subclassResponsibility ! first ^self at: 1 ! fourth ^self at: 4 ! last ^self at: self size ! second ^self at: 2 ! third ^self at: 3 ! allButFirst ^self copyFrom: 2 to: self size ! allButLast ^self copyFrom: 1 to: self size - 1 ! indexOf: anObject ^self indexOf: anObject ifAbsent: [self errorNotFound] ! indexOf: anObject ifAbsent: aBlock < for(var i=0;i ! ! !SequenceableCollection methodsFor: 'adding'! removeLast self remove: self last ! addLast: anObject self add: anObject ! ! !SequenceableCollection methodsFor: 'copying'! copyFrom: anIndex to: anotherIndex self subclassResponsibility ! ! !SequenceableCollection methodsFor: 'enumerating'! withIndexDo: aBlock ! ! SequenceableCollection subclass: #String instanceVariableNames: '' category: 'Kernel'! !String methodsFor: 'accessing'! size ! at: anIndex ! at: anIndex put: anObject self errorReadOnly ! at: anIndex ifAbsent: aBlock (self at: anIndex) ifNil: [aBlock] ! escaped ! unescaped ! ! !String methodsFor: 'adding'! add: anObject self errorReadOnly ! remove: anObject self errorReadOnly ! ! !String methodsFor: 'comparing'! = aString ! > aString > aString> ! < aString ! >= aString >= aString> ! <= aString ! ! !String methodsFor: 'converting'! asSelector "If you change this method, change smalltalk.convertSelector too (see js/boot.js file)" | selector | selector := '_', self. selector := selector replace: ':' with: '_'. selector := selector replace: '[+]' with: '_plus'. selector := selector replace: '-' with: '_minus'. selector := selector replace: '[*]' with: '_star'. selector := selector replace: '[/]' with: '_slash'. selector := selector replace: '>' with: '_gt'. selector := selector replace: '<' with: '_lt'. selector := selector replace: '=' with: '_eq'. selector := selector replace: ',' with: '_comma'. selector := selector replace: '[@]' with: '_at'. ^selector ! asJavascript < if(self.search(/^[a-zA-Z0-9_:.$ ]*$/) == -1) return "unescape(\"" + escape(self) + "\")"; else return "\"" + self + "\""; > ! tokenize: aString ! asString ^self ! asNumber ! asParser ^PPStringParser new string: self ! asChoiceParser ^PPChoiceParser withAll: (self asArray collect: [:each | each asParser]) ! asCharacterParser ^PPCharacterParser new string: self ! asJSONObject ^self ! asLowercase ! asUppercase ! ! !String methodsFor: 'copying'! , aString ! copyFrom: anIndex to: anotherIndex ! shallowCopy ^self class fromString: self ! deepCopy ^self shallowCopy ! ! !String methodsFor: 'error handling'! errorReadOnly self error: 'Object is read-only' ! ! !String methodsFor: 'printing'! printString ^'''', self, '''' ! printNl ! ! !String methodsFor: 'regular expressions'! replace: aString with: anotherString ^self replaceRegexp: (RegularExpression fromString: aString flag: 'g') with: anotherString ! replaceRegexp: aRegexp with: aString ! match: aRegexp ! trimLeft: separators ^self replaceRegexp: (RegularExpression fromString: '^[', separators, ']+' flag: 'g') with: '' ! trimRight: separators ^self replaceRegexp: (RegularExpression fromString: '[', separators, ']+$' flag: 'g') with: '' ! trimLeft ^self trimLeft: '\s' ! trimRight ^self trimRight: '\s' ! trimBoth ^self trimBoth: '\s' ! trimBoth: separators ^(self trimLeft: separators) trimRight: separators ! ! !String methodsFor: 'split join'! join: aCollection ^ String streamContents: [:stream | aCollection do: [:each | stream nextPutAll: each asString] separatedBy: [stream nextPutAll: self]] ! ! !String methodsFor: 'testing'! isString ^true ! includesSubString: subString < return self.indexOf(subString) !!= -1 > ! ! !String class methodsFor: 'accessing'! streamClass ^StringStream ! cr ! lf ! space ! tab ! crlf ! ! !String class methodsFor: 'instance creation'! fromString: aString ! streamContents: blockWithArg |stream| stream := (self streamClass on: String new). blockWithArg value: stream. ^ stream contents ! ! SequenceableCollection subclass: #Array instanceVariableNames: '' category: 'Kernel'! !Array methodsFor: 'accessing'! size ! at: anIndex put: anObject ! at: anIndex ifAbsent: aBlock < var value = self[anIndex - 1]; if(value === undefined) { return aBlock(); } else { return value; } > ! ! !Array methodsFor: 'adding/removing'! add: anObject ! remove: anObject < for(var i=0;i ! removeFrom: aNumber to: anotherNumber ! ! !Array methodsFor: 'converting'! asJavascript ^'[', ((self collect: [:each | each asJavascript]) join: ', '), ']' ! asJSONObject ^self collect: [:each | each asJSONObject] ! ! !Array methodsFor: 'copying'! shallowCopy | newCollection | newCollection := self class new. self do: [:each | newCollection add: each]. ^newCollection ! deepCopy | newCollection | newCollection := self class new. self do: [:each | newCollection add: each deepCopy]. ^newCollection ! copyFrom: anIndex to: anotherIndex | array | array := self class new. anIndex to: anotherIndex do: [:each | array add: (self at: each)]. ^array ! ! !Array methodsFor: 'enumerating'! join: aString ! sort ^self basicPerform: 'sort' ! sort: aBlock < return self.sort(function(a, b) { if(aBlock(a,b)) {return -1} else {return 1} }) > ! sorted ^self copy sort ! sorted: aBlock ^self copy sort: aBlock ! printString | str | str := '' writeStream. str nextPutAll: super printString, ' ('. self do: [:each | str nextPutAll: each printString] separatedBy: [str nextPutAll: ' ']. str nextPutAll: ')'. ^str contents ! ! Object subclass: #RegularExpression instanceVariableNames: '' category: 'Kernel'! !RegularExpression methodsFor: 'evaluating'! compile: aString ! exec: aString ! test: aString ! ! !RegularExpression class methodsFor: 'instance creation'! fromString: aString flag: anotherString ! fromString: aString ^self fromString: aString flag: '' ! ! Object subclass: #Error instanceVariableNames: 'messageText' category: 'Kernel'! !Error methodsFor: 'accessing'! messageText ^messageText ! messageText: aString messageText := aString ! context ! ! !Error methodsFor: 'signaling'! signal ! ! !Error class methodsFor: 'instance creation'! signal: aString ^self new messageText: aString; signal ! ! Object subclass: #MethodContext instanceVariableNames: '' category: 'Kernel'! !MethodContext methodsFor: 'accessing'! receiver ! selector ! home ! temps ! printString ^super printString, '(', self asString, ')' ! asString ^self receiver class printString, ' >> ', self selector ! ! Object subclass: #Association instanceVariableNames: 'key value' category: 'Kernel'! !Association methodsFor: 'accessing'! key: aKey key := aKey ! key ^key ! value: aValue value := aValue ! value ^value ! ! !Association methodsFor: 'comparing'! = anAssociation ^self class = anAssociation class and: [ self key = anAssociation key and: [ self value = anAssociation value]] ! ! !Association class methodsFor: 'instance creation'! key: aKey value: aValue ^self new key: aKey; value: aValue; yourself ! ! Collection subclass: #Dictionary instanceVariableNames: 'keys' category: 'Kernel'! !Dictionary methodsFor: 'accessing'! size ^keys size ! associations | associations | associations := #(). keys do: [:each | associations add: (Association key: each value: (self at: each))]. ^associations ! keys ^keys copy ! values ^keys collect: [:each | self at: each] ! at: aKey put: aValue (keys includes: aKey) ifFalse: [keys add: aKey]. ^self basicAt: aKey put: aValue ! at: aKey ifAbsent: aBlock ^(self keys includes: aKey) ifTrue: [self basicAt: aKey] ifFalse: aBlock ! at: aKey ifAbsentPut: aBlock ^self at: aKey ifAbsent: [ self at: aKey put: aBlock value] ! at: aKey ifPresent: aBlock ^(self basicAt: aKey) ifNotNil: [aBlock value: (self at: aKey)] ! at: aKey ifPresent: aBlock ifAbsent: anotherBlock ^(self basicAt: aKey) ifNil: anotherBlock ifNotNil: [aBlock value: (self at: aKey)] ! at: aKey ^self at: aKey ifAbsent: [self errorNotFound] ! ! !Dictionary methodsFor: 'adding/removing'! add: anAssociation self at: anAssociation key put: anAssociation value ! addAll: aDictionary super addAll: aDictionary associations. ^aDictionary ! remove: aKey self removeKey: aKey ! removeKey: aKey keys remove: aKey ! ! !Dictionary methodsFor: 'comparing'! = aDictionary self class = aDictionary class ifFalse: [^false]. self associationsDo: [:assoc | (aDictionary at: assoc key ifAbsent: [^false]) = assoc value ifFalse: [^false]]. ^true ! ! !Dictionary methodsFor: 'converting'! asJSONObject | object | object := Object new. self keysAndValuesDo: [:key :value | object basicAt: key put: value asJSONObject]. ^object ! ! !Dictionary methodsFor: 'copying'! shallowCopy | copy | copy := self class new. self associationsDo: [:each | copy at: each key put: each value]. ^copy ! , aCollection self shouldNotImplement ! copyFrom: anIndex to: anotherIndex self shouldNotImplement ! ! !Dictionary methodsFor: 'enumerating'! associationsDo: aBlock self associations do: aBlock ! keysAndValuesDo: aBlock self associationsDo: [:each | aBlock value: each key value: each value] ! do: aBlock self values do: aBlock ! select: aBlock | newDict | newDict := self class new. self keysAndValuesDo: [:key :value | (aBlock value: value) ifTrue: [newDict at: key put: value]]. ^newDict ! collect: aBlock | newDict | newDict := self class new. self keysAndValuesDo: [:key :value | newDict at: key put: (aBlock value: value)]. ^newDict ! detect: aBlock ifNone: anotherBlock ^self values detect: aBlock ifNone: anotherBlock ! includes: anObject ^self values includes: anObject ! ! !Dictionary methodsFor: 'initialization'! initialize super initialize. keys := #() ! ! !Dictionary methodsFor: 'printing'! printString ^ String streamContents: [:aStream| aStream nextPutAll: super printString; nextPutAll: '('. self associations do: [:anAssociation| aStream nextPutAll: anAssociation key printString; nextPutAll: ' -> '; nextPutAll: anAssociation value printString] separatedBy: [aStream nextPutAll: ' , ']. aStream nextPutAll: ')'. ] ! ! Object subclass: #ClassBuilder instanceVariableNames: '' category: 'Kernel'! !ClassBuilder methodsFor: 'class creation'! superclass: aClass subclass: aString self superclass: aClass subclass: aString instanceVariableNames: '' category: nil ! superclass: aClass subclass: aString instanceVariableNames: aString2 category: aString3 | newClass | newClass := self addSubclassOf: aClass named: aString instanceVariableNames: (self instanceVariableNamesFor: aString2). self setupClass: newClass. newClass category: (aString3 ifNil: ['unclassified']) ! class: aClass instanceVariableNames: aString aClass isMetaclass ifFalse: [self error: aClass name, ' is not a metaclass']. aClass basicAt: 'iVarNames' put: (self instanceVariableNamesFor: aString). self setupClass: aClass ! ! !ClassBuilder methodsFor: 'private'! instanceVariableNamesFor: aString ^(aString tokenize: ' ') reject: [:each | each isEmpty] ! addSubclassOf: aClass named: aString instanceVariableNames: aCollection ! setupClass: aClass ! ! Object subclass: #ClassCategoryReader instanceVariableNames: 'class category chunkParser' category: 'Kernel'! !ClassCategoryReader methodsFor: 'accessing'! class: aClass category: aString class := aClass. category := aString ! ! !ClassCategoryReader methodsFor: 'fileIn'! scanFrom: aStream | nextChunk | nextChunk := (chunkParser emptyChunk / chunkParser chunk) parse: aStream. nextChunk isEmptyChunk ifFalse: [ self compileMethod: nextChunk contents. self scanFrom: aStream]. ! ! !ClassCategoryReader methodsFor: 'initialization'! initialize super initialize. chunkParser := ChunkParser new. ! ! !ClassCategoryReader methodsFor: 'private'! compileMethod: aString | method | method := Compiler new load: aString forClass: class. method category: category. class addCompiledMethod: method ! ! Object subclass: #Stream instanceVariableNames: 'collection position streamSize' category: 'Kernel'! !Stream methodsFor: 'accessing'! collection ^collection ! setCollection: aCollection collection := aCollection ! position ^position ifNil: [position := 0] ! position: anInteger position := anInteger ! streamSize ^streamSize ! setStreamSize: anInteger streamSize := anInteger ! contents ^self collection copyFrom: 1 to: self streamSize ! size ^self streamSize ! ! !Stream methodsFor: 'actions'! reset self position: 0 ! close ! flush ! resetContents self reset. self setStreamSize: 0 ! ! !Stream methodsFor: 'enumerating'! do: aBlock [self atEnd] whileFalse: [aBlock value: self next] ! ! !Stream methodsFor: 'positioning'! setToEnd self position: self size ! skip: anInteger self position: ((self position + anInteger) min: self size max: 0) ! ! !Stream methodsFor: 'reading'! next self position: self position + 1. ^collection at: self position ! next: anInteger | tempCollection | tempCollection := self collection class new. anInteger timesRepeat: [ self atEnd ifFalse: [ tempCollection add: self next]]. ^tempCollection ! peek ^self atEnd ifFalse: [ self collection at: self position + 1] ! ! !Stream methodsFor: 'testing'! atEnd ^self position = self size ! atStart ^self position = 0 ! isEmpty ^self size = 0 ! ! !Stream methodsFor: 'writing'! nextPut: anObject self position: self position + 1. self collection at: self position put: anObject. self setStreamSize: (self streamSize max: self position) ! nextPutAll: aCollection aCollection do: [:each | self nextPut: each] ! ! !Stream class methodsFor: 'instance creation'! on: aCollection ^self new setCollection: aCollection; setStreamSize: aCollection size; yourself ! ! Stream subclass: #StringStream instanceVariableNames: '' category: 'Kernel'! !StringStream methodsFor: 'reading'! next: anInteger | tempCollection | tempCollection := self collection class new. anInteger timesRepeat: [ self atEnd ifFalse: [ tempCollection := tempCollection, self next]]. ^tempCollection ! ! !StringStream methodsFor: 'writing'! nextPut: aString self nextPutAll: aString ! nextPutAll: aString self setCollection: (self collection copyFrom: 1 to: self position), aString, (self collection copyFrom: (self position + 1 + aString size) to: self collection size). self position: self position + aString size. self setStreamSize: (self streamSize max: self position) ! cr ^self nextPutAll: String cr ! crlf ^self nextPutAll: String crlf ! lf ^self nextPutAll: String lf ! space self nextPut: ' ' ! ! Object subclass: #ClassCommentReader instanceVariableNames: 'class chunkParser' category: 'Kernel'! !ClassCommentReader methodsFor: 'accessing'! class: aClass class := aClass ! ! !ClassCommentReader methodsFor: 'fileIn'! scanFrom: aStream | nextChunk | nextChunk := (chunkParser emptyChunk / chunkParser chunk) parse: aStream. nextChunk isEmptyChunk ifFalse: [ self setComment: nextChunk contents]. ! ! !ClassCommentReader methodsFor: 'initialization'! initialize super initialize. chunkParser := ChunkParser new. ! ! !ClassCommentReader methodsFor: 'private'! setComment: aString class comment: aString ! ! Object subclass: #Random instanceVariableNames: '' category: 'Kernel'! !Random methodsFor: 'accessing'! next ! next: anInteger ^1 to: anInteger collect: [:each | self next] ! ! Object subclass: #Point instanceVariableNames: 'x y' category: 'Kernel'! !Point methodsFor: 'accessing'! x ^x ! y ^y ! y: aNumber y := aNumber ! x: aNumber x := aNumber ! ! !Point methodsFor: 'arithmetic'! * aPoint ^Point x: self x * aPoint asPoint x y: self y * aPoint asPoint y ! + aPoint ^Point x: self x + aPoint asPoint x y: self y + aPoint asPoint y ! - aPoint ^Point x: self x - aPoint asPoint x y: self y - aPoint asPoint y ! / aPoint ^Point x: self x / aPoint asPoint x y: self y / aPoint asPoint y ! ! !Point methodsFor: 'converting'! asPoint ^self ! ! !Point class methodsFor: 'instance creation'! x: aNumber y: anotherNumber ^self new x: aNumber; y: anotherNumber; yourself ! ! Object subclass: #Message instanceVariableNames: 'selector arguments' category: 'Kernel'! !Message methodsFor: 'accessing'! selector ^selector ! selector: aString selector := aString ! arguments: anArray arguments := anArray ! arguments ^arguments ! ! !Message class methodsFor: 'instance creation'! selector: aString arguments: anArray ^self new selector: aString; arguments: anArray; yourself ! ! Error subclass: #MessageNotUnderstood instanceVariableNames: 'message receiver' category: 'Kernel'! !MessageNotUnderstood methodsFor: 'accessing'! message ^message ! message: aMessage message := aMessage ! receiver ^receiver ! receiver: anObject receiver := anObject ! messageText ^self receiver asString, ' does not understand #', self message selector ! ! Object subclass: #ErrorHandler instanceVariableNames: '' category: 'Kernel'! !ErrorHandler methodsFor: 'error handling'! handleError: anError anError context ifNotNil: [self logErrorContext: anError context]. self logError: anError ! ! !ErrorHandler methodsFor: 'private'! logContext: aContext aContext home ifNotNil: [ self logContext: aContext home]. self log: aContext receiver asString, '>>', aContext selector ! logErrorContext: aContext aContext ifNotNil: [ aContext home ifNotNil: [ self logContext: aContext home]] ! logError: anError self log: anError messageText ! log: aString console log: aString ! ! ErrorHandler class instanceVariableNames: 'current'! !ErrorHandler class methodsFor: 'accessing'! current ^current ! setCurrent: anHandler current := anHandler ! ! !ErrorHandler class methodsFor: 'initialization'! initialize self register ! register ErrorHandler setCurrent: self new ! !