summary refs log tree commit diff stats
path: root/compiler/parser.nim
Commit message (Expand)AuthorAgeFilesLines
* 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
| * | nimpretty: fixes pragma renderingAndreas Rumpf2018-06-171-1/+1
| * | nimpretty: more featuresAndreas Rumpf2018-06-161-2/+24
* | | Implement the `is` operator for the new static and typedesc type classesZahary Karadjov2018-06-161-2/+1
078834dfb6f0ac337a5278'>226595515 ^
5920edf6e ^



12a0f88a5 ^




20b011de1 ^
12a0f88a5 ^



5920edf6e ^

12a0f88a5 ^

5920edf6e ^
f514be077 ^
7e747d11c ^
7dd787b8a ^


8e08ff559 ^
226595515 ^
d59e9c37f ^



20b011de1 ^
226595515 ^
d59e9c37f ^









bfd2fd67f ^

7e747d11c ^
bfd2fd67f ^

7e747d11c ^
bfd2fd67f ^
ec253ada7 ^
bf592c4e9 ^
ec253ada7 ^
226595515 ^
17cace280 ^

20b011de1 ^
7e747d11c ^
17cace280 ^
a8af664e8 ^
17cace280 ^




7e747d11c ^



17cace280 ^




226595515 ^
02be027e9 ^
ad608838b ^



131027969 ^
8e08ff559 ^
bc179ccc3 ^
20b011de1 ^
ad608838b ^


8e08ff559 ^
85ffcd80c ^





eed443d4b ^

7e747d11c ^

c65a5d754 ^
85ffcd80c ^
eed443d4b ^
f514be077 ^
eed443d4b ^


7e747d11c ^

eed443d4b ^
7e747d11c ^

eed443d4b ^

ec253ada7 ^



7e747d11c ^

ec253ada7 ^

226595515 ^
3f5ababfe ^


7e747d11c ^

3f5ababfe ^

7e747d11c ^

3f5ababfe ^
7e747d11c ^

3f5ababfe ^
7e747d11c ^
3f5ababfe ^


226595515 ^
3f5ababfe ^

83dabb69a ^
8e08ff559 ^

226595515 ^
20b011de1 ^
226595515 ^

8e08ff559 ^
5334dc921 ^


b92fd3028 ^
c65a5d754 ^
7e747d11c ^
424e87fd0 ^

7e747d11c ^
85ffcd80c ^
83dabb69a ^
8e08ff559 ^
226595515 ^

bd19b5f4d ^
20b011de1 ^
226595515 ^


59f61bae0 ^
b92fd3028 ^
c65a5d754 ^
7e747d11c ^

bd19b5f4d ^
59f61bae0 ^
9db369063 ^
8e08ff559 ^
226595515 ^
8e08ff559 ^
7e747d11c ^

8e08ff559 ^

226595515 ^
3f5ababfe ^

e51e98997 ^
3f5ababfe ^





db603237c ^
3f5ababfe ^




131027969 ^
7e747d11c ^
3f5ababfe ^
7e747d11c ^

3f5ababfe ^

9db369063 ^
8e08ff559 ^

e51e98997 ^
2de99653d ^
d2dbcf2fa ^
40ec7be45 ^
d2dbcf2fa ^

c12c41c7a ^
d2dbcf2fa ^
db603237c ^
d2dbcf2fa ^
3a13706d7 ^
7014d0c5c ^
9673e4f2d ^
7014d0c5c ^
131027969 ^
7e747d11c ^
8e08ff559 ^
7e747d11c ^

8e08ff559 ^

7014d0c5c ^

7014d0c5c ^


226595515 ^
7014d0c5c ^
e51e98997 ^
7014d0c5c ^
3a13706d7 ^
7014d0c5c ^
f514be077 ^
417b9f5a1 ^
226595515 ^
417b9f5a1 ^
8e08ff559 ^


226595515 ^
8e08ff559 ^
7e747d11c ^
02be027e9 ^
8e08ff559 ^

a3e27ffa2 ^

e51e98997 ^
417b9f5a1 ^

ee14ace5d ^
796aafe7e ^
b0a98cc01 ^

ee14ace5d ^
131027969 ^
8e08ff559 ^
ee14ace5d ^
8e08ff559 ^

