Parser.st
author claus
Wed, 30 Mar 1994 12:10:24 +0200
changeset 19 84a1ddf215a5
parent 15 992c3d87edbf
child 20 f8dd8ba75205
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
"
4
f6fd83437415 *** empty log message ***
claus
parents: 3
diff changeset
     2
 COPYRIGHT (c) 1989 by Claus Gittinger
0
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
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    25
                              selfNode superNode 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    26
                              hasPrimitiveCode primitiveNr logged
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    27
                              warnedUndefVars
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    28
                              correctedSource'
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
    29
       classVariableNames:'PrevClass PrevInstVarNames 
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    30
                           PrevClassVarNames PrevClassInstVarNames
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    31
                           LazyCompilation'
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
    32
       poolDictionaries:''
7ad01559b262 Initial revision
claus
parents:
diff changeset
    33
       category:'System-Compiler'
7ad01559b262 Initial revision
claus
parents:
diff changeset
    34
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
    35
7ad01559b262 Initial revision
claus
parents:
diff changeset
    36
Parser comment:'
7ad01559b262 Initial revision
claus
parents:
diff changeset
    37
4
f6fd83437415 *** empty log message ***
claus
parents: 3
diff changeset
    38
COPYRIGHT (c) 1989 by Claus Gittinger
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
    39
             All Rights Reserved
7ad01559b262 Initial revision
claus
parents:
diff changeset
    40
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    41
$Header: /cvs/stx/stx/libcomp/Parser.st,v 1.10 1994-03-30 10:10:24 claus Exp $
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    42
'!
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    43
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    44
!Parser class methodsFor:'documentation'!
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    45
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    46
documentation
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    47
"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    48
    Parser is used for both parsing and evaluating smalltalk expressions;
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    49
    it first builds a parseTree which is then interpreted (evaluate) or
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    50
    compiled. Compilation is done in the subclass ByteCodeCompiler and/or
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    51
    the (planned) MachineCodeCompiler.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    52
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    53
    methods of main interrest are:
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    54
        Parser evaluateExpression:...
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    55
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    56
    and:
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    57
        Parser parseExpression:...
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    58
        Parser parseMethod:...
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    59
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    60
    there is protocol to parse complete methods, selector specs, body only etc.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    61
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    62
    Parser is also used to find the referenced/modified inst/classvars of
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    63
    a method - this is done by sending parseXXX message to a parser and asking
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    64
    the parser for referencedXVars or modifiedXVars (see SystemBrowser).
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    65
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    66
    You can also use parsers for all kinds of other things (ChangesBrowser for
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    67
    example analyzes the expressions in the changelist ...) by looking at the
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    68
    parsers tree. (Although this is somewhat dangerous, since it exports the
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    69
    compilers internals ... better style would be to add specialized query
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    70
     methods here.)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    71
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    72
    One instance of Parser is created to parse one method or expression - i.e.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    73
    its not suggested to reuse parsers.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    74
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    75
    Instance variables:
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    76
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    77
        classToCompileFor   <Class>             the class (or nil) we are compiling for
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    78
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    79
        selfValue           <any>               value to use as self when interpreting
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    80
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    81
        contextToEvaluateIn <Context>           the context (or nil) when interpreting
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    82
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    83
        selector            <Symbol>            the selector of the parsed method
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    84
                                                (valid after parseMethodSpecification)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    85
        methodArgs                              internal
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    86
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    87
        methodArgNames      <Collection>        the names of the arguments
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    88
                                                (valid after parseMethodSpecification)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    89
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    90
        methodVars                              internal
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
    91
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    92
        methodVarNames      <Collection>        the names of the method locals
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    93
                                                (valid after parseMethodBodyVarSpec)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    94
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    95
        tree                <ParseTree>         the parse tree - valid after parsing
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    96
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    97
        currentBlock                            if currently parsing for a block
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    98
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
    99
        usedInstVars                            set of all accessed instances variables
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   100
                                                (valid after parsing)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   101
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   102
        usedClassVars                           same for classVars
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   103
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   104
        usedVars                                all used variables (inst, class & globals)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   105
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   106
        modifiedInstVars                        set of all modified instance variables
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   107
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   108
        modifiedClassVars                       same for clasVars
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   109
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   110
        localVarDefPosition <Integer>           the character offset of the local variable
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   111
                                                def. (i.e. the first '|' if any)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   112
                                                Not yet used - prepared for automatic add of
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   113
                                                undefined variables
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   114
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   115
        evalExitBlock                           internal for interpretation
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   116
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   117
        selfNode            <Node>              cached one-and-only 'self' node
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   118
        superNode           <Node>              cached one-and-only 'super' node
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   119
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   120
        hasPrimitiveCode    <Boolean>           true, if it contains ST/X style primitive code
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   121
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   122
        primitiveNr         <Integer>           the parsed ST-80 type primitive number (or nil)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   123
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   124
        logged
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   125
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   126
        warnedUndefVars     <Set>               set of all variables which the parser has
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   127
                                                already output a warning (to avoid multiple
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   128
                                                warnings about the same variable)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   129
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   130
    Class variables:
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   131
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   132
        PrevClass           <Class>             class, of which properties are
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   133
                                                cached in:
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   134
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   135
        PrevInstVarNames      <Collection>      instance variablenames of cached class
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   136
        PrevClassVarNames     <Collection>      class variablenames of cached class
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   137
        PrevClassInstVarNames <Collection>      class instance variablenames of cached class
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   138
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   139
        LazyCompilation     <Boolean>           EXPERIMENTAL: lazy compilation
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   140
"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   141
! !
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   142
7ad01559b262 Initial revision
claus
parents:
diff changeset
   143
!Parser class methodsFor:'evaluating expressions'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   144
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   145
evaluate:aStringOrStream
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   146
    "return the result of evaluating an expression in aStringOrStream"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   147
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   148
    ^ self 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   149
        evaluate:aStringOrStream 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   150
        in:nil 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   151
        receiver:nil 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   152
        notifying:nil 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   153
        ifFail:nil 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   154
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   155
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   156
     Compiler evaluate:'1 + 2'
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   157
     Compiler evaluate:'''hello world'' asSortedCollection displayString printNL'
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   158
     Compiler evaluate:'''hello world'' asSortedCollection printNL'
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   159
    "
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   160
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   161
7ad01559b262 Initial revision
claus
parents:
diff changeset
   162
evaluate:aStringOrStream notifying:requestor
7ad01559b262 Initial revision
claus
parents:
diff changeset
   163
    "return the result of evaluating aString, 
7ad01559b262 Initial revision
claus
parents:
diff changeset
   164
     errors are reported to requestor"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   165
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   166
    ^ self 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   167
        evaluate:aStringOrStream 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   168
        in:nil 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   169
        receiver:nil 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   170
        notifying:requestor
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   171
        ifFail:nil 
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   172
7ad01559b262 Initial revision
claus
parents:
diff changeset
   173
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   174
7ad01559b262 Initial revision
claus
parents:
diff changeset
   175
evaluate:aString receiver:anObject notifying:requestor
7ad01559b262 Initial revision
claus
parents:
diff changeset
   176
    "return the result of evaluating aString, 
7ad01559b262 Initial revision
claus
parents:
diff changeset
   177
     errors are reported to requestor. Allow access to
7ad01559b262 Initial revision
claus
parents:
diff changeset
   178
     anObject as self and to its instVars (used in the inspector)"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   179
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   180
    ^ self 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   181
        evaluate:aString
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   182
        in:nil
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   183
        receiver:anObject
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   184
        notifying:requestor
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   185
        ifFail:nil
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   186
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   187
7ad01559b262 Initial revision
claus
parents:
diff changeset
   188
evaluate:aStringOrStream in:aContext receiver:anObject 
7ad01559b262 Initial revision
claus
parents:
diff changeset
   189
                                    notifying:requestor
7ad01559b262 Initial revision
claus
parents:
diff changeset
   190
                                       ifFail:failBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
   191
    |parser tree mustBackup|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   192
7ad01559b262 Initial revision
claus
parents:
diff changeset
   193
    aStringOrStream isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   194
    aStringOrStream isStream ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   195
        parser := self for:aStringOrStream.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   196
        mustBackup := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   197
    ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   198
        parser := self for:(ReadStream on:aStringOrStream).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   199
        mustBackup := false
7ad01559b262 Initial revision
claus
parents:
diff changeset
   200
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   201
    parser setSelf:anObject.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   202
    parser setContext:aContext.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   203
    parser notifying:requestor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   204
    parser nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   205
    tree := parser parseMethodBodyOrNil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   206
