diff --git a/src/nimony/sem.nim b/src/nimony/sem.nim index a33666426..7782b06e7 100644 --- a/src/nimony/sem.nim +++ b/src/nimony/sem.nim @@ -4697,6 +4697,27 @@ proc semDefer(c: var SemContext; it: var Item) = takeParRi c, it.n c.routine.hasDefer = true +proc expandSymChoice(c: var SemContext; n: var Cursor) = + let info = n.info + takeToken c, n + assert n.kind == Symbol + var name = pool.syms[n.symId] + extractBasename(name) + var marker = initHashSet[SymId]() + while n.kind != ParRi: + assert n.kind == Symbol + marker.incl n.symId + takeToken c, n + addSymChoiceSyms(c, pool.strings.getOrIncl(name), marker, info) + takeParRi c, n + +proc semSymChoice(c: var SemContext; it: var Item; flags: set[SemFlag] = {}) = + if it.n.exprKind == OchoiceX: + # could restrict to callees + expandSymChoice c, it.n + else: + takeTree c, it.n + proc semExpr(c: var SemContext; it: var Item; flags: set[SemFlag] = {}) = case it.n.kind of IntLit: @@ -4973,7 +4994,7 @@ proc semExpr(c: var SemContext; it: var Item; flags: set[SemFlag] = {}) = of FieldsX, FieldpairsX, InternalFieldPairsX: takeTree c, it.n of OchoiceX, CchoiceX: - takeTree c, it.n + semSymChoice c, it of HaddrX, HderefX: takeToken c, it.n # this is exactly what we need here as these operators have the same diff --git a/src/nimony/sembasics.nim b/src/nimony/sembasics.nim index 7bf539623..2f5a39913 100644 --- a/src/nimony/sembasics.nim +++ b/src/nimony/sembasics.nim @@ -136,6 +136,22 @@ proc buildSymChoice*(c: var SemContext; identifier: StrId; info: PackedLineInfo; c.dest.shrink oldLen c.dest.add identToken(identifier, info) +proc addSymChoiceSyms*(c: var SemContext; identifier: StrId; marker: var HashSet[SymId]; info: PackedLineInfo) = + # like rawBuildSymChoice but adds to an existing symchoice, ignoring duplicates + var it = c.currentScope + while it != nil: + for sym in it.tab.getOrDefault(identifier): + if not marker.containsOrIncl(sym.name): + c.dest.addSymUse sym, info + it = it.up + # mirror considerImportedSymbols: + for moduleId in c.importTab.getOrDefault(identifier): + # prevent copies + let candidates = addr c.importedModules[moduleId].iface[identifier] + for defId in candidates[]: + if not marker.containsOrIncl(defId): + c.dest.add symToken(defId, info) + proc isDeclared*(c: var SemContext; name: StrId): bool = var scope = c.currentScope while scope != nil: