mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-03 18:34:43 +00:00
Merge branch 'devel' into araq-big-refactoring
This commit is contained in:
@@ -33,22 +33,22 @@ when declared(echo):
|
||||
|
||||
template mdbg*: bool {.dirty.} =
|
||||
when compiles(c.module):
|
||||
c.module.fileIdx.int32 == gProjectMainIdx
|
||||
c.module.fileIdx.int32 == c.config.projectMainIdx
|
||||
elif compiles(c.c.module):
|
||||
c.c.module.fileIdx.int32 == gProjectMainIdx
|
||||
c.c.module.fileIdx.int32 == c.c.config.projectMainIdx
|
||||
elif compiles(m.c.module):
|
||||
m.c.module.fileIdx.int32 == gProjectMainIdx
|
||||
m.c.module.fileIdx.int32 == m.c.config.projectMainIdx
|
||||
elif compiles(cl.c.module):
|
||||
cl.c.module.fileIdx.int32 == gProjectMainIdx
|
||||
cl.c.module.fileIdx.int32 == cl.c.config.projectMainIdx
|
||||
elif compiles(p):
|
||||
when compiles(p.lex):
|
||||
p.lex.fileIdx.int32 == gProjectMainIdx
|
||||
p.lex.fileIdx.int32 == p.lex.config.projectMainIdx
|
||||
else:
|
||||
p.module.module.fileIdx.int32 == gProjectMainIdx
|
||||
p.module.module.fileIdx.int32 == p.config.projectMainIdx
|
||||
elif compiles(m.module.fileIdx):
|
||||
m.module.fileIdx.int32 == gProjectMainIdx
|
||||
m.module.fileIdx.int32 == m.config.projectMainIdx
|
||||
elif compiles(L.fileIdx):
|
||||
L.fileIdx.int32 == gProjectMainIdx
|
||||
L.fileIdx.int32 == L.config.projectMainIdx
|
||||
else:
|
||||
error()
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool)
|
||||
proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode
|
||||
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType
|
||||
proc semStmt(c: PContext, n: PNode): PNode
|
||||
proc semOpAux(c: PContext, n: PNode)
|
||||
proc semParamList(c: PContext, n, genericParams: PNode, s: PSym)
|
||||
proc addParams(c: PContext, n: PNode, kind: TSymKind)
|
||||
proc maybeAddResult(c: PContext, s: PSym, n: PNode)
|
||||
|
||||
@@ -254,6 +254,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||
var f = n.sons[0]
|
||||
if f.kind == nkBracketExpr:
|
||||
# fill in the bindings:
|
||||
semOpAux(c, f)
|
||||
initialBinding = f
|
||||
f = f.sons[0]
|
||||
else:
|
||||
|
||||
@@ -21,6 +21,8 @@ include "system/inclrtl"
|
||||
{.push debugger:off .} # the user does not want to trace a part
|
||||
# of the standard library!
|
||||
|
||||
import bitops
|
||||
|
||||
proc binom*(n, k: int): int {.noSideEffect.} =
|
||||
## Computes the binomial coefficient
|
||||
if k <= 0: return 1
|
||||
@@ -455,16 +457,42 @@ proc `^`*[T](x: T, y: Natural): T =
|
||||
x *= x
|
||||
|
||||
proc gcd*[T](x, y: T): T =
|
||||
## Computes the greatest common divisor of ``x`` and ``y``.
|
||||
## Computes the greatest common (positive) divisor of ``x`` and ``y``.
|
||||
## Note that for floats, the result cannot always be interpreted as
|
||||
## "greatest decimal `z` such that ``z*N == x and z*M == y``
|
||||
## where N and M are positive integers."
|
||||
var (x,y) = (x,y)
|
||||
var (x, y) = (x, y)
|
||||
while y != 0:
|
||||
x = x mod y
|
||||
swap x, y
|
||||
abs x
|
||||
|
||||
proc gcd*(x, y: SomeInteger): SomeInteger =
|
||||
## Computes the greatest common (positive) divisor of ``x`` and ``y``.
|
||||
## Using binary GCD (aka Stein's) algorithm.
|
||||
when x is SomeSignedInt:
|
||||
var x = abs(x)
|
||||
else:
|
||||
var x = x
|
||||
when y is SomeSignedInt:
|
||||
var y = abs(y)
|
||||
else:
|
||||
var y = y
|
||||
|
||||
if x == 0:
|
||||
return y
|
||||
if y == 0:
|
||||
return x
|
||||
|
||||
let shift = countTrailingZeroBits(x or y)
|
||||
y = y shr countTrailingZeroBits(y)
|
||||
while x != 0:
|
||||
x = x shr countTrailingZeroBits(x)
|
||||
if y > x:
|
||||
swap y, x
|
||||
x -= y
|
||||
y shl shift
|
||||
|
||||
proc lcm*[T](x, y: T): T =
|
||||
## Computes the least common multiple of ``x`` and ``y``.
|
||||
x div gcd(x, y) * y
|
||||
|
||||
@@ -197,6 +197,9 @@ proc parseUntil*(s: string, token: var string, until: string,
|
||||
## parses a token and stores it in ``token``. Returns
|
||||
## the number of the parsed characters or 0 in case of an error. A token
|
||||
## consists of any character that comes before the `until` token.
|
||||
if until.len == 0:
|
||||
token.setLen(0)
|
||||
return 0
|
||||
var i = start
|
||||
while i < s.len:
|
||||
if s[i] == until[0]:
|
||||
|
||||
@@ -70,8 +70,9 @@ type
|
||||
bump: pointer
|
||||
head, tail: Chunk
|
||||
nextChunkSize, totalSize: int
|
||||
freeLists: array[MaxSmallObject div MemAlign, FreeEntry]
|
||||
holes: SizedFreeEntry
|
||||
when false:
|
||||
freeLists: array[MaxSmallObject div MemAlign, FreeEntry]
|
||||
holes: SizedFreeEntry
|
||||
when hasThreadSupport:
|
||||
lock: SysLock
|
||||
|
||||
@@ -145,21 +146,22 @@ proc allocSlowPath(r: var MemRegion; size: int) =
|
||||
r.remaining = s - sizeof(BaseChunk)
|
||||
|
||||
proc allocFast(r: var MemRegion; size: int): pointer =
|
||||
if size <= MaxSmallObject:
|
||||
var it = r.freeLists[size div MemAlign]
|
||||
if it != nil:
|
||||
r.freeLists[size div MemAlign] = it.next
|
||||
return pointer(it)
|
||||
else:
|
||||
var it = r.holes
|
||||
var prev: SizedFreeEntry = nil
|
||||
while it != nil:
|
||||
if it.size >= size:
|
||||
if prev != nil: prev.next = it.next
|
||||
else: r.holes = it.next
|
||||
when false:
|
||||
if size <= MaxSmallObject:
|
||||
var it = r.freeLists[size div MemAlign]
|
||||
if it != nil:
|
||||
r.freeLists[size div MemAlign] = it.next
|
||||
return pointer(it)
|
||||
prev = it
|
||||
it = it.next
|
||||
else:
|
||||
var it = r.holes
|
||||
var prev: SizedFreeEntry = nil
|
||||
while it != nil:
|
||||
if it.size >= size:
|
||||
if prev != nil: prev.next = it.next
|
||||
else: r.holes = it.next
|
||||
return pointer(it)
|
||||
prev = it
|
||||
it = it.next
|
||||
if size > r.remaining:
|
||||
allocSlowPath(r, size)
|
||||
sysAssert(size <= r.remaining, "size <= r.remaining")
|
||||
@@ -184,15 +186,16 @@ proc dealloc(r: var MemRegion; p: pointer; size: int) =
|
||||
# it is benefitial to not use the free lists here:
|
||||
if r.bump -! size == p:
|
||||
dec r.bump, size
|
||||
elif size <= MaxSmallObject:
|
||||
let it = cast[FreeEntry](p)
|
||||
it.next = r.freeLists[size div MemAlign]
|
||||
r.freeLists[size div MemAlign] = it
|
||||
else:
|
||||
let it = cast[SizedFreeEntry](p)
|
||||
it.size = size
|
||||
it.next = r.holes
|
||||
r.holes = it
|
||||
when false:
|
||||
if size <= MaxSmallObject:
|
||||
let it = cast[FreeEntry](p)
|
||||
it.next = r.freeLists[size div MemAlign]
|
||||
r.freeLists[size div MemAlign] = it
|
||||
else:
|
||||
let it = cast[SizedFreeEntry](p)
|
||||
it.size = size
|
||||
it.next = r.holes
|
||||
r.holes = it
|
||||
|
||||
proc deallocAll(r: var MemRegion; head: Chunk) =
|
||||
var it = head
|
||||
@@ -220,9 +223,10 @@ proc setObstackPtr*(r: var MemRegion; sp: StackPtr) =
|
||||
if sp.current.next != nil:
|
||||
deallocAll(r, sp.current.next)
|
||||
sp.current.next = nil
|
||||
# better leak this memory than be sorry:
|
||||
for i in 0..high(r.freeLists): r.freeLists[i] = nil
|
||||
r.holes = nil
|
||||
when false:
|
||||
# better leak this memory than be sorry:
|
||||
for i in 0..high(r.freeLists): r.freeLists[i] = nil
|
||||
r.holes = nil
|
||||
#else:
|
||||
# deallocAll(r, r.head)
|
||||
# r.head = nil
|
||||
|
||||
@@ -332,7 +332,7 @@ proc cmpStrings(a, b: string): int {.asmNoStackFrame, compilerProc.} =
|
||||
return `a`.length - `b`.length;
|
||||
"""
|
||||
|
||||
proc cmp(x, y: string): int =
|
||||
proc cmp(x, y: string): int =
|
||||
return cmpStrings(x, y)
|
||||
|
||||
proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerProc.} =
|
||||
@@ -750,3 +750,16 @@ when defined(nodejs):
|
||||
else:
|
||||
# Deprecated. Use `alert` defined in dom.nim
|
||||
proc alert*(s: cstring) {.importc, nodecl, deprecated.}
|
||||
|
||||
# Workaround for IE, IE up to version 11 lacks 'Math.trunc'. We produce
|
||||
# 'Math.trunc' for Nim's ``div`` and ``mod`` operators:
|
||||
when not defined(nodejs):
|
||||
{.emit: """
|
||||
if (!Math.trunc) {
|
||||
Math.trunc = function(v) {
|
||||
v = +v;
|
||||
if (!isFinite(v)) return v;
|
||||
|
||||
return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
|
||||
};
|
||||
}""".}
|
||||
|
||||
@@ -390,7 +390,7 @@ proc ERR_peek_last_error*(): cInt{.cdecl, dynlib: DLLUtilName, importc.}
|
||||
|
||||
proc OPENSSL_config*(configName: cstring){.cdecl, dynlib: DLLSSLName, importc.}
|
||||
|
||||
when not useWinVersion and not defined(macosx) and not defined(android):
|
||||
when not useWinVersion and not defined(macosx) and not defined(android) and not defined(nimNoAllocForSSL):
|
||||
proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl,
|
||||
dynlib: DLLUtilName, importc.}
|
||||
|
||||
@@ -404,7 +404,7 @@ when not useWinVersion and not defined(macosx) and not defined(android):
|
||||
if p != nil: dealloc(p)
|
||||
|
||||
proc CRYPTO_malloc_init*() =
|
||||
when not useWinVersion and not defined(macosx) and not defined(android):
|
||||
when not useWinVersion and not defined(macosx) and not defined(android) and not defined(nimNoAllocForSSL):
|
||||
CRYPTO_set_mem_functions(allocWrapper, reallocWrapper, deallocWrapper)
|
||||
|
||||
proc SSL_CTX_ctrl*(ctx: SslCtx, cmd: cInt, larg: int, parg: pointer): int{.
|
||||
|
||||
@@ -11,3 +11,27 @@ template someTemplate[T](): tuple[id: int32, obj: T] =
|
||||
|
||||
let ret = someTemplate[SomeObj]()
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/7829
|
||||
proc inner*[T](): int =
|
||||
discard
|
||||
|
||||
template outer*[A](): untyped =
|
||||
inner[A]()
|
||||
|
||||
template outer*[B](x: int): untyped =
|
||||
inner[B]()
|
||||
|
||||
var i1 = outer[int]()
|
||||
var i2 = outer[int](i1)
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/7883
|
||||
template t1[T: int|int64](s: string): T =
|
||||
var t: T
|
||||
t
|
||||
|
||||
template t1[T: int|int64](x: int, s: string): T =
|
||||
var t: T
|
||||
t
|
||||
|
||||
var i3: int = t1[int]("xx")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user