summary refs log tree commit diff stats
path: root/compiler/parser.nim
Commit message (Expand)AuthorAgeFilesLines
* make case-object transitions explicit, make unknownLineInfo a const, replace ...Jasper Jenkins2020-01-171-9/+9
* fixes #10665 (#13141) [backport]Andreas Rumpf2020-01-141-22/+26
* Cosmetic compiler cleanup (#12718)Clyybber2019-11-281-191/+190
* Fix spellings (#12277) [backport]Federico Ceratto2019-09-271-1/+1
* nimpretty: fixes #11616Araq2019-07-181-6/+27
* [refactoring] remove unused imports in the compiler and in some stdlib modulesAraq2019-07-181-1/+1
* styleCheck: make the compiler and large parts of the stdlib compatible with -...Araq2019-07-101-3/+3
* nimpretty: nimpretty now understands splitting newlinesAraq2019-07-041-4/+13
* [bugfix] fix #11469, new rules for a newline in nimpretty (#11512)Miran2019-06-261-0/+2
* [bugfix] nimpretty: fixes #11468Araq2019-06-131-2/+6
* nimpretty: smart tabs support, fixes #9399 [bugfix]Andreas Rumpf2019-06-101-21/+34
* nimpretty: fixes #10295Araq2019-06-071-0/+2
* revert parser stmtListExpr (#11007)cooldome2019-04-171-19/+9
* relax warning about inconsistent spacing (#10968)Miran2019-04-051-1/+1
* fixes #10896 (#10903)Andreas Rumpf2019-03-251-1/+3
* fixes #10861 (#10877)cooldome2019-03-211-2/+3
* REVERT "optPar"Andrii Riabushenko2019-03-211-3/+2
* optParAndrii Riabushenko2019-03-211-2/+3
* Support for stmtListExpr in parser after major keywords. Scaled down version....cooldome2019-03-181-10/+21
* fixes #10838 (#10841)cooldome2019-03-181-0/+2
* Tuple unpacking now works for `for` vars (#10152)Neelesh Chandola2019-02-231-15/+24
* gc: destructors is beginning to work (#10483)Andreas Rumpf2019-01-291-26/+22
* Correct lineinfo for accent quoted symbols in proc definition (#10399)alaviss2019-01-211-1/+4
* Deprecate gc v2 (#10151)Neelesh Chandola2019-01-011-2/+2
* Deprecated pragma is now supported on enum fields (#10113)Neelesh Chandola2018-12-301-11/+21
* Pragma syntax is now consistent (#9993)Neelesh Chandola2018-12-271-3/+34
* much simpler implementation of constant tuple declarationsAndreas Rumpf2018-12-191-37/+17
* Const tuple unpacking (#9964)Neelesh Chandola2018-12-191-9/+31
* nimpretty: explicit --indent option; fixes #9502; refs #9510 [backport]Andreas Rumpf2018-11-111-1/+1
* er... 'a not b' is an infix callAndreas Rumpf2018-11-081-1/+1
* fixes parsing regressions; binary 'not' for 'not nil' must stayAndreas Rumpf2018-11-081-2/+17
* fixes #9633Andreas Rumpf2018-11-081-5/+8
* parser/grammar sync; fixes #9608 [backport]Andreas Rumpf2018-11-071-1/+1
* compiler cleanup: flag tfOldSchoolExprStmt is goneAraq2018-11-061-2/+0
* removed the undocumented #? strongSpaces parsing modeAraq2018-11-061-11/+7
* Maps `out` keyword to an nnkIdent. Fixes #6011. (#9536)Dominik Picheta2018-10-291-2/+1
* nimpretty: add #!nimpretty on/off directivesAndreas Rumpf2018-10-161-2/+2
* nimpretty: fixes #8626Andreas Rumpf2018-10-161-0/+2
* Add checks for except: body blocks (#9191)Dheepak Krishnamurthy2018-10-091-1/+0
* parser.nim: minor code style fixAndreas Rumpf2018-09-161-1/+1
* Merge branch 'devel' into araq-better-docgenAraq2018-09-141-18/+21
|\
| * fixes merge conflictsAndreas Rumpf2018-09-111-157/+234
| |\
| * | steps to get for loops as expressionsAndreas Rumpf2018-02-281-18/+21
* | | compiler refactoring; use typesafe path handing; docgen: render symbols betwe...Andreas Rumpf2018-09-071-3/+4
| |/ |/|
* | Renderer bug fixes (#8804)cooldome2018-09-071-35/+0
* | Cosmetic: fix typo on TRIPLESTR_LIT (#8663)Iván Montes2018-08-211-1/+1
* | WIP: disallow 'nil' for strings and seqsAndreas Rumpf2018-08-131-1/+2
* | Render bug: if expression with statement list expression as condition (#8375)cooldome2018-07-211-0/+1
* | Merge branch 'devel' into typedesc-reformsAndreas Rumpf2018-06-261-3/+25
|\ \
| * | nimpretty improvementsAndreas Rumpf2018-06-191-1/+1
c9313d'>^
92b8fac94 ^
2962ca789 ^










d68181246 ^
2962ca789 ^





d68181246 ^
2962ca789 ^









d68181246 ^
2962ca789 ^
d68181246 ^
2962ca789 ^


1a61c4d46 ^
2962ca789 ^

d68181246 ^
2962ca789 ^








7e747d11c ^
2962ca789 ^

d68181246 ^

2962ca789 ^

d68181246 ^
92b8fac94 ^
2962ca789 ^





d68181246 ^
2962ca789 ^











d68181246 ^
2962ca789 ^



73c6efdf6 ^
2962ca789 ^


d68181246 ^
2962ca789 ^
6b8bd2bbb ^
2962ca789 ^





d68181246 ^
2962ca789 ^
d68181246 ^
2962ca789 ^


d68181246 ^
2962ca789 ^


d68181246 ^
2962ca789 ^







d68181246 ^
2962ca789 ^



73c6efdf6 ^
a5e4d2f7a ^

7e747d11c ^
a5e4d2f7a ^



19b142401 ^
6be9b98e3 ^
7e747d11c ^
6be9b98e3 ^



1db21721e ^


73c6efdf6 ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

 
                            
                                         







                                                             
                                     
 



                         
                                                                  
 
                                                                           

               
               

                                           

                                

                                         
                              

                       
                            
                                                      
                                  
                                                     

                                              
               

                                                                    
               

                                         

                                                         
              

                                                               
                                                           
                                                
                                               
                             

                                           
                                
               
 
                                             
                                                                  
                           










                                                                             
           





                                     
    









                                                             
    
                                   
    


                      
                                                      

                                             
                                                            








                                                                            
                                   

                                                                               

                                                                       

                                                                     
 
                                            





                                                             
 











                                                                 
 



                                                      
                 


                                                                    
         
                                                                       
                                                   





                                                           
 
                  
                      


                                           
 


                                 
 







                                            
 



                                             
                   

                   
                         



                                      
                   
                   
                         



                                   


                                  
                 
#
#
#           The Nim Compiler
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## Simple alias analysis for the HLO and the code generators.

import
  ast, astalgo, types, trees, intsets

type
  TAnalysisResult* = enum
    arNo, arMaybe, arYes

proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult

proc isPartOfAux(n: PNode, b: PType, marker: var IntSet): TAnalysisResult =
  result = arNo
  case n.kind
  of nkRecList:
    for i in 0..<n.len:
      result = isPartOfAux(n[i], b, marker)
      if result == arYes: return
  of nkRecCase:
    assert(n[0].kind == nkSym)
    result = isPartOfAux(n[0], b, marker)
    if result == arYes: return
    for i in 1..<n.len:
      case n[i].kind
      of nkOfBranch, nkElse:
        result = isPartOfAux(lastSon(n[i]), b, marker)
        if result == arYes: return
      else: discard "isPartOfAux(record case branch)"
  of nkSym:
    result = isPartOfAux(n.sym.typ, b, marker)
  else: discard

proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
  result = arNo
  if a == nil or b == nil: return
  if containsOrIncl(marker, a.id): return
  if compareTypes(a, b, dcEqIgnoreDistinct): return arYes
  case a.kind
  of tyObject:
    if a[0] != nil:
      result = isPartOfAux(a[0].skipTypes(skipPtrs), b, marker)
    if result == arNo: result = isPartOfAux(a.n, b, marker)
  of tyGenericInst, tyDistinct, tyAlias, tySink:
    result = isPartOfAux(lastSon(a), b, marker)
  of tyArray, tySet, tyTuple:
    for i in 0..<a.len:
      result = isPartOfAux(a[i], b, marker)
      if result == arYes: return
  else: discard

proc isPartOf(a, b: PType): TAnalysisResult =
  ## checks iff 'a' can be part of 'b'. Iterates over VALUE types!
  var marker = initIntSet()
  # watch out: parameters reversed because I'm too lazy to change the code...
  result = isPartOfAux(b, a, marker)

proc isPartOf*(a, b: PNode): TAnalysisResult =
  ## checks if location `a` can be part of location `b`. We treat seqs and
  ## strings as pointers because the code gen often just passes them as such.
  ##
  ## Note: `a` can only be part of `b`, if `a`'s type can be part of `b`'s
  ## type. Since however type analysis is more expensive, we perform it only
  ## if necessary.
  ##
  ## cases:
  ##
  ## YES-cases:
  ##  x    <| x   # for general trees
  ##  x[]  <| x
  ##  x[i] <| x
  ##  x.f  <| x
  ##
  ## NO-cases:
  ## x           !<| y    # depending on type and symbol kind
  ## x[constA]   !<| x[constB]
  ## x.f         !<| x.g
  ## x.f         !<| y.f  iff x !<= y
  ##
  ## MAYBE-cases:
  ##
  ##  x[] ?<| y[]   iff compatible type
  ##
  ##
  ##  x[]  ?<| y  depending on type
  ##
  if a.kind == b.kind:
    case a.kind
    of nkSym:
      const varKinds = {skVar, skTemp, skProc, skFunc}
      # same symbol: aliasing:
      if a.sym.id == b.sym.id: result = arYes
      elif a.sym.kind in varKinds or b.sym.kind in varKinds:
        # actually, a param could alias a var but we know that cannot happen
        # here. XXX make this more generic
        result = arNo
      else:
        # use expensive type check:
        if isPartOf(a.sym.typ, b.sym.typ) != arNo:
          result = arMaybe
    of nkBracketExpr:
      result = isPartOf(a[0], b[0])
      if a.len >= 2 and b.len >= 2:
        # array accesses:
        if result == arYes and isDeepConstExpr(a[1]) and isDeepConstExpr(b[1]):
          # we know it's the same array and we have 2 constant indexes;
          # if they are
          var x = if a[1].kind == nkHiddenStdConv: a[1][1] else: a[1]
          var y = if b[1].kind == nkHiddenStdConv: b[1][1] else: b[1]

          if sameValue(x, y): result = arYes
          else: result = arNo
        # else: maybe and no are accurate
      else:
        # pointer derefs:
        if result != arYes:
          if isPartOf(a.typ, b.typ) != arNo: result = arMaybe

    of nkDotExpr:
      result = isPartOf(a[0], b[0])
      if result != arNo:
        # if the fields are different, it's not the same location
        if a[1].sym.id != b[1].sym.id:
          result = arNo

    of nkHiddenDeref, nkDerefExpr:
      result = isPartOf(a[0], b[0])
      # weaken because of indirection:
      if result != arYes:
        if isPartOf(a.typ, b.typ) != arNo: result = arMaybe

    of nkHiddenStdConv, nkHiddenSubConv, nkConv:
      result = isPartOf(a[1], b[1])
    of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
      result = isPartOf(a[0], b[0])
    else: discard
    # Calls return a new location, so a default of ``arNo`` is fine.
  else:
    # go down recursively; this is quite demanding:
    const
      Ix0Kinds = {nkDotExpr, nkBracketExpr, nkObjUpConv, nkObjDownConv,
                  nkCheckedFieldExpr, nkHiddenAddr}
      Ix1Kinds = {nkHiddenStdConv, nkHiddenSubConv, nkConv}
      DerefKinds = {nkHiddenDeref, nkDerefExpr}
    case b.kind
    of Ix0Kinds:
      # a* !<| b.f  iff  a* !<| b
      result = isPartOf(a, b[0])

    of DerefKinds:
      # a* !<| b[] iff
      if isPartOf(a.typ, b.typ) != arNo:
        result = isPartOf(a, b[0])
        if result == arNo: result = arMaybe

    of Ix1Kinds:
      # a* !<| T(b)  iff a* !<| b
      result = isPartOf(a, b[1])

    of nkSym:
      # b is an atom, so we have to check a:
      case a.kind
      of Ix0Kinds:
        # a.f !<| b*  iff  a.f !<| b*
        result = isPartOf(a[0], b)
      of Ix1Kinds:
        result = isPartOf(a[1], b)

      of DerefKinds:
        if isPartOf(a.typ, b.typ) != arNo:
          result = isPartOf(a[0], b)
          if result == arNo: result = arMaybe
      else: discard
    of nkObjConstr:
      result = arNo
      for i in 1..<b.len:
        let res = isPartOf(a, b[i][1])
        if res != arNo:
          result = res
          if res == arYes: break
    of nkCallKinds:
      result = arNo
      for i in 1..<b.len:
        let res = isPartOf(a, b[i])
        if res != arNo:
          result = res
          if res == arYes: break
    of nkBracket:
      if b.len > 0:
        result = isPartOf(a, b[0])
    else: discard