ee14ace5d ^
8e08ff559 ^

94f54700c ^
7e747d11c ^
94f54700c ^
e51e98997 ^
8e08ff559 ^
131027969 ^
417b9f5a1 ^
131027969 ^
417b9f5a1 ^
131027969 ^
e6c5622aa ^
afbcd1b33 ^
417b9f5a1 ^

131027969 ^
7e747d11c ^

417b9f5a1 ^
62ab33890 ^

afbcd1b33 ^
62ab33890 ^


7e747d11c ^

62ab33890 ^
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370

 
                            
                                         









                                                          

                                                                          
 


                                   
                                            
                                                              
              
 
                                                                 
                              
                                                                                                      

                                                                                                            

                                                                           
                     

                                                                  

                                        

                                                                           
                  
 
                                
                                              



                                      
 






                                              
                                         
                                       

                
 
                                             
                                           

                
 
                                                             


                                                

                                                                  
 
                                                                                             



                                       




                                     
                                                                  



                                                      

                                            

                               
               
 
                       


                                              
 
                                                                                      



                                                                                         
                                                                
                                                        









                                               

                                                    
                          

                                        
                
 
                                                
                                                                    
 
                                                                                   

                                                                               
                                                                                             
                     
                                 
                            




                                              



                                      




                                              
                                                                                                      
                                          



                              
                                                        
                                      
                                                                                                      
                                                    


                      
 





                                           

                                            

                             
                                  
              
 
                                                                        


                                           

                                              
                                    

                              

                        



                                                

                              

                        
                                                 


               

                                       

                              

                                     
                            

                       
                            
                                                  


                                
                                                                                              

               
                                                                                  

                                                                            
                                                                     
                                                       

                                                                      
               


                                                 
                          
                          
                            

                                                                
                             
              
                
 

                                                                                                        
                   
                                                                              


                                                                        
                 
                            
                            

                               
                  
 
                                       
                                        
                                                 
                               

                              

                        
                                                                   

                                           
                                                       





                                           
                   




                             
                     
             
                                    

                              

                        
                                                                                      

                                           
                                                       
                                           
                 
                             

                             
                                   
                          
                   
                      
                             
                   
                     
                    
                     
             
                                    

                              

                        

                                                


                             
                                          
                           
                   
                      
                             
 
                                                                 
                           
                                            
 


                                                          
                                                                        
                                      
               
                                                    

                             

                                                    
                                                               

              
                                                   
                                                        

                                                                            
                                 
                                             
                
                                                              

                              
                                   

                                   
                           
                                      
                                  
                                   
 
                                                                            
                                     
                                         
 
                                                
                                                   
                                                                                            

                                        
                                             

                                                                 
 

                                                   
                                                                                                


                                             

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

## This module implements common simple lowerings.

const
  genPrefix* = ":tmp"         # prefix for generated names

import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs,
  lineinfos

when defined(nimPreviewSlimSystem):
  import std/assertions

proc newDeref*(n: PNode): PNode {.inline.} =
  result = newNodeIT(nkHiddenDeref, n.info, n.typ.elementType)
  result.add n

proc newTupleAccess*(g: ModuleGraph; tup: PNode, i: int): PNode =
  if tup.kind == nkHiddenAddr:
    result = newNodeIT(nkHiddenAddr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent}))
    result.add newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent})[i])
    result[0].add tup[0]
    var lit = newNodeIT(nkIntLit, tup.info, getSysType(g, tup.info, tyInt))
    lit.intVal = i
    result[0].add lit
  else:
    result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
                       abstractInst)[i])
    result.add copyTree(tup)
    var lit = newNodeIT(nkIntLit, tup.info, getSysType(g, tup.info, tyInt))
    lit.intVal = i
    result.add lit

proc addVar*(father, v: PNode) =
  var vpart = newNodeI(nkIdentDefs, v.info, 3)
  vpart[0] = v
  vpart[1] = newNodeI(nkEmpty, v.info)
  vpart[2] = vpart[1]
  father.add vpart

proc addVar*(father, v, value: PNode) =
  var vpart = newNodeI(nkIdentDefs, v.info, 3)
  vpart[0] = v
  vpart[1] = newNodeI(nkEmpty, v.info)
  vpart[2] = value
  father.add vpart

