diff options
Diffstat (limited to 'compiler/ast.nim')
-rw-r--r-- | compiler/ast.nim | 93 |
1 files changed, 61 insertions, 32 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index d81ccf33b..a9793fb21 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -10,7 +10,7 @@ # abstract syntax tree + symbol table import - lineinfos, hashes, options, ropes, idents, idgen, int128 + lineinfos, hashes, options, ropes, idents, int128 from strutils import toLowerAscii export int128 @@ -717,6 +717,14 @@ const mInSet, mRepr} type + ItemId* = object + module*: int32 + item*: int32 + + TIdObj* = object of RootObj + itemId*: ItemId + PIdObj* = ref TIdObj + PNode* = ref TNode TNodeSeq* = seq[PNode] PType* = ref TType @@ -926,7 +934,7 @@ type loc*: TLoc typeInst*: PType # for generic instantiations the tyGenericInst that led to this # type. - uniqueId*: int # due to a design mistake, we need to keep the real ID here as it + uniqueId*: ItemId # due to a design mistake, we need to keep the real ID here as it # required by the --incremental:on mode. TPair* = object @@ -1060,6 +1068,35 @@ proc getnimblePkg*(a: PSym): PSym = else: assert false, $result.kind +const + moduleShift = when defined(cpu32): 20 else: 24 + +template id*(a: PIdObj): int = + let x = a + (x.itemId.module.int shl moduleShift) + x.itemId.item.int + +type + IdGenerator* = ref ItemId # unfortunately, we really need the 'shared mutable' aspect here. + +const + PackageModuleId* = -3'i32 + +proc idGeneratorFromModule*(m: PSym): IdGenerator = + assert m.kind == skModule + result = IdGenerator(module: m.itemId.module, item: m.itemId.item) + +proc nextId*(x: IdGenerator): ItemId {.inline.} = + inc x.item + result = x[] + +when false: + proc storeBack*(dest: var IdGenerator; src: IdGenerator) {.inline.} = + assert dest.ItemId.module == src.ItemId.module + if dest.ItemId.item > src.ItemId.item: + echo dest.ItemId.item, " ", src.ItemId.item, " ", src.ItemId.module + assert dest.ItemId.item <= src.ItemId.item + dest = src + proc getnimblePkgId*(a: PSym): int = let b = a.getnimblePkg result = if b == nil: -1 else: b.id @@ -1164,13 +1201,11 @@ proc newTreeIT*(kind: TNodeKind; info: TLineInfo; typ: PType; children: varargs[ template previouslyInferred*(t: PType): PType = if t.sons.len > 1: t.lastSon else: nil -proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym, +proc newSym*(symKind: TSymKind, name: PIdent, id: ItemId, owner: PSym, info: TLineInfo; options: TOptions = {}): PSym = # generates a symbol and initializes the hash field too - result = PSym(name: name, kind: symKind, flags: {}, info: info, id: getID(), + result = PSym(name: name, kind: symKind, flags: {}, info: info, itemId: id, options: options, owner: owner, offset: defaultOffset) - when debugIds: - registerId(result) proc astdef*(s: PSym): PNode = # get only the definition (initializer) portion of the ast @@ -1344,13 +1379,11 @@ proc `$`*(s: PSym): string = else: result = "<nil>" -proc newType*(kind: TTypeKind, owner: PSym): PType = - let id = getID() +proc newType*(kind: TTypeKind, id: ItemId; owner: PSym): PType = result = PType(kind: kind, owner: owner, size: defaultSize, - align: defaultAlignment, id: id, uniqueId: id, - lockLevel: UnspecifiedLockLevel) - when debugIds: - registerId(result) + align: defaultAlignment, itemId: id, + lockLevel: UnspecifiedLockLevel, + uniqueId: id) when false: if result.id == 76426: echo "KNID ", kind @@ -1392,22 +1425,18 @@ proc assignType*(dest, src: PType) = newSons(dest, src.len) for i in 0..<src.len: dest[i] = src[i] -proc copyType*(t: PType, owner: PSym, keepId: bool): PType = - result = newType(t.kind, owner) +proc copyType*(t: PType, id: ItemId, owner: PSym): PType = + result = newType(t.kind, id, owner) assignType(result, t) - if keepId: - result.id = t.id - else: - when debugIds: registerId(result) result.sym = t.sym # backend-info should not be copied -proc exactReplica*(t: PType): PType = copyType(t, t.owner, true) +proc exactReplica*(t: PType): PType = + result = copyType(t, t.itemId, t.owner) -proc copySym*(s: PSym): PSym = - result = newSym(s.kind, s.name, s.owner, s.info, s.options) +proc copySym*(s: PSym; id: ItemId): PSym = + result = newSym(s.kind, s.name, id, s.owner, s.info, s.options) #result.ast = nil # BUGFIX; was: s.ast which made problems result.typ = s.typ - when debugIds: registerId(result) result.flags = s.flags result.magic = s.magic if s.kind == skModule: @@ -1421,12 +1450,12 @@ proc copySym*(s: PSym): PSym = result.bitsize = s.bitsize result.alignment = s.alignment -proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo; +proc createModuleAlias*(s: PSym, id: ItemId, newIdent: PIdent, info: TLineInfo; options: TOptions): PSym = - result = newSym(s.kind, newIdent, s.owner, info, options) + result = newSym(s.kind, newIdent, id, s.owner, info, options) # keep ID! result.ast = s.ast - result.id = s.id + #result.id = s.id # XXX figure out what to do with the ID. result.flags = s.flags system.shallowCopy(result.tab, s.tab) result.options = s.options @@ -1576,7 +1605,7 @@ proc transitionNoneToSym*(n: PNode) = template transitionSymKindCommon*(k: TSymKind) = let obj {.inject.} = s[] - s[] = TSym(kind: k, id: obj.id, magic: obj.magic, typ: obj.typ, name: obj.name, + s[] = TSym(kind: k, itemId: obj.itemId, magic: obj.magic, typ: obj.typ, name: obj.name, info: obj.info, owner: obj.owner, flags: obj.flags, ast: obj.ast, options: obj.options, position: obj.position, offset: obj.offset, loc: obj.loc, annex: obj.annex, constraint: obj.constraint) @@ -1797,19 +1826,19 @@ proc skipStmtList*(n: PNode): PNode = else: result = n -proc toVar*(typ: PType; kind: TTypeKind): PType = +proc toVar*(typ: PType; kind: TTypeKind; idgen: IdGenerator): PType = ## If ``typ`` is not a tyVar then it is converted into a `var <typ>` and ## returned. Otherwise ``typ`` is simply returned as-is. result = typ if typ.kind != kind: - result = newType(kind, typ.owner) + result = newType(kind, nextId(idgen), typ.owner) rawAddSon(result, typ) -proc toRef*(typ: PType): PType = +proc toRef*(typ: PType; idgen: IdGenerator): PType = ## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and ## returned. Otherwise ``typ`` is simply returned as-is. if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject: - result = newType(tyRef, typ.owner) + result = newType(tyRef, nextId(idgen), typ.owner) rawAddSon(result, typ) proc toObject*(typ: PType): PType = @@ -1888,8 +1917,8 @@ proc isSinkParam*(s: PSym): bool {.inline.} = proc isSinkType*(t: PType): bool {.inline.} = t.kind == tySink or tfHasOwned in t.flags -proc newProcType*(info: TLineInfo; owner: PSym): PType = - result = newType(tyProc, owner) +proc newProcType*(info: TLineInfo; id: ItemId; owner: PSym): PType = + result = newType(tyProc, id, owner) result.n = newNodeI(nkFormalParams, info) rawAddSon(result, nil) # return type # result.n[0] used to be `nkType`, but now it's `nkEffectList` because |