diff options
Diffstat (limited to 'nim/lookups.pas')
-rwxr-xr-x | nim/lookups.pas | 307 |
1 files changed, 0 insertions, 307 deletions
diff --git a/nim/lookups.pas b/nim/lookups.pas deleted file mode 100755 index e4c07224f..000000000 --- a/nim/lookups.pas +++ /dev/null @@ -1,307 +0,0 @@ -// -// -// The Nimrod Compiler -// (c) Copyright 2009 Andreas Rumpf -// -// See the file "copying.txt", included in this -// distribution, for details about the copyright. -// -unit lookups; - -// This module implements lookup helpers. - -interface - -uses - nsystem, ast, astalgo, idents, semdata, types, msgs, options, rodread, - rnimsyn; - -{$include 'config.inc'} - -type - TOverloadIterMode = (oimDone, oimNoQualifier, oimSelfModule, oimOtherModule, - oimSymChoice); - TOverloadIter = record - stackPtr: int; - it: TIdentIter; - m: PSym; - mode: TOverloadIterMode; - end; - -function getSymRepr(s: PSym): string; - -procedure CloseScope(var tab: TSymTab); - -procedure AddSym(var t: TStrTable; n: PSym); - -procedure addDecl(c: PContext; sym: PSym); -procedure addDeclAt(c: PContext; sym: PSym; at: Natural); -procedure addOverloadableSymAt(c: PContext; fn: PSym; at: Natural); - -procedure addInterfaceDecl(c: PContext; sym: PSym); -procedure addInterfaceOverloadableSymAt(c: PContext; sym: PSym; at: int); - -function lookUp(c: PContext; n: PNode): PSym; -// Looks up a symbol. Generates an error in case of nil. - -function QualifiedLookUp(c: PContext; n: PNode; ambiguousCheck: bool): PSym; - -function InitOverloadIter(out o: TOverloadIter; c: PContext; n: PNode): PSym; -function nextOverloadIter(var o: TOverloadIter; c: PContext; n: PNode): PSym; - -implementation - -function getSymRepr(s: PSym): string; -begin - case s.kind of - skProc, skMethod, skConverter, skIterator: result := getProcHeader(s); - else result := s.name.s - end -end; - -procedure CloseScope(var tab: TSymTab); -var - it: TTabIter; - s: PSym; -begin - // check if all symbols have been used and defined: - if (tab.tos > length(tab.stack)) then InternalError('CloseScope'); - s := InitTabIter(it, tab.stack[tab.tos-1]); - while s <> nil do begin - if sfForward in s.flags then - liMessage(s.info, errImplOfXexpected, getSymRepr(s)) - else if ([sfUsed, sfInInterface] * s.flags = []) and - (optHints in s.options) then // BUGFIX: check options in s! - if not (s.kind in [skForVar, skParam, skMethod, skUnknown]) then - liMessage(s.info, hintXDeclaredButNotUsed, getSymRepr(s)); - s := NextIter(it, tab.stack[tab.tos-1]); - end; - astalgo.rawCloseScope(tab); -end; - -procedure AddSym(var t: TStrTable; n: PSym); -begin - if StrTableIncl(t, n) then liMessage(n.info, errAttemptToRedefine, n.name.s); -end; - -procedure addDecl(c: PContext; sym: PSym); -begin - if SymTabAddUnique(c.tab, sym) = Failure then - liMessage(sym.info, errAttemptToRedefine, sym.Name.s); -end; - -procedure addDeclAt(c: PContext; sym: PSym; at: Natural); -begin - if SymTabAddUniqueAt(c.tab, sym, at) = Failure then - liMessage(sym.info, errAttemptToRedefine, sym.Name.s); -end; - -procedure addOverloadableSymAt(c: PContext; fn: PSym; at: Natural); -var - check: PSym; -begin - if not (fn.kind in OverloadableSyms) then - InternalError(fn.info, 'addOverloadableSymAt'); - check := StrTableGet(c.tab.stack[at], fn.name); - if (check <> nil) and not (check.Kind in OverloadableSyms) then - liMessage(fn.info, errAttemptToRedefine, fn.Name.s); - SymTabAddAt(c.tab, fn, at); -end; - -procedure AddInterfaceDeclAux(c: PContext; sym: PSym); -begin - if (sfInInterface in sym.flags) then begin - // add to interface: - if c.module = nil then InternalError(sym.info, 'AddInterfaceDeclAux'); - StrTableAdd(c.module.tab, sym); - end; - if getCurrOwner().kind = skModule then - include(sym.flags, sfGlobal) -end; - -procedure addInterfaceDecl(c: PContext; sym: PSym); -begin // it adds the symbol to the interface if appropriate - addDecl(c, sym); - AddInterfaceDeclAux(c, sym); -end; - -procedure addInterfaceOverloadableSymAt(c: PContext; sym: PSym; at: int); -begin // it adds the symbol to the interface if appropriate - addOverloadableSymAt(c, sym, at); - AddInterfaceDeclAux(c, sym); -end; - -function lookUp(c: PContext; n: PNode): PSym; -// Looks up a symbol. Generates an error in case of nil. -begin - case n.kind of - nkAccQuoted: result := lookup(c, n.sons[0]); - nkSym: begin (* - result := SymtabGet(c.Tab, n.sym.name); - if result = nil then - liMessage(n.info, errUndeclaredIdentifier, n.sym.name.s); *) - result := n.sym; - end; - nkIdent: begin - result := SymtabGet(c.Tab, n.ident); - if result = nil then - liMessage(n.info, errUndeclaredIdentifier, n.ident.s); - end - else InternalError(n.info, 'lookUp'); - end; - if IntSetContains(c.AmbiguousSymbols, result.id) then - liMessage(n.info, errUseQualifier, result.name.s); - if result.kind = skStub then loadStub(result); -end; - -function QualifiedLookUp(c: PContext; n: PNode; ambiguousCheck: bool): PSym; -var - m: PSym; - ident: PIdent; -begin - case n.kind of - nkIdent: begin - result := SymtabGet(c.Tab, n.ident); - if result = nil then - liMessage(n.info, errUndeclaredIdentifier, n.ident.s) - else if ambiguousCheck - and IntSetContains(c.AmbiguousSymbols, result.id) then - liMessage(n.info, errUseQualifier, n.ident.s) - end; - nkSym: begin (* - result := SymtabGet(c.Tab, n.sym.name); - if result = nil then - liMessage(n.info, errUndeclaredIdentifier, n.sym.name.s) - else *) - result := n.sym; - if ambiguousCheck and IntSetContains(c.AmbiguousSymbols, result.id) then - liMessage(n.info, errUseQualifier, n.sym.name.s) - end; - nkDotExpr: begin - result := nil; - m := qualifiedLookUp(c, n.sons[0], false); - if (m <> nil) and (m.kind = skModule) then begin - ident := nil; - if (n.sons[1].kind = nkIdent) then - ident := n.sons[1].ident - else if (n.sons[1].kind = nkAccQuoted) - and (n.sons[1].sons[0].kind = nkIdent) then - ident := n.sons[1].sons[0].ident; - if ident <> nil then begin - if m = c.module then - // a module may access its private members: - result := StrTableGet(c.tab.stack[ModuleTablePos], ident) - else - result := StrTableGet(m.tab, ident); - if result = nil then - liMessage(n.sons[1].info, errUndeclaredIdentifier, ident.s) - end - else - liMessage(n.sons[1].info, errIdentifierExpected, - renderTree(n.sons[1])); - end - end; - nkAccQuoted: result := QualifiedLookup(c, n.sons[0], ambiguousCheck); - else begin - result := nil; - //liMessage(n.info, errIdentifierExpected, '') - end; - end; - if (result <> nil) and (result.kind = skStub) then loadStub(result); -end; - -function InitOverloadIter(out o: TOverloadIter; c: PContext; n: PNode): PSym; -var - ident: PIdent; -begin - result := nil; - case n.kind of - nkIdent: begin - o.stackPtr := c.tab.tos; - o.mode := oimNoQualifier; - while (result = nil) do begin - dec(o.stackPtr); - if o.stackPtr < 0 then break; - result := InitIdentIter(o.it, c.tab.stack[o.stackPtr], n.ident); - end; - end; - nkSym: begin - result := n.sym; - o.mode := oimDone; - (* - o.stackPtr := c.tab.tos; - o.mode := oimNoQualifier; - while (result = nil) do begin - dec(o.stackPtr); - if o.stackPtr < 0 then break; - result := InitIdentIter(o.it, c.tab.stack[o.stackPtr], n.sym.name); - end; *) - end; - nkDotExpr: begin - o.mode := oimOtherModule; - o.m := qualifiedLookUp(c, n.sons[0], false); - if (o.m <> nil) and (o.m.kind = skModule) then begin - ident := nil; - if (n.sons[1].kind = nkIdent) then - ident := n.sons[1].ident - else if (n.sons[1].kind = nkAccQuoted) - and (n.sons[1].sons[0].kind = nkIdent) then - ident := n.sons[1].sons[0].ident; - if ident <> nil then begin - if o.m = c.module then begin - // a module may access its private members: - result := InitIdentIter(o.it, c.tab.stack[ModuleTablePos], ident); - o.mode := oimSelfModule; - end - else - result := InitIdentIter(o.it, o.m.tab, ident); - end - else - liMessage(n.sons[1].info, errIdentifierExpected, - renderTree(n.sons[1])); - end - end; - nkAccQuoted: result := InitOverloadIter(o, c, n.sons[0]); - nkSymChoice: begin - o.mode := oimSymChoice; - result := n.sons[0].sym; - o.stackPtr := 1 - end; - else begin end - end; - if (result <> nil) and (result.kind = skStub) then loadStub(result); -end; - -function nextOverloadIter(var o: TOverloadIter; c: PContext; n: PNode): PSym; -begin - case o.mode of - oimDone: result := nil; - oimNoQualifier: begin - if n.kind = nkAccQuoted then - result := nextOverloadIter(o, c, n.sons[0]) // BUGFIX - else if o.stackPtr >= 0 then begin - result := nextIdentIter(o.it, c.tab.stack[o.stackPtr]); - while (result = nil) do begin - dec(o.stackPtr); - if o.stackPtr < 0 then break; - result := InitIdentIter(o.it, c.tab.stack[o.stackPtr], o.it.name); - // BUGFIX: o.it.name <-> n.ident - end - end - else result := nil; - end; - oimSelfModule: result := nextIdentIter(o.it, c.tab.stack[ModuleTablePos]); - oimOtherModule: result := nextIdentIter(o.it, o.m.tab); - oimSymChoice: begin - if o.stackPtr < sonsLen(n) then begin - result := n.sons[o.stackPtr].sym; - inc(o.stackPtr); - end - else - result := nil - end; - end; - if (result <> nil) and (result.kind = skStub) then loadStub(result); -end; - -end. |