Merge branch 'devel' into araq-misc

This commit is contained in:
Andreas Rumpf
2018-08-10 12:06:16 +02:00
13 changed files with 193 additions and 17 deletions

31
build_all.sh Normal file
View File

@@ -0,0 +1,31 @@
#! /bin/sh
# build development version of the compiler; can be rerun safely
set -u # error on undefined variables
set -e # exit on first error
echo_run(){
echo "\n$@"
"$@"
}
[ -d csources ] || echo_run git clone --depth 1 https://github.com/nim-lang/csources.git
nim_csources=bin/nim_csources
build_nim_csources(){
## avoid changing dir in case of failure
(
echo_run cd csources
echo_run sh build.sh
)
# keep $nim_csources in case needed to investigate bootstrap issues
# without having to rebuild from csources
echo_run cp bin/nim $nim_csources
}
[ -f $nim_csources ] || echo_run build_nim_csources
echo_run bin/nim c koch
echo_run ./koch boot -d:release
echo_run ./koch tools # Compile Nimble and other tools.

View File

@@ -482,7 +482,7 @@ include packagehandling
proc getOsCacheDir(): string =
when defined(posix):
result = getHomeDir() / ".cache"
result = string getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache")
else:
result = getHomeDir() / genSubDir

View File

@@ -1611,7 +1611,8 @@ A ``distinct`` type is new type derived from a `base type`:idx: that is
incompatible with its base type. In particular, it is an essential property
of a distinct type that it **does not** imply a subtype relation between it
and its base type. Explicit type conversions from a distinct type to its
base type and vice versa are allowed.
base type and vice versa are allowed. See also ``distinctBase`` to get the
reverse operation.
Modelling currencies

View File

@@ -159,7 +159,8 @@ Generated C code directory
The generated files that Nim produces all go into a subdirectory called
``nimcache``. Its full path is
- ``~/.cache/$projectname(_r|_d)`` on Posix
- ``$XDG_CACHE_HOME/$projectname(_r|_d)`` or ``~/.cache/$projectname(_r|_d)``
on Posix
- ``$HOME/nimcache/$projectname(_r|_d)`` on Windows.
The ``_r`` suffix is used for release builds, ``_d`` is for debug builds.

View File

@@ -676,8 +676,8 @@ template mapIt*(s, op: untyped): untyped =
var it{.inject.}: type(items(s));
op))
var result: seq[outType]
evalOnce(t, s)
when compiles(t.len):
when compiles(s.len):
evalOnce(t, s)
var i = 0
result = newSeq[outType](t.len)
for it {.inject.} in t:
@@ -685,7 +685,7 @@ template mapIt*(s, op: untyped): untyped =
i += 1
else:
result = @[]
for it {.inject.} in t:
for it {.inject.} in s:
result.add(op)
result
@@ -1071,5 +1071,10 @@ when isMainModule:
proc foo(x: openArray[int]): seq[int] = x.mapIt(it + 1)
doAssert foo([1,2,3]) == @[2,3,4]
block: # mapIt with invalid RHS for `let` (#8566)
type X = enum
A, B
doAssert mapIt(X, $it) == @["A", "B"]
when not defined(testing):
echo "Finished doc tests"

View File

@@ -807,6 +807,7 @@ type
lastProgressReport: float
when SocketType is AsyncSocket:
bodyStream: FutureStream[string]
parseBodyFut: Future[void]
else:
bodyStream: Stream
getBody: bool ## When `false`, the body is never read in requestAux.
@@ -1066,10 +1067,14 @@ proc parseResponse(client: HttpClient | AsyncHttpClient,
if getBody:
when client is HttpClient:
client.bodyStream = newStringStream()
result.bodyStream = client.bodyStream
parseBody(client, result.headers, result.version)
else:
client.bodyStream = newFutureStream[string]("parseResponse")
await parseBody(client, result.headers, result.version)
result.bodyStream = client.bodyStream
result.bodyStream = client.bodyStream
assert(client.parseBodyFut.isNil or client.parseBodyFut.finished)
client.parseBodyFut = parseBody(client, result.headers, result.version)
# do not wait here for the body request to complete
proc newConnection(client: HttpClient | AsyncHttpClient,
url: Uri) {.multisync.} =
@@ -1159,6 +1164,12 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string,
# Helper that actually makes the request. Does not handle redirects.
let requestUrl = parseUri(url)
when client is AsyncHttpClient:
if not client.parseBodyFut.isNil:
# let the current operation finish before making another request
await client.parseBodyFut
client.parseBodyFut = nil
await newConnection(client, requestUrl)
let effectiveHeaders = client.headers.override(headers)

View File

@@ -198,3 +198,41 @@ macro dump*(x: typed): untyped =
let r = quote do:
debugEcho `s`, " = ", `x`
return r
# TODO: consider exporting this in macros.nim
proc freshIdentNodes(ast: NimNode): NimNode =
# Replace NimIdent and NimSym by a fresh ident node
# see also https://github.com/nim-lang/Nim/pull/8531#issuecomment-410436458
proc inspect(node: NimNode): NimNode =
case node.kind:
of nnkIdent, nnkSym:
result = ident($node)
of nnkEmpty, nnkLiterals:
result = node
else:
result = node.kind.newTree()
for child in node:
result.add inspect(child)
result = inspect(ast)
macro distinctBase*(T: typedesc): untyped =
## reverses ``type T = distinct A``; works recursively.
runnableExamples:
type T = distinct int
doAssert distinctBase(T) is int
doAssert: not compiles(distinctBase(int))
type T2 = distinct T
doAssert distinctBase(T2) is int
let typeNode = getTypeImpl(T)
expectKind(typeNode, nnkBracketExpr)
if typeNode[0].typeKind != ntyTypeDesc:
error "expected typeDesc, got " & $typeNode[0]
var typeSym = typeNode[1]
typeSym = getTypeImpl(typeSym)
if typeSym.typeKind != ntyDistinct:
error "type is not distinct"
typeSym = typeSym[0]
while typeSym.typeKind == ntyDistinct:
typeSym = getTypeImpl(typeSym)[0]
typeSym.freshIdentNodes

View File

@@ -233,7 +233,7 @@ proc send*[TMsg](c: var Channel[TMsg], msg: TMsg) {.inline.} =
proc trySend*[TMsg](c: var Channel[TMsg], msg: TMsg): bool {.inline.} =
## Tries to send a message to a thread. `msg` is deeply copied. Doesn't block.
## Returns `false` if the message was not sent because number of pending items
## in the cannel exceeded `maxItems`.
## in the channel exceeded `maxItems`.
sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), unsafeAddr(msg), true)
proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) =

