9 category:'PetitCompiler-Visitors' |
9 category:'PetitCompiler-Visitors' |
10 ! |
10 ! |
11 |
11 |
12 !PPCTokenizingCodeGenerator methodsFor:'visiting'! |
12 !PPCTokenizingCodeGenerator methodsFor:'visiting'! |
13 |
13 |
14 visitLLChoiceNode: node |
14 visitChoiceNode: node |
15 | dictionary currentTokenVar | |
15 " true ifTrue: [ ^ super visitChoiceNode: node ]." |
16 dictionary := IdentityDictionary new. |
16 "HACK alert: We are inside token..." |
17 |
17 node firstSetWithTokens detect: [ :e | e isTokenNode not ] ifFound: [ ^ super visitChoiceNode: node ]. |
18 node children do: [ :child | |
18 |
19 | firstSet | |
19 node children do: [ :child | |
20 firstSet := child firstSetSuchThat: [ :e | e isKindOf: PPCTokenNode ]. |
20 | tokenMethodName | |
21 self assert: firstSet size = 1. |
21 |
22 dictionary at: child |
22 child firstSetWithTokens do: [ :first | |
23 put: firstSet anyOne. |
23 "For each child, for each first compile this:" |
24 |
24 tokenMethodName := compiler idFor: first. |
25 ]. |
25 compiler add: '(self currentTokenTypeIs: ', tokenMethodName storeString, ')'. |
26 "Tokens are unique" |
26 compiler addOnLine: ' ifTrue: ['. |
27 self assert: dictionary values asSet size = node children size. |
27 compiler indent. |
28 |
28 compiler codeStoreValueOf: [ self visit: child ] intoVariable: self retvalVar. |
29 compiler addConstant: (dictionary values collect: [ :e | compiler idFor: e ]) |
29 compiler add: 'error ifFalse: ['. |
30 as: #tokenMethods. |
30 compiler indent. |
31 |
31 compiler codeReturn: self retvalVar. |
32 currentTokenVar := compiler allocateTemporaryVariableNamed: 'currentToken'. |
32 compiler dedent. |
33 compiler codeAssign: 'self currentTokenType.' to: currentTokenVar. |
33 compiler add: '] ifTrue: ['. |
34 node children do: [ :child | |
34 compiler indent. |
35 | tokenMethodName | |
35 compiler codeClearError. |
36 tokenMethodName := compiler idFor: (dictionary at: child). |
36 compiler codeAssign: 'nil.' to: 'currentTokenType'. |
37 compiler add: currentTokenVar , ' = ', tokenMethodName storeString. |
37 compiler add: 'context position: currentTokenValue start - 1.'. |
38 compiler add: 'ifTrue: ['. |
38 compiler dedent. |
39 compiler codeStoreValueOf: [ self visit: child ] intoVariable: self retvalVar. |
39 compiler add: ']'. |
40 compiler codeReturn: self retvalVar. |
40 compiler dedent. |
41 compiler add: '].' |
41 compiler add: '].' |
42 ]. |
42 ] |
|
43 ]. |
43 |
44 |
44 compiler codeError: 'no choice found'. |
45 compiler codeError: 'no choice found'. |
|
46 ! |
|
47 |
|
48 visitDeterministicChoiceNode: node |
|
49 | dictionary | |
|
50 dictionary := IdentityDictionary new. |
|
51 |
|
52 node children do: [ :child | |
|
53 | firstSet | |
|
54 firstSet := child firstSetWithTokens. |
|
55 self assert: firstSet size = 1. |
|
56 dictionary at: child |
|
57 put: firstSet anyOne. |
|
58 |
|
59 ]. |
|
60 "Tokens are unique" |
|
61 self assert: dictionary values asSet size = node children size. |
|
62 |
|
63 " currentTokenVar := compiler allocateTemporaryVariableNamed: 'currentToken'. |
|
64 compiler codeAssign: 'self currentTokenType.' to: currentTokenVar. |
|
65 " node children do: [ :child | |
|
66 | tokenMethodName | |
|
67 tokenMethodName := compiler idFor: (dictionary at: child). |
|
68 compiler add: '(self currentTokenTypeIs: ', tokenMethodName storeString, ')'. |
|
69 compiler addOnLine: ' ifTrue: ['. |
|
70 compiler indent. |
|
71 compiler codeStoreValueOf: [ self visit: child ] intoVariable: self retvalVar. |
|
72 compiler codeReturn: self retvalVar. |
|
73 compiler dedent. |
|
74 compiler add: '].' |
|
75 ]. |
|
76 |
|
77 compiler codeError: 'no choice found'. |
|
78 ! |
|
79 |
|
80 visitTokenChoiceNode: node |
|
81 | trimmingToken | |
|
82 self assert: (node children allSatisfy: [ :e | e isMarkedForInline not ]). |
|
83 |
|
84 |
|
85 trimmingToken := node children detect: [ :e | e isTrimmingTokenNode ] ifNone: [ nil ]. |
|
86 trimmingToken isNil ifFalse: [ |
|
87 compiler codeStoreValueOf: [ self visit: trimmingToken whitespace ] intoVariable: #whatever. |
|
88 ]. |
|
89 super visitChoiceNode: node. |
45 ! |
90 ! |
46 |
91 |
47 visitTokenConsumeNode: node |
92 visitTokenConsumeNode: node |
48 compiler codeReturn: 'self consume: ', (compiler idFor: node child) storeString, '.' |
93 compiler codeReturn: 'self consume: ', (compiler idFor: node child) storeString, '.' |
49 ! |
94 ! |
50 |
95 |
51 visitTokenNode: node |
96 visitTokenNode: node |
52 | tokenType | |
97 | id startVar endVar | |
53 self assert: node isMarkedForInline. |
98 startVar := compiler allocateTemporaryVariableNamed: 'start'. |
|
99 endVar := compiler allocateTemporaryVariableNamed: 'end'. |
54 |
100 |
55 super visitTokenNode: node. |
101 id := compiler idFor: node. |
56 |
102 compiler toTokenRememberStrategy. |
57 tokenType := compiler idFor: node. |
103 |
|
104 compiler codeAssign: 'context position + 1.' to: startVar. |
|
105 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever. |
|
106 compiler add: 'error ifFalse: [ '. |
|
107 compiler indent. |
|
108 compiler codeAssign: 'context position.' to: endVar. |
|
109 |
|
110 compiler codeTranscriptShow: 'current token type: ', id storeString. |
|
111 compiler codeAssign: id storeString, '.' to: 'currentTokenType'. |
|
112 compiler codeAssign: node tokenClass asString, ' on: (context collection) |
|
113 start: ', startVar, ' |
|
114 stop: ', endVar, ' |
|
115 value: nil.' |
|
116 to: 'currentTokenValue := ', self retvalVar. |
|
117 compiler codeReturn. |
|
118 compiler dedent. |
|
119 compiler add: '].'. |
|
120 compiler toNormalRememberStrategy. |
|
121 ! |
58 |
122 |
59 compiler codeAssign: tokenType storeString, '.' to: 'currentTokenType'. |
123 visitTokenizingParserNode: node |
60 compiler codeAssign: self retvalVar, '.' to: 'currentTokenValue'. |
124 self visit: node tokenizer. |
|
125 |
|
126 " compiler codeNextToken." |
|
127 compiler codeHaltIfShiftPressed. |
|
128 compiler codeStoreValueOf: [ self visit: node parser ] intoVariable: self retvalVar. |
|
129 compiler codeReturn. |
|
130 ! |
|
131 |
|
132 visitTrimmingTokenNode: node |
|
133 | id startVar endVar | |
|
134 |
|
135 startVar := compiler allocateTemporaryVariableNamed: 'start'. |
|
136 endVar := compiler allocateTemporaryVariableNamed: 'end'. |
|
137 |
|
138 id := compiler idFor: node. |
|
139 compiler toTokenRememberStrategy. |
|
140 |
|
141 |
|
142 compiler addComment: 'Consume Whitespace:'. |
|
143 compiler codeStoreValueOf: [ self visit: node whitespace ] intoVariable: #whatever. |
|
144 compiler nl. |
|
145 |
|
146 compiler codeAssign: 'context position + 1.' to: startVar. |
|
147 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever. |
|
148 |
|
149 compiler add: 'error ifFalse: [ '. |
|
150 compiler indent. |
|
151 compiler codeAssign: 'context position.' to: endVar. |
|
152 |
|
153 compiler addComment: 'Consume Whitespace:'. |
|
154 compiler codeStoreValueOf: [ self visit: node whitespace ] intoVariable: #whatever. |
|
155 compiler nl. |
|
156 |
|
157 |
|
158 compiler codeTranscriptShow: 'current token type: ', id storeString. |
|
159 compiler codeAssign: id storeString, '.' to: 'currentTokenType'. |
|
160 compiler codeAssign: node tokenClass asString, ' on: (context collection) |
|
161 start: ', startVar, ' |
|
162 stop: ', endVar, ' |
|
163 value: nil.' |
|
164 to: 'currentTokenValue := ', self retvalVar. |
|
165 compiler codeReturn. |
|
166 compiler dedent. |
|
167 compiler add: '].' . |
|
168 compiler toNormalRememberStrategy. |
61 ! ! |
169 ! ! |
62 |
170 |