--- a/compiler/PPCTokenizingCodeGenerator.st Tue May 12 01:24:03 2015 +0100
+++ b/compiler/PPCTokenizingCodeGenerator.st Thu May 21 14:12:22 2015 +0100
@@ -26,43 +26,102 @@
tokenGenerator: whatever
tokenGenerator := whatever
+!
+
+tokenGuards
+ "When tokenizing, do not use guards"
+ ^ arguments guards
+! !
+
+!PPCTokenizingCodeGenerator methodsFor:'guards'!
+
+addGuard: node ifTrue: trueBlock ifFalse: falseBlock
+ | guard id |
+ guard := PPCTokenGuard on: node.
+ (self guards not or: guard makesSense not) ifTrue: [ ^ false ].
+
+ id := compiler idFor: guard firstToken.
+
+ compiler add: 'self ', id asString.
+
+ trueBlock isNil ifFalse: [
+ compiler addOnLine: ' ifTrue: ['.
+ compiler indent.
+ trueBlock value.
+ compiler dedent.
+ falseBlock isNil ifTrue: [ compiler addOnLine: '].' ]
+ ifFalse: [ compiler add: ']'. ]
+ ].
+ falseBlock isNil ifFalse: [
+ compiler addOnLine: ' ifFalse: ['.
+ compiler indent.
+ falseBlock value.
+ compiler dedent.
+ compiler addOnLine: '].'.
+ ].
+ ^ true
! !
!PPCTokenizingCodeGenerator methodsFor:'visiting'!
+visitAndNode: node
+ | mementoVar currentTokenVar |
+
+ mementoVar := compiler allocateTemporaryVariableNamed: 'memento'.
+ currentTokenVar := compiler allocateTemporaryVariableNamed: 'currentToken'.
+
+ compiler smartRemember: node child to: mementoVar.
+ compiler codeAssign: '{ currentTokenValue . currentTokenType }.' to: currentTokenVar.
+
+ compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar.
+
+ compiler smartRestore: node child from: mementoVar.
+ compiler codeAssign: '(', currentTokenVar, ' at: 1).' to: 'currentTokenValue'.
+ compiler codeAssign: '(', currentTokenVar, ' at: 2).' to: 'currentTokenType'.
+
+ compiler codeReturn.
+!
+
visitChoiceNode: node
" true ifTrue: [ ^ super visitChoiceNode: node ]."
- "HACK alert: We are inside token..."
+ | possibleError |
+ possibleError := true.
- (node firstSetWithTokens contains: [ :e | e isTokenNode not ]) ifTrue: [ ^ super visitChoiceNode: node ].
-
node children do: [ :child |
| tokenMethodName |
- child firstSetWithTokens do: [ :first |
- "For each child, for each first compile this:"
- tokenMethodName := compiler idFor: first.
- compiler add: '(self currentTokenTypeIs: ', tokenMethodName storeString, ')'.
- compiler addOnLine: ' ifTrue: ['.
- compiler indent.
+ child acceptsEpsilon ifTrue: [
+ possibleError := false.
compiler codeStoreValueOf: [ self visit: child ] intoVariable: self retvalVar.
- compiler add: 'error ifFalse: ['.
- compiler indent.
- compiler codeReturn: self retvalVar.
- compiler dedent.
- compiler add: '] ifTrue: ['.
- compiler indent.
- compiler codeClearError.
- compiler codeAssign: 'nil.' to: 'currentTokenType'.
- compiler add: 'context position: currentTokenValue start - 1.'.
- compiler dedent.
- compiler add: ']'.
- compiler dedent.
- compiler add: '].'
+ compiler codeReturn
+ ] ifFalse: [
+ child firstSetWithTokens do: [ :first |
+ "For each child, for each first compile this:"
+
+ tokenMethodName := compiler idFor: first.
+ compiler add: '(self ', tokenMethodName asString, ')'.
+ compiler addOnLine: ' ifTrue: ['.
+ compiler indent.
+ compiler codeStoreValueOf: [ self visit: child ] intoVariable: self retvalVar.
+ compiler add: 'error ifFalse: ['.
+ compiler indent.
+ compiler codeReturn: self retvalVar.
+ compiler dedent.
+ compiler add: '] ifTrue: ['.
+ compiler indent.
+ compiler codeClearError.
+ compiler codeAssign: 'nil.' to: 'currentTokenType'.
+ compiler add: 'context position: currentTokenValue start - 1.'.
+ compiler dedent.
+ compiler add: ']'.
+ compiler dedent.
+ compiler add: '].'
+ ]
]
].
-
- compiler codeError: 'no choice found'.
+ possibleError ifTrue: [
+ compiler codeError: 'no choice found'.
+ ]
"Modified: / 10-05-2015 / 07:37:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
@@ -75,23 +134,19 @@
| firstSet |
firstSet := child firstSetWithTokens.
self assert: firstSet size = 1.
- dictionary at: child
- put: firstSet anyOne.
-
+ dictionary at: child put: firstSet anyOne.
].
"Tokens are unique"
self assert: dictionary values asSet size = node children size.
-" currentTokenVar := compiler allocateTemporaryVariableNamed: 'currentToken'.
- compiler codeAssign: 'self currentTokenType.' to: currentTokenVar.
-" node children do: [ :child |
+ node children do: [ :child |
| tokenMethodName |
tokenMethodName := compiler idFor: (dictionary at: child).
- compiler add: '(self currentTokenTypeIs: ', tokenMethodName storeString, ')'.
+ compiler add: '(self ', tokenMethodName asString, ')'.
compiler addOnLine: ' ifTrue: ['.
compiler indent.
- compiler codeStoreValueOf: [ self visit: child ] intoVariable: self retvalVar.
- compiler codeReturn: self retvalVar.
+ compiler codeStoreValueOf: [ self visit: child ] intoVariable: self retvalVar.
+ compiler codeReturn: self retvalVar.
compiler dedent.
compiler add: '].'
].
@@ -116,7 +171,22 @@
!
visitTokenConsumeNode: node
+ | id |
+ id := (compiler idFor: node child).
+ compiler add: 'self ', id asString, ' ifTrue: ['.
+ compiler indent.
+ compiler codeAssign: 'nil.' to: 'currentTokenType'.
+ compiler codeReturn: 'currentTokenValue'.
+ compiler dedent.
+ compiler add: '] ifFalse: ['.
+ compiler indent.
+ compiler codeError: id asString, ' expected'.
+ compiler dedent.
+ compiler add: '].'.
+
+"
compiler codeReturn: 'self consume: ', (compiler idFor: node child) storeString, '.'
+"
!
visitTokenNode: node
@@ -127,7 +197,6 @@
self visit: node tokenizer.
self visit: node whitespace.
-" compiler codeNextToken."
compiler codeHaltIfShiftPressed.
compiler codeStoreValueOf: [ self visit: node parser ] intoVariable: self retvalVar.
compiler codeReturn.