proc newAsgnStmt*(le, ri: PNode): PNode =
  result = newNodeI(nkAsgn, le.info, 2)
  result[0] = le
  result[1] = ri

proc newFastAsgnStmt*(le, ri: PNode): PNode =
  result = newNodeI(nkFastAsgn, le.info, 2)
  result[0] = le
  result[1] = ri

proc newFastMoveStmt*(g: ModuleGraph, le, ri: PNode): PNode =
  result = newNodeI(nkFastAsgn, le.info, 2)
  result[0] = le
  result[1] = newNodeIT(nkCall, ri.info, ri.typ)
  result[1].add newSymNode(getSysMagic(g, ri.info, "move", mMove))
  result[1].add ri

proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode =
  assert n.kind == nkVarTuple
  let value = n.lastSon
  result = newNodeI(nkStmtList, n.info)

  var tempAsNode: PNode
  let avoidTemp = value.kind == nkSym
  if avoidTemp:
    tempAsNode = value
  else:
    var temp = newSym(skTemp, getIdent(g.cache, genPrefix), idgen,
                  owner, value.info, g.config.options)
    temp.typ = skipTypes(value.typ, abstractInst)
    incl(temp.flags, sfFromGeneric)
    tempAsNode = newSymNode(temp)

  var v = newNodeI(nkVarSection, value.info)
  if not avoidTemp:
    v.addVar(tempAsNode, value)
  result.add(v)

  for i in 0..<n.len-2:
    let val = newTupleAccess(g, tempAsNode, i)
    if n[i].kind == nkSym: v.addVar(n[i], val)
    else: result.add newAsgnStmt(n[i], val)

proc evalOnce*(g: ModuleGraph; value: PNode; idgen: IdGenerator; owner: PSym): PNode =
  ## Turns (value) into (let tmp = value; tmp) so that 'value' can be re-used
  ## freely, multiple times. This is frequently required and such a builtin would also be
  ## handy to have in macros.nim. The value that can be reused is 'result.lastSon'!
  result = newNodeIT(nkStmtListExpr, value.info, value.typ)
  var temp = newSym(skTemp, getIdent(g.cache, genPrefix), idgen,
                    owner, value.info, g.config.options)
  temp.typ = skipTypes(value.typ, abstractInst)
  incl(temp.flags, sfFromGeneric)

  var v = newNodeI(nkLetSection, value.info)
  let tempAsNode = newSymNode(temp)
  v.addVar(tempAsNode)
  result.add(v)
  result.add newAsgnStmt(tempAsNode, value)
  result.add tempAsNode

proc newTupleAccessRaw*(tup: PNode, i: int): PNode =
  result = newNodeI(nkBracketExpr, tup.info)
  result.add copyTree(tup)
  var lit = newNodeI(nkIntLit, tup.info)
  lit.intVal = i
  result.add lit

proc newTryFinally*(body, final: PNode): PNode =
  result = newTree(nkHiddenTryStmt, body, newTree(nkFinally, final))

proc lowerSwap*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode =
  result = newNodeI(nkStmtList, n.info)
  # note: cannot use 'skTemp' here cause we really need the copy for the VM :-(
  var temp = newSym(skVar, getIdent(g.cache, genPrefix), idgen, owner, n.info, owner.options)
  temp.typ = n[1].typ
  incl(temp.flags, sfFromGeneric)
  incl(temp.flags, sfGenSym)

  var v = newNodeI(nkVarSection, n.info)
  let tempAsNode = newSymNode(temp)

  var vpart = newNodeI(nkIdentDefs, v.info, 3)
  vpart[0] = tempAsNode
  vpart[1] = newNodeI(nkEmpty, v.info)
  vpart[2] = n[1]
  v.add vpart

  result.add(v)
  result.add newFastAsgnStmt(n[1], n[2])
  result.add newFastAsgnStmt(n[2], tempAsNode)

proc createObj*(g: ModuleGraph; idgen: IdGenerator; owner: PSym, info: TLineInfo; final=true): PType =
  result = newType(tyObject, idgen, owner)
  if final:
    rawAddSon(result, nil)
    incl result.flags, tfFinal
  else:
    rawAddSon(result, getCompilerProc(g, "RootObj").typ)
  result.n = newNodeI(nkRecList, info)
  let s = newSym(skType, getIdent(g.cache, "Env_" & toFilename(g.config, info) & "_" & $owner.name.s),
                  idgen, owner, info, owner.options)
  incl s.flags, sfAnon
  s.typ = result
  result.sym = s

