Parser.st
author claus
Wed, 13 Oct 1993 01:26:26 +0100
changeset 3 b63b8a6b71fb
parent 0 7ad01559b262
child 4 f6fd83437415
permissions -rw-r--r--
*** empty log message ***
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
     1
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
     2
 COPYRIGHT (c) 1989-93 by Claus Gittinger
7ad01559b262 Initial revision
claus
parents:
diff changeset
     3
              All Rights Reserved
7ad01559b262 Initial revision
claus
parents:
diff changeset
     4
7ad01559b262 Initial revision
claus
parents:
diff changeset
     5
 This software is furnished under a license and may be used
7ad01559b262 Initial revision
claus
parents:
diff changeset
     6
 only in accordance with the terms of that license and with the
7ad01559b262 Initial revision
claus
parents:
diff changeset
     7
 inclusion of the above copyright notice.   This software may not
7ad01559b262 Initial revision
claus
parents:
diff changeset
     8
 be provided or otherwise made available to, or used by, any
7ad01559b262 Initial revision
claus
parents:
diff changeset
     9
 other person.  No title to or ownership of the software is
7ad01559b262 Initial revision
claus
parents:
diff changeset
    10
 hereby transferred.
7ad01559b262 Initial revision
claus
parents:
diff changeset
    11
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
    12
7ad01559b262 Initial revision
claus
parents:
diff changeset
    13
Scanner subclass:#Parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
    14
       instanceVariableNames:'classToCompileFor selfValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
    15
                              contextToEvaluateIn
7ad01559b262 Initial revision
claus
parents:
diff changeset
    16
                              selector
7ad01559b262 Initial revision
claus
parents:
diff changeset
    17
                              methodArgs methodArgNames 
7ad01559b262 Initial revision
claus
parents:
diff changeset
    18
                              methodVars methodVarNames 
7ad01559b262 Initial revision
claus
parents:
diff changeset
    19
                              tree
7ad01559b262 Initial revision
claus
parents:
diff changeset
    20
                              currentBlock
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
    21
                              usedInstVars usedClassVars usedVars
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
    22
                              modifiedInstVars modifiedClassVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
    23
                              localVarDefPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
    24
                              evalExitBlock
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
    25
                              selfNode superNode primNr logged
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
    26
			      warnedUndefVars'
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
    27
       classVariableNames:'prevClass prevInstVarNames 
7ad01559b262 Initial revision
claus
parents:
diff changeset
    28
                           prevClassVarNames prevClassInstVarNames'
7ad01559b262 Initial revision
claus
parents:
diff changeset
    29
       poolDictionaries:''
7ad01559b262 Initial revision
claus
parents:
diff changeset
    30
       category:'System-Compiler'
7ad01559b262 Initial revision
claus
parents:
diff changeset
    31
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
    32
7ad01559b262 Initial revision
claus
parents:
diff changeset
    33
Parser comment:'
7ad01559b262 Initial revision
claus
parents:
diff changeset
    34
7ad01559b262 Initial revision
claus
parents:
diff changeset
    35
COPYRIGHT (c) 1989-93 by Claus Gittinger
7ad01559b262 Initial revision
claus
parents:
diff changeset
    36
             All Rights Reserved
7ad01559b262 Initial revision
claus
parents:
diff changeset
    37
7ad01559b262 Initial revision
claus
parents:
diff changeset
    38
Parser is used for both evaluating and compiling smalltalk expressions;
7ad01559b262 Initial revision
claus
parents:
diff changeset
    39
it first builds a parseTree which is then interpreted (evaluate) or
7ad01559b262 Initial revision
claus
parents:
diff changeset
    40
compiled. Compilation is done in the subclass BCompiler.
7ad01559b262 Initial revision
claus
parents:
diff changeset
    41
7ad01559b262 Initial revision
claus
parents:
diff changeset
    42
Parser is also used to find the referenced/modified inst/classvars of
7ad01559b262 Initial revision
claus
parents:
diff changeset
    43
a method - this is done by sending parseXXX message to a parser and asking
7ad01559b262 Initial revision
claus
parents:
diff changeset
    44
the parser for referencedXVars or modifiedXVars (see SystemBrowser).
7ad01559b262 Initial revision
claus
parents:
diff changeset
    45
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
    46
$Header: /cvs/stx/stx/libcomp/Parser.st,v 1.2 1993-10-13 00:26:01 claus Exp $
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
    47
'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
    48
7ad01559b262 Initial revision
claus
parents:
diff changeset
    49
!Parser class methodsFor:'evaluating expressions'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
    50
7ad01559b262 Initial revision
claus
parents:
diff changeset
    51
evaluate:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
    52
    "return the result of evaluating aString"
7ad01559b262 Initial revision
claus
parents:
diff changeset
    53
7ad01559b262 Initial revision
claus
parents:
diff changeset
    54
    ^ self evaluate:aString notifying:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
    55
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
    56
7ad01559b262 Initial revision
claus
parents:
diff changeset
    57
evaluate:aStringOrStream notifying:requestor
7ad01559b262 Initial revision
claus
parents:
diff changeset
    58
    "return the result of evaluating aString, 
7ad01559b262 Initial revision
claus
parents:
diff changeset
    59
     errors are reported to requestor"
7ad01559b262 Initial revision
claus
parents:
diff changeset
    60
7ad01559b262 Initial revision
claus
parents:
diff changeset
    61
    |parser tree mustBackup|
7ad01559b262 Initial revision
claus
parents:
diff changeset
    62
7ad01559b262 Initial revision
claus
parents:
diff changeset
    63
    aStringOrStream isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
    64
    aStringOrStream isStream ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
    65
        parser := self for:aStringOrStream.
7ad01559b262 Initial revision
claus
parents:
diff changeset
    66
        mustBackup := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
    67
    ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
    68
        parser := self for:(ReadStream on:aStringOrStream).
7ad01559b262 Initial revision
claus
parents:
diff changeset
    69
        mustBackup := false
7ad01559b262 Initial revision
claus
parents:
diff changeset
    70
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
    71
    parser notifying:requestor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
    72
    parser nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
    73
    tree := parser parseMethodBodyOrNil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
    74
7ad01559b262 Initial revision
claus
parents:
diff changeset
    75
    "if reading from a stream, backup for next expression"
7ad01559b262 Initial revision
claus
parents:
diff changeset
    76
    mustBackup ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
    77
        parser backupPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
    78
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
    79
