stricter symbol lookup in generics
This commit is contained in:
parent
75abf72503
commit
c934db86ad
6 changed files with 19 additions and 20 deletions
|
|
@ -80,15 +80,13 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
of nkIdent, nkAccQuoted:
|
of nkIdent, nkAccQuoted:
|
||||||
var s = SymtabGet(c.Tab, n.ident)
|
var s = SymtabGet(c.Tab, n.ident)
|
||||||
if s == nil:
|
if s == nil:
|
||||||
# no error if symbol cannot be bound, unless in ``bind`` context:
|
localError(n.info, errUndeclaredIdentifier, n.ident.s)
|
||||||
if withinBind in flags:
|
|
||||||
localError(n.info, errUndeclaredIdentifier, n.ident.s)
|
|
||||||
else:
|
else:
|
||||||
if withinBind in flags or s.id in toBind:
|
if withinBind in flags or s.id in toBind:
|
||||||
result = symChoice(c, n, s, scClosed)
|
result = symChoice(c, n, s, scClosed)
|
||||||
else: result = semGenericStmtSymbol(c, n, s)
|
else: result = semGenericStmtSymbol(c, n, s)
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
var s = QualifiedLookUp(c, n, {})
|
var s = QualifiedLookUp(c, n, {checkUndeclared})
|
||||||
if s != nil: result = semGenericStmtSymbol(c, n, s)
|
if s != nil: result = semGenericStmtSymbol(c, n, s)
|
||||||
# XXX for example: ``result.add`` -- ``add`` needs to be looked up here...
|
# XXX for example: ``result.add`` -- ``add`` needs to be looked up here...
|
||||||
of nkEmpty, nkSym..nkNilLit:
|
of nkEmpty, nkSym..nkNilLit:
|
||||||
|
|
@ -100,10 +98,12 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkCommand, nkCallStrLit:
|
of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkCommand, nkCallStrLit:
|
||||||
# check if it is an expression macro:
|
# check if it is an expression macro:
|
||||||
checkMinSonsLen(n, 1)
|
checkMinSonsLen(n, 1)
|
||||||
var s = qualifiedLookup(c, n.sons[0], {})
|
var s = qualifiedLookup(c, n.sons[0], {checkUndeclared})
|
||||||
var first = 0
|
var first = 0
|
||||||
|
var isDefinedMagic = false
|
||||||
if s != nil:
|
if s != nil:
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
|
isDefinedMagic = s.magic in {mDefined, mDefinedInScope, mCompiles}
|
||||||
case s.kind
|
case s.kind
|
||||||
of skMacro:
|
of skMacro:
|
||||||
if macroToExpand(s):
|
if macroToExpand(s):
|
||||||
|
|
@ -135,14 +135,15 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
else:
|
else:
|
||||||
result.sons[0] = newSymNode(s, n.sons[0].info)
|
result.sons[0] = newSymNode(s, n.sons[0].info)
|
||||||
first = 1
|
first = 1
|
||||||
for i in countup(first, sonsLen(result) - 1):
|
if not isDefinedMagic:
|
||||||
result.sons[i] = semGenericStmt(c, result.sons[i], flags, toBind)
|
for i in countup(first, sonsLen(result) - 1):
|
||||||
|
result.sons[i] = semGenericStmt(c, result.sons[i], flags, toBind)
|
||||||
of nkMacroStmt:
|
of nkMacroStmt:
|
||||||
checkMinSonsLen(n, 2)
|
checkMinSonsLen(n, 2)
|
||||||
var a: PNode
|
var a: PNode
|
||||||
if isCallExpr(n.sons[0]): a = n.sons[0].sons[0]
|
if isCallExpr(n.sons[0]): a = n.sons[0].sons[0]
|
||||||
else: a = n.sons[0]
|
else: a = n.sons[0]
|
||||||
var s = qualifiedLookup(c, a, {})
|
var s = qualifiedLookup(c, a, {checkUndeclared})
|
||||||
if s != nil and macroToExpand(s):
|
if s != nil and macroToExpand(s):
|
||||||
result = semMacroStmt(c, n, {}, false)
|
result = semMacroStmt(c, n, {}, false)
|
||||||
for i in countup(0, sonsLen(result)-1):
|
for i in countup(0, sonsLen(result)-1):
|
||||||
|
|
@ -287,6 +288,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
else: body = n.sons[bodyPos]
|
else: body = n.sons[bodyPos]
|
||||||
n.sons[bodyPos] = semGenericStmtScope(c, body, flags, toBind)
|
n.sons[bodyPos] = semGenericStmtScope(c, body, flags, toBind)
|
||||||
closeScope(c.tab)
|
closeScope(c.tab)
|
||||||
|
of nkPragma, nkPragmaExpr: nil
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result.sons[i] = semGenericStmt(c, n.sons[i], flags, toBind)
|
result.sons[i] = semGenericStmt(c, n.sons[i], flags, toBind)
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ var
|
||||||
totalCalls = 0
|
totalCalls = 0
|
||||||
|
|
||||||
var
|
var
|
||||||
interval: TNanos = 1_000_000 - tickCountCorrection # 5ms
|
interval: TNanos = 5_000_000 - tickCountCorrection # 5ms
|
||||||
|
|
||||||
proc setSamplingFrequency*(intervalInUs: int) =
|
proc setSamplingFrequency*(intervalInUs: int) =
|
||||||
## set this to change the sampling frequency. Default value is 5ms.
|
## set this to change the sampling frequency. Default value is 5ms.
|
||||||
|
|
|
||||||
|
|
@ -168,9 +168,6 @@ proc `..`*[T](b: T): TSlice[T] {.noSideEffect, inline.} =
|
||||||
## `slice`:idx: operator that constructs an interval ``[default(T), b]``
|
## `slice`:idx: operator that constructs an interval ``[default(T), b]``
|
||||||
result.b = b
|
result.b = b
|
||||||
|
|
||||||
proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} =
|
|
||||||
result = value >= s.a and value <= s.b
|
|
||||||
|
|
||||||
when not defined(niminheritable):
|
when not defined(niminheritable):
|
||||||
{.pragma: inheritable.}
|
{.pragma: inheritable.}
|
||||||
|
|
||||||
|
|
@ -672,6 +669,9 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.}
|
||||||
## is achieved by reversing the parameters for ``contains``; ``in`` then
|
## is achieved by reversing the parameters for ``contains``; ``in`` then
|
||||||
## passes its arguments in reverse order.
|
## passes its arguments in reverse order.
|
||||||
|
|
||||||
|
proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} =
|
||||||
|
result = s.a <= value and value <= s.b
|
||||||
|
|
||||||
template `in` * (x, y: expr): expr {.immediate.} = contains(y, x)
|
template `in` * (x, y: expr): expr {.immediate.} = contains(y, x)
|
||||||
template `not_in` * (x, y: expr): expr {.immediate.} = not contains(y, x)
|
template `not_in` * (x, y: expr): expr {.immediate.} = not contains(y, x)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,8 @@ proc objectInit(dest: Pointer, typ: PNimType) =
|
||||||
|
|
||||||
# ---------------------- assign zero -----------------------------------------
|
# ---------------------- assign zero -----------------------------------------
|
||||||
|
|
||||||
|
# dummy declaration; XXX we need 'mixin' here
|
||||||
|
proc destroy(x: int) = nil
|
||||||
proc nimDestroyRange*[T](r: T) =
|
proc nimDestroyRange*[T](r: T) =
|
||||||
# internal proc used for destroying sequences and arrays
|
# internal proc used for destroying sequences and arrays
|
||||||
for i in countup(0, r.len - 1): destroy(r[i])
|
for i in countup(0, r.len - 1): destroy(r[i])
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,7 @@
|
||||||
# code generator. The idea is to inject the instruction stream
|
# code generator. The idea is to inject the instruction stream
|
||||||
# with 'nimProfile()' calls. These calls are injected at every loop end
|
# with 'nimProfile()' calls. These calls are injected at every loop end
|
||||||
# (except perhaps loops that have no side-effects). At every Nth call a
|
# (except perhaps loops that have no side-effects). At every Nth call a
|
||||||
# stack trace is taken. A stack tace is a list of cstrings. We have a count
|
# stack trace is taken. A stack tace is a list of cstrings.
|
||||||
# table of those.
|
|
||||||
#
|
|
||||||
# The nice thing about this profiler is that it's completely time independent!
|
|
||||||
|
|
||||||
{.push profiler: off.}
|
{.push profiler: off.}
|
||||||
|
|
||||||
|
|
|
||||||
6
todo.txt
6
todo.txt
|
|
@ -2,12 +2,10 @@ version 0.9.0
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- make 'bind' default for templates and introduce 'mixin'
|
- make 'bind' default for templates and introduce 'mixin'
|
||||||
|
- make 'm: stmt' use overloading resolution
|
||||||
|
|
||||||
- implicit deref for parameter matching
|
- implicit deref for parameter matching
|
||||||
- optimize genericAssign in the code generator
|
- optimize genericAssign in the code generator
|
||||||
- the lookup rules for generics really are too permissive; global scope only
|
|
||||||
doesn't fly with closures though; for a start add a warning when processing
|
|
||||||
generic code
|
|
||||||
|
|
||||||
|
|
||||||
Bugs
|
Bugs
|
||||||
|
|
@ -38,7 +36,7 @@ version 0.9.XX
|
||||||
echo a
|
echo a
|
||||||
echo b)
|
echo b)
|
||||||
|
|
||||||
- make 'm: stmt' use overloading resolution
|
- implement the "snoopResult" pragma
|
||||||
- implement "closure tuple consists of a single 'ref'" optimization
|
- implement "closure tuple consists of a single 'ref'" optimization
|
||||||
- implement for loop transformation for first class iterators
|
- implement for loop transformation for first class iterators
|
||||||
- JS gen:
|
- JS gen:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue