summary refs log tree commit diff stats
path: root/tests/stdlib
Commit message (Expand)AuthorAgeFilesLines
* make devel green again: tnetdial still doesn't work on Travisnarimiran2020-02-251-0/+1
* fix 3 minor bugs in joinPath (see #13455) (#13462) [backport]Andrey Makarov2020-02-231-0/+4
* relativePath("foo", "foo") is now ".", not "" (#13452)Timothee Cour2020-02-221-4/+8
* fix several bugs with `repr` (#13386)Timothee Cour2020-02-111-2/+2
* fix #6736: templates in unittest now show actual value (#13354)Miran2020-02-071-0/+25
* fix #13132 tnetdial (#13318)Timothee Cour2020-02-041-2/+2
* fix lots of bugs with parentDir, refs #8734 (#13236)Timothee Cour2020-01-231-5/+5
* new os.isRelativeTo (#13212)Timothee Cour2020-01-231-0/+12
* fix #13211 relativePath("foo", ".") (#13213)Timothee Cour2020-01-211-0/+4
* maybe: allows optional chaining of field access and indexing when LHS i snil ...Timothee Cour2020-01-181-0/+82
* distinctBase type trait for distinct types (#13031)cooldome2020-01-082-38/+16
* clean up deprecated stuff and unused imports in tests (#13059)Miran2020-01-071-1/+3
* Rst parser respect `:start-after:` and `:end-before:` in `include` directive ...Kamanji2020-01-051-0/+79
* add a StringTable.clear that requires no mode specification (#12853)Andy Davidoff2019-12-091-0/+3
* better support for PROGMEM like annotations for lets/vars; fixes #12216 (#12799)Andreas Rumpf2019-12-051-1/+1
* #12103 - CI for FreeBSD (#12179)Euan2019-11-291-1/+1
* fixes #12612 [backport] (#12681)Andreas Rumpf2019-11-191-0/+8
* Version of trimZeros without temp strings (#12633)b3liever2019-11-111-0/+36
* remove deprecated procs (#12535)Andreas Rumpf2019-11-051-28/+1
* [feature]strformat: add 2 'fmt' macros that use specified characters instead ...Tomohiro2019-10-281-0/+32
* Extent json.to testing to VM, add workrounds for VM bugs. (#12493)Arne Döring2019-10-281-116/+122
* Refactor json macro (#12391)Arne Döring2019-10-172-22/+41
* About 50% faster base64 implemention. (#12436)treeform2019-10-171-0/+44
* On windows, os.relativePath returns path as is when roots are different (#12329)Tomohiro2019-10-071-0/+15
* azure: disable failing testsLeorize2019-10-031-2/+1
* Fix how `relativePath` handle case sensitiviy (#12312) [backport]Tomohiro2019-10-011-0/+4
* More of StringStream now works at compile time (#12284)Clyybber2019-09-291-0/+11
* Fix spellings (#12277) [backport]Federico Ceratto2019-09-275-6/+6
* Locks modules should give a compile error when threads are not enabled. (#12231)Ray Imber2019-09-261-0/+1
* fixes #11713, fixes #1034Araq2019-09-041-0/+20
* makes more tests greenAndreas Rumpf2019-09-021-7/+7
* fixes #12015 by also checking kind of `typeNode` (#12016)Vindaar2019-08-271-0/+36
* Fixes splitfile (#11918) [bugfix]pgkos2019-08-151-0/+1
* Fix issue #10726 - HTTP response without Content-Length is not accessible (#1...konradmb2019-08-081-28/+40
* tgetaddrinfo: disable ICMP tests for HaikuLeorize2019-08-041-1/+1
* tgetaddrinfo: use sizeof() instead of hardcodingLeorize2019-08-041-3/+3
* fixes #11723Araq2019-07-151-0/+18
* [bugfix] fix #11588, don't check if SharedTable is initializednarimiran2019-06-261-0/+14
* [feature] Added os.delEnv; add delEnv support to nimscript too (#11466)Kaushal Modi2019-06-151-0/+13
* Attempt to close https://github.com/nim-lang/Nim/issues/11430Charles Blake2019-06-121-7/+14
* Use TMPDIR env var if available to get the temp dir name (#11443) [bugfix]Kaushal Modi2019-06-101-0/+12
* Bit operator names 2 (#11413)Arne Döring2019-06-061-1/+37
* fixes #11369 (#11381)Andreas Rumpf2019-06-021-0/+7
* move test for #7632 above `import strformat` (#11270)jcosborn2019-05-201-10/+11
* fixes #10952, UNC paths (#11260)Miran2019-05-161-0/+9
* fixes #7816 (#11261)Andreas Rumpf2019-05-151-1/+10
* Allow for locale-based parsing/formatting of dates (#11170)Matt Haggard2019-05-081-0/+27
* fixes another regression; the behaviour of 'array' formatting was changedAraq2019-04-151-0/+8
* fixes #11012Araq2019-04-152-22/+18
* rst: parse brackets individually, fixes #10475 (#10997)Miran2019-04-101-0/+12
/Nim/blame/compiler/lowerings.nim?h=devel&id=9295251e68ee86b512de51a2f650729ac6893104'>^
7d9fe106e ^

d3b013206 ^
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