7ad01559b262 Initial revision
claus
parents:
diff changeset
   207
    "if reading from a stream, backup for next expression"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   208
    mustBackup ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   209
        parser backupPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
   210
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   211
7ad01559b262 Initial revision
claus
parents:
diff changeset
   212
    (parser errorFlag or:[tree == #Error]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   213
        failBlock notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   214
            ^ failBlock value
7ad01559b262 Initial revision
claus
parents:
diff changeset
   215
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   216
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   217
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   218
    tree notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   219
        parser evalExitBlock:[:value | ^ value].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   220
        ^ tree evaluate
7ad01559b262 Initial revision
claus
parents:
diff changeset
   221
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   222
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   223
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   224
7ad01559b262 Initial revision
claus
parents:
diff changeset
   225
!Parser class methodsFor:'instance creation'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   226
7ad01559b262 Initial revision
claus
parents:
diff changeset
   227
for:aStream in:aClass
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   228
    "return a new parser, reading code for aClass from aStream"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   229
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   230
    |parser|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   231
7ad01559b262 Initial revision
claus
parents:
diff changeset
   232
    parser := self for:aStream.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   233
    parser setClassToCompileFor:aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   234
    ^ parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
   235
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   236
7ad01559b262 Initial revision
claus
parents:
diff changeset
   237
!Parser class methodsFor:'parsing'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   238
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   239
selectorInExpression:aString
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   240
    "parse an expression - return the selector. Used for
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   241
     SystemBrowsers implementors/senders query-box initial text"
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   242
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   243
    |tree parser|
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   244
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   245
    (aString isNil or:[aString isEmpty]) ifTrue:[^ nil].
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   246
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   247
    tree := self withSelf:nil parseExpression:aString notifying:nil ignoreErrors:true. 
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   248
    (tree notNil and:[tree ~~ #Error]) ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   249
        tree isAssignment ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   250
            tree expression isMessage ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   251
                tree := tree expression
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   252
            ]
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   253
        ].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   254
9
a855c33612fb *** empty log message ***
claus
parents: 7
diff changeset
   255
        tree isMessage ifTrue:[
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   256
            ^ tree selector
9
a855c33612fb *** empty log message ***
claus
parents: 7
diff changeset
   257
        ].
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   258
    ].
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   259
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   260
    "mhmh, try expression without receiver"
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   261
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   262
    parser := self for:(ReadStream on:aString).
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   263
    parser ignoreErrors.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   264
    parser nextToken.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   265
    ^ parser degeneratedKeywordExpressionForSelector
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   266
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   267
"
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   268
    Parser selectorInExpression:'foo at:1 put:(5 * bar)'
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   269
    Parser selectorInExpression:'(foo at:1) at:1'
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   270
    Parser selectorInExpression:'1 + 4'
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   271
    Parser selectorInExpression:'1 negated'
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   272
    Parser selectorInExpression:'at:1 put:5'
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   273
    Parser selectorInExpression:'a := foo at:1 put:5'
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   274
"
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   275
!
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   276
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   277
parseExpression:aString
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   278
    "parse aString as an expression; return the parseTree, nil or #error"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   279
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   280
    ^ self withSelf:nil parseExpression:aString notifying:nil ignoreErrors:false 
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   281
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   282
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   283
withSelf:anObject parseExpression:aString notifying:someOne 
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   284
    "parse aString as an expression with self set to anObject;
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   285
     return the parseTree, nil or #error"
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   286
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   287
    ^ self withSelf:anObject parseExpression:aString notifying:someOne ignoreErrors:false 
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   288
!
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   289
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   290
withSelf:anObject parseExpression:aString notifying:someOne ignoreErrors:ignore
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   291
    "parse aString as an expression with self set to anObject;
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   292
     return the parseTree, nil or #error"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   293
7ad01559b262 Initial revision
claus
parents:
diff changeset
   294
    |parser tree|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   295
7ad01559b262 Initial revision
claus
parents:
diff changeset
   296
    aString isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   297
    parser := self for:(ReadStream on:aString).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   298
    parser setSelf:anObject.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   299
    parser notifying:someOne.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   300
    ignore ifTrue:[parser ignoreErrors].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   301
    parser nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   302
    tree := parser expression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   303
    (parser errorFlag or:[tree == #Error]) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   304
    ^ tree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   305
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   306
7ad01559b262 Initial revision
claus
parents:
diff changeset
   307
parseMethodSpecification:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
   308
    "parse a methods selector & arg specification; 
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   309
     return the parser, nil or #error"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   310
7ad01559b262 Initial revision
claus
parents:
diff changeset
   311
    ^ self parseMethodSpecification:aString in:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   312
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   313
7ad01559b262 Initial revision
claus
parents:
diff changeset
   314
parseMethodSpecification:aString in:aClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   315
    "parse a methods selector & arg spec for a given class;
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   316
     return the parser, nil or #error"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   317
7ad01559b262 Initial revision
claus
parents:
diff changeset
   318
    |parser tree|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   319
7ad01559b262 Initial revision
claus
parents:
diff changeset
   320
    aString isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   321
    parser := self for:(ReadStream on:aString) in:aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   322
    parser nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   323
    tree := parser parseMethodSpec.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   324
    (parser errorFlag or:[tree == #Error]) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   325
    ^ parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
   326
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   327
7ad01559b262 Initial revision
claus
parents:
diff changeset
   328
parseMethodArgAndVarSpecification:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
   329
    "parse a methods selector, arg and var spec;
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   330
     return the parser, nil or #error"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   331
7ad01559b262 Initial revision
claus
parents:
diff changeset
   332
    ^ self parseMethodArgAndVarSpecification:aString in:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   333
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   334
7ad01559b262 Initial revision
claus
parents:
diff changeset
   335
parseMethodArgAndVarSpecification:aString in:aClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   336
    "parse a methods selector, arg and var spec for a given class;
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   337
     return the parser, nil or #error"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   338
7ad01559b262 Initial revision
claus
parents:
diff changeset
   339
    |parser|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   340
7ad01559b262 Initial revision
claus
parents:
diff changeset
   341
    aString isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   342
    parser := self for:(ReadStream on:aString) in:aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   343
    parser nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   344
    (parser parseMethodSpec == #Error) ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   345
    (parser parseMethodBodyVarSpec == #Error) ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   346
    parser errorFlag ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   347
    ^ parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
   348
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   349
7ad01559b262 Initial revision
claus
parents:
diff changeset
   350
parseMethod:aString
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   351
    "parse a method; return parser, nil or #error"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   352
7ad01559b262 Initial revision
claus
parents:
diff changeset
   353
    ^ self parseMethod:aString in:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   354
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   355
7ad01559b262 Initial revision
claus
parents:
diff changeset
   356
parseMethod:aString in:aClass
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   357
    "parse a method for a given class; return , nil or #error"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   358
7ad01559b262 Initial revision
claus
parents:
diff changeset
   359
    |parser tree|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   360
7ad01559b262 Initial revision
claus
parents:
diff changeset
   361
    aString isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   362
    parser := self for:(ReadStream on:aString) in:aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   363
    tree := parser parseMethod.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   364
    (parser errorFlag or:[tree == #Error]) ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   365
    ^ parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
   366
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   367
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   368
!Parser class methodsFor:'controlling compilation'!
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   369
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   370
compileLazy:aBoolean
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   371
    "turn on/off lazy compilation - return previous setting.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   372
     Actually this flag belongs into the ByteCodeCompiler subclass,
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   373
     but it also controls the reporting of some errors here; therefore
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   374
     its located here"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   375
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   376
    |oldLazy|
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   377
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   378
    oldLazy := LazyCompilation.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   379
    LazyCompilation := aBoolean.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   380
    ^ oldLazy
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   381
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   382
    "Compiler compileLazy:false"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   383
! !
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   384
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   385
!Parser methodsFor:'ST-80 compatibility'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   386
7ad01559b262 Initial revision
claus
parents:
diff changeset
   387
evaluate:aString in:aClass to:to notifying:aRequestor ifFail:failBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
   388
    |parseTree|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   389
7ad01559b262 Initial revision
claus
parents:
diff changeset
   390
    aString isNil ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   391
    self initializeFor:(ReadStream on:aString).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   392
    self setClassToCompileFor:aClass.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   393
    selfValue := nil.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   394
    requestor := aRequestor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   395
7ad01559b262 Initial revision
claus
parents:
diff changeset
   396
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   397
    parseTree := self parseMethodBody.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   398
    (errorFlag or:[tree == #Error]) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   399
    parseTree notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   400
        self evalExitBlock:[:value | ^ failBlock value].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   401
        ^ parseTree evaluate
7ad01559b262 Initial revision
claus
parents:
diff changeset
   402
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   403
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   404
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   405
7ad01559b262 Initial revision
claus
parents:
diff changeset
   406
!Parser class methodsFor:'changes'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   407
7ad01559b262 Initial revision
claus
parents:
diff changeset
   408
update:aClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   409
    "aClass has changed its definition - flush name caches if we have to"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   410
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   411
    (aClass == PrevClass) ifTrue:[
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   412
        PrevClass := nil.
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   413
        PrevInstVarNames := nil.
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   414
        PrevClassVarNames := nil.
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   415
        PrevClassInstVarNames := nil.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   416
        aClass removeDependent:Parser
7ad01559b262 Initial revision
claus
parents:
diff changeset
   417
    ]
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   418
!
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   419
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   420
flush
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   421
    "unconditional flush name caches"
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   422
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   423
    PrevClass notNil ifTrue:[
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   424
        PrevClass removeDependent:Parser
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   425
    ].
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   426
    PrevClass := nil.
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   427
    PrevInstVarNames := nil.
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   428
    PrevClassVarNames := nil.
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   429
    PrevClassInstVarNames := nil.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   430
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   431
    "Parser flush"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   432
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   433
7ad01559b262 Initial revision
claus
parents:
diff changeset
   434
!Parser methodsFor:'setup'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   435
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   436
initialize
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   437
    super initialize.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   438
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   439
    hasPrimitiveCode := false
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   440
!
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   441
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   442
initializeFor:aStringOrStream
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   443
    super initializeFor:aStringOrStream.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   444
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   445
    hasPrimitiveCode := false
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   446
!
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   447
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   448
setClassToCompileFor:aClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
   449
    "set the class to be used for parsing/evaluating"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   450
7ad01559b262 Initial revision
claus
parents:
diff changeset
   451
    classToCompileFor := aClass.
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   452
    (classToCompileFor ~~ PrevClass) ifTrue:[
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   453
        PrevClass notNil ifTrue:[
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   454
            Parser update:PrevClass
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   455
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   456
    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   457
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   458
7ad01559b262 Initial revision
claus
parents:
diff changeset
   459
setSelf:anObject
7ad01559b262 Initial revision
claus
parents:
diff changeset
   460
    "set the value to be used for self while evaluating"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   461
7ad01559b262 Initial revision
claus
parents:
diff changeset
   462
    selfValue := anObject.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   463
    classToCompileFor := anObject class.
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   464
    (classToCompileFor ~~ PrevClass) ifTrue:[
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   465
        PrevClass notNil ifTrue:[
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
   466
            Parser update:PrevClass
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   467
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   468
    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   469
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   470
7ad01559b262 Initial revision
claus
parents:
diff changeset
   471
setContext:aContext
7ad01559b262 Initial revision
claus
parents:
diff changeset
   472
    "set the context used while evaluating"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   473
7ad01559b262 Initial revision
claus
parents:
diff changeset
   474
    contextToEvaluateIn := aContext
7ad01559b262 Initial revision
claus
parents:
diff changeset
   475
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   476
7ad01559b262 Initial revision
claus
parents:
diff changeset
   477
!Parser methodsFor:'accessing'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   478
7ad01559b262 Initial revision
claus
parents:
diff changeset
   479
tree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   480
    "return the parsetree"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   481
7ad01559b262 Initial revision
claus
parents:
diff changeset
   482
    ^tree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   483
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   484
7ad01559b262 Initial revision
claus
parents:
diff changeset
   485
tree:aTree
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   486
    "private: set the tree - for internal use only"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   487
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   488
    tree := aTree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   489
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   490
7ad01559b262 Initial revision
claus
parents:
diff changeset
   491
selector
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   492
    "return the selector (valid after parsing spec)"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   493
7ad01559b262 Initial revision
claus
parents:
diff changeset
   494
    ^ selector
7ad01559b262 Initial revision
claus
parents:
diff changeset
   495
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   496
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   497
correctedSource
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   498
    ^ correctedSource
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   499
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   500
7ad01559b262 Initial revision
claus
parents:
diff changeset
   501
numberOfMethodArgs
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   502
    "return the number of methodargs (valid after parsing spec)"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   503
7ad01559b262 Initial revision
claus
parents:
diff changeset
   504
    ^ methodArgs size
7ad01559b262 Initial revision
claus
parents:
diff changeset
   505
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   506
7ad01559b262 Initial revision
claus
parents:
diff changeset
   507
methodArgs
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   508
    "return an array with methodarg names (valid after parsing spec)"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   509
7ad01559b262 Initial revision
claus
parents:
diff changeset
   510
    ^ methodArgNames
7ad01559b262 Initial revision
claus
parents:
diff changeset
   511
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   512
7ad01559b262 Initial revision
claus
parents:
diff changeset
   513
numberOfMethodVars
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   514
    "return the number of method variables (valid after parsing)"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   515
7ad01559b262 Initial revision
claus
parents:
diff changeset
   516
    ^ methodVars size
7ad01559b262 Initial revision
claus
parents:
diff changeset
   517
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   518
7ad01559b262 Initial revision
claus
parents:
diff changeset
   519
methodVars
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   520
    "return a collection with method variablenames (valid after parsing)"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   521
7ad01559b262 Initial revision
claus
parents:
diff changeset
   522
    ^ methodVarNames
7ad01559b262 Initial revision
claus
parents:
diff changeset
   523
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   524
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   525
usedVars
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   526
    "return a collection with variablenames refd by method (valid after parsing)"
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   527
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   528
    ^ usedVars
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   529
!
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   530
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   531
usedInstVars
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   532
    "return a collection with instvariablenames refd by method (valid after parsing)"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   533
7ad01559b262 Initial revision
claus
parents:
diff changeset
   534
    ^ usedInstVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   535
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   536
7ad01559b262 Initial revision
claus
parents:
diff changeset
   537
usedClassVars
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   538
    "return a collection with classvariablenames refd by method (valid after parsing)"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   539
7ad01559b262 Initial revision
claus
parents:
diff changeset
   540
    ^ usedClassVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   541
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   542
7ad01559b262 Initial revision
claus
parents:
diff changeset
   543
modifiedInstVars
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   544
    "return a collection with instvariablenames modified by method (valid after parsing)"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   545
7ad01559b262 Initial revision
claus
parents:
diff changeset
   546
    ^ modifiedInstVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   547
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   548
7ad01559b262 Initial revision
claus
parents:
diff changeset
   549
modifiedClassVars
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   550
    "return a collection with classvariablenames modified by method (valid after parsing)"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   551
7ad01559b262 Initial revision
claus
parents:
diff changeset
   552
    ^ modifiedClassVars
7ad01559b262 Initial revision
claus
parents:
diff changeset
   553
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   554
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   555
primitiveNumber
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   556
    "return the ST-80 style primitiveNumber or nil (valid after parsing)"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   557
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   558
    ^ primitiveNr
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   559
!
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   560
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   561
hasPrimitiveCode
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   562
    "return true if there was any ST/X style primitive code (valid after parsing)"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   563
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   564
    ^ hasPrimitiveCode
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   565
!
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   566
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   567
errorFlag
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   568
    "return true if there where any errors (valid after parsing)"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   569
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   570
    ^ errorFlag
7ad01559b262 Initial revision
claus
parents:
diff changeset
   571
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   572
7ad01559b262 Initial revision
claus
parents:
diff changeset
   573
evalExitBlock:aBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
   574
    "when evaluating a return expression, this block is evaluated"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   575
7ad01559b262 Initial revision
claus
parents:
diff changeset
   576
    evalExitBlock := aBlock
7ad01559b262 Initial revision
claus
parents:
diff changeset
   577
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   578
7ad01559b262 Initial revision
claus
parents:
diff changeset
   579
!Parser methodsFor:'error handling'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   580
7ad01559b262 Initial revision
claus
parents:
diff changeset
   581
showErrorMessage:aMessage position:pos
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   582
    "redefined since parser can give more detailed info about
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   583
     the class & selector where the error occured."
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   584
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   585
    ignoreErrors ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   586
        Smalltalk silentLoading == true ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   587
            Transcript show:(pos printString).
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   588
            Transcript show:' '.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   589
            selector notNil ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   590
                Transcript show:aMessage.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   591
                classToCompileFor notNil ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   592
                    Transcript showCr:(' in ' , classToCompileFor name , '>>' , selector)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   593
                ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   594
                    Transcript showCr:(' in ' , selector)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   595
                ]
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   596
            ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   597
                classToCompileFor notNil ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   598
                    Transcript showCr:aMessage , ' (' , classToCompileFor name , ')'
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   599
                ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   600
                    Transcript showCr:aMessage
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   601
                ]
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   602
            ]
11
60691e5007e3 *** empty log message ***
claus
parents: 10
diff changeset
   603
        ]
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   604
    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   605
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   606
7ad01559b262 Initial revision
claus
parents:
diff changeset
   607
parseError:aMessage position:position to:endPos
7ad01559b262 Initial revision
claus
parents:
diff changeset
   608
    "report a syntax error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   609
7ad01559b262 Initial revision
claus
parents:
diff changeset
   610
    |m|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   611
7ad01559b262 Initial revision
claus
parents:
diff changeset
   612
    errorFlag := true.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   613
    m := ' Error:' , aMessage.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   614
    self notifyError:m position:position to:endPos.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   615
    exitBlock notNil ifTrue:[exitBlock value].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   616
    ^ false
7ad01559b262 Initial revision
claus
parents:
diff changeset
   617
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   618
7ad01559b262 Initial revision
claus
parents:
diff changeset
   619
parseError:aMessage position:position
7ad01559b262 Initial revision
claus
parents:
diff changeset
   620
    "report a syntax error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   621
7ad01559b262 Initial revision
claus
parents:
diff changeset
   622
    ^ self parseError:aMessage position:position to:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   623
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   624
7ad01559b262 Initial revision
claus
parents:
diff changeset
   625
parseError:aMessage
7ad01559b262 Initial revision
claus
parents:
diff changeset
   626
    "report a syntax error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   627
7ad01559b262 Initial revision
claus
parents:
diff changeset
   628
    ^ self parseError:aMessage position:tokenPosition to:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   629
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   630
7ad01559b262 Initial revision
claus
parents:
diff changeset
   631
correctableError:message position:pos1 to:pos2
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   632
    "report an error which can be corrected by compiler -
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   633
     return true if correction is wanted"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   634
7ad01559b262 Initial revision
claus
parents:
diff changeset
   635
    |correctIt|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   636
7ad01559b262 Initial revision
claus
parents:
diff changeset
   637
    requestor isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   638
        self showErrorMessage:message position:pos1.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   639
        correctIt := false
7ad01559b262 Initial revision
claus
parents:
diff changeset
   640
    ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   641
        correctIt := requestor correctableError:message position:pos1 to:pos2
7ad01559b262 Initial revision
claus
parents:
diff changeset
   642
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   643
    correctIt ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   644
        exitBlock notNil ifTrue:[exitBlock value]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   645
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   646
    ^ correctIt
7ad01559b262 Initial revision
claus
parents:
diff changeset
   647
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   648
7ad01559b262 Initial revision
claus
parents:
diff changeset
   649
undefError:aName position:pos1 to:pos2
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   650
    "report an undefined variable error - return true, if it should be
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   651
     corrected"
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   652
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   653
    requestor isNil ifTrue:[
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   654
        warnedUndefVars notNil ifTrue:[
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   655
            (warnedUndefVars includes:aName) ifTrue:[
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   656
                "already warned about this one"
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   657
                ^ false
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   658
            ].
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   659
        ].
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   660
        self showErrorMessage:('Error: ' , aName , ' is undefined') position:pos1.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   661
        warnedUndefVars isNil ifTrue:[
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   662
            warnedUndefVars := Set new.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   663
        ].
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   664
        warnedUndefVars add:aName.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   665
        ^ false
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
   666
    ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   667
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   668
    ^ self correctableError:('Error: ' , aName , ' is undefined') position:pos1 to:pos2
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   669
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   670
7ad01559b262 Initial revision
claus
parents:
diff changeset
   671
exitWith:something
7ad01559b262 Initial revision
claus
parents:
diff changeset
   672
    "this is the longjump out of evaluation via a return expression"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   673
7ad01559b262 Initial revision
claus
parents:
diff changeset
   674
    evalExitBlock value:something
7ad01559b262 Initial revision
claus
parents:
diff changeset
   675
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
   676
7ad01559b262 Initial revision
claus
parents:
diff changeset
   677
!Parser methodsFor:'parsing'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   678
7ad01559b262 Initial revision
claus
parents:
diff changeset
   679
parseMethod
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   680
    "parse a method.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   681
     Return the parseTree or #Error.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   682
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   683
     method ::= methodSpec methodBody
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   684
    "
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   685
7ad01559b262 Initial revision
claus
parents:
diff changeset
   686
    |parseTree|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   687
7ad01559b262 Initial revision
claus
parents:
diff changeset
   688
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   689
    (self parseMethodSpec == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   690
    parseTree := self parseMethodBody.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   691
    (parseTree == #Error) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   692
        self tree:parseTree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   693
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   694
    ^ parseTree
7ad01559b262 Initial revision
claus
parents:
diff changeset
   695
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   696
7ad01559b262 Initial revision
claus
parents:
diff changeset
   697
parseMethodSpec
7ad01559b262 Initial revision
claus
parents:
diff changeset
   698
    "parse a methods selector & arg specification;
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   699
     Set selector and methodArgs in the receiver as a side effect.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   700
     Return the receiver or #Error.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   701
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   702
     methodSpec ::= { KEYWORD IDENTIFIER }
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   703
                    | binaryOperator IDENTIFIER
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   704
                    | IDENTIFIER
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   705
    "
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   706
7ad01559b262 Initial revision
claus
parents:
diff changeset
   707
    |var|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   708
7ad01559b262 Initial revision
claus
parents:
diff changeset
   709
    (tokenType == #Keyword) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   710
        selector := ''.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   711
        [tokenType == #Keyword] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   712
            selector := selector , tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   713
            self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   714
            (tokenType ~~ #Identifier) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   715
            var := Variable name:tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   716
            methodArgs isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   717
                methodArgs := Array with:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   718
                methodArgNames := Array with:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   719
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   720
                methodArgs := methodArgs copyWith:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   721
                methodArgNames := methodArgNames copyWith:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   722
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   723
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
   724
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   725
        selector := selector asSymbol.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   726
        ^ self
7ad01559b262 Initial revision
claus
parents:
diff changeset
   727
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   728
    (tokenType == #Identifier) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   729
        selector := tokenName asSymbol.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   730
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   731
        ^ self
7ad01559b262 Initial revision
claus
parents:
diff changeset
   732
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   733
    (tokenType == #BinaryOperator) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   734
        selector := tokenName asSymbol.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   735
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   736
        (tokenType ~~ #Identifier) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   737
        var := Variable name:tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   738
        methodArgs isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   739
            methodArgs := Array with:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   740
            methodArgNames := Array with:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   741
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   742
            methodArgs := methodArgs copyWith:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   743
            methodArgNames := methodArgNames copyWith:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   744
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   745
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   746
        ^ self
7ad01559b262 Initial revision
claus
parents:
diff changeset
   747
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   748
    ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   749
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   750
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   751
parseMethodBody
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   752
    "parse a methods body (locals & statements). 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   753
     No more tokens may follow.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   754
     Return a node-tree, or #Error
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   755
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   756
     methodBody ::= '<' st80Primitive '>' #EOF
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   757
                    | '<' st80Primitive '>' methodBodyVarSpec statementList #EOF
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   758
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   759
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   760
    |stats|
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   761
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   762
    stats := self parseMethodBodyOrNil.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   763
    (stats == #Error) ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   764
        (tokenType ~~ #EOF) ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   765
            self parseError:(tokenType printString , ' unexpected').
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   766
            ^#Error
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   767
        ]
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   768
    ].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   769
    ^ stats
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   770
!
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   771
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   772
parseMethodBodyOrNil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   773
    "parse a methods body (locals & statements);
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   774
     return  a node-tree, nil or #Error. 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   775
     empty (or comment only) input is accepted and returns nil.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   776
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   777
     methodBodyOrNil ::= '<' st80Primitive '>'
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   778
                         | '<' st80Primitive '>' methodBodyVarSpec statementList
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   779
                         | <empty>
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   780
    "
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   781
7ad01559b262 Initial revision
claus
parents:
diff changeset
   782
    |stats|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   783
7ad01559b262 Initial revision
claus
parents:
diff changeset
   784
    ((tokenType == #BinaryOperator) and:[tokenName = '<']) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   785
        "an ST-80 primitive - parsed but ignored"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   786
        self nextToken.
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   787
        primitiveNr := self parseST80Primitive.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   788
        (primitiveNr == #Error) ifTrue:[^ #Error].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   789
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   790
        self warning:'ST-80 primitives not supported - ignored'
7ad01559b262 Initial revision
claus
parents:
diff changeset
   791
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   792
7ad01559b262 Initial revision
claus
parents:
diff changeset
   793
    (self parseMethodBodyVarSpec == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   794
7ad01559b262 Initial revision
claus
parents:
diff changeset
   795
    (tokenType ~~ #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   796
        stats := self statementList
7ad01559b262 Initial revision
claus
parents:
diff changeset
   797
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   798
    ^ stats
7ad01559b262 Initial revision
claus
parents:
diff changeset
   799
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   800
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   801
parseMethodBodyVarSpec
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   802
    "parse a methods local variable specification. 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   803
     Leave spec of locals in methodLocals as a side effect.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   804
     Return #Error or nil.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   805
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   806
     methodBodyVarSpec ::= '|' { IDENTIFIER } '|'
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   807
                            | <empty>
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   808
    "
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   809
7ad01559b262 Initial revision
claus
parents:
diff changeset
   810
    |var|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   811
7ad01559b262 Initial revision
claus
parents:
diff changeset
   812
    (tokenType == $|) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   813
        "memorize position for declaration in correction"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   814
        localVarDefPosition := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   815
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   816
        [tokenType == #Identifier] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   817
            var := Variable name:tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   818
            methodVars isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   819
                methodVars := Array with:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   820
                methodVarNames := Array with:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   821
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   822
                methodVars := methodVars copyWith:var.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   823
                methodVarNames := methodVarNames copyWith:tokenName
7ad01559b262 Initial revision
claus
parents:
diff changeset
   824
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   825
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
   826
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   827
        (tokenType ~~ $|) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   828
            self syntaxError:'error in local var specification; | expected.'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   829
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   830
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   831
        self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
   832
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   833
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
   834
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   835
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   836
parseST80Primitive
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
   837
    "parse an ST-80 type primitive as '< primitive: nr >';
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   838
     return primitive number or #Error.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   839
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   840
     st80Primitive ::= 'primitive:' INTEGER
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   841
    "
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   842
7ad01559b262 Initial revision
claus
parents:
diff changeset
   843
    |primNumber|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   844
7ad01559b262 Initial revision
claus
parents:
diff changeset
   845
    ((tokenType == #Keyword) and:[tokenName = 'primitive:']) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   846
        self parseError:'bad primitive definition (primitive: expected)'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   847
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   848
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   849
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   850
    (tokenType == #Integer) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   851
        self parseError:'primitive number expected'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   852
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   853
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   854
    primNumber := tokenValue.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   855
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   856
    ((tokenType == #BinaryOperator) and:[tokenName = '>']) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   857
        self parseError:'bad primitive definition (> expected)'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   858
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   859
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   860
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   861
    ^ primNumber
7ad01559b262 Initial revision
claus
parents:
diff changeset
   862
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   863
7ad01559b262 Initial revision
claus
parents:
diff changeset
   864
statementList
7ad01559b262 Initial revision
claus
parents:
diff changeset
   865
    "parse a statementlist; return a node-tree, nil or #Error.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   866
     Statements must be separated by periods."
7ad01559b262 Initial revision
claus
parents:
diff changeset
   867
7ad01559b262 Initial revision
claus
parents:
diff changeset
   868
    |thisStatement prevStatement firstStatement correctIt periodPos|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   869
7ad01559b262 Initial revision
claus
parents:
diff changeset
   870
    thisStatement := self statement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   871
    (thisStatement == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   872
    firstStatement := thisStatement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   873
    [tokenType == $.] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   874
        periodPos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   875
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   876
        (tokenType == $]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   877
            currentBlock isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   878
                self parseError:'block nesting error'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   879
                errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   880
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   881
            *** I had a warning here (since it was not defined
7ad01559b262 Initial revision
claus
parents:
diff changeset
   882
            *** in the blue-book; but PD-code contains a lot of
7ad01559b262 Initial revision
claus
parents:
diff changeset
   883
            *** code with periods at the end so that the warnings
7ad01559b262 Initial revision
claus
parents:
diff changeset
   884
            *** became annoying
7ad01559b262 Initial revision
claus
parents:
diff changeset
   885
7ad01559b262 Initial revision
claus
parents:
diff changeset
   886
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   887
                self warning:'period after last statement' position:periodPos
7ad01559b262 Initial revision
claus
parents:
diff changeset
   888
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   889
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   890
            ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   891
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   892
        (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   893
            currentBlock notNil ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   894
                self parseError:'block nesting error (expected '']'')'.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   895
                errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   896
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   897
            *** I had a warning here (since it was not defined
7ad01559b262 Initial revision
claus
parents:
diff changeset
   898
            *** in the blue-book; but PD-code contains a lot of
7ad01559b262 Initial revision
claus
parents:
diff changeset
   899
            *** code with periods at the end so that the warnings
7ad01559b262 Initial revision
claus
parents:
diff changeset
   900
            *** became annoying
7ad01559b262 Initial revision
claus
parents:
diff changeset
   901
7ad01559b262 Initial revision
claus
parents:
diff changeset
   902
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   903
                self warning:'period after last statement' position:periodPos
7ad01559b262 Initial revision
claus
parents:
diff changeset
   904
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   905
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   906
            ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   907
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   908
7ad01559b262 Initial revision
claus
parents:
diff changeset
   909
        prevStatement := thisStatement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   910
        (prevStatement isKindOf:ReturnNode) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   911
            self warning:'statements after return' position:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
   912
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   913
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   914
        periodPos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   915
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   916
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   917
7ad01559b262 Initial revision
claus
parents:
diff changeset
   918
        ((tokenType == $]) or:[tokenType == #EOF]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   919
            (currentBlock isNil and:[tokenType == $]]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   920
                self parseError:'block nesting error'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   921
                errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   922
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   923
                correctIt := self correctableError:'period after last statement in block'
7ad01559b262 Initial revision
claus
parents:
diff changeset
   924
                                          position:periodPos to:(periodPos + 1).
7ad01559b262 Initial revision
claus
parents:
diff changeset
   925
                correctIt ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   926
                    (self correctByDeleting == #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   927
                        errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
   928
                    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   929
                ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   930
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   931
            ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   932
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   933
        thisStatement := self statement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   934
        (thisStatement == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   935
        prevStatement nextStatement:thisStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   936
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   937
    ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
   938
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   939
7ad01559b262 Initial revision
claus
parents:
diff changeset
   940
statement
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   941
    "parse a statement; return a node-tree or #Error.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   942
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   943
     statement ::= '^' expression
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   944
                   | PRIMITIVECODE
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   945
                   | expression
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   946
    "
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   947
7ad01559b262 Initial revision
claus
parents:
diff changeset
   948
    |expr node|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   949
7ad01559b262 Initial revision
claus
parents:
diff changeset
   950
    (tokenType == $^) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   951
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   952
        expr := self expression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   953
        (expr == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   954
        node := ReturnNode expression:expr.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   955
        node home:self blockHome:currentBlock.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   956
        ^ node
7ad01559b262 Initial revision
claus
parents:
diff changeset
   957
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   958
    (tokenType == #Primitive) ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   959
"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   960
        self parseError:'cannot compile primitives (yet)'.
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   961
"
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   962
        self nextToken.
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   963
        hasPrimitiveCode := true.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   964
        ^ PrimitiveNode code:''
7ad01559b262 Initial revision
claus
parents:
diff changeset
   965
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   966
    (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   967
        self syntaxError:'period after last statement'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
   968
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
   969
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   970
    expr := self expression.
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
   971
    (expr == #Error) ifTrue:[^ #Error].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   972
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   973
    classToCompileFor notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   974
        currentBlock isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   975
            (expr isKindOf:PrimaryNode) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
   976
                self warning:'useless computation - missing ^ ?'
7ad01559b262 Initial revision
claus
parents:
diff changeset
   977
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   978
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
   979
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
   980
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
   981
    ^ StatementNode expression:expr
7ad01559b262 Initial revision
claus
parents:
diff changeset
   982
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
   983
7ad01559b262 Initial revision
claus
parents:
diff changeset
   984
expression
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   985
    "parse a cascade-expression; return a node-tree, nil or #Error.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   986
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   987
     expression ::= keywordExpression
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   988
                    | keywordExpression cascade
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   989
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   990
     cascade ::= ';' expressionSendPart
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   991
                 | cascade ';' expressionSendPart
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   992
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   993
     expressionSendPart ::= { KEYWORD binaryExpression }
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   994
                            | BINARYOPERATOR unaryExpression
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   995
                            | IDENTIFIER
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
   996
    "
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
   997
7ad01559b262 Initial revision
claus
parents:
diff changeset
   998
    |receiver arg sel args pos pos2|
7ad01559b262 Initial revision
claus
parents:
diff changeset
   999
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1000
    pos := tokenPosition.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1001
    receiver := self keywordExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1002
    (receiver == #Error) ifTrue:[^ #Error].
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1003
    (tokenType == $;) ifTrue:[
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1004
        [tokenType == $;] whileTrue:[
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1005
            receiver isMessage ifFalse:[
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1006
                self syntaxError:'left side of cascade must be a message expression'
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1007
                        position:pos to:tokenPosition
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1008
            ].
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1009
            self nextToken.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1010
            (tokenType == #Identifier) ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1011
                sel := self selectorCheck:tokenName for:receiver position:tokenPosition to:(tokenPosition + tokenName size - 1).
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1012
                receiver := CascadeNode receiver:receiver selector:sel.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1013
                self nextToken
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1014
            ] ifFalse:[
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1015
                (tokenType == #BinaryOperator) ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1016
                    sel := self selectorCheck:tokenName for:receiver position:tokenPosition to:(tokenPosition + tokenName size - 1).
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1017
                    self nextToken.
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1018
                    arg := self unaryExpression.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1019
                    (arg == #Error) ifTrue:[^ #Error].
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1020
                    receiver := CascadeNode receiver:receiver selector:sel arg:arg
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1021
                ] ifFalse:[
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1022
                    (tokenType == #Keyword) ifTrue:[
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1023
                        pos := tokenPosition.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1024
                        sel := tokenName.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1025
                        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1026
                        arg := self binaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1027
                        (arg == #Error) ifTrue:[^ #Error].
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1028
                        args := Array with:arg.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1029
                        [tokenType == #Keyword] whileTrue:[
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1030
                            sel := sel , tokenName.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1031
                            self nextToken.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1032
                            arg := self binaryExpression.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1033
                            (arg == #Error) ifTrue:[^ #Error].
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1034
                            args := args copyWith:arg.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1035
                            pos2 := tokenPosition
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1036
                        ].
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1037
                        sel := self selectorCheck:sel for:receiver position:pos to:pos2.
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1038
                        receiver := CascadeNode receiver:receiver selector:sel args:args
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1039
                    ] ifFalse:[
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1040
                        (tokenType == #Error) ifTrue:[^ #Error].
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1041
                        self syntaxError:('invalid cascade; ' , tokenType printString , ' unexpected')
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1042
                                position:tokenPosition to:source position - 1.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1043
                        ^ #Error
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1044
                    ]
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1045
                ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1046
            ]
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1047
        ].
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1048
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1049
        "obscure (uspecified ?) if selector follows; Question:
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1050
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1051
        is
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1052
                'expr sel1; sel2 sel3'
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1053
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1054
        to be parsed as: 
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1055
                (t := expr.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1056
                 t sel1.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1057
                 t sel2) sel3
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1058
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1059
         or:
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1060
                (t := expr.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1061
                 t sel1.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1062
                 t sel2 sel3)
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1063
        "
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1064
        ((tokenType == #Identifier) 
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1065
         or:[(tokenType == #BinaryOperator)
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1066
             or:[tokenType == #Keyword]]) ifTrue:[
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1067
            self syntaxError:'ambigous cascade - please group using ( ...)'
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1068
                    position:tokenPosition to:source position - 1.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1069
            ^ #Error
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1070
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1071
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1072
    ^ receiver
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1073
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1074
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1075
keywordExpression
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1076
    "parse a keyword-expression; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1077
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1078
    |receiver sel arg args pos1 pos2 try lno note|
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1079
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1080
    receiver := self binaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1081
    (receiver == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1082
    (tokenType == #Keyword) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1083
        pos1 := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1084
        sel := tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1085
        lno := tokenLineNr.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1086
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1087
        arg := self binaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1088
        (arg == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1089
        args := Array with:arg.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1090
        [tokenType == #Keyword] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1091
            sel := sel , tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1092
            self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1093
            arg := self binaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1094
            (arg == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1095
            args := args copyWith:arg.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1096
            pos2 := tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1097
        ].
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1098
        sel := self selectorCheck:sel for:receiver position:pos1 to:pos2.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1099
        try := MessageNode receiver:receiver selector:sel args:args.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1100
        (try isMemberOf:String) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1101
            self parseError:try position:pos1 to:pos2.
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1102
            receiver := MessageNode receiver:receiver selector:sel args:args fold:false
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1103
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1104
            receiver := try
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1105
        ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1106
        note := receiver plausibilityCheck.
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1107
        note notNil ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1108
            self warning:note position:pos1 to:pos2
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1109
        ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1110
        receiver lineNumber:lno
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1111
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1112
    ^ receiver
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1113
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1114
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1115
degeneratedKeywordExpressionForSelector
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1116
    "parse a keyword-expression without receiver - for the selector
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1117
     only. return the selector or nil"
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1118
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1119
    |sel arg|
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1120
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1121
    (tokenType == #Keyword) ifTrue:[
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1122
        sel := tokenName.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1123
        self nextToken.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1124
        arg := self binaryExpression.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1125
        (arg == #Error) ifTrue:[^ sel].
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1126
        [tokenType == #Keyword] whileTrue:[
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1127
            sel := sel , tokenName.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1128
            self nextToken.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1129
            arg := self binaryExpression.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1130
            (arg == #Error) ifTrue:[^ sel].
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1131
        ].
9
a855c33612fb *** empty log message ***
claus
parents: 7
diff changeset
  1132
        ^ sel
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1133
    ].
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1134
    ^ nil
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1135
!
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1136
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1137
binaryExpression
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1138
    "parse a binary-expression; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1139
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1140
    |receiver arg sel pos try lno note|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1141
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1142
    receiver := self unaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1143
    (receiver == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1144
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1145
    "special kludge: since Scanner cannot know if -digit is a binary
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1146
     expression or a negative constant, handle cases here"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1147
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1148
    [(tokenType == #BinaryOperator) or:[(tokenType == $|)
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1149
     or:[(tokenType == #Integer) and:[tokenValue < 0]]]] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1150
        pos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1151
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1152
        lno := tokenLineNr.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1153
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1154
        "kludge here: bar and minus are not scanned as binop "
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1155
        (tokenType == $|) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1156
            sel := '|'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1157
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1158
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1159
            (tokenType == #BinaryOperator) ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1160
                sel := self selectorCheck:tokenName for:receiver position:tokenPosition to:(tokenPosition + tokenName size - 1).
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1161
                self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1162
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1163
                sel := '-'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1164
                tokenValue := tokenValue negated
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1165
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1166
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1167
        arg := self unaryExpression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1168
        (arg == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1169
        try := BinaryNode receiver:receiver selector:sel arg:arg.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1170
        (try isMemberOf:String) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1171
            self parseError:try position:pos to:tokenPosition.
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1172
            receiver := BinaryNode receiver:receiver selector:sel arg:arg fold:false
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1173
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1174
            receiver := try
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1175
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1176
        note := receiver plausibilityCheck.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1177
        note notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1178
            self warning:note position:pos to:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1179
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1180
        receiver lineNumber:lno
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1181
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1182
    ^ receiver
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1183
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1184
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1185
unaryExpression
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1186
    "parse a unary-expression; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1187
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1188
    |receiver sel pos pos2 try|
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1189
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1190
    receiver := self primary.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1191
    (receiver == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1192
    [tokenType == #Identifier] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1193
        pos := tokenPosition.
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1194
        pos2 := pos + tokenName size - 1.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1195
        sel := self selectorCheck:tokenName for:receiver position:pos to:pos2.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1196
        try := UnaryNode receiver:receiver selector:sel.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1197
        (try isMemberOf:String) ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1198
            self warning:try position:pos to:pos2.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1199
            receiver := UnaryNode receiver:receiver selector:sel fold:false
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1200
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1201
            receiver := try
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1202
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1203
        receiver lineNumber:tokenLineNr.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1204
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1205
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1206
    ^ receiver
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1207
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1208
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1209
primary
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1210
    "parse a primary-expression; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1211
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1212
    |val var expr pos name|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1213
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1214
    pos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1215
    (tokenType == #Identifier) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1216
        var := self variable.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1217
        (var == #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1218
            errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1219
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1220
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1221
        (tokenType == $_) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1222
            ^ var
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1223
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1224
        (var ~~ #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1225
            (var type == #MethodArg) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1226
                self parseError:'assignment to method argument' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1227
                errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1228
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1229
            (var type == #BlockArg) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1230
                self parseError:'assignment to block argument' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1231
                errorFlag := true
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1232
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1233
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1234
            (var type == #InstanceVariable) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1235
                modifiedInstVars isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1236
                    modifiedInstVars := OrderedCollection new
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1237
                ].
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1238
                name := PrevInstVarNames at:(var index).
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1239
                (modifiedInstVars includes:name) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1240
                    modifiedInstVars add:name
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1241
                ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1242
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1243
                (var type == #ClassVariable) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1244
                    modifiedClassVars isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1245
                        modifiedClassVars := OrderedCollection new
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1246
                    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1247
                    name := var name.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1248
                    name := name copyFrom:((name indexOf:$:) + 1).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1249
                    (modifiedClassVars includes:name) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1250
                        modifiedClassVars add:name
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1251
                    ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1252
                ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1253
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1254
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1255
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1256
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1257
        expr := self expression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1258
        (errorFlag or:[expr == #Error]) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1259
        ^ AssignmentNode variable:var expression:expr
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1260
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1261
    ((tokenType == #Integer) or:
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1262
     [(tokenType == #Character) or:
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1263
      [tokenType == #Float]]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1264
        val := ConstantNode type:tokenType value:tokenValue.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1265
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1266
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1267
            self parseError:'assignment to a constant' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1268
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1269
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1270
        ^ val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1271
    ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1272
    (tokenType == #Self) ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1273
        self nextToken.
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1274
        (tokenType == $_) ifTrue:[
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1275
            self parseError:'assignment to self' position:pos to:tokenPosition.
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1276
            ^ #Error
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1277
        ].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1278
        selfNode isNil ifTrue:[
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1279
            selfNode := SelfNode value:selfValue
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1280
        ].
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1281
        ^ selfNode
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1282
    ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1283
    (tokenType == #String) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1284
        val := ConstantNode type:tokenType value:tokenValue.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1285
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1286
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1287
            self parseError:'assignment to a constant' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1288
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1289
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1290
        ^ val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1291
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1292
    (tokenType == #Symbol) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1293
        val := ConstantNode type:tokenType value:tokenValue.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1294
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1295
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1296
            self parseError:'assignment to a constant' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1297
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1298
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1299
        ^ val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1300
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1301
    (tokenType == #Nil) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1302
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1303
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1304
            self parseError:'assignment to nil' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1305
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1306
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1307
        ^ ConstantNode type:#Nil value:nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1308
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1309
    (tokenType == #True) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1310
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1311
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1312
            self parseError:'assignment to true' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1313
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1314
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1315
        ^ ConstantNode type:#True value:true
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1316
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1317
    (tokenType == #False) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1318
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1319
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1320
            self parseError:'assignment to false' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1321
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1322
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1323
        ^ ConstantNode type:#False value:false
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1324
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1325
    (tokenType  == #Super) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1326
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1327
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1328
            self parseError:'assignment to super' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1329
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1330
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1331
        superNode isNil ifTrue:[
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1332
            superNode := SuperNode value:selfValue inClass:classToCompileFor
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1333
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1334
        ^ superNode
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1335
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1336
    (tokenType == #ThisContext) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1337
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1338
        (tokenType == $_) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1339
            self parseError:'assignment to thisContext' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1340
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1341
        ].
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1342
        ^ VariableNode type:#ThisContext
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1343
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1344
    (tokenType == #HashLeftParen) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1345
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1346
        val := self array.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1347
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1348
        ^ ConstantNode type:#Array value:val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1349
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1350
    (tokenType == #HashLeftBrack) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1351
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1352
        val := self byteArray.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1353
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1354
        ^ ConstantNode type:#Array value:val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1355
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1356
    (tokenType == $() ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1357
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1358
        val := self expression.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1359
        (val == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1360
        (tokenType ~~ $) ) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1361
            (tokenType isMemberOf:Character) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1362
                self syntaxError:'missing '')'' (i.e. ''' , tokenType asString , ''' unexpected)' withCRs position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1363
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1364
                self syntaxError:'missing '')''' position:pos to:tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1365
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1366
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1367
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1368
        self nextToken.
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1369
        val parenthized:true.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1370
        ^ val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1371
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1372
    (tokenType == $[ ) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1373
        val := self block.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1374
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1375
        ^ val
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1376
    ].
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1377
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1378
    (tokenType == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1379
    (tokenType isKindOf:Character) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1380
        self syntaxError:('error in primary; ' 
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1381
                           , tokenType printString , 
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1382
                           ' unexpected') position:tokenPosition to:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1383
    ] ifFalse:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1384
        (#(BinaryOperator Keyword) includes:tokenType) ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1385
            self syntaxError:('error in primary; ' 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1386
                               , tokenType printString , '(' , tokenName , ') ' ,
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1387
                               ' unexpected')
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1388
        ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1389
            self syntaxError:('error in primary; ' 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1390
                               , tokenType printString ,
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1391
                               ' unexpected') 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1392
        ]
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1393
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1394
    ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1395
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1396
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1397
variableOrError
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1398
    "parse a variable; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1399
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1400
    |var instIndex aClass searchBlock args vars
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1401
     varName tokenSymbol className|
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1402
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1403
    varName := tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1404
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1405
    "is it a block-arg or block-var ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1406
    searchBlock := currentBlock.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1407
    [searchBlock notNil] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1408
        args := searchBlock arguments.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1409
        args notNil ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1410
            instIndex := args findFirst:[:aBlockArg | aBlockArg name = varName].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1411
            instIndex ~~ 0 ifTrue:[
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1412
                ^ VariableNode type:#BlockArg
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1413
                               name:varName
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1414
                              token:(args at:instIndex)
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1415
                              index:instIndex
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1416
                              block:searchBlock
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1417
            ].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1418
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1419
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1420
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1421
        vars := searchBlock variables.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1422
        vars notNil ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1423
            instIndex := vars findFirst:[:aBlockVar | aBlockVar name = varName].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1424
            instIndex ~~ 0 ifTrue:[
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1425
                ^ VariableNode type:#BlockVariable
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1426
                               name:varName
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1427
                              token:(vars at:instIndex)
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1428
                              index:instIndex
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1429
                              block:searchBlock
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1430
            ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1431
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1432
        searchBlock := searchBlock home
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1433
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1434
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1435
    "is it a method-variable ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1436
    methodVars notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1437
        instIndex := methodVarNames indexOf:varName.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1438
        instIndex ~~ 0 ifTrue:[
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1439
            var := methodVars at:instIndex.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1440
            var used:true.
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1441
            ^ VariableNode type:#MethodVariable
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1442
                           name:varName
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1443
                          token:var
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1444
                          index:instIndex
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1445
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1446
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1447
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1448
    "is it a method-argument ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1449
    methodArgs notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1450
        instIndex := methodArgNames indexOf:varName.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1451
        instIndex ~~ 0 ifTrue:[
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1452
            ^ VariableNode type:#MethodArg
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1453
                           name:varName
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1454
                          token:(methodArgs at:instIndex)
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1455
                          index:instIndex
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1456
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1457
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1458
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1459
    "is it an instance-variable ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1460
    classToCompileFor notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1461
        "caching allInstVarNames for next compilation saves time ..."
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1462
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1463
        (PrevInstVarNames isNil or:[PrevClass ~~ classToCompileFor]) ifTrue:[
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1464
            PrevClass notNil ifTrue:[
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1465
                PrevClass removeDependent:Parser
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1466
            ].
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1467
            PrevClass := classToCompileFor.
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1468
            PrevInstVarNames := classToCompileFor allInstVarNames.
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1469
            PrevClassInstVarNames := nil.
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1470
            PrevClassVarNames := nil.
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1471
            PrevClass addDependent:Parser
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1472
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1473
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1474
        instIndex := PrevInstVarNames indexOf:varName startingAt:1.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1475
        instIndex ~~ 0 ifTrue:[
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1476
            usedInstVars isNil ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1477
                usedInstVars := OrderedCollection with:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1478
            ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1479
                (usedInstVars includes:varName) ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1480
                    usedInstVars add:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1481
                ]
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1482
            ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1483
            usedVars isNil ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1484
                usedVars := OrderedCollection with:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1485
            ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1486
                (usedVars includes:varName) ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1487
                    usedVars add:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1488
                ]
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1489
            ].
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1490
            ^ VariableNode type:#InstanceVariable 
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1491
                           name:varName
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1492
                          index:instIndex
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1493
                      selfValue:selfValue
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1494
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1495
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1496
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1497
    "is it a class-instance-variable ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1498
    classToCompileFor notNil ifTrue:[
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1499
        PrevClassInstVarNames isNil ifTrue:[
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1500
            PrevClassInstVarNames := classToCompileFor class allInstVarNames
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1501
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1502
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1503
        instIndex := PrevClassInstVarNames indexOf:varName startingAt:1.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1504
        instIndex ~~ 0 ifTrue:[
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1505
            aClass := self inWhichClassIsClassInstVar:varName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1506
            aClass notNil ifTrue:[
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1507
                usedVars isNil ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1508
                    usedVars := OrderedCollection with:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1509
                ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1510
                    (usedVars includes:varName) ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1511
                        usedVars add:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1512
                    ]
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1513
                ].
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1514
                ^ VariableNode type:#ClassInstanceVariable
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1515
                               name:varName
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1516
                              index:instIndex
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1517
                          selfClass:aClass
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1518
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1519
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1520
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1521
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1522
    "is it a class-variable ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1523
    classToCompileFor notNil ifTrue:[
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1524
        PrevClassVarNames isNil ifTrue:[
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1525
            aClass := classToCompileFor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1526
            classToCompileFor isMeta ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1527
                className := aClass name.
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1528
                className := className copyTo:(className size - 5).
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1529
                aClass := Smalltalk at:(className asSymbol).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1530
                aClass isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1531
                    aClass := classToCompileFor
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1532
                ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1533
            ].
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1534
            PrevClassVarNames := aClass allClassVarNames
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1535
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1536
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1537
        instIndex := PrevClassVarNames indexOf:varName startingAt:1.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1538
        instIndex ~~ 0 ifTrue:[
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1539
            aClass := self inWhichClassIsClassVar:varName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1540
            aClass notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1541
                usedClassVars isNil ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1542
                    usedClassVars := OrderedCollection with:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1543
                ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1544
                    (usedClassVars includes:varName) ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1545
                        usedClassVars add:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1546
                    ].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1547
                ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1548
                usedVars isNil ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1549
                    usedVars := OrderedCollection with:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1550
                ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1551
                    (usedVars includes:varName) ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1552
                        usedVars add:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1553
                    ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1554
                ].
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1555
                ^ VariableNode type:#ClassVariable 
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1556
                               name:(aClass name , ':' , varName) asSymbol
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1557
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1558
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1559
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1560
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1561
    "is it a global-variable ?"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1562
    tokenSymbol := varName asSymbol.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1563
    (Smalltalk includesKey:tokenSymbol) ifTrue:[
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1564
        usedVars isNil ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1565
            usedVars := OrderedCollection with:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1566
        ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1567
            (usedVars includes:varName) ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1568
                usedVars add:varName
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1569
            ]
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1570
        ].
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1571
        ^ VariableNode type:#GlobalVariable name:tokenSymbol
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1572
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1573
    ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1574
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1575
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1576
variable
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1577
    "parse a variable; if undefined, notify error and correct if user wants to"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1578
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1579
    |v|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1580
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1581
    v := self variableOrError.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1582
    (v == #Error) ifFalse:[^ v].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1583
    v := self correctVariable.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1584
    (v == #Error) ifFalse:[^ v].
13
30e69e21d1d1 *** empty log message ***
claus
parents: 11
diff changeset
  1585
    ^ VariableNode type:#GlobalVariable name:tokenName asSymbol
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1586
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1587
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1588
inWhichClassIsClassVar:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1589
    "search class-chain for the classvariable named aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1590
     - return the class or nil if not found"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1591
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1592
    |aClass className baseClass|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1593
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1594
    aClass := classToCompileFor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1595
    aClass isMeta ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1596
        className := aClass name.
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1597
        className := className copyTo:(className size - 5).
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1598
        baseClass := Smalltalk at:(className asSymbol).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1599
        baseClass notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1600
            aClass := baseClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1601
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1602
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1603
    [aClass notNil] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1604
        (aClass classVarNames includes:aString) ifTrue:[ ^ aClass].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1605
        aClass := aClass superclass
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1606
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1607
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1608
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1609
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1610
inWhichClassIsClassInstVar:aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1611
    "search class-chain for the class-instance variable named aString
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1612
     - return the class or nil if not found"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1613
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1614
    |aClass|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1615
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1616
    aClass := classToCompileFor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1617
    [aClass notNil] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1618
        (aClass class instVarNames includes:aString) ifTrue:[ ^ aClass].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1619
        aClass := aClass superclass
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1620
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1621
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1622
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1623
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1624
block
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1625
    "parse a block; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1626
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1627
    |stats node args var vars pos lno b|
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1628
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1629
    lno := tokenLineNr.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1630
    self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1631
    (tokenType == $: ) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1632
        [tokenType == $:] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1633
            pos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1634
            self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1635
            (tokenType == #Identifier) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1636
                self syntaxError:'Identifier expected in block-arg declaration'
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1637
                        position:pos to:tokenPosition-1.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1638
                ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1639
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1640
            var := Variable name:tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1641
            args isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1642
                args := Array with:var
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1643
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1644
                args := args copyWith:var
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1645
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1646
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1647
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1648
        (tokenType ~~ $| ) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1649
            "ST-80 allows [:arg ]"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1650
            (tokenType == $] ) ifTrue:[
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1651
                b := BlockNode arguments:args home:currentBlock variables:nil.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1652
                b lineNumber:lno.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1653
                ^ b
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1654
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1655
            self syntaxError:'| expected after block-arg declaration'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1656
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1657
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1658
        self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1659
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1660
    (tokenType == $| ) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1661
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1662
        pos := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1663
        [tokenType == $|] whileFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1664
            (tokenType == #Identifier) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1665
                self syntaxError:'Identifier expected in block-var declaration' position:pos.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1666
                ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1667
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1668
            var := Variable name:tokenName.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1669
            vars isNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1670
                vars := Array with:var
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1671
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1672
                vars := vars copyWith:var
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1673
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1674
            self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1675
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1676
        self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1677
    ].
3
b63b8a6b71fb *** empty log message ***
claus
parents: 0
diff changeset
  1678
    node := BlockNode arguments:args home:currentBlock variables:vars.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1679
    node lineNumber:lno.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1680
    currentBlock := node.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1681
    stats := self blockStatementList.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1682
    node statements:stats.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1683
    currentBlock := node home.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1684
    (stats == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1685
    ^ node
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1686
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1687
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1688
blockStatementList
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1689
    "parse a blocks statementlist; return a node-tree, nil or #Error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1690
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1691
    |thisStatement prevStatement firstStatement|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1692
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1693
    (tokenType == $] ) ifTrue:[^ nil].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1694
    thisStatement := self statement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1695
    (thisStatement == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1696
    firstStatement := thisStatement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1697
    [tokenType == $] ] whileFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1698
        (tokenType == $.) ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1699
            (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1700
                self syntaxError:'missing '']'' in block'
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1701
            ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1702
                self syntaxError:'missing ''.'' in block'
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1703
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1704
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1705
        ] ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1706
            prevStatement := thisStatement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1707
            self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1708
            tokenType == $] ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1709
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1710
                *** I had a warning here (since it was not defined
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1711
                *** in the blue-book; but PD-code contains a lot of
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1712
                *** code with periods at the end so that the warnings
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1713
                *** became annoying
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1714
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1715
                self warning:'period after last statement in block'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1716
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1717
                ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1718
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1719
            thisStatement := self statement.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1720
            (thisStatement == #Error) ifTrue:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1721
            prevStatement nextStatement:thisStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1722
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1723
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1724
    ^ firstStatement
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1725
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1726
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1727
array
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1728
    |arr elem pos1|
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1729
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1730
    pos1 := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1731
    arr := OrderedCollection new:200.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1732
    [tokenType ~~ $) ] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1733
        elem := self arrayConstant.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1734
        (elem == #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1735
            (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1736
                self syntaxError:'unterminated array-constant; '')'' expected' 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1737
                        position:pos1 to:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1738
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1739
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1740
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1741
        arr add:elem.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1742
        self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1743
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1744
    ^ Array withAll:arr
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1745
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1746
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1747
byteArray
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1748
    "started with ST-80 R4 - allow byteArray constants as #[ ... ]"
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1749
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1750
    |arr elem pos1 pos2|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1751
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1752
    pos1 := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1753
    arr := OrderedCollection new.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1754
    [tokenType ~~ $] ] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1755
        pos2 := tokenPosition.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1756
        elem := self arrayConstant.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1757
        (elem == #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1758
            (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1759
                self syntaxError:'unterminated bytearray-constant; '']'' expected' 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1760
                        position:pos1 to:tokenPosition
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1761
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1762
            ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1763
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1764
        ((elem isMemberOf:SmallInteger) and:
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1765
        [(elem >= 0) and:[elem <= 255]]) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1766
            arr add:elem
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1767
        ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1768
            self parseError:'invalid ByteArray element' position:pos2 to:tokenPosition - 1
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1769
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1770
        self nextToken
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1771
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1772
    ^ ByteArray withAll:arr
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1773
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1774
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1775
arrayConstant
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1776
    (tokenType == #String) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1777
        ^ tokenValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1778
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1779
    (tokenType == #Nil) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1780
        ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1781
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1782
    (tokenType == #Integer) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1783
        ^ tokenValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1784
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1785
    (tokenType == #Character) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1786
        ^ tokenValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1787
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1788
    (tokenType == #Float) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1789
        ^ tokenValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1790
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1791
    (tokenType == #True) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1792
        ^ true
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1793
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1794
    (tokenType == #False) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1795
        ^ false
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1796
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1797
    (tokenType == #Error) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1798
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1799
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1800
    (tokenType == #BinaryOperator) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1801
        ^ tokenName asSymbol
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1802
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1803
    (tokenType == #Keyword) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1804
        ^ tokenName asSymbol
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1805
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1806
    (tokenType == #Identifier) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1807
        ^ tokenName asSymbol
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1808
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1809
    (tokenType == $() ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1810
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1811
        ^ self array
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1812
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1813
    (tokenType == $[) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1814
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1815
        ^ self byteArray
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1816
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1817
    (tokenType == #Symbol) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1818
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1819
        self warning:'no # for symbols within array-constants'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1820
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1821
        ^ tokenValue
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1822
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1823
    (tokenType == #HashLeftParen) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1824
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1825
        self warning:'no # for arrays within array-constants'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1826
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1827
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1828
        ^ self array
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1829
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1830
    (tokenType == #HashLeftBrack) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1831
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1832
        self warning:'no # for arrays within array-constants'.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1833
"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1834
        self nextToken.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1835
        ^ self byteArray
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1836
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1837
    (tokenType == #EOF) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1838
        "just for the better error-hilight; let caller handle error"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1839
        ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1840
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1841
    self syntaxError:('error in array-constant; ' 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1842
                      , tokenType printString 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1843
                      , ' unexpected').
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1844
    ^ #Error
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1845
! !
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1846
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1847
!Parser methodsFor:'error correction'!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1848
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1849
correctByDeleting
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1850
    "correct (by deleting token) if user wants to;
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1851
     return #Error if there was no correction;
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1852
     nil if there was one." 
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1853
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1854
    (self confirm:'confirm deleting') ifFalse:[^ #Error].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1855
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1856
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1857
     tell requestor (i.e. CodeView) about the change
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1858
     this will update what the requestor shows.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1859
    "
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1860
    requestor deleteSelection.
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1861
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1862
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1863
     get the updated source-string 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1864
     which is needed, when we eventually install the new method
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1865
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1866
    correctedSource := requestor currentSourceCode.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1867
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1868
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1869
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1870
findBestVariablesFor:aString
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1871
    "collect known variables with their spelling distances to aString;
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1872
     return the 10 best suggestions"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1873
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1874
    |names dists searchBlock args vars globalVarName aClass className baseClass n|
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1875
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1876
    names := OrderedCollection new.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1877
    dists := OrderedCollection new.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1878
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1879
    "block arguments"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1880
    searchBlock := currentBlock.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1881
    [searchBlock notNil] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1882
        args := searchBlock arguments.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1883
        args notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1884
            args do:[:aBlockArg |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1885
                names add:(aBlockArg name).
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1886
                dists add:(aString spellAgainst: "levenshteinTo:"(aBlockArg name))
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1887
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1888
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1889
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1890
        vars := searchBlock variables.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1891
        vars notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1892
            vars do:[:aBlockVar |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1893
                names add:(aBlockVar name).
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1894
                dists add:(aString spellAgainst: "levenshteinTo:"(aBlockVar name))
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1895
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1896
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1897
        searchBlock := searchBlock home
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1898
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1899
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1900
    "method-variables"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1901
    methodVars notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1902
        methodVarNames do:[:methodVarName |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1903
            names add:methodVarName.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1904
            dists add:(aString spellAgainst: "levenshteinTo:"methodVarName)
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1905
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1906
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1907
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1908
    "method-arguments"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1909
    methodArgs notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1910
        methodArgNames do:[:methodArgName |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1911
            names add:methodArgName.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1912
            dists add:(aString spellAgainst: "levenshteinTo:"methodArgName)
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1913
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1914
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1915
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1916
    "instance-variables"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1917
    classToCompileFor notNil ifTrue:[
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1918
        PrevInstVarNames do:[:instVarName |
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1919
            names add:instVarName.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1920
            dists add:(aString spellAgainst: "levenshteinTo:"instVarName)
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1921
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1922
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1923
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1924
    "class-variables"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1925
    classToCompileFor notNil ifTrue:[
10
73e97b6175c4 *** empty log message ***
claus
parents: 9
diff changeset
  1926
        PrevClassVarNames do:[:classVarName |
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1927
            names add:classVarName.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1928
            dists add:(aString spellAgainst: "levenshteinTo:"classVarName)
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1929
        ].
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1930
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1931
false ifTrue:[
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1932
        aClass := classToCompileFor.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1933
        aClass isMeta ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1934
            className := aClass name.
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1935
            className := className copyTo:(className size - 5).
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1936
            baseClass := Smalltalk at:(className asSymbol).
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1937
            baseClass notNil ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1938
                aClass := baseClass
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1939
            ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1940
        ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1941
        [aClass notNil] whileTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1942
            (aClass classVarNames) do:[:classVarName |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1943
                names add:classVarName.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1944
                dists add:(aString spellAgainst: "levenshteinTo:"classVarName)
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1945
            ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1946
            aClass := aClass superclass
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1947
        ]
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1948
].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1949
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1950
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1951
    "globals"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1952
    Smalltalk allKeysDo:[:aKey |
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1953
        globalVarName := aKey asString.
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1954
        "only compare strings where length is about right"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1955
        ((globalVarName size - aString size) abs < 3) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1956
            names add:globalVarName.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1957
            dists add:(aString spellAgainst: "levenshteinTo:"globalVarName)
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1958
        ]
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1959
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1960
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1961
    "misc"
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1962
    #('self' 'super' 'nil' 'thisContext') do:[:name |
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1963
        names add:name.
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1964
        dists add:(aString spellAgainst: "levenshteinTo:"name)
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1965
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1966
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1967
    (dists size ~~ 0) ifTrue:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1968
        dists sortWith:names.
7
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1969
        dists := dists reverse.             
6c2bc76f0b8f *** empty log message ***
claus
parents: 4
diff changeset
  1970
        names := names reverse.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1971
        n := names size min:10.
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  1972
        ^ names copyTo:n
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1973
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1974
    ^ nil
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1975
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  1976
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1977
correctVariable
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1978
    "notify error and correct if user wants to;
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1979
     return #Error if there was no correction 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1980
     or a ParseNode as returned by variable"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1981
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1982
    |correctIt varName suggestedNames newName pos1 pos2|
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1983
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1984
    pos1 := tokenPosition.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1985
    varName := tokenName.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1986
    pos2 := pos1 + varName size - 1.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1987
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1988
"OLD:
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1989
    (varName at:1) isLowercase ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1990
        correctIt := self undefError:varName position:pos1 to:pos2.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1991
        correctIt ifFalse:[^ #Error]
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1992
    ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1993
        correctIt := self warning:(varName , ' is undefined') position:pos1 to:pos2.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1994
        correctIt ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1995
            ^ VariableNode type:#GlobalVariable name:(varName asSymbol)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1996
        ]
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1997
    ].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1998
"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  1999
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2000
    correctIt := self undefError:varName position:pos1 to:pos2.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2001
    correctIt ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2002
        (varName at:1) isLowercase ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2003
            ^ #Error
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2004
        ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2005
            ^ VariableNode type:#GlobalVariable name:(varName asSymbol)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2006
        ]
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2007
    ].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2008
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2009
    suggestedNames := self findBestVariablesFor:varName.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2010
    suggestedNames notNil ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2011
        newName := self askForCorrection:'correct variable to: ' fromList:suggestedNames.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2012
        newName isNil ifTrue:[^ #Error].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2013
"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2014
        newName := suggestedNames at:1.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2015
        (self confirm:('confirm correction to: ' , newName)) ifFalse:[^ #Error]
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2016
"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2017
    ] ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2018
        self notify:'no good correction found'.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2019
        ^ #Error
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2020
    ].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2021
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2022
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2023
     tell requestor (i.e. CodeView) about the change
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2024
     this will update what the requestor shows.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2025
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2026
    requestor replaceSelectionBy:newName.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2027
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2028
     get the updated source-string 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2029
     which is needed, when we eventually install the new method
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2030
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2031
    correctedSource := requestor currentSourceCode.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2032
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2033
    "redo parse with new value"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2034
    tokenName := newName.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2035
    ^ self variableOrError
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2036
!
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2037
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2038
askForCorrection:aString fromList:aList
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2039
    "launch a selection box, which allows user to enter correction.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2040
     return true for yes, false for no"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2041
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2042
    |box|
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2043
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2044
    ListSelectionBox isNil ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2045
        ^ self confirm:aString
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2046
    ].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2047
    box := ListSelectionBox new.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2048
    box title:aString.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2049
    box initialText:(aList at:1).
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2050
    box list:aList.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2051
    box okText:'correct'.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2052
    "box abortText:'abort'."
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2053
    box action:[:aString | ^ aString].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2054
    box showAtPointer.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2055
    ^ nil
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2056
!
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2057
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2058
findBestSelectorsFor:aString
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2059
    "collect known selectors with their spelling distances to aString;
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2060
     return the 10 best suggestions"
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2061
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2062
    |info n|
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2063
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2064
    info := SortedCollection new.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2065
    info sortBlock:[:a :b | a value > b value].
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2066
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2067
    n := 0.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2068
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2069
    Symbol allInstancesDo:[:sym |
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2070
        |dist|
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2071
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2072
        dist := aString spellAgainst:sym.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2073
        dist > 20 ifTrue:[
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2074
            info add:(sym -> dist).
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2075
            n := n + 1.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2076
            n > 10 ifTrue:[
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2077
                info removeLast.
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2078
            ]
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2079
        ]
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2080
    ].
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2081
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2082
    ^ info asOrderedCollection collect:[:a | a key]
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2083
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2084
    "Time millisecondsToRun:[Parser new findBestSelectorsFor:'foo']"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2085
    "Parser new findBestSelectorsFor:'findBestSel'"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2086
    "Parser new findBestSelectorsFor:'fildBestSelectrFr'"
15
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2087
!
992c3d87edbf *** empty log message ***
claus
parents: 13
diff changeset
  2088
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2089
correctSelector:aSelectorString message:msg position:pos1 to:pos2
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2090
    "notify error and correct if user wants to;
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2091
     return #Error if there was no correction 
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2092
     or a ParseNode as returned by variable"
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2093
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2094
    |correctIt suggestedNames newSelector l c|
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2095
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2096
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2097
     sorry, but I cannot handle keywords with more than one-part
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2098
     currently (too much work - maybe Ill do it later when everything else works :-)
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2099
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2100
    (aSelectorString occurrencesOf:$:) > 1 ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2101
        self warning:msg position:pos1 to:pos2.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2102
        ^ aSelectorString
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2103
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2104
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2105
    correctIt := self correctableError:msg position:pos1 to:pos2.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2106
    correctIt ifFalse:[^ aSelectorString].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2107
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2108
    suggestedNames := self findBestSelectorsFor:aSelectorString.
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2109
    suggestedNames notNil ifTrue:[
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2110
        newSelector := self askForCorrection:'correct selector to: ' fromList:suggestedNames.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2111
        newSelector isNil ifTrue:[^ aSelectorString].
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2112
    ] ifFalse:[
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2113
        self notify:'no good correction found'.
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2114
        ^ aSelectorString
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2115
    ].
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2116
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2117
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2118
     tell requestor (i.e. CodeView) about the change
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2119
     this will update what the requestor shows.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2120
    "
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2121
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2122
    requestor replaceSelectionBy:newSelector keepCursor:false.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2123
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2124
     get the updated source-string 
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2125
     which is needed, when we eventually install the new method
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2126
    "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2127
    correctedSource := requestor currentSourceCode.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2128
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2129
    ^ newSelector
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2130
!
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2131
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2132
selectorCheck:aSelectorString for:receiver position:pos1 to:pos2
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2133
    "just a quick check: if the selector is totally unknown
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2134
     as a symbol, it cannot possibly be understood.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2135
     Simple, but catches many typos"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2136
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2137
    |ok err|
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2138
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2139
    (LazyCompilation == true) ifFalse:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2140
        ok := aSelectorString knownAsSymbol.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2141
        err := ' is currently nowhere implemented'.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2142
        ok ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2143
            (receiver notNil and:[receiver isConstant]) ifTrue:[
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2144
                ok := receiver evaluate respondsTo:(aSelectorString asSymbol).
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2145
                err := ' will not be understood here'.
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2146
            ]
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2147
        ].
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2148
        ok ifFalse:[
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2149
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2150
"OLD: "
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2151
            self warning:(aSelectorString , err) position:pos1 to:pos2
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2152
" "   
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2153
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2154
"NEW:    - not finished - need more interfaces
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2155
   (currently produces warning output on Transcript while filing in
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2156
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2157
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2158
            ^ self correctSelector:aSelectorString message:(aSelectorString , err) position:pos1 to:pos2
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2159
"
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2160
        ]
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2161
    ].
19
84a1ddf215a5 *** empty log message ***
claus
parents: 15
diff changeset
  2162
    ^ aSelectorString
0
7ad01559b262 Initial revision
claus
parents:
diff changeset
  2163
! !