View File

@@ -50,24 +50,33 @@ Next, to build from source you will need:
other distros as well).
Then, if you are on a \*nix system or Windows, the following steps should compile
Nim from source using ``gcc``, ``git`` and the ``koch`` build tool (in the place
of ``sh build.sh`` you should substitute ``build.bat`` on x86 Windows or
``build64.bat`` on x86_64 Windows):
Nim from source using ``gcc``, ``git`` and the ``koch`` build tool.
**Note: The following commands are for the development version of the compiler.**
For most users, installing the latest stable version is enough. Check out
the installation instructions on the website to do so: https://nim-lang.org/install.html.
```
# step 1:
git clone https://github.com/nim-lang/Nim.git
cd Nim
# step 2 (posix) clones `csources.git`, bootstraps Nim compiler and compiles tools
sh build_all.sh
# step 2 (windows)
git clone --depth 1 https://github.com/nim-lang/csources.git
cd csources
sh build.sh
cd ../
bin/nim c koch
./koch boot -d:release
./koch tools # Compile Nimble and other tools.
# requires `gcc` in your PATH, see also https://nim-lang.org/install_windows.html
build.bat # x86 Windows
build64.bat # x86_64 Windows
cd ..
bin\nim c koch
koch boot -d:release
koch tools # Compile Nimble and other tools
# end of step 2 (windows)
```
Finally, once you have finished the build steps (on Windows, Mac or Linux) you

29
tests/generics/t6137.nim Normal file
View File

@@ -0,0 +1,29 @@
discard """
action: "reject"
line: 29
errormsg: "\'vectFunc\' doesn't have a concrete type, due to unspecified generic parameters."
"""
type
# simple vector of declared fixed length
vector[N : static[int]] = array[0..N-1, float]
proc `*`[T](x: float, a: vector[T]): vector[T] =
# multiplication by scalar
for ii in 0..high(a):
result[ii] = a[ii]*x
let
# define a vector of length 3
x: vector[3] = [1.0, 3.0, 5.0]
proc vectFunc[T](x: vector[T]): vector[T] {.procvar.} =
# Define a vector function
result = 2.0*x
proc passVectFunction[T](g: proc(x: vector[T]): vector[T], x: vector[T]): vector[T] =
# pass a vector function as input in another procedure
result = g(x)
let
xNew = passVectFunction(vectFunc,x)

10
tests/generics/t7141.nim Normal file
View File

@@ -0,0 +1,10 @@
discard """
action: "reject"
line: 7
errormsg: "cannot instantiate: \'T\'"
"""
proc foo[T](x: T) =
discard
var fun = if true: foo else: foo

View File

@@ -99,3 +99,15 @@ echo sizeof(a)
echo sizeof(b)
echo sizeof(c)
# This is the same example but using a proc instead of a macro
# Instead of type mismatch for macro, proc just failed with internal error: getTypeDescAux(tyNone)
# https://github.com/nim-lang/Nim/issues/7231
proc getBase2*(bits: static[int]): typedesc =
if bits == 128:
result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint64"))
else:
result = newTree(nnkBracketExpr, ident("MpUintBase"), ident("uint32"))
type
MpUint2*[bits: static[int]] = getbase2(bits)

29
tests/stdlib/tsugar.nim Normal file
View File

@@ -0,0 +1,29 @@
discard """
file: "tsugar.nim"
output: ""
"""
import sugar
import macros
block distinctBase:
block:
type
Foo[T] = distinct seq[T]
var a: Foo[int]
doAssert a.type.distinctBase is seq[int]
block:
# simplified from https://github.com/nim-lang/Nim/pull/8531#issuecomment-410436458
macro uintImpl(bits: static[int]): untyped =
if bits >= 128:
let inner = getAST(uintImpl(bits div 2))
result = newTree(nnkBracketExpr, ident("UintImpl"), inner)
else:
result = ident("uint64")
type
BaseUint = UintImpl or SomeUnsignedInt
UintImpl[Baseuint] = object
Uint[bits: static[int]] = distinct uintImpl(bits)
doAssert Uint[128].distinctBase is UintImpl[uint64]