--- a/SmallSense__SmalltalkParser.st Wed Sep 18 02:36:36 2013 +0100
+++ b/SmallSense__SmalltalkParser.st Fri Sep 20 01:55:35 2013 +0100
@@ -3,7 +3,7 @@
"{ NameSpace: SmallSense }"
SyntaxHighlighter subclass:#SmalltalkParser
- instanceVariableNames:'error'
+ instanceVariableNames:'errorRecovery error'
classVariableNames:''
poolDictionaries:''
category:'SmallSense-Smalltalk'
@@ -31,6 +31,15 @@
"Created: / 27-11-2011 / 09:45:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
+!SmalltalkParser methodsFor:'initialization'!
+
+initialize
+ super initialize.
+ errorRecovery := true
+
+ "Created: / 19-09-2013 / 11:25:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
!SmalltalkParser methodsFor:'parsing'!
blockStatementList
@@ -141,6 +150,83 @@
"Created: / 14-12-1999 / 15:11:37 / cg"
"Created: / 09-07-2011 / 22:23:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+statement
+ "parse a statement; return a node-tree or #Error.
+
+ statement ::= '^' expression
+ | PRIMITIVECODE
+ | expression
+ "
+
+ |expr node lnr code pos|
+
+ pos := tokenPosition.
+
+ (tokenType == $^) ifTrue:[
+ ^ self returnStatement
+ ].
+
+ (tokenType == #Primitive) ifTrue:[
+ code := tokenValue.
+ node := PrimitiveNode code:code.
+ node startPosition: tokenPosition endPosition: source position + 1.
+ self nextToken.
+ node isOptional ifFalse:[
+ hasNonOptionalPrimitiveCode := true
+ ].
+ hasPrimitiveCode := true.
+ ^ node
+ ].
+
+ (tokenType == #EOF) ifTrue:[
+ currentBlock notNil ifTrue:[
+ self syntaxError:'missing '']'' at end of block'.
+ errorRecovery ifTrue:[
+ tokenType := $].
+ ^ error.
+ ].
+ ] ifFalse:[
+ self syntaxError:'period after last statement'.
+ errorRecovery ifTrue:[
+ tokenType := $..
+ ^ error.
+ ].
+ ].
+ ^ #Error
+ ].
+
+ (tokenType == $.) ifTrue:[
+ (parserFlags allowEmptyStatements
+ or:[parserFlags allowSqueakExtensions == true]) ifTrue:[
+ "/ allow empty statement
+ self warnAboutEmptyStatement.
+ node := StatementNode expression:nil.
+ node startPosition:pos.
+ ^ node
+ ].
+ ].
+
+ lnr := tokenLineNr.
+
+ expr := self expression.
+ (expr == #Error) ifTrue:[^ #Error].
+
+"/ classToCompileFor notNil ifTrue:[
+"/ currentBlock isNil ifTrue:[
+"/ expr isPrimary ifTrue:[
+"/ self warning:'useless computation - missing ^ ?'
+"/ ]
+"/ ]
+"/ ].
+
+ node := StatementNode expression:expr.
+ parserFlags fullLineNumberInfo ifTrue:[node lineNumber:lnr].
+ node startPosition:pos.
+ ^ node
+
+ "Created: / 19-09-2013 / 11:32:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!SmalltalkParser methodsFor:'parsing-expressions'!
@@ -168,7 +254,7 @@
"/ would be parsed as unary message foo; detect this here, instead of high up in the calling hierarchy,
"/ where it is difficult to provide a reasonable error message
tokenType == #':=' ifTrue:[
- | positionOfPeriod exprLast |
+ | positionOfPeriod exprLast exprLastParent |
"/ Find the very last unary send node, Consider:
"/ x := 2
@@ -180,8 +266,10 @@
"/ x := 2 between: 0 and: self max
"/ y := false
+ exprLastParent := nil.
exprLast := expr.
[ exprLast isMessage and: [ exprLast isUnaryMessage not ] ] whileTrue:[
+ exprLastParent := exprLast.
exprLast := exprLast args last.
].
(exprLast isMessage and: [ exprLast isUnaryMessage ] ) ifTrue:[
@@ -189,6 +277,13 @@
].
positionOfPeriod notNil ifTrue:[
"/Try to recover
+ "/ Strip the last unary message whose selector is actually a variable name..."
+ exprLastParent notNil ifTrue:[
+ exprLastParent args at: exprLastParent args size put: exprLast receiver.
+ ] ifFalse:[
+ "/ no nesting, the expr itself is errorneouts...
+ expr := expr receiver.
+ ].
expr := ParseErrorNode new
startPosition:expr startPosition endPosition: positionOfPeriod - 1;
errorString: ('":=" unexpected. Probably missing "." in previous expression.');
@@ -203,7 +298,7 @@
^ expr
"Created: / 16-09-2013 / 17:23:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 16-09-2013 / 23:18:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 19-09-2013 / 11:47:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
primary