|
1 "{ Package: 'stx:goodies/petitparser' }" |
|
2 |
|
3 Object subclass:#PPContextMemento |
|
4 instanceVariableNames:'stream position properties' |
|
5 classVariableNames:'' |
|
6 poolDictionaries:'' |
|
7 category:'PetitParser-Core' |
|
8 ! |
|
9 |
|
10 !PPContextMemento methodsFor:'accessing'! |
|
11 |
|
12 position |
|
13 ^ position |
|
14 ! |
|
15 |
|
16 position: anInteger |
|
17 position := anInteger |
|
18 ! |
|
19 |
|
20 stream |
|
21 ^ stream |
|
22 ! |
|
23 |
|
24 stream: aStream |
|
25 stream := aStream |
|
26 ! ! |
|
27 |
|
28 !PPContextMemento methodsFor:'accessing - properties'! |
|
29 |
|
30 hasProperty: aKey |
|
31 "Test if the property aKey is present." |
|
32 |
|
33 ^ properties notNil and: [ properties includesKey: aKey ] |
|
34 ! |
|
35 |
|
36 keysAndValuesDo: aBlock |
|
37 properties ifNil: [ ^ self ]. |
|
38 properties keysAndValuesDo: [ :key :value | aBlock value: key value: value copy ] |
|
39 ! |
|
40 |
|
41 propertiesSize |
|
42 properties ifNil: [ ^ 0 ]. |
|
43 ^ properties size. |
|
44 ! |
|
45 |
|
46 propertyAt: aKey |
|
47 "Answer the property value associated with aKey." |
|
48 |
|
49 ^ self propertyAt: aKey ifAbsent: [ self error: 'Property not found' ] |
|
50 ! |
|
51 |
|
52 propertyAt: aKey ifAbsent: aBlock |
|
53 "Answer the property value associated with aKey or, if aKey isn't found, answer the result of evaluating aBlock." |
|
54 |
|
55 properties isNil |
|
56 ifTrue: [ ^ aBlock value ] |
|
57 ifFalse: [ |
|
58 (properties includesKey: aKey) ifTrue: [ |
|
59 ^ (properties at: aKey) copy |
|
60 ]. |
|
61 ^ aBlock value |
|
62 ] |
|
63 |
|
64 "Created: / 03-10-2014 / 02:17:26 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
65 ! |
|
66 |
|
67 propertyAt: aKey ifAbsentPut: aBlock |
|
68 "Answer the property associated with aKey or, if aKey isn't found store the result of evaluating aBlock as new value." |
|
69 |
|
70 ^ self propertyAt: aKey ifAbsent: [ self propertyAt: aKey put: aBlock value ] |
|
71 ! |
|
72 |
|
73 propertyAt: aKey put: anObject |
|
74 "Set the property at aKey to be anObject. If aKey is not found, create a new entry for aKey and set is value to anObject. Answer anObject." |
|
75 |
|
76 ^ (properties ifNil: [ properties := Dictionary new: 1 ]) |
|
77 at: aKey put: (anObject copy) |
|
78 ! |
|
79 |
|
80 removeProperty: aKey |
|
81 "Remove the property with aKey. Answer the property or raise an error if aKey isn't found." |
|
82 |
|
83 ^ self removeProperty: aKey ifAbsent: [ self error: 'Property not found' ] |
|
84 ! |
|
85 |
|
86 removeProperty: aKey ifAbsent: aBlock |
|
87 "Remove the property with aKey. Answer the value or, if aKey isn't found, answer the result of evaluating aBlock." |
|
88 |
|
89 | answer | |
|
90 properties isNil ifTrue: [ ^ aBlock value ]. |
|
91 answer := properties removeKey: aKey ifAbsent: aBlock. |
|
92 properties isEmpty ifTrue: [ properties := nil ]. |
|
93 ^ answer |
|
94 ! ! |
|
95 |
|
96 !PPContextMemento methodsFor:'comparing'! |
|
97 |
|
98 = anObject |
|
99 |
|
100 (self == anObject) ifTrue: [ ^ true ]. |
|
101 (anObject class = PPContextMemento) ifFalse: [ ^ false ]. |
|
102 |
|
103 (anObject stream == stream) ifFalse: [ ^ false ]. |
|
104 (anObject position = position) ifFalse: [ ^ false ]. |
|
105 |
|
106 (self propertiesSize = anObject propertiesSize) ifFalse: [ ^ false ]. |
|
107 |
|
108 self keysAndValuesDo: [ :key :value | |
|
109 (anObject hasProperty: key) ifFalse: [ ^ false ]. |
|
110 ((anObject propertyAt: key) = value) ifFalse: [ ^ false ]. |
|
111 ]. |
|
112 |
|
113 ^ true. |
|
114 ! |
|
115 |
|
116 hash |
|
117 ^ (position hash bitXor: stream hash) bitXor: properties hash. |
|
118 ! ! |
|
119 |