template fieldCheck {.dirty.} =
  when false:
    if tfCheckedForDestructor in obj.flags:
      echo "missed field ", field.name.s
      writeStackTrace()

proc rawAddField*(obj: PType; field: PSym) =
  assert field.kind == skField
  field.position = obj.n.len
  obj.n.add newSymNode(field)
  propagateToOwner(obj, field.typ)
  fieldCheck()

proc rawIndirectAccess*(a: PNode; field: PSym; info: TLineInfo): PNode =
  # returns a[].field as a node
  assert field.kind == skField
  var deref = newNodeI(nkHiddenDeref, info)
  deref.typ = a.typ.skipTypes(abstractInst)[0]
  deref.add a
  result = newNodeI(nkDotExpr, info)
  result.add deref
  result.add newSymNode(field)
  result.typ = field.typ

proc rawDirectAccess*(obj, field: PSym): PNode =
  # returns a.field as a node
  assert field.kind == skField
  result = newNodeI(nkDotExpr, field.info)
  result.add newSymNode(obj)
  result.add newSymNode(field)
  result.typ = field.typ

proc lookupInRecord(n: PNode, id: ItemId): PSym =
  result = nil
  case n.kind
  of nkRecList:
    for i in 0..<n.len:
      result = lookupInRecord(n[i], id)
      if result != nil: return
  of nkRecCase:
    if n[0].kind != nkSym: return
    result = lookupInRecord(n[0], id)
    if result != nil: return
    for i in 1..<n.len:
      case n[i].kind
      of nkOfBranch, nkElse:
        result = lookupInRecord(lastSon(n[i]), id)
        if result != nil: return
      else: discard
  of nkSym:
    if n.sym.itemId.module == id.module and n.sym.itemId.item == -abs(id.item): result = n.sym
  else: discard

proc addField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator): PSym =
  # because of 'gensym' support, we have to mangle the name with its ID.
  # This is hacky but the clean solution is much more complex than it looks.
  var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len),
                     idgen, s.owner, s.info, s.options)
  field.itemId = ItemId(module: s.itemId.module, item: -s.itemId.item)
  let t = skipIntLit(s.typ, idgen)
  field.typ = t
  if s.kind in {skLet, skVar, skField, skForVar}:
    #field.bitsize = s.bitsize
    field.alignment = s.alignment
  assert t.kind != tyTyped
  propagateToOwner(obj, t)
  field.position = obj.n.len
  # sfNoInit flag for skField is used in closureiterator codegen
  field.flags = s.flags * {sfCursor, sfNoInit}
  obj.n.add newSymNode(field)
  fieldCheck()
  result = field

proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator): PSym {.discardable.} =
  result = lookupInRecord(obj.n, s.itemId)
  if result == nil:
    var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len), idgen,
                       s.owner, s.info, s.options)
    field.itemId = ItemId(module: s.itemId.module, item: -s.itemId.item)
    let t = skipIntLit(s.typ, idgen)
    field.typ = t
    assert t.kind != tyTyped
    propagateToOwner(obj, t)
    field.position = obj.n.len
    obj.n.add newSymNode(field)
    result = field

proc newDotExpr*(obj, b: PSym): PNode =
  result = newNodeI(nkDotExpr, obj.info)
  let field = lookupInRecord(obj.typ.n, b.itemId)
  assert field != nil, b.name.s
  result.add newSymNode(obj)
  result.add newSymNode(field)
  result.typ = field.typ

proc indirectAccess*(a: PNode, b: ItemId, info: TLineInfo): PNode =
  # returns a[].b as a node
  var deref = newNodeI(nkHiddenDeref, info)
  deref.typ = a.typ.skipTypes(abstractInst).elementType
  var t = deref.typ.skipTypes(abstractInst)
  var field: PSym
  while true:
    assert t.kind == tyObject
    field = lookupInRecord(t.n, b)
    if field != nil: break
    t = t.baseClass
    if t == nil: break
    t = t.skipTypes(skipPtrs)
  #if field == nil:
  #  echo "FIELD ", b
  #  debug deref.typ
  assert field != nil
  deref.add a
  result = newNodeI(nkDotExpr, info)
  result.add deref
  result.add newSymNode(field)
  result.typ = field.typ