7ad01559b262 Initial revision
claus
parents:
diff changeset
    80
    (parser errorFlag or:[tree == #Error]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
    81
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
    82
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
    83
    tree notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
    84
        parser evalExitBlock:[:value | ^ value].
7ad01559b262 Initial revision
claus
parents:
diff changeset
    85
        ^ tree evaluate
7ad01559b262 Initial revision
claus
parents:
diff changeset
    86
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
    87
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
    88
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
    89
7ad01559b262 Initial revision
claus
parents:
diff changeset
    90
evaluate:aString receiver:anObject notifying:requestor
7ad01559b262 Initial revision
claus
parents:
diff changeset
    91
    "return the result of evaluating aString, 
7ad01559b262 Initial revision
claus
parents:
diff changeset
    92
     errors are reported to requestor. Allow access to
7ad01559b262 Initial revision
claus
parents:
diff changeset
    93
     anObject as self and to its instVars (used in the inspector)"
7ad01559b262 Initial revision
claus
parents:
diff changeset
    94
7ad01559b262 Initial revision
claus
parents:
diff changeset
    95
    ^ self evaluate:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
    96
                 in:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
    97
           receiver:anObject
7ad01559b262 Initial revision
claus
parents:
diff changeset
    98
          notifying:requestor
7ad01559b262 Initial revision
claus
parents:
diff changeset
    99
             ifFail:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   100
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   101
7ad01559b262 Initial revision
claus
parents:
diff changeset
   102
evaluate:aStringOrStream in:aContext receiver:anObject 
7ad01559b262 Initial revision
claus
parents:
diff changeset
   103
                                    notifying:requestor
7ad01559b262 Initial revision
claus
parents:
diff changeset
   104
                                       ifFail:failBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
   105
    |parser tree mustBackup|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   106
7ad01559b262 Initial revision
claus
parents:
diff changeset
   107
    aStringOrStream isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   108
    aStringOrStream isStream ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   109
        parser := self for:aStringOrStream.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   110
        mustBackup := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   111
    ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   112
        parser := self for:(ReadStream on:aStringOrStream).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   113
        mustBackup := false
7ad01559b262 Initial revision
claus
parents:
diff changeset
   114
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   115
    parser setSelf:anObject.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   116
    parser setContext:aContext.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   117
    parser notifying:requestor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   118
    parser nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   119
    tree := parser parseMethodBodyOrNil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   120
7ad01559b262 Initial revision
claus
parents:
diff changeset
   121
    "if reading from a stream, backup for next expression"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   122
    mustBackup ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   123
        parser backupPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
   124
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   125
7ad01559b262 Initial revision
claus
parents:
diff changeset
   126
    (parser errorFlag or:[tree == #Error]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   127
        failBlock notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   128
            ^ failBlock value
7ad01559b262 Initial revision
claus
parents:
diff changeset
   129
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   130
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   131
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   132
    tree notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   133
        parser evalExitBlock:[:value | ^ value].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   134
        ^ tree evaluate
7ad01559b262 Initial revision
claus
parents:
diff changeset
   135
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   136
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   137
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   138
7ad01559b262 Initial revision
claus
parents:
diff changeset
   139
!Parser class methodsFor:'instance creation'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   140
7ad01559b262 Initial revision
claus
parents:
diff changeset
   141
for:aStream in:aClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   142
    |parser|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   143
7ad01559b262 Initial revision
claus
parents:
diff changeset
   144
    parser := self for:aStream.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   145
    parser setClassToCompileFor:aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   146
    ^ parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
   147
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   148
7ad01559b262 Initial revision
claus
parents:
diff changeset
   149
!Parser class methodsFor:'parsing'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   150
7ad01559b262 Initial revision
claus
parents:
diff changeset
   151
parseExpression:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
   152
    "parse aString as an expression; return the parseTree"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   153
7ad01559b262 Initial revision
claus
parents:
diff changeset
   154
    ^ self withSelf:nil parseExpression:aString notifying:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   155
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   156
7ad01559b262 Initial revision
claus
parents:
diff changeset
   157
withSelf:anObject parseExpression:aString notifying:someOne
7ad01559b262 Initial revision
claus
parents:
diff changeset
   158
    "parse aString as an expression with self set to anObject;
7ad01559b262 Initial revision
claus
parents:
diff changeset
   159
     return the parseTree"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   160
7ad01559b262 Initial revision
claus
parents:
diff changeset
   161
    |parser tree|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   162
7ad01559b262 Initial revision
claus
parents:
diff changeset
   163
    aString isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   164
    parser := self for:(ReadStream on:aString).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   165
    parser setSelf:anObject.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   166
    parser notifying:someOne.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   167
    parser nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   168
    tree := parser expression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   169
    (parser errorFlag or:[tree == #Error]) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   170
    ^ tree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   171
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   172
7ad01559b262 Initial revision
claus
parents:
diff changeset
   173
parseMethodSpecification:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
   174
    "parse a methods selector & arg specification; 
7ad01559b262 Initial revision
claus
parents:
diff changeset
   175
     return the parser or nil on error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   176
7ad01559b262 Initial revision
claus
parents:
diff changeset
   177
    ^ self parseMethodSpecification:aString in:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   178
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   179
7ad01559b262 Initial revision
claus
parents:
diff changeset
   180
parseMethodSpecification:aString in:aClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   181
    "parse a methods selector & arg spec for a given class;
7ad01559b262 Initial revision
claus
parents:
diff changeset
   182
     return the parser or nil on error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   183
7ad01559b262 Initial revision
claus
parents:
diff changeset
   184
    |parser tree|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   185
7ad01559b262 Initial revision
claus
parents:
diff changeset
   186
    aString isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   187
    parser := self for:(ReadStream on:aString) in:aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   188
    parser nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   189
    tree := parser parseMethodSpec.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   190
    (parser errorFlag or:[tree == #Error]) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   191
    ^ parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
   192
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   193
7ad01559b262 Initial revision
claus
parents:
diff changeset
   194
parseMethodArgAndVarSpecification:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
   195
    "parse a methods selector, arg and var spec;
7ad01559b262 Initial revision
claus
parents:
diff changeset
   196
     return the parser or nil on error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   197
7ad01559b262 Initial revision
claus
parents:
diff changeset
   198
    ^ self parseMethodArgAndVarSpecification:aString in:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   199
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   200
7ad01559b262 Initial revision
claus
parents:
diff changeset
   201
parseMethodArgAndVarSpecification:aString in:aClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   202
    "parse a methods selector, arg and var spec for a given class;
7ad01559b262 Initial revision
claus
parents:
diff changeset
   203
     return the parser or nil on error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   204
7ad01559b262 Initial revision
claus
parents:
diff changeset
   205
    |parser|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   206
7ad01559b262 Initial revision
claus
parents:
diff changeset
   207
    aString isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   208
    parser := self for:(ReadStream on:aString) in:aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   209
    parser nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   210
    (parser parseMethodSpec == #Error) ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   211
    (parser parseMethodBodyVarSpec == #Error) ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   212
    parser errorFlag ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   213
    ^ parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
   214
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   215
7ad01559b262 Initial revision
claus
parents:
diff changeset
   216
parseMethod:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
   217
    "parse a method; return parseTree"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   218
7ad01559b262 Initial revision
claus
parents:
diff changeset
   219
    ^ self parseMethod:aString in:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   220
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   221
7ad01559b262 Initial revision
claus
parents:
diff changeset
   222
parseMethod:aString in:aClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   223
    "parse a method for a given class; return parser or nil on error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   224
7ad01559b262 Initial revision
claus
parents:
diff changeset
   225
    |parser tree|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   226
7ad01559b262 Initial revision
claus
parents:
diff changeset
   227
    aString isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   228
    parser := self for:(ReadStream on:aString) in:aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   229
    tree := parser parseMethod.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   230
    (parser errorFlag or:[tree == #Error]) ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   231
    ^ parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
   232
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   233
7ad01559b262 Initial revision
claus
parents:
diff changeset
   234
!Parser methodsFor:'ST-80 compatibility'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   235
7ad01559b262 Initial revision
claus
parents:
diff changeset
   236
evaluate:aString in:aClass to:to notifying:aRequestor ifFail:failBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
   237
    |parseTree|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   238
7ad01559b262 Initial revision
claus
parents:
diff changeset
   239
    aString isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   240
    self initializeFor:(ReadStream on:aString).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   241
    self setClassToCompileFor:aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   242
    selfValue := nil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   243
    requestor := aRequestor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   244
7ad01559b262 Initial revision
claus
parents:
diff changeset
   245
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   246
    parseTree := self parseMethodBody.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   247
    (errorFlag or:[tree == #Error]) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   248
    parseTree notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   249
        self evalExitBlock:[:value | ^ failBlock value].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   250
        ^ parseTree evaluate
7ad01559b262 Initial revision
claus
parents:
diff changeset
   251
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   252
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   253
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   254
7ad01559b262 Initial revision
claus
parents:
diff changeset
   255
!Parser class methodsFor:'changes'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   256
7ad01559b262 Initial revision
claus
parents:
diff changeset
   257
update:aClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   258
    "aClass has changed its definition - flush name caches if we have to"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   259
7ad01559b262 Initial revision
claus
parents:
diff changeset
   260
    (aClass == prevClass) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   261
        prevClass := nil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   262
        prevInstVarNames := nil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   263
        prevClassVarNames := nil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   264
        prevClassInstVarNames := nil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   265
        aClass removeDependent:Parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
   266
    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   267
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   268
7ad01559b262 Initial revision
claus
parents:
diff changeset
   269
!Parser methodsFor:'setup'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   270
7ad01559b262 Initial revision
claus
parents:
diff changeset
   271
setClassToCompileFor:aClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   272
    "set the class to be used for parsing/evaluating"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   273
7ad01559b262 Initial revision
claus
parents:
diff changeset
   274
    classToCompileFor := aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   275
    (classToCompileFor ~~ prevClass) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   276
        prevClass notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   277
            Parser update:prevClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   278
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   279
    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   280
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   281
7ad01559b262 Initial revision
claus
parents:
diff changeset
   282
setSelf:anObject
7ad01559b262 Initial revision
claus
parents:
diff changeset
   283
    "set the value to be used for self while evaluating"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   284
7ad01559b262 Initial revision
claus
parents:
diff changeset
   285
    selfValue := anObject.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   286
    classToCompileFor := anObject class.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   287
    (classToCompileFor ~~ prevClass) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   288
        prevClass notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   289
            Parser update:prevClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   290
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   291
    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   292
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   293
7ad01559b262 Initial revision
claus
parents:
diff changeset
   294
setContext:aContext
7ad01559b262 Initial revision
claus
parents:
diff changeset
   295
    "set the context used while evaluating"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   296
7ad01559b262 Initial revision
claus
parents:
diff changeset
   297
    contextToEvaluateIn := aContext
7ad01559b262 Initial revision
claus
parents:
diff changeset
   298
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   299
7ad01559b262 Initial revision
claus
parents:
diff changeset
   300
!Parser methodsFor:'accessing'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   301
7ad01559b262 Initial revision
claus
parents:
diff changeset
   302
tree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   303
    "return the parsetree"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   304
7ad01559b262 Initial revision
claus
parents:
diff changeset
   305
    ^tree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   306
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   307
7ad01559b262 Initial revision
claus
parents:
diff changeset
   308
tree:aTree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   309
    tree := aTree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   310
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   311
7ad01559b262 Initial revision
claus
parents:
diff changeset
   312
selector
7ad01559b262 Initial revision
claus
parents:
diff changeset
   313
    "return the selector"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   314
7ad01559b262 Initial revision
claus
parents:
diff changeset
   315
    ^ selector
7ad01559b262 Initial revision
claus
parents:
diff changeset
   316
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   317
7ad01559b262 Initial revision
claus
parents:
diff changeset
   318
primitiveNumber
7ad01559b262 Initial revision
claus
parents:
diff changeset
   319
    "return the primitiveNumber"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   320
7ad01559b262 Initial revision
claus
parents:
diff changeset
   321
    ^ primNr
7ad01559b262 Initial revision
claus
parents:
diff changeset
   322
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   323
7ad01559b262 Initial revision
claus
parents:
diff changeset
   324
numberOfMethodArgs
7ad01559b262 Initial revision
claus
parents:
diff changeset
   325
    "return the number of methodargs"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   326
7ad01559b262 Initial revision
claus
parents:
diff changeset
   327
    ^ methodArgs size
7ad01559b262 Initial revision
claus
parents:
diff changeset
   328
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   329
7ad01559b262 Initial revision
claus
parents:
diff changeset
   330
methodArgs
7ad01559b262 Initial revision
claus
parents:
diff changeset
   331
    "return an array with methodarg names"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   332
7ad01559b262 Initial revision
claus
parents:
diff changeset
   333
    ^ methodArgNames
7ad01559b262 Initial revision
claus
parents:
diff changeset
   334
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   335
7ad01559b262 Initial revision
claus
parents:
diff changeset
   336
numberOfMethodVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   337
    "return the number of method variables"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   338
7ad01559b262 Initial revision
claus
parents:
diff changeset
   339
    ^ methodVars size
7ad01559b262 Initial revision
claus
parents:
diff changeset
   340
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   341
7ad01559b262 Initial revision
claus
parents:
diff changeset
   342
methodVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   343
    "return a collection with method variablenames"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   344
7ad01559b262 Initial revision
claus
parents:
diff changeset
   345
    ^ methodVarNames
7ad01559b262 Initial revision
claus
parents:
diff changeset
   346
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   347
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   348
usedVars
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   349
    "return a collection with variablenames refd by method"
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   350
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   351
    ^ usedVars
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   352
!
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   353
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   354
usedInstVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   355
    "return a collection with instvariablenames refd by method"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   356
7ad01559b262 Initial revision
claus
parents:
diff changeset
   357
    ^ usedInstVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   358
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   359
7ad01559b262 Initial revision
claus
parents:
diff changeset
   360
usedClassVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   361
    "return a collection with classvariablenames refd by method"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   362
7ad01559b262 Initial revision
claus
parents:
diff changeset
   363
    ^ usedClassVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   364
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   365
7ad01559b262 Initial revision
claus
parents:
diff changeset
   366
modifiedInstVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   367
    "return a collection with instvariablenames modified by method"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   368
7ad01559b262 Initial revision
claus
parents:
diff changeset
   369
    ^ modifiedInstVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   370
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   371
7ad01559b262 Initial revision
claus
parents:
diff changeset
   372
modifiedClassVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   373
    "return a collection with classvariablenames modified by method"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   374
7ad01559b262 Initial revision
claus
parents:
diff changeset
   375
    ^ modifiedClassVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   376
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   377
7ad01559b262 Initial revision
claus
parents:
diff changeset
   378
errorFlag
7ad01559b262 Initial revision
claus
parents:
diff changeset
   379
    ^ errorFlag
7ad01559b262 Initial revision
claus
parents:
diff changeset
   380
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   381
7ad01559b262 Initial revision
claus
parents:
diff changeset
   382
evalExitBlock:aBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
   383
    "when evaluating a return expression, this block is evaluated"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   384
7ad01559b262 Initial revision
claus
parents:
diff changeset
   385
    evalExitBlock := aBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
   386
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   387
7ad01559b262 Initial revision
claus
parents:
diff changeset
   388
!Parser methodsFor:'error handling'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   389
7ad01559b262 Initial revision
claus
parents:
diff changeset
   390
showErrorMessage:aMessage position:pos
7ad01559b262 Initial revision
claus
parents:
diff changeset
   391
    Transcript show:(pos printString).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   392
    Transcript show:' '.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   393
    selector notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   394
        Transcript show:aMessage.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   395
        Transcript showCr:(' in ' , selector)
7ad01559b262 Initial revision
claus
parents:
diff changeset
   396
    ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   397
        Transcript showCr:aMessage
7ad01559b262 Initial revision
claus
parents:
diff changeset
   398
    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   399
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   400
7ad01559b262 Initial revision
claus
parents:
diff changeset
   401
parseError:aMessage position:position to:endPos
7ad01559b262 Initial revision
claus
parents:
diff changeset
   402
    "report a syntax error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   403
7ad01559b262 Initial revision
claus
parents:
diff changeset
   404
    |m|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   405
7ad01559b262 Initial revision
claus
parents:
diff changeset
   406
    errorFlag := true.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   407
    m := ' Error:' , aMessage.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   408
    self notifyError:m position:position to:endPos.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   409
    exitBlock notNil ifTrue:[exitBlock value].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   410
    ^ false
7ad01559b262 Initial revision
claus
parents:
diff changeset
   411
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   412
7ad01559b262 Initial revision
claus
parents:
diff changeset
   413
parseError:aMessage position:position
7ad01559b262 Initial revision
claus
parents:
diff changeset
   414
    "report a syntax error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   415
7ad01559b262 Initial revision
claus
parents:
diff changeset
   416
    ^ self parseError:aMessage position:position to:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   417
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   418
7ad01559b262 Initial revision
claus
parents:
diff changeset
   419
parseError:aMessage
7ad01559b262 Initial revision
claus
parents:
diff changeset
   420
    "report a syntax error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   421
7ad01559b262 Initial revision
claus
parents:
diff changeset
   422
    ^ self parseError:aMessage position:tokenPosition to:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   423
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   424
7ad01559b262 Initial revision
claus
parents:
diff changeset
   425
selectorCheck:aSelectorString position:pos to:pos2
7ad01559b262 Initial revision
claus
parents:
diff changeset
   426
    aSelectorString knownAsSymbol ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   427
        self warning:(aSelectorString , ' is currently nowhere implemented') 
7ad01559b262 Initial revision
claus
parents:
diff changeset
   428
            position:pos to:pos2
7ad01559b262 Initial revision
claus
parents:
diff changeset
   429
    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   430
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   431
7ad01559b262 Initial revision
claus
parents:
diff changeset
   432
correctableError:message position:pos1 to:pos2
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   433
    "report an error which can be corrected by compiler -
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   434
     return true if correction is wanted"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   435
7ad01559b262 Initial revision
claus
parents:
diff changeset
   436
    |correctIt|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   437
7ad01559b262 Initial revision
claus
parents:
diff changeset
   438
    requestor isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   439
        self showErrorMessage:message position:pos1.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   440
        correctIt := false
7ad01559b262 Initial revision
claus
parents:
diff changeset
   441
    ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   442
        correctIt := requestor correctableError:message position:pos1 to:pos2
7ad01559b262 Initial revision
claus
parents:
diff changeset
   443
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   444
    correctIt ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   445
        exitBlock notNil ifTrue:[exitBlock value]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   446
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   447
    ^ correctIt
7ad01559b262 Initial revision
claus
parents:
diff changeset
   448
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   449
7ad01559b262 Initial revision
claus
parents:
diff changeset
   450
undefError:aName position:pos1 to:pos2
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   451
    "report an undefined variable error - return true, if it should be
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   452
     corrected"
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   453
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   454
    requestor isNil ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   455
	warnedUndefVars notNil ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   456
	    (warnedUndefVars includes:aName) ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   457
		"already warned about this one"
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   458
		^ false
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   459
	    ].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   460
	].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   461
	self showErrorMessage:('Error: ' , aName , ' is undefined') position:pos1.
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   462
	warnedUndefVars isNil ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   463
	    warnedUndefVars := Set new.
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   464
	].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   465
	warnedUndefVars add:aName.
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   466
	^ false
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   467
    ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   468
7ad01559b262 Initial revision
claus
parents:
diff changeset
   469
    ^ self correctableError:('Error: ' , aName , ' is undefined') 
7ad01559b262 Initial revision
claus
parents:
diff changeset
   470
                   position:pos1 to:pos2
7ad01559b262 Initial revision
claus
parents:
diff changeset
   471
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   472
7ad01559b262 Initial revision
claus
parents:
diff changeset
   473
exitWith:something
7ad01559b262 Initial revision
claus
parents:
diff changeset
   474
    "this is the longjump out of evaluation via a return expression"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   475
7ad01559b262 Initial revision
claus
parents:
diff changeset
   476
    evalExitBlock value:something
7ad01559b262 Initial revision
claus
parents:
diff changeset
   477
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   478
7ad01559b262 Initial revision
claus
parents:
diff changeset
   479
!Parser methodsFor:'parsing'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   480
7ad01559b262 Initial revision
claus
parents:
diff changeset
   481
parseMethod
7ad01559b262 Initial revision
claus
parents:
diff changeset
   482
    "parse a method"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   483
7ad01559b262 Initial revision
claus
parents:
diff changeset
   484
    |parseTree|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   485
7ad01559b262 Initial revision
claus
parents:
diff changeset
   486
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   487
    (self parseMethodSpec == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   488
    parseTree := self parseMethodBody.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   489
    (parseTree == #Error) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   490
        self tree:parseTree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   491
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   492
    ^ parseTree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   493
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   494
7ad01559b262 Initial revision
claus
parents:
diff changeset
   495
parseMethodSpec
7ad01559b262 Initial revision
claus
parents:
diff changeset
   496
    "parse a methods selector & arg specification;
7ad01559b262 Initial revision
claus
parents:
diff changeset
   497
     set selector and methodArgs as a side effect"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   498
7ad01559b262 Initial revision
claus
parents:
diff changeset
   499
    |var|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   500
7ad01559b262 Initial revision
claus
parents:
diff changeset
   501
    (tokenType == #Keyword) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   502
        selector := ''.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   503
        [tokenType == #Keyword] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   504
            selector := selector , tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   505
            self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   506
            (tokenType ~~ #Identifier) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   507
            var := Variable name:tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   508
            methodArgs isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   509
                methodArgs := Array with:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   510
                methodArgNames := Array with:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   511
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   512
                methodArgs := methodArgs copyWith:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   513
                methodArgNames := methodArgNames copyWith:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   514
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   515
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
   516
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   517
        selector := selector asSymbol.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   518
        ^ self
7ad01559b262 Initial revision
claus
parents:
diff changeset
   519
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   520
    (tokenType == #Identifier) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   521
        selector := tokenName asSymbol.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   522
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   523
        ^ self
7ad01559b262 Initial revision
claus
parents:
diff changeset
   524
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   525
    (tokenType == #BinaryOperator) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   526
        selector := tokenName asSymbol.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   527
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   528
        (tokenType ~~ #Identifier) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   529
        var := Variable name:tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   530
        methodArgs isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   531
            methodArgs := Array with:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   532
            methodArgNames := Array with:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   533
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   534
            methodArgs := methodArgs copyWith:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   535
            methodArgNames := methodArgNames copyWith:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   536
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   537
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   538
        ^ self
7ad01559b262 Initial revision
claus
parents:
diff changeset
   539
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   540
    ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   541
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   542
7ad01559b262 Initial revision
claus
parents:
diff changeset
   543
parseMethodBodyOrNil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   544
    "parse a methods body (locals & statements);
7ad01559b262 Initial revision
claus
parents:
diff changeset
   545
     return  a node-tree, nil or #Error. empty (or comment only) input
7ad01559b262 Initial revision
claus
parents:
diff changeset
   546
     is accepted and returns nil"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   547
7ad01559b262 Initial revision
claus
parents:
diff changeset
   548
    |stats|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   549
7ad01559b262 Initial revision
claus
parents:
diff changeset
   550
    ((tokenType == #BinaryOperator) and:[tokenName = '<']) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   551
        "an ST-80 primitive - parsed but ignored"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   552
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   553
        primNr := self parsePrimitive.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   554
        (primNr == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   555
        self warning:'ST-80 primitives not supported - ignored'
7ad01559b262 Initial revision
claus
parents:
diff changeset
   556
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   557
7ad01559b262 Initial revision
claus
parents:
diff changeset
   558
    (self parseMethodBodyVarSpec == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   559
7ad01559b262 Initial revision
claus
parents:
diff changeset
   560
    (tokenType ~~ #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   561
        stats := self statementList
7ad01559b262 Initial revision
claus
parents:
diff changeset
   562
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   563
    ^ stats
7ad01559b262 Initial revision
claus
parents:
diff changeset
   564
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   565
7ad01559b262 Initial revision
claus
parents:
diff changeset
   566
parseMethodBody
7ad01559b262 Initial revision
claus
parents:
diff changeset
   567
    "parse a methods body (locals & statements); no more token may follow
7ad01559b262 Initial revision
claus
parents:
diff changeset
   568
    return  a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   569
7ad01559b262 Initial revision
claus
parents:
diff changeset
   570
    |stats|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   571
7ad01559b262 Initial revision
claus
parents:
diff changeset
   572
    stats := self parseMethodBodyOrNil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   573
    (stats == #Error) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   574
        (tokenType ~~ #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   575
            self parseError:(tokenType printString , ' unexpected').
7ad01559b262 Initial revision
claus
parents:
diff changeset
   576
            ^#Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   577
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   578
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   579
    ^ stats
7ad01559b262 Initial revision
claus
parents:
diff changeset
   580
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   581
    
7ad01559b262 Initial revision
claus
parents:
diff changeset
   582
parseMethodBodyVarSpec
7ad01559b262 Initial revision
claus
parents:
diff changeset
   583
    "parse a methods local variable specification"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   584
7ad01559b262 Initial revision
claus
parents:
diff changeset
   585
    |var|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   586
7ad01559b262 Initial revision
claus
parents:
diff changeset
   587
    (tokenType == $|) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   588
        "memorize position for declaration in correction"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   589
        localVarDefPosition := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   590
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   591
        [tokenType == #Identifier] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   592
            var := Variable name:tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   593
            methodVars isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   594
                methodVars := Array with:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   595
                methodVarNames := Array with:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   596
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   597
                methodVars := methodVars copyWith:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   598
                methodVarNames := methodVarNames copyWith:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   599
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   600
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
   601
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   602
        (tokenType ~~ $|) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   603
            self syntaxError:'error in local var specification; | expected.'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   604
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   605
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   606
        self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
   607
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   608
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   609
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   610
7ad01559b262 Initial revision
claus
parents:
diff changeset
   611
parsePrimitive
7ad01559b262 Initial revision
claus
parents:
diff changeset
   612
    "parse an ST-80 type primitive;
7ad01559b262 Initial revision
claus
parents:
diff changeset
   613
    return primitive number or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   614
7ad01559b262 Initial revision
claus
parents:
diff changeset
   615
    |primNumber|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   616
7ad01559b262 Initial revision
claus
parents:
diff changeset
   617
    ((tokenType == #Keyword) and:[tokenName = 'primitive:']) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   618
        self parseError:'bad primitive definition (primitive: expected)'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   619
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   620
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   621
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   622
    (tokenType == #Integer) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   623
        self parseError:'primitive number expected'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   624
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   625
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   626
    primNumber := tokenValue.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   627
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   628
    ((tokenType == #BinaryOperator) and:[tokenName = '>']) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   629
        self parseError:'bad primitive definition (> expected)'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   630
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   631
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   632
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   633
    ^ primNumber
7ad01559b262 Initial revision
claus
parents:
diff changeset
   634
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   635
7ad01559b262 Initial revision
claus
parents:
diff changeset
   636
statementList
7ad01559b262 Initial revision
claus
parents:
diff changeset
   637
    "parse a statementlist; return a node-tree, nil or #Error.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   638
     Statements must be separated by periods."
7ad01559b262 Initial revision
claus
parents:
diff changeset
   639
7ad01559b262 Initial revision
claus
parents:
diff changeset
   640
    |thisStatement prevStatement firstStatement correctIt periodPos|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   641
7ad01559b262 Initial revision
claus
parents:
diff changeset
   642
    thisStatement := self statement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   643
    (thisStatement == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   644
    firstStatement := thisStatement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   645
    [tokenType == $.] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   646
        periodPos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   647
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   648
        (tokenType == $]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   649
            currentBlock isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   650
                self parseError:'block nesting error'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   651
                errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   652
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   653
            *** I had a warning here (since it was not defined
7ad01559b262 Initial revision
claus
parents:
diff changeset
   654
            *** in the blue-book; but PD-code contains a lot of
7ad01559b262 Initial revision
claus
parents:
diff changeset
   655
            *** code with periods at the end so that the warnings
7ad01559b262 Initial revision
claus
parents:
diff changeset
   656
            *** became annoying
7ad01559b262 Initial revision
claus
parents:
diff changeset
   657
7ad01559b262 Initial revision
claus
parents:
diff changeset
   658
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   659
                self warning:'period after last statement' position:periodPos
7ad01559b262 Initial revision
claus
parents:
diff changeset
   660
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   661
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   662
            ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   663
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   664
        (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   665
            currentBlock notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   666
                self parseError:'block nesting error'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   667
                errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   668
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   669
            *** I had a warning here (since it was not defined
7ad01559b262 Initial revision
claus
parents:
diff changeset
   670
            *** in the blue-book; but PD-code contains a lot of
7ad01559b262 Initial revision
claus
parents:
diff changeset
   671
            *** code with periods at the end so that the warnings
7ad01559b262 Initial revision
claus
parents:
diff changeset
   672
            *** became annoying
7ad01559b262 Initial revision
claus
parents:
diff changeset
   673
7ad01559b262 Initial revision
claus
parents:
diff changeset
   674
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   675
                self warning:'period after last statement' position:periodPos
7ad01559b262 Initial revision
claus
parents:
diff changeset
   676
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   677
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   678
            ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   679
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   680
7ad01559b262 Initial revision
claus
parents:
diff changeset
   681
        prevStatement := thisStatement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   682
        (prevStatement isKindOf:ReturnNode) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   683
            self warning:'statements after return' position:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
   684
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   685
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   686
        periodPos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   687
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   688
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   689
7ad01559b262 Initial revision
claus
parents:
diff changeset
   690
        ((tokenType == $]) or:[tokenType == #EOF]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   691
            (currentBlock isNil and:[tokenType == $]]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   692
                self parseError:'block nesting error'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   693
                errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   694
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   695
                correctIt := self correctableError:'period after last statement in block'
7ad01559b262 Initial revision
claus
parents:
diff changeset
   696
                                          position:periodPos to:(periodPos + 1).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   697
                correctIt ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   698
                    (self correctByDeleting == #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   699
                        errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   700
                    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   701
                ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   702
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   703
            ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   704
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   705
        thisStatement := self statement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   706
        (thisStatement == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   707
        prevStatement nextStatement:thisStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   708
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   709
    ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   710
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   711
7ad01559b262 Initial revision
claus
parents:
diff changeset
   712
statement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   713
    "parse a statement; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   714
7ad01559b262 Initial revision
claus
parents:
diff changeset
   715
    |expr node|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   716
7ad01559b262 Initial revision
claus
parents:
diff changeset
   717
    (tokenType == $^) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   718
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   719
        expr := self expression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   720
        (expr == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   721
        node := ReturnNode expression:expr.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   722
        node home:self blockHome:currentBlock.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   723
        ^ node
7ad01559b262 Initial revision
claus
parents:
diff changeset
   724
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   725
    (tokenType == #Primitive) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   726
        self parseError:'cannot compile primitives (yet)'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   727
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   728
        ^ PrimitiveNode code:''
7ad01559b262 Initial revision
claus
parents:
diff changeset
   729
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   730
    (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   731
        self syntaxError:'period after last statement'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   732
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   733
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   734
    expr := self expression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   735
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   736
    classToCompileFor notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   737
        currentBlock isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   738
            (expr isKindOf:PrimaryNode) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   739
                self warning:'useless computation - missing ^ ?'
7ad01559b262 Initial revision
claus
parents:
diff changeset
   740
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   741
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   742
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   743
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   744
    (expr == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   745
    ^ StatementNode expression:expr
7ad01559b262 Initial revision
claus
parents:
diff changeset
   746
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   747
7ad01559b262 Initial revision
claus
parents:
diff changeset
   748
expression
7ad01559b262 Initial revision
claus
parents:
diff changeset
   749
    "parse a cascade-expression; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   750
7ad01559b262 Initial revision
claus
parents:
diff changeset
   751
    |receiver arg sel args pos pos2|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   752
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   753
    pos := tokenPosition.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   754
    receiver := self keywordExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   755
    (receiver == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   756
    [tokenType == $;] whileTrue:[
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   757
        receiver isMessage ifFalse:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   758
            self syntaxError:'left side of cascade must be a message expression'
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   759
                    position:pos to:tokenPosition
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   760
        ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   761
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   762
        (tokenType == #Identifier) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   763
            sel := tokenName.
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   764
            self selectorCheck:sel position:tokenPosition to:(tokenPosition + sel size - 1).
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   765
            receiver := CascadeNode receiver:receiver selector:sel.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   766
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
   767
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   768
            (tokenType == #BinaryOperator) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   769
                sel := tokenName.
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   770
                self selectorCheck:sel position:tokenPosition to:(tokenPosition + sel size - 1).
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   771
                self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   772
                arg := self unaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   773
                (arg == #Error) ifTrue:[^ #Error].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   774
                receiver := CascadeNode receiver:receiver selector:sel arg:arg
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   775
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   776
                (tokenType == #Keyword) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   777
                    pos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   778
                    sel := tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   779
                    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   780
                    arg := self binaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   781
                    (arg == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   782
                    args := Array with:arg.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   783
                    [tokenType == #Keyword] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   784
                        sel := sel , tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   785
                        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   786
                        arg := self binaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   787
                        (arg == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   788
                        args := args copyWith:arg.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   789
                        pos2 := tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
   790
                    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   791
                    self selectorCheck:sel position:pos to:pos2.
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   792
                    receiver := CascadeNode receiver:receiver selector:sel args:args
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   793
                ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   794
                    (tokenType == #Error) ifTrue:[^ #Error].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   795
                    self syntaxError:('invalid cascade; ' , tokenType printString , ' unexpected')
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   796
                            position:tokenPosition to:source position - 1.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   797
                    ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   798
                ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   799
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   800
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   801
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   802
    ^ receiver
7ad01559b262 Initial revision
claus
parents:
diff changeset
   803
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   804
7ad01559b262 Initial revision
claus
parents:
diff changeset
   805
keywordExpression
7ad01559b262 Initial revision
claus
parents:
diff changeset
   806
    "parse a keyword-expression; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   807
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   808
    |receiver sel arg args pos1 pos2 try lno note|
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   809
7ad01559b262 Initial revision
claus
parents:
diff changeset
   810
    receiver := self binaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   811
    (receiver == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   812
    (tokenType == #Keyword) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   813
        pos1 := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   814
        sel := tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   815
        lno := tokenLineNr.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   816
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   817
        arg := self binaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   818
        (arg == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   819
        args := Array with:arg.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   820
        [tokenType == #Keyword] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   821
            sel := sel , tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   822
            self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   823
            arg := self binaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   824
            (arg == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   825
            args := args copyWith:arg.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   826
            pos2 := tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
   827
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   828
        self selectorCheck:sel position:pos1 to:pos2.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   829
        try := MessageNode receiver:receiver selector:sel args:args.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   830
        (try isMemberOf:String) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   831
            self parseError:try position:pos1 to:pos2.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   832
            receiver := MessageNode receiver:receiver selector:sel args:args
7ad01559b262 Initial revision
claus
parents:
diff changeset
   833
                                        fold:false
7ad01559b262 Initial revision
claus
parents:
diff changeset
   834
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   835
            receiver := try
7ad01559b262 Initial revision
claus
parents:
diff changeset
   836
        ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   837
        note := receiver plausibilityCheck.
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   838
        note notNil ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   839
            self warning:note position:pos1 to:pos2
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   840
        ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   841
        receiver lineNumber:lno
7ad01559b262 Initial revision
claus
parents:
diff changeset
   842
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   843
    ^ receiver
7ad01559b262 Initial revision
claus
parents:
diff changeset
   844
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   845
7ad01559b262 Initial revision
claus
parents:
diff changeset
   846
binaryExpression
7ad01559b262 Initial revision
claus
parents:
diff changeset
   847
    "parse a binary-expression; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   848
7ad01559b262 Initial revision
claus
parents:
diff changeset
   849
    |receiver arg sel pos try lno note|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   850
7ad01559b262 Initial revision
claus
parents:
diff changeset
   851
    receiver := self unaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   852
    (receiver == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   853
7ad01559b262 Initial revision
claus
parents:
diff changeset
   854
    "special kludge: since Scanner cannot know if -digit is a binary
7ad01559b262 Initial revision
claus
parents:
diff changeset
   855
     expression or a negative constant, handle cases here"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   856
7ad01559b262 Initial revision
claus
parents:
diff changeset
   857
    [(tokenType == #BinaryOperator) or:[(tokenType == $|)
7ad01559b262 Initial revision
claus
parents:
diff changeset
   858
     or:[(tokenType == #Integer) and:[tokenValue < 0]]]] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   859
        pos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   860
7ad01559b262 Initial revision
claus
parents:
diff changeset
   861
        lno := tokenLineNr.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   862
7ad01559b262 Initial revision
claus
parents:
diff changeset
   863
        "kludge here: bar and minus are not scanned as binop "
7ad01559b262 Initial revision
claus
parents:
diff changeset
   864
        (tokenType == $|) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   865
            sel := '|'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   866
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
   867
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   868
            (tokenType == #BinaryOperator) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   869
                sel := tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   870
                self selectorCheck:sel position:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
   871
                                             to:(tokenPosition + sel size - 1).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   872
                self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
   873
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   874
                sel := '-'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   875
                tokenValue := tokenValue negated
7ad01559b262 Initial revision
claus
parents:
diff changeset
   876
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   877
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   878
        arg := self unaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   879
        (arg == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   880
        try := BinaryNode receiver:receiver selector:sel arg:arg.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   881
        (try isMemberOf:String) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   882
            self parseError:try position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   883
            receiver := BinaryNode receiver:receiver selector:sel arg:arg
7ad01559b262 Initial revision
claus
parents:
diff changeset
   884
                                       fold:false
7ad01559b262 Initial revision
claus
parents:
diff changeset
   885
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   886
            receiver := try
7ad01559b262 Initial revision
claus
parents:
diff changeset
   887
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   888
        note := receiver plausibilityCheck.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   889
        note notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   890
            self warning:note position:pos to:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
   891
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   892
        receiver lineNumber:lno
7ad01559b262 Initial revision
claus
parents:
diff changeset
   893
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   894
    ^ receiver
7ad01559b262 Initial revision
claus
parents:
diff changeset
   895
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   896
7ad01559b262 Initial revision
claus
parents:
diff changeset
   897
unaryExpression
7ad01559b262 Initial revision
claus
parents:
diff changeset
   898
    "parse a unary-expression; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   899
7ad01559b262 Initial revision
claus
parents:
diff changeset
   900
    |receiver sel pos try|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   901
7ad01559b262 Initial revision
claus
parents:
diff changeset
   902
    receiver := self primary.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   903
    (receiver == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   904
    [tokenType == #Identifier] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   905
        pos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   906
        sel := tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   907
        self selectorCheck:sel position:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
   908
                                     to:(tokenPosition + sel size - 1).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   909
        try := UnaryNode receiver:receiver selector:sel.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   910
        (try isMemberOf:String) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   911
            self warning:try position:pos to:(tokenPosition + sel size - 1).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   912
            receiver := UnaryNode receiver:receiver selector:sel fold:false
7ad01559b262 Initial revision
claus
parents:
diff changeset
   913
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   914
            receiver := try
7ad01559b262 Initial revision
claus
parents:
diff changeset
   915
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   916
        receiver lineNumber:tokenLineNr.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   917
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   918
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   919
    ^ receiver
7ad01559b262 Initial revision
claus
parents:
diff changeset
   920
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   921
7ad01559b262 Initial revision
claus
parents:
diff changeset
   922
primary
7ad01559b262 Initial revision
claus
parents:
diff changeset
   923
    "parse a primary-expression; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   924
7ad01559b262 Initial revision
claus
parents:
diff changeset
   925
    |val var expr pos name|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   926
7ad01559b262 Initial revision
claus
parents:
diff changeset
   927
    pos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   928
    (tokenType == #Identifier) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   929
        var := self variable.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   930
        (var == #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   931
            errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   932
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   933
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   934
        (tokenType == $_) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   935
            ^ var
7ad01559b262 Initial revision
claus
parents:
diff changeset
   936
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   937
        (var ~~ #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   938
            (var type == #MethodArg) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   939
                self parseError:'assignment to method argument' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   940
                errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   941
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   942
            (var type == #BlockArg) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   943
                self parseError:'assignment to block argument' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   944
                errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   945
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   946
7ad01559b262 Initial revision
claus
parents:
diff changeset
   947
            (var type == #InstanceVariable) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   948
                modifiedInstVars isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   949
                    modifiedInstVars := OrderedCollection new
7ad01559b262 Initial revision
claus
parents:
diff changeset
   950
                ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   951
                name := prevInstVarNames at:(var index).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   952
                (modifiedInstVars includes:name) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   953
                    modifiedInstVars add:name
7ad01559b262 Initial revision
claus
parents:
diff changeset
   954
                ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   955
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   956
                (var type == #ClassVariable) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   957
                    modifiedClassVars isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   958
                        modifiedClassVars := OrderedCollection new
7ad01559b262 Initial revision
claus
parents:
diff changeset
   959
                    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   960
                    name := var name.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   961
                    name := name copyFrom:((name indexOf:$:) + 1).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   962
                    (modifiedClassVars includes:name) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   963
                        modifiedClassVars add:name
7ad01559b262 Initial revision
claus
parents:
diff changeset
   964
                    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   965
                ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   966
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   967
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   968
7ad01559b262 Initial revision
claus
parents:
diff changeset
   969
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   970
        expr := self expression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   971
        (errorFlag or:[expr == #Error]) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   972
        ^ AssignmentNode variable:var expression:expr
7ad01559b262 Initial revision
claus
parents:
diff changeset
   973
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   974
    ((tokenType == #Integer) or:
7ad01559b262 Initial revision
claus
parents:
diff changeset
   975
     [(tokenType == #Character) or:
7ad01559b262 Initial revision
claus
parents:
diff changeset
   976
      [tokenType == #Float]]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   977
        val := ConstantNode type:tokenType value:tokenValue.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   978
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   979
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   980
            self parseError:'assignment to a constant' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   981
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   982
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   983
        ^ val
7ad01559b262 Initial revision
claus
parents:
diff changeset
   984
    ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   985
    (tokenType == #Self) ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   986
        self nextToken.
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   987
        (tokenType == $_) ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   988
            self parseError:'assignment to self' position:pos to:tokenPosition.
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   989
            ^ #Error
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   990
        ].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   991
        selfNode isNil ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   992
            selfNode := PrimaryNode type:#Self value:selfValue
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   993
        ].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   994
        ^ selfNode
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   995
    ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   996
    (tokenType == #String) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   997
        val := ConstantNode type:tokenType value:tokenValue.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   998
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   999
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1000
            self parseError:'assignment to a constant' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1001
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1002
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1003
        ^ val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1004
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1005
    (tokenType == #Symbol) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1006
        val := ConstantNode type:tokenType value:tokenValue.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1007
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1008
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1009
            self parseError:'assignment to a constant' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1010
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1011
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1012
        ^ val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1013
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1014
    (tokenType == #Nil) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1015
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1016
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1017
            self parseError:'assignment to nil' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1018
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1019
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1020
        ^ ConstantNode type:#Nil value:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1021
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1022
    (tokenType == #True) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1023
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1024
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1025
            self parseError:'assignment to true' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1026
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1027
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1028
        ^ ConstantNode type:#True value:true
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1029
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1030
    (tokenType == #False) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1031
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1032
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1033
            self parseError:'assignment to false' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1034
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1035
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1036
        ^ ConstantNode type:#False value:false
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1037
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1038
    (tokenType  == #Super) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1039
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1040
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1041
            self parseError:'assignment to super' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1042
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1043
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1044
        superNode isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1045
            superNode := PrimaryNode type:#Super value:selfValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1046
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1047
        ^ superNode
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1048
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1049
    (tokenType == #ThisContext) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1050
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1051
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1052
            self parseError:'assignment to thisContext' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1053
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1054
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1055
        ^ PrimaryNode type:#ThisContext value:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1056
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1057
    (tokenType == #HashLeftParen) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1058
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1059
        val := self array.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1060
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1061
        ^ ConstantNode type:#Array value:val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1062
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1063
    (tokenType == #HashLeftBrack) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1064
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1065
        val := self byteArray.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1066
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1067
        ^ ConstantNode type:#Array value:val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1068
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1069
    (tokenType == $() ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1070
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1071
        val := self expression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1072
        (val == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1073
        (tokenType ~~ $) ) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1074
            (tokenType isMemberOf:Character) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1075
                self syntaxError:'missing '')'' (i.e. ''' , tokenType asString , ''' unexpected)' withCRs position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1076
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1077
                self syntaxError:'missing '')''' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1078
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1079
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1080
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1081
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1082
        ^ val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1083
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1084
    (tokenType == $[ ) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1085
        val := self block.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1086
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1087
        ^ val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1088
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1089
    (tokenType == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1090
    (tokenType isKindOf:Character) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1091
        self syntaxError:('error in primary; ' 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1092
                           , tokenType printString ,
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1093
                           ' unexpected') position:tokenPosition to:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1094
    ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1095
        self syntaxError:('error in primary; ' 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1096
                           , tokenType printString ,
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1097
                           ' unexpected') 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1098
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1099
    ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1100
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1101
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1102
variableOrError
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1103
    "parse a variable; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1104
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1105
    |tokenFound var instIndex aClass searchBlock args vars
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1106
     varName tokenSymbol theBlock className
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1107
     runIndex "{ Class: SmallInteger }" |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1108
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1109
    varName := tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1110
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1111
    "is it a block-arg or block-var ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1112
    searchBlock := currentBlock.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1113
    [searchBlock notNil] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1114
        runIndex := 1.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1115
        args := searchBlock arguments.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1116
        args notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1117
            args do:[:aBlockArg |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1118
                (aBlockArg name = varName) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1119
                    tokenFound := aBlockArg.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1120
                    instIndex := runIndex.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1121
                    theBlock := searchBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1122
                ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1123
                runIndex := runIndex + 1
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1124
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1125
            tokenFound notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1126
                ^ PrimaryNode type:#BlockArg
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1127
                              name:varName
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1128
                             token:tokenFound
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1129
                             index:instIndex
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1130
                             block:theBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1131
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1132
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1133
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1134
        runIndex := 1.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1135
        vars := searchBlock variables.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1136
        vars notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1137
            vars do:[:aBlockVar |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1138
                (aBlockVar name = varName) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1139
                    tokenFound := aBlockVar.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1140
                    instIndex := runIndex.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1141
                    theBlock := searchBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1142
                ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1143
                runIndex := runIndex + 1
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1144
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1145
            tokenFound notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1146
                ^ PrimaryNode type:#BlockVariable
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1147
                              name:varName
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1148
                             token:tokenFound
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1149
                             index:instIndex
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1150
                             block:theBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1151
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1152
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1153
        searchBlock := searchBlock home
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1154
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1155
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1156
    "is it a method-variable ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1157
    methodVars notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1158
        instIndex := methodVarNames indexOf:varName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1159
        (instIndex ~~ 0) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1160
            var := methodVars at:instIndex.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1161
            var used:true.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1162
            ^ PrimaryNode type:#MethodVariable
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1163
                          name:varName
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1164
                         token:var
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1165
                         index:instIndex
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1166
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1167
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1168
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1169
    "is it a method-argument ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1170
    methodArgs notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1171
        instIndex := methodArgNames indexOf:varName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1172
        (instIndex ~~ 0) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1173
            ^ PrimaryNode type:#MethodArg
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1174
                          name:varName
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1175
                         token:(methodArgs at:instIndex)
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1176
                         index:instIndex
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1177
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1178
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1179
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1180
    "is it an instance-variable ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1181
    classToCompileFor notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1182
        "caching allInstVarNames for next compilation saves time ..."
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1183
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1184
        (prevInstVarNames isNil or:[prevClass ~~ classToCompileFor]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1185
            prevClass notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1186
                prevClass removeDependent:Parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1187
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1188
            prevClass := classToCompileFor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1189
            prevInstVarNames := classToCompileFor allInstVarNames.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1190
            prevClassInstVarNames := nil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1191
            prevClassVarNames := nil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1192
            prevClass addDependent:Parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1193
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1194
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1195
        instIndex := prevInstVarNames indexOf:varName startingAt:1
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1196
                                                        ifAbsent:[nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1197
        instIndex notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1198
            usedInstVars isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1199
                usedInstVars := OrderedCollection new
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1200
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1201
            (usedInstVars includes:varName) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1202
                usedInstVars add:varName
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1203
            ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1204
            usedVars isNil ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1205
                usedVars := OrderedCollection new
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1206
            ].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1207
            (usedVars includes:varName) ifFalse:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1208
                usedVars add:varName
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1209
            ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1210
            ^ PrimaryNode type:#InstanceVariable 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1211
                          name:varName
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1212
                         index:instIndex
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1213
                     selfValue:selfValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1214
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1215
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1216
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1217
    "is it a class-instance-variable ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1218
    classToCompileFor notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1219
        prevClassInstVarNames isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1220
            prevClassInstVarNames := classToCompileFor class allInstVarNames
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1221
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1222
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1223
        instIndex := prevClassInstVarNames indexOf:varName startingAt:1
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1224
                                                             ifAbsent:[nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1225
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1226
        instIndex notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1227
            aClass := self inWhichClassIsClassInstVar:varName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1228
            aClass notNil ifTrue:[
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1229
                usedVars isNil ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1230
                    usedVars := OrderedCollection new
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1231
                ].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1232
                (usedVars includes:varName) ifFalse:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1233
                    usedVars add:varName
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1234
                ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1235
                ^ PrimaryNode type:#ClassInstanceVariable
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1236
                              name:varName
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1237
                             index:instIndex
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1238
                         selfValue:selfValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1239
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1240
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1241
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1242
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1243
    "is it a class-variable ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1244
    classToCompileFor notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1245
        prevClassVarNames isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1246
            aClass := classToCompileFor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1247
            classToCompileFor isMeta ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1248
                className := aClass name.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1249
                className := className copyFrom:1 to:(className size - 5).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1250
                aClass := Smalltalk at:(className asSymbol).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1251
                aClass isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1252
                    aClass := classToCompileFor
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1253
                ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1254
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1255
            prevClassVarNames := aClass allClassVarNames
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1256
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1257
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1258
        instIndex := prevClassVarNames indexOf:varName startingAt:1
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1259
                                                         ifAbsent:[nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1260
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1261
        instIndex notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1262
            aClass := self inWhichClassIsClassVar:varName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1263
            aClass notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1264
                usedClassVars isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1265
                    usedClassVars := OrderedCollection new
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1266
                ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1267
                (usedClassVars includes:varName) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1268
                    usedClassVars add:varName
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1269
                ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1270
                usedVars isNil ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1271
                    usedVars := OrderedCollection new
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1272
                ].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1273
                (usedVars includes:varName) ifFalse:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1274
                    usedVars add:varName
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1275
                ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1276
                ^ PrimaryNode type:#ClassVariable 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1277
                              name:(aClass name , ':' , varName) asSymbol
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1278
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1279
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1280
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1281
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1282
    "is it a global-variable ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1283
    tokenSymbol := varName asSymbol.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1284
    (Smalltalk includesKey:tokenSymbol) ifTrue:[
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1285
        usedVars isNil ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1286
            usedVars := OrderedCollection new
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1287
        ].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1288
        (usedVars includes:varName) ifFalse:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1289
            usedVars add:varName
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1290
        ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1291
        ^ PrimaryNode type:#GlobalVariable 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1292
                      name:tokenSymbol
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1293
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1294
    ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1295
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1296
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1297
variable
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1298
    "parse a variable; if undefined, notify error and correct if user wants to"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1299
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1300
    |v|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1301
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1302
    v := self variableOrError.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1303
    (v == #Error) ifFalse:[^ v].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1304
    v := self correctVariable.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1305
    (v == #Error) ifFalse:[^ v].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1306
    ^ PrimaryNode type:#GlobalVariable
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1307
                  name:tokenName asSymbol
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1308
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1309
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1310
inWhichClassIsClassVar:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1311
    "search class-chain for the classvariable named aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1312
     - return the class or nil if not found"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1313
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1314
    |aClass className baseClass|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1315
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1316
    aClass := classToCompileFor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1317
    aClass isMeta ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1318
        className := aClass name.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1319
        className := className copyFrom:1 to:(className size - 5).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1320
        baseClass := Smalltalk at:(className asSymbol).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1321
        baseClass notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1322
            aClass := baseClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1323
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1324
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1325
    [aClass notNil] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1326
        (aClass classVarNames includes:aString) ifTrue:[ ^ aClass].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1327
        aClass := aClass superclass
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1328
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1329
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1330
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1331
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1332
inWhichClassIsClassInstVar:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1333
    "search class-chain for the class-instance variable named aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1334
     - return the class or nil if not found"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1335
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1336
    |aClass|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1337
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1338
    aClass := classToCompileFor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1339
    [aClass notNil] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1340
        (aClass class instVarNames includes:aString) ifTrue:[ ^ aClass].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1341
        aClass := aClass superclass
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1342
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1343
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1344
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1345
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1346
block
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1347
    "parse a block; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1348
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1349
    |stats node args var vars pos|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1350
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1351
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1352
    (tokenType == $: ) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1353
        [tokenType == $:] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1354
            pos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1355
            self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1356
            (tokenType == #Identifier) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1357
                self syntaxError:'Identifier expected in block-arg declaration'
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1358
                        position:pos to:tokenPosition-1.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1359
                ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1360
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1361
            var := Variable name:tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1362
            args isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1363
                args := Array with:var
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1364
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1365
                args := args copyWith:var
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1366
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1367
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1368
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1369
        (tokenType ~~ $| ) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1370
            "ST-80 allows [:arg ]"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1371
            (tokenType == $] ) ifTrue:[
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1372
                ^ BlockNode arguments:args home:currentBlock variables:nil.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1373
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1374
            self syntaxError:'| expected after block-arg declaration'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1375
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1376
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1377
        self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1378
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1379
    (tokenType == $| ) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1380
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1381
        pos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1382
        [tokenType == $|] whileFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1383
            (tokenType == #Identifier) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1384
                self syntaxError:'Identifier expected in block-var declaration' position:pos.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1385
                ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1386
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1387
            var := Variable name:tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1388
            vars isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1389
                vars := Array with:var
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1390
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1391
                vars := vars copyWith:var
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1392
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1393
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1394
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1395
        self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1396
    ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1397
    node := BlockNode arguments:args home:currentBlock variables:vars.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1398
    currentBlock := node.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1399
    stats := self blockStatementList.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1400
    node statements:stats.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1401
    currentBlock := node home.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1402
    (stats == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1403
    ^ node
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1404
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1405
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1406
blockStatementList
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1407
    "parse a blocks statementlist; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1408
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1409
    |thisStatement prevStatement firstStatement|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1410
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1411
    (tokenType == $] ) ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1412
    thisStatement := self statement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1413
    (thisStatement == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1414
    firstStatement := thisStatement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1415
    [tokenType == $] ] whileFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1416
        (tokenType == $.) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1417
            (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1418
                self syntaxError:'missing '']'' in block'
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1419
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1420
                self syntaxError:'missing ''.'' in block'
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1421
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1422
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1423
        ] ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1424
            prevStatement := thisStatement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1425
            self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1426
            tokenType == $] ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1427
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1428
                *** I had a warning here (since it was not defined
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1429
                *** in the blue-book; but PD-code contains a lot of
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1430
                *** code with periods at the end so that the warnings
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1431
                *** became annoying
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1432
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1433
                self warning:'period after last statement in block'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1434
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1435
                ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1436
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1437
            thisStatement := self statement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1438
            (thisStatement == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1439
            prevStatement nextStatement:thisStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1440
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1441
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1442
    ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1443
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1444
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1445
array
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1446
    |arr elem pos1 pos2|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1447
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1448
    pos1 := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1449
    arr := OrderedCollection new:200.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1450
    [tokenType ~~ $) ] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1451
        elem := self arrayConstant.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1452
        (elem == #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1453
            (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1454
                self syntaxError:'unterminated array-constant; '')'' expected' 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1455
                        position:pos1 to:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1456
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1457
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1458
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1459
        arr add:elem.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1460
        self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1461
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1462
    ^ Array withAll:arr
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1463
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1464
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1465
byteArray
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1466
    "for ST-80 R4 - allow byteArray constants"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1467
    |arr elem pos1 pos2|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1468
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1469
    pos1 := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1470
    arr := OrderedCollection new.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1471
    [tokenType ~~ $] ] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1472
        pos2 := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1473
        elem := self arrayConstant.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1474
        (elem == #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1475
            (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1476
                self syntaxError:'unterminated bytearray-constant; '']'' expected' 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1477
                        position:pos1 to:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1478
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1479
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1480
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1481
        ((elem isMemberOf:SmallInteger) and:
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1482
        [(elem >= 0) and:[elem <= 255]]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1483
            arr add:elem
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1484
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1485
            self parseError:'invalid ByteArray element' position:pos2 to:tokenPosition - 1
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1486
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1487
        self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1488
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1489
    ^ ByteArray withAll:arr
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1490
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1491
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1492
arrayConstant
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1493
    (tokenType == #String) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1494
        ^ tokenValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1495
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1496
    (tokenType == #Nil) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1497
        ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1498
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1499
    (tokenType == #Integer) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1500
        ^ tokenValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1501
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1502
    (tokenType == #Character) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1503
        ^ tokenValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1504
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1505
    (tokenType == #Float) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1506
        ^ tokenValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1507
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1508
    (tokenType == #True) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1509
        ^ true
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1510
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1511
    (tokenType == #False) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1512
        ^ false
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1513
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1514
    (tokenType == #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1515
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1516
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1517
    (tokenType == #BinaryOperator) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1518
        ^ tokenName asSymbol
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1519
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1520
    (tokenType == #Keyword) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1521
        ^ tokenName asSymbol
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1522
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1523
    (tokenType == #Identifier) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1524
        ^ tokenName asSymbol
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1525
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1526
    (tokenType == $() ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1527
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1528
        ^ self array
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1529
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1530
    (tokenType == $[) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1531
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1532
        ^ self byteArray
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1533
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1534
    (tokenType == #Symbol) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1535
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1536
        self warning:'no # for symbols within array-constants'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1537
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1538
        ^ tokenValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1539
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1540
    (tokenType == #HashLeftParen) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1541
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1542
        self warning:'no # for arrays within array-constants'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1543
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1544
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1545
        ^ self array
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1546
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1547
    (tokenType == #HashLeftBrack) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1548
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1549
        self warning:'no # for arrays within array-constants'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1550
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1551
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1552
        ^ self byteArray
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1553
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1554
    (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1555
        "just for the better error-hilight; let caller handle error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1556
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1557
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1558
    self syntaxError:('error in array-constant; ' 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1559
                      , tokenType printString 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1560
                      , ' unexpected').
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1561
    ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1562
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1563
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1564
!Parser methodsFor:'error correction'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1565
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1566
correctByDeleting
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1567
    "correct (by deleting token) if user wants to;
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1568
     return #Error if there was no correction or nil" 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1569
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1570
    (self confirm:'confirm deleting') ifFalse:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1571
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1572
    "tell requestor about the change"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1573
    requestor deleteSelection.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1574
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1575
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1576
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1577
findBestVariableFor:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1578
    "collect known variables with their levenshtein distances to aString;
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1579
     return the 10 best suggestions"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1580
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1581
    |names dists searchBlock args vars globalVarName aClass className baseClass n|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1582
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1583
    names := VariableArray new.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1584
    dists := VariableArray new.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1585
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1586
    "block arguments"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1587
    searchBlock := currentBlock.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1588
    [searchBlock notNil] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1589
        args := searchBlock arguments.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1590
        args notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1591
            args do:[:aBlockArg |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1592
                names add:(aBlockArg name).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1593
                dists add:(aString levenshteinTo:(aBlockArg name))
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1594
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1595
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1596
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1597
        vars := searchBlock variables.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1598
        vars notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1599
            vars do:[:aBlockVar |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1600
                names add:(aBlockVar name).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1601
                dists add:(aString levenshteinTo:(aBlockVar name))
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1602
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1603
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1604
        searchBlock := searchBlock home
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1605
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1606
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1607
    "method-variables"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1608
    methodVars notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1609
        methodVarNames do:[:methodVarName |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1610
            names add:methodVarName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1611
            dists add:(aString levenshteinTo:methodVarName)
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1612
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1613
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1614
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1615
    "method-arguments"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1616
    methodArgs notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1617
        methodArgNames do:[:methodArgName |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1618
            names add:methodArgName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1619
            dists add:(aString levenshteinTo:methodArgName)
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1620
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1621
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1622
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1623
    "instance-variables"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1624
    classToCompileFor notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1625
        prevInstVarNames do:[:instVarName |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1626
            names add:instVarName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1627
            dists add:(aString levenshteinTo:instVarName)
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1628
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1629
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1630
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1631
    "class-variables"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1632
    classToCompileFor notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1633
        aClass := classToCompileFor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1634
        aClass isMeta ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1635
            className := aClass name.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1636
            className := className copyFrom:1 to:(className size - 5).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1637
            baseClass := Smalltalk at:(className asSymbol).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1638
            baseClass notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1639
                aClass := baseClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1640
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1641
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1642
        [aClass notNil] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1643
            (aClass classVarNames) do:[:classVarName |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1644
                names add:classVarName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1645
                dists add:(aString levenshteinTo:classVarName)
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1646
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1647
            aClass := aClass superclass
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1648
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1649
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1650
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1651
    "globals"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1652
    Smalltalk allKeysDo:[:aKey |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1653
        globalVarName := aKey asString.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1654
        "only compare strings where length is about right"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1655
        ((globalVarName size - aString size) abs < 3) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1656
            names add:globalVarName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1657
            dists add:(aString levenshteinTo:globalVarName)
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1658
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1659
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1660
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1661
    "misc"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1662
    #('self' 'super' 'nil') do:[:name |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1663
        "only compare strings where length is about right"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1664
        ((name size - aString size) abs < 3) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1665
            names add:name.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1666
            dists add:(aString levenshteinTo:name)
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1667
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1668
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1669
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1670
    (dists size ~~ 0) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1671
        dists sortWith:names.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1672
        n := names size min:10.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1673
        ^ names copyFrom:1 to:n
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1674
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1675
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1676
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1677
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1678
correctVariable
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1679
    "notify error and correct if user wants to;
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1680
     return #Error if there was no correction 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1681
     or a ParseNode as returned by variable"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1682
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1683
    |correctIt varName suggestedNames newName pos1 pos2|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1684
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1685
    pos1 := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1686
    varName := tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1687
    pos2 := pos1 + varName size - 1.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1688
    (varName at:1) isLowercase ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1689
        correctIt := self undefError:varName position:pos1 to:pos2.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1690
        correctIt ifFalse:[^ #Error]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1691
    ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1692
        correctIt := self warning:(varName , ' is undefined') position:pos1 to:pos2.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1693
        correctIt ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1694
            ^ PrimaryNode type:#GlobalVariable
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1695
                          name:(varName asSymbol)
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1696
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1697
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1698
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1699
    suggestedNames := self findBestVariableFor:varName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1700
    suggestedNames notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1701
        newName := self askForVariable:'correct variable to: ' fromList:suggestedNames.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1702
        newName isNil ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1703
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1704
        newName := suggestedNames at:1.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1705
        (self confirm:('confirm correction to: ' , newName)) ifFalse:[^ #Error]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1706
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1707
    ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1708
        self notify:'no good correction found'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1709
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1710
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1711
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1712
    "tell requestor about the change"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1713
    requestor replaceSelectionBy:newName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1714
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1715
    "redo parse with new value"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1716
    tokenName := newName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1717
    ^ self variableOrError
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1718
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1719
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1720
askForVariable:aString fromList:aList
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1721
    "launch a selection box, which allows user to enter correction.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1722
     return true for yes, false for no"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1723
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1724
    |box|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1725
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1726
    ListSelectionBox isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1727
        ^ self confirm:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1728
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1729
    box := ListSelectionBox new.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1730
    box title:aString.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1731
    box initialText:(aList at:1).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1732
    box list:aList.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1733
    box okText:'replace'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1734
    box abortText:'abort'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1735
    box action:[:aString | ^ aString].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1736
    box showAtPointer.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1737
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1738
! !