refactored primitive-decl parsing;
authorClaus Gittinger <cg@exept.de>
Tue, 06 May 2003 14:21:36 +0200
changeset 1405 f888caa1f2d8
parent 1404 f008ac0eca46
child 1406 cb80600efd76
refactored primitive-decl parsing; preps for arrayindexing expression
Parser.st
--- a/Parser.st	Tue May 06 14:15:02 2003 +0200
+++ b/Parser.st	Tue May 06 14:21:36 2003 +0200
@@ -37,7 +37,8 @@
 		ParseErrorSignal RestartCompilationSignal
 		AllowFunctionCallSyntaxForBlockEvaluation AllowLazyValueExtension
 		AllowVariableReferences AllowReservedWordsAsSelectors
-		AllowLocalVariableDeclarationWithInitializerExpression'
+		AllowLocalVariableDeclarationWithInitializerExpression
+		AllowArrayIndexSyntax'
 	poolDictionaries:''
 	category:'System-Compiler'
 !
@@ -3737,6 +3738,51 @@
     "Created: / 17.11.2001 / 10:23:47 / cg"
 !
 
+parseApiPragma
+    |cString|
+
+    cString := source upTo:$>.
+    self nextToken.
+    "/ TODO: generate that interface ...
+    ^ -1
+!
+
+parseCDeclPragma
+    |cString cStream cParser returnType functionName argTypes|
+
+    cString := source upTo:$>.
+    self nextToken.
+    cStream := cString readStream.
+
+    cParser := CParser new.
+    cParser source:cStream scannerClass:CDeclScanner.
+    cParser nextToken.
+    returnType := cParser type.
+
+    cParser tokenType ~~ #String ifTrue:[
+        self parseError:'invalid cdecl - functionName expected'.
+        ^ -1
+    ].
+    functionName := cParser token.
+    cParser nextToken.
+    argTypes := cParser parseFunctionArgumentSpec.
+self halt.
+    "/ TODO: generate that ffi-calling code ...
+    ^ -1
+!
+
+parseCPragma
+    |cString cParser cType|
+
+    cString := source upTo:$>.
+    self nextToken.
+    "/ TODO: generate that type
+    cParser := CParser parse:(cString , ';').
+    cType := cParser types first.
+    primitiveResource "primitiveType" := cType.
+    ^ -1
+!
+
 parseExceptionOrContextPragma
     |pragmaType|
 