proc indirectAccess*(a: PNode, b: string, info: TLineInfo; cache: IdentCache): PNode =
  # returns a[].b as a node
  var deref = newNodeI(nkHiddenDeref, info)
  deref.typ = a.typ.skipTypes(abstractInst).elementType
  var t = deref.typ.skipTypes(abstractInst)
  var field: PSym
  let bb = getIdent(cache, b)
  while true:
    assert t.kind == tyObject
    field = getSymFromList(t.n, bb)
    if field != nil: break
    t = t.baseClass
    if t == nil: break
    t = t.skipTypes(skipPtrs)
  #if field == nil:
  #  echo "FIELD ", b
  #  debug deref.typ
  assert field != nil
  deref.add a
  result = newNodeI(nkDotExpr, info)
  result.add deref
  result.add newSymNode(field)
  result.typ = field.typ

proc getFieldFromObj*(t: PType; v: PSym): PSym =
  assert v.kind != skField
  var t = t
  while true:
    assert t.kind == tyObject
    result = lookupInRecord(t.n, v.itemId)
    if result != nil: break
    t = t.baseClass
    if t == nil: break
    t = t.skipTypes(skipPtrs)

proc indirectAccess*(a: PNode, b: PSym, info: TLineInfo): PNode =
  # returns a[].b as a node
  result = indirectAccess(a, b.itemId, info)

proc indirectAccess*(a, b: PSym, info: TLineInfo): PNode =
  result = indirectAccess(newSymNode(a), b, info)

proc genAddrOf*(n: PNode; idgen: IdGenerator; typeKind = tyPtr): PNode =
  result = newNodeI(nkAddr, n.info, 1)
  result[0] = n
  result.typ = newType(typeKind, idgen, n.typ.owner)
  result.typ.rawAddSon(n.typ)

proc genDeref*(n: PNode; k = nkHiddenDeref): PNode =
  result = newNodeIT(k, n.info,
                     n.typ.skipTypes(abstractInst).elementType)
  result.add n

proc callCodegenProc*(g: ModuleGraph; name: string;
                      info: TLineInfo = unknownLineInfo;
                      arg1: PNode = nil, arg2: PNode = nil,
                      arg3: PNode = nil, optionalArgs: PNode = nil): PNode =
  result = newNodeI(nkCall, info)
  let sym = magicsys.getCompilerProc(g, name)
  if sym == nil:
    localError(g.config, info, "system module needs: " & name)
  else:
    result.add newSymNode(sym)
    if arg1 != nil: result.add arg1
    if arg2 != nil: result.add arg2
    if arg3 != nil: result.add arg3
    if optionalArgs != nil:
      for i in 1..<optionalArgs.len-2:
        result.add optionalArgs[i]
    result.typ = sym.typ.returnType

proc newIntLit*(g: ModuleGraph; info: TLineInfo; value: BiggestInt): PNode =
  result = nkIntLit.newIntNode(value)
  result.typ = getSysType(g, info, tyInt)

proc genHigh*(g: ModuleGraph; n: PNode): PNode =
  if skipTypes(n.typ, abstractVar).kind == tyArray:
    result = newIntLit(g, n.info, toInt64(lastOrd(g.config, skipTypes(n.typ, abstractVar))))
  else:
    result = newNodeI(nkCall, n.info, 2)
    result.typ = getSysType(g, n.info, tyInt)
    result[0] = newSymNode(getSysMagic(g, n.info, "high", mHigh))
    result[1] = n

proc genLen*(g: ModuleGraph; n: PNode): PNode =
  if skipTypes(n.typ, abstractVar).kind == tyArray:
    result = newIntLit(g, n.info, toInt64(lastOrd(g.config, skipTypes(n.typ, abstractVar)) + 1))
  else:
    result = newNodeI(nkCall, n.info, 2)
    result.typ = getSysType(g, n.info, tyInt)
    result[0] = newSymNode(getSysMagic(g, n.info, "len", mLengthSeq))
    result[1] = n