@@ -4182,29 +4228,24 @@
                     self parseExceptionOrContextPragma.    
                 ] ifFalse:[
                     (tokenName = 'C:') ifTrue:[
-                        cString := source upTo:$>.
-                        self nextToken.
-                        "/ TODO: generate that type
-                        cParser := CParser parse:(cString , ';').
-                        cType := cParser types first.
-                        primitiveResource "primitiveType" := cType.
-                        ^ -1
+                        ^ self parseCPragma.    
                     ] ifFalse:[
                         (tokenName = 'api:') ifTrue:[
-                            cString := source upTo:$>.
-                            self nextToken.
-                            "/ TODO: generate that interface ...
-                            ^ -1
+                            ^ self parseApiPragma.    
                         ] ifFalse:[
-                            self parseError:'unrecognized pragma: ' , tokenName.
-
-                            "/ skip
-                            [tokenType ~~ #EOF] whileTrue:[
-                                ((tokenType == #BinaryOperator) and:[tokenName = '>']) ifTrue:[
+                            (tokenName = 'cdecl:') ifTrue:[
+                                ^ self parseCDeclPragma.
+                            ] ifFalse:[
+                                self parseError:'unrecognized pragma: ' , tokenName.
+
+                                "/ skip
+                                [tokenType ~~ #EOF] whileTrue:[
+                                    ((tokenType == #BinaryOperator) and:[tokenName = '>']) ifTrue:[
+                                        self nextToken.
+                                        ^ -1 "/ primNr.
+                                    ].
                                     self nextToken.
-                                    ^ -1 "/ primNr.
                                 ].
-                                self nextToken.
                             ].
                         ].
                     ].
@@ -4643,6 +4684,87 @@
     "Modified: / 14.4.1998 / 18:22:54 / cg"
 !
 
+arrayIndexingExpression
+    "parse an array index expression; this is a squeak/stx extension.
+     foo[idx] is syntactic sugar for foo matrixAt:x
+     and foo[idx] := expr is syntactic sugar for foo matrixAt:x put:expr"
+
+    |receiver argList  evalSelector selectorStream
+     valNode|
+
+    receiver := self functionCallExpression.
+    tokenType == $[ ifFalse:[^ receiver].
+    AllowArrayIndexSyntax == true ifFalse:[^ receiver.].
+    (receiver == #Error) ifTrue:[^ #Error].
+
+"/    receiver isVariable ifFalse:[
+"/        ((receiver isMessage or:[receiver isAssignment]) and:[receiver parenthized]) ifFalse:[
+"/            receiver isBlock ifFalse:[
+"/                ^ receiver
+"/            ]
+"/        ].
+"/    ].
+
+    selectorStream := WriteStream on: (String new: 32).
+    argList := OrderedCollection new.
+    [      
+        |indexNode|
+
+        self nextToken.
+        indexNode := self primary.
+        argList isEmpty
+            ifTrue:[selectorStream nextPutAll:'matrixAt:']
+            ifFalse:[selectorStream nextPutAll:'at:'].
+        argList add: indexNode.
+        tokenType == $, 
+    ] whileTrue.
+    tokenType == $] ifFalse:[ 
+        self parseError:''']'' expected'.
+        ^ #Error
+    ].
+    self nextToken.
+
+    tokenType == #':=' ifTrue:[
+        self nextToken.
+        selectorStream nextPutAll:'put:'.
+        valNode := self expression.
+        valNode == #Error ifTrue:[
+            ^ valNode
+        ].
+"/        (valNode isKindOf: BlockNode) ifFalse:[
+"/                valNode _ BlockNode new
+"/                                        arguments: #()
+"/                                        statements: (OrderedCollection with: valNode)
+"/                                        returns: false
+"/                                        from: encoder.
+"/        ].
+        argList add: valNode
+    ].
+    evalSelector := selectorStream contents.
+
+    ^ MessageNode 
+            receiver:receiver 
+            selector:evalSelector
+            args:argList.
+
+    "
+     AllowArrayIndexSyntax := true.
+    "
+
+    "
+     |foo|
+
+     foo := Array new:10.
+     1 + foo[1].     
+    "
+    "
+     |foo|
+
+     foo := Array new:10.
+     foo[1] := 'hello'.     
+    "
+!
+
 binaryExpression
     "parse a binary-expression; return a node-tree, nil or #Error"
 
@@ -4699,6 +4821,7 @@
         arg := self unaryExpression.
         (arg == #Error) ifTrue:[^ #Error].
         theReceiver := receiver.
+
         try := BinaryNode receiver:receiver selector:sel arg:arg fold:foldConstants.
         (try isMemberOf:String) ifTrue:[
             self parseError:try position:pos to:tokenPosition.
@@ -4790,7 +4913,7 @@
         ^ sel
     ].
 
-    (rec := self functionCallExpression) ~~ #Error ifTrue:[
+    (rec := self arrayIndexingExpression) ~~ #Error ifTrue:[
         sel := self degeneratedKeywordExpressionForSelector.
         sel isNil ifTrue:[
             rec isMessage ifTrue:[
@@ -6103,7 +6226,7 @@
 
     |receiver|
 
-    receiver := self functionCallExpression.
+    receiver := self arrayIndexingExpression.
     (receiver == #Error) ifTrue:[^ #Error].
     ^ self unaryExpressionFor:receiver
 !
@@ -7201,7 +7324,7 @@
 !Parser class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libcomp/Parser.st,v 1.381 2003-04-21 15:58:11 martin Exp $'
+    ^ '$Header: /cvs/stx/stx/libcomp/Parser.st,v 1.382 2003-05-06 12:21:36 cg Exp $'
 ! !
 
 Parser initialize!