Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
commit
bea2af7ba2
49 changed files with 379 additions and 254 deletions
|
|
@ -938,7 +938,7 @@ const
|
||||||
genericParamsPos* = 2
|
genericParamsPos* = 2
|
||||||
paramsPos* = 3
|
paramsPos* = 3
|
||||||
pragmasPos* = 4
|
pragmasPos* = 4
|
||||||
optimizedCodePos* = 5 # will be used for exception tracking
|
miscPos* = 5 # used for undocumented and hacky stuff
|
||||||
bodyPos* = 6 # position of body; use rodread.getBody() instead!
|
bodyPos* = 6 # position of body; use rodread.getBody() instead!
|
||||||
resultPos* = 7
|
resultPos* = 7
|
||||||
dispatcherPos* = 8 # caution: if method has no 'result' it can be position 7!
|
dispatcherPos* = 8 # caution: if method has no 'result' it can be position 7!
|
||||||
|
|
|
||||||
|
|
@ -262,13 +262,7 @@ proc processPath(path: string, info: TLineInfo,
|
||||||
else:
|
else:
|
||||||
options.gProjectPath / path
|
options.gProjectPath / path
|
||||||
try:
|
try:
|
||||||
result = unixToNativePath(p % ["nimrod", getPrefixDir(),
|
result = pathSubs(p, info.toFullPath().splitFile().dir)
|
||||||
"nim", getPrefixDir(),
|
|
||||||
"lib", libpath,
|
|
||||||
"home", removeTrailingDirSep(os.getHomeDir()),
|
|
||||||
"config", info.toFullPath().splitFile().dir,
|
|
||||||
"projectname", options.gProjectName,
|
|
||||||
"projectpath", options.gProjectPath])
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
localError(info, "invalid path: " & p)
|
localError(info, "invalid path: " & p)
|
||||||
result = p
|
result = p
|
||||||
|
|
@ -322,6 +316,9 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
||||||
of "nonimblepath", "nobabelpath":
|
of "nonimblepath", "nobabelpath":
|
||||||
expectNoArg(switch, arg, pass, info)
|
expectNoArg(switch, arg, pass, info)
|
||||||
options.gNoNimblePath = true
|
options.gNoNimblePath = true
|
||||||
|
options.lazyPaths.head = nil
|
||||||
|
options.lazyPaths.tail = nil
|
||||||
|
options.lazyPaths.counter = 0
|
||||||
of "excludepath":
|
of "excludepath":
|
||||||
expectArg(switch, arg, pass, info)
|
expectArg(switch, arg, pass, info)
|
||||||
let path = processPath(arg, info)
|
let path = processPath(arg, info)
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,11 @@ proc getModuleName*(n: PNode): string =
|
||||||
# The proc won't perform any checks that the path is actually valid
|
# The proc won't perform any checks that the path is actually valid
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
||||||
result = unixToNativePath(n.strVal)
|
try:
|
||||||
|
result = pathSubs(n.strVal, n.info.toFullPath().splitFile().dir)
|
||||||
|
except ValueError:
|
||||||
|
localError(n.info, "invalid path: " & n.strVal)
|
||||||
|
result = n.strVal
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
result = n.ident.s
|
result = n.ident.s
|
||||||
of nkSym:
|
of nkSym:
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ proc mainCommand* =
|
||||||
clearPasses()
|
clearPasses()
|
||||||
gLastCmdTime = epochTime()
|
gLastCmdTime = epochTime()
|
||||||
appendStr(searchPaths, options.libpath)
|
appendStr(searchPaths, options.libpath)
|
||||||
if gProjectFull.len != 0:
|
when false: # gProjectFull.len != 0:
|
||||||
# current path is always looked first for modules
|
# current path is always looked first for modules
|
||||||
prependStr(searchPaths, gProjectPath)
|
prependStr(searchPaths, gProjectPath)
|
||||||
setId(100)
|
setId(100)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ path:"$projectPath/.."
|
||||||
path:"$lib/packages/docutils"
|
path:"$lib/packages/docutils"
|
||||||
|
|
||||||
define:booting
|
define:booting
|
||||||
import:testability
|
#import:"$projectpath/testability"
|
||||||
|
|
||||||
@if windows:
|
@if windows:
|
||||||
cincludes: "$lib/wrappers/libffi/common"
|
cincludes: "$lib/wrappers/libffi/common"
|
||||||
|
|
|
||||||
|
|
@ -242,6 +242,21 @@ proc getNimcacheDir*: string =
|
||||||
result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir /
|
result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir /
|
||||||
genSubDir
|
genSubDir
|
||||||
|
|
||||||
|
|
||||||
|
proc pathSubs*(p, config: string): string =
|
||||||
|
let home = removeTrailingDirSep(os.getHomeDir())
|
||||||
|
result = unixToNativePath(p % [
|
||||||
|
"nim", getPrefixDir(),
|
||||||
|
"lib", libpath,
|
||||||
|
"home", home,
|
||||||
|
"config", config,
|
||||||
|
"projectname", options.gProjectName,
|
||||||
|
"projectpath", options.gProjectPath,
|
||||||
|
"projectdir", options.gProjectPath,
|
||||||
|
"nimcache", getNimcacheDir()])
|
||||||
|
if '~' in result:
|
||||||
|
result = result.replace("~", home)
|
||||||
|
|
||||||
template newPackageCache(): expr =
|
template newPackageCache(): expr =
|
||||||
newStringTable(when FileSystemCaseSensitive:
|
newStringTable(when FileSystemCaseSensitive:
|
||||||
modeCaseInsensitive
|
modeCaseInsensitive
|
||||||
|
|
|
||||||
|
|
@ -393,21 +393,23 @@ type
|
||||||
TLinkFeature = enum
|
TLinkFeature = enum
|
||||||
linkNormal, linkSys
|
linkNormal, linkSys
|
||||||
|
|
||||||
proc processCompile(c: PContext, n: PNode) =
|
proc relativeFile(c: PContext; n: PNode; ext=""): string =
|
||||||
var s = expectStrLit(c, n)
|
var s = expectStrLit(c, n)
|
||||||
var found = findFile(s)
|
if ext.len > 0 and splitFile(s).ext == "":
|
||||||
if found == "": found = s
|
s = addFileExt(s, ext)
|
||||||
var trunc = changeFileExt(found, "")
|
result = parentDir(n.info.toFullPath) / s
|
||||||
if not isAbsolute(found):
|
if not fileExists(result):
|
||||||
found = parentDir(n.info.toFullPath) / found
|
if isAbsolute(s): result = s
|
||||||
|
else: result = findFile(s)
|
||||||
|
|
||||||
|
proc processCompile(c: PContext, n: PNode) =
|
||||||
|
let found = relativeFile(c, n)
|
||||||
|
let trunc = found.changeFileExt("")
|
||||||
extccomp.addExternalFileToCompile(found)
|
extccomp.addExternalFileToCompile(found)
|
||||||
extccomp.addFileToLink(completeCFilePath(trunc, false))
|
extccomp.addFileToLink(completeCFilePath(trunc, false))
|
||||||
|
|
||||||
proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) =
|
proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) =
|
||||||
var f = expectStrLit(c, n)
|
let found = relativeFile(c, n, CC[cCompiler].objExt)
|
||||||
if splitFile(f).ext == "": f = addFileExt(f, CC[cCompiler].objExt)
|
|
||||||
var found = findFile(f)
|
|
||||||
if found == "": found = f # use the default
|
|
||||||
case feature
|
case feature
|
||||||
of linkNormal: extccomp.addFileToLink(found)
|
of linkNormal: extccomp.addFileToLink(found)
|
||||||
of linkSys:
|
of linkSys:
|
||||||
|
|
|
||||||
|
|
@ -712,7 +712,11 @@ proc gproc(g: var TSrcGen, n: PNode) =
|
||||||
gpattern(g, n.sons[patternPos])
|
gpattern(g, n.sons[patternPos])
|
||||||
let oldCheckAnon = g.checkAnon
|
let oldCheckAnon = g.checkAnon
|
||||||
g.checkAnon = true
|
g.checkAnon = true
|
||||||
gsub(g, n.sons[genericParamsPos])
|
if renderNoBody in g.flags and n[miscPos].kind != nkEmpty and
|
||||||
|
n[miscPos][1].kind != nkEmpty:
|
||||||
|
gsub(g, n[miscPos][1])
|
||||||
|
else:
|
||||||
|
gsub(g, n.sons[genericParamsPos])
|
||||||
g.checkAnon = oldCheckAnon
|
g.checkAnon = oldCheckAnon
|
||||||
gsub(g, n.sons[paramsPos])
|
gsub(g, n.sons[paramsPos])
|
||||||
gsub(g, n.sons[pragmasPos])
|
gsub(g, n.sons[pragmasPos])
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,11 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
|
||||||
add(result, ')')
|
add(result, ')')
|
||||||
var candidates = ""
|
var candidates = ""
|
||||||
for err in errors:
|
for err in errors:
|
||||||
add(candidates, err.getProcHeader(prefer))
|
if err.kind in routineKinds and err.ast != nil:
|
||||||
|
add(candidates, renderTree(err.ast,
|
||||||
|
{renderNoBody, renderNoComments,renderNoPragmas}))
|
||||||
|
else:
|
||||||
|
add(candidates, err.getProcHeader(prefer))
|
||||||
add(candidates, "\n")
|
add(candidates, "\n")
|
||||||
if candidates != "":
|
if candidates != "":
|
||||||
add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates)
|
add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates)
|
||||||
|
|
|
||||||
|
|
@ -929,6 +929,17 @@ proc semProcAnnotation(c: PContext, prc: PNode;
|
||||||
pragma(c, result[namePos].sym, result[pragmasPos], validPragmas)
|
pragma(c, result[namePos].sym, result[pragmasPos], validPragmas)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
proc setGenericParamsMisc(c: PContext; n: PNode): PNode =
|
||||||
|
let orig = n.sons[genericParamsPos]
|
||||||
|
# we keep the original params around for better error messages, see
|
||||||
|
# issue https://github.com/nim-lang/Nim/issues/1713
|
||||||
|
result = semGenericParamList(c, orig)
|
||||||
|
if n.sons[miscPos].kind == nkEmpty:
|
||||||
|
n.sons[miscPos] = newTree(nkBracket, ast.emptyNode, orig)
|
||||||
|
else:
|
||||||
|
n.sons[miscPos].sons[1] = orig
|
||||||
|
n.sons[genericParamsPos] = result
|
||||||
|
|
||||||
proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# XXX semProcAux should be good enough for this now, we will eventually
|
# XXX semProcAux should be good enough for this now, we will eventually
|
||||||
# remove semLambda
|
# remove semLambda
|
||||||
|
|
@ -947,8 +958,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
openScope(c)
|
openScope(c)
|
||||||
var gp: PNode
|
var gp: PNode
|
||||||
if n.sons[genericParamsPos].kind != nkEmpty:
|
if n.sons[genericParamsPos].kind != nkEmpty:
|
||||||
n.sons[genericParamsPos] = semGenericParamList(c, n.sons[genericParamsPos])
|
gp = setGenericParamsMisc(c, n)
|
||||||
gp = n.sons[genericParamsPos]
|
|
||||||
else:
|
else:
|
||||||
gp = newNodeI(nkGenericParams, n.info)
|
gp = newNodeI(nkGenericParams, n.info)
|
||||||
|
|
||||||
|
|
@ -1170,8 +1180,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
openScope(c)
|
openScope(c)
|
||||||
var gp: PNode
|
var gp: PNode
|
||||||
if n.sons[genericParamsPos].kind != nkEmpty:
|
if n.sons[genericParamsPos].kind != nkEmpty:
|
||||||
n.sons[genericParamsPos] = semGenericParamList(c, n.sons[genericParamsPos])
|
gp = setGenericParamsMisc(c, n)
|
||||||
gp = n.sons[genericParamsPos]
|
|
||||||
else:
|
else:
|
||||||
gp = newNodeI(nkGenericParams, n.info)
|
gp = newNodeI(nkGenericParams, n.info)
|
||||||
# process parameters:
|
# process parameters:
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
import ast, types, msgs, osproc, streams, options, idents, securehash
|
import ast, types, msgs, os, osproc, streams, options, idents, securehash
|
||||||
|
|
||||||
proc readOutput(p: Process): string =
|
proc readOutput(p: Process): string =
|
||||||
result = ""
|
result = ""
|
||||||
|
|
@ -51,7 +51,9 @@ proc opGorge*(cmd, input, cache: string): string =
|
||||||
|
|
||||||
proc opSlurp*(file: string, info: TLineInfo, module: PSym): string =
|
proc opSlurp*(file: string, info: TLineInfo, module: PSym): string =
|
||||||
try:
|
try:
|
||||||
let filename = file.findFile
|
var filename = parentDir(info.toFullPath) / file
|
||||||
|
if not fileExists(filename):
|
||||||
|
filename = file.findFile
|
||||||
result = readFile(filename)
|
result = readFile(filename)
|
||||||
# we produce a fake include statement for every slurped filename, so that
|
# we produce a fake include statement for every slurped filename, so that
|
||||||
# the module dependencies are accurate:
|
# the module dependencies are accurate:
|
||||||
|
|
|
||||||
|
|
@ -1887,8 +1887,8 @@ proc optimizeJumps(c: PCtx; start: int) =
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc genProc(c: PCtx; s: PSym): int =
|
proc genProc(c: PCtx; s: PSym): int =
|
||||||
let x = s.ast.sons[optimizedCodePos]
|
var x = s.ast.sons[miscPos]
|
||||||
if x.kind == nkEmpty:
|
if x.kind == nkEmpty or x[0].kind == nkEmpty:
|
||||||
#if s.name.s == "outterMacro" or s.name.s == "innerProc":
|
#if s.name.s == "outterMacro" or s.name.s == "innerProc":
|
||||||
# echo "GENERATING CODE FOR ", s.name.s
|
# echo "GENERATING CODE FOR ", s.name.s
|
||||||
let last = c.code.len-1
|
let last = c.code.len-1
|
||||||
|
|
@ -1899,7 +1899,11 @@ proc genProc(c: PCtx; s: PSym): int =
|
||||||
c.debug.setLen(last)
|
c.debug.setLen(last)
|
||||||
#c.removeLastEof
|
#c.removeLastEof
|
||||||
result = c.code.len+1 # skip the jump instruction
|
result = c.code.len+1 # skip the jump instruction
|
||||||
s.ast.sons[optimizedCodePos] = newIntNode(nkIntLit, result)
|
if x.kind == nkEmpty:
|
||||||
|
x = newTree(nkBracket, newIntNode(nkIntLit, result), ast.emptyNode)
|
||||||
|
else:
|
||||||
|
x.sons[0] = newIntNode(nkIntLit, result)
|
||||||
|
s.ast.sons[miscPos] = x
|
||||||
# thanks to the jmp we can add top level statements easily and also nest
|
# thanks to the jmp we can add top level statements easily and also nest
|
||||||
# procs easily:
|
# procs easily:
|
||||||
let body = s.getBody
|
let body = s.getBody
|
||||||
|
|
@ -1934,4 +1938,4 @@ proc genProc(c: PCtx; s: PSym): int =
|
||||||
c.prc = oldPrc
|
c.prc = oldPrc
|
||||||
else:
|
else:
|
||||||
c.prc.maxSlots = s.offset
|
c.prc.maxSlots = s.offset
|
||||||
result = x.intVal.int
|
result = x[0].intVal.int
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,9 @@ Math libraries
|
||||||
* `mersenne <mersenne.html>`_
|
* `mersenne <mersenne.html>`_
|
||||||
Mersenne twister random number generator.
|
Mersenne twister random number generator.
|
||||||
|
|
||||||
|
* `random <random.html>`_
|
||||||
|
Fast and tiny random number generator.
|
||||||
|
|
||||||
* `stats <stats.html>`_
|
* `stats <stats.html>`_
|
||||||
Statistical analysis
|
Statistical analysis
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -155,4 +155,4 @@ Exception hierarchy
|
||||||
|
|
||||||
The exception tree is defined in the `system <system.html>`_ module:
|
The exception tree is defined in the `system <system.html>`_ module:
|
||||||
|
|
||||||
.. include:: exception_hierarchy_fragment.txt
|
.. include:: ../exception_hierarchy_fragment.txt
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ operator characters instead.
|
||||||
The following keywords are reserved and cannot be used as identifiers:
|
The following keywords are reserved and cannot be used as identifiers:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
:file: keywords.txt
|
:file: ../keywords.txt
|
||||||
|
|
||||||
Some keywords are unused; they are reserved for future developments of the
|
Some keywords are unused; they are reserved for future developments of the
|
||||||
language.
|
language.
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,6 @@ Grammar
|
||||||
|
|
||||||
The grammar's start symbol is ``module``.
|
The grammar's start symbol is ``module``.
|
||||||
|
|
||||||
.. include:: grammar.txt
|
.. include:: ../grammar.txt
|
||||||
:literal:
|
:literal:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -694,7 +694,7 @@ branch switch ``system.reset`` has to be used.
|
||||||
Set type
|
Set type
|
||||||
--------
|
--------
|
||||||
|
|
||||||
.. include:: sets_fragment.txt
|
.. include:: ../sets_fragment.txt
|
||||||
|
|
||||||
Reference and pointer types
|
Reference and pointer types
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ Configuration file
|
||||||
niminst uses the Nim `parsecfg <parsecfg.html>`_ module to parse the
|
niminst uses the Nim `parsecfg <parsecfg.html>`_ module to parse the
|
||||||
configuration file. Here's an example of how the syntax looks like:
|
configuration file. Here's an example of how the syntax looks like:
|
||||||
|
|
||||||
.. include:: doc/mytest.cfg
|
.. include:: mytest.cfg
|
||||||
:literal:
|
:literal:
|
||||||
|
|
||||||
The value of a key-value pair can reference user-defined variables via
|
The value of a key-value pair can reference user-defined variables via
|
||||||
|
|
@ -190,6 +190,6 @@ Real world example
|
||||||
The installers for the Nim compiler itself are generated by niminst. Have a
|
The installers for the Nim compiler itself are generated by niminst. Have a
|
||||||
look at its configuration file:
|
look at its configuration file:
|
||||||
|
|
||||||
.. include:: compiler/installer.ini
|
.. include:: ../compiler/installer.ini
|
||||||
:literal:
|
:literal:
|
||||||
|
|
||||||
|
|
|
||||||
5
koch.nim
5
koch.nim
|
|
@ -336,10 +336,11 @@ template `|`(a, b): expr = (if a.len > 0: a else: b)
|
||||||
proc tests(args: string) =
|
proc tests(args: string) =
|
||||||
# we compile the tester with taintMode:on to have a basic
|
# we compile the tester with taintMode:on to have a basic
|
||||||
# taint mode test :-)
|
# taint mode test :-)
|
||||||
exec "nim cc --taintMode:on tests/testament/tester"
|
let nimexe = findNim()
|
||||||
|
exec nimexe & " cc --taintMode:on tests/testament/tester"
|
||||||
# Since tests take a long time (on my machine), and we want to defy Murhpys
|
# Since tests take a long time (on my machine), and we want to defy Murhpys
|
||||||
# law - lets make sure the compiler really is freshly compiled!
|
# law - lets make sure the compiler really is freshly compiled!
|
||||||
exec "nim c --lib:lib -d:release --opt:speed compiler/nim.nim"
|
exec nimexe & " c --lib:lib -d:release --opt:speed compiler/nim.nim"
|
||||||
let tester = quoteShell(getCurrentDir() / "tests/testament/tester".exe)
|
let tester = quoteShell(getCurrentDir() / "tests/testament/tester".exe)
|
||||||
let success = tryExec tester & " " & (args|"all")
|
let success = tryExec tester & " " & (args|"all")
|
||||||
if not existsEnv("TRAVIS") and not existsEnv("APPVEYOR"):
|
if not existsEnv("TRAVIS") and not existsEnv("APPVEYOR"):
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ include "system/inclrtl"
|
||||||
## This module contains the interface to the compiler's abstract syntax
|
## This module contains the interface to the compiler's abstract syntax
|
||||||
## tree (`AST`:idx:). Macros operate on this tree.
|
## tree (`AST`:idx:). Macros operate on this tree.
|
||||||
|
|
||||||
## .. include:: ../doc/astspec.txt
|
## .. include:: ../../doc/astspec.txt
|
||||||
|
|
||||||
type
|
type
|
||||||
NimNodeKind* = enum
|
NimNodeKind* = enum
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
## though.
|
## though.
|
||||||
## PRCE's licence follows:
|
## PRCE's licence follows:
|
||||||
##
|
##
|
||||||
## .. include:: ../doc/regexprs.txt
|
## .. include:: ../../doc/regexprs.txt
|
||||||
##
|
##
|
||||||
|
|
||||||
import
|
import
|
||||||
|
|
|
||||||
|
|
@ -323,6 +323,11 @@ proc newSharedState(options: RstParseOptions,
|
||||||
result.msgHandler = if not isNil(msgHandler): msgHandler else: defaultMsgHandler
|
result.msgHandler = if not isNil(msgHandler): msgHandler else: defaultMsgHandler
|
||||||
result.findFile = if not isNil(findFile): findFile else: defaultFindFile
|
result.findFile = if not isNil(findFile): findFile else: defaultFindFile
|
||||||
|
|
||||||
|
proc findRelativeFile(p: RstParser; filename: string): string =
|
||||||
|
result = p.filename.splitFile.dir / filename
|
||||||
|
if not existsFile(result):
|
||||||
|
result = p.s.findFile(filename)
|
||||||
|
|
||||||
proc rstMessage(p: RstParser, msgKind: MsgKind, arg: string) =
|
proc rstMessage(p: RstParser, msgKind: MsgKind, arg: string) =
|
||||||
p.s.msgHandler(p.filename, p.line + p.tok[p.idx].line,
|
p.s.msgHandler(p.filename, p.line + p.tok[p.idx].line,
|
||||||
p.col + p.tok[p.idx].col, msgKind, arg)
|
p.col + p.tok[p.idx].col, msgKind, arg)
|
||||||
|
|
@ -1500,7 +1505,7 @@ proc dirInclude(p: var RstParser): PRstNode =
|
||||||
result = nil
|
result = nil
|
||||||
var n = parseDirective(p, {hasArg, argIsFile, hasOptions}, nil)
|
var n = parseDirective(p, {hasArg, argIsFile, hasOptions}, nil)
|
||||||
var filename = strip(addNodes(n.sons[0]))
|
var filename = strip(addNodes(n.sons[0]))
|
||||||
var path = p.s.findFile(filename)
|
var path = p.findRelativeFile(filename)
|
||||||
if path == "":
|
if path == "":
|
||||||
rstMessage(p, meCannotOpenFile, filename)
|
rstMessage(p, meCannotOpenFile, filename)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1511,7 +1516,7 @@ proc dirInclude(p: var RstParser): PRstNode =
|
||||||
else:
|
else:
|
||||||
var q: RstParser
|
var q: RstParser
|
||||||
initParser(q, p.s)
|
initParser(q, p.s)
|
||||||
q.filename = filename
|
q.filename = path
|
||||||
q.col += getTokens(readFile(path), false, q.tok)
|
q.col += getTokens(readFile(path), false, q.tok)
|
||||||
# workaround a GCC bug; more like the interior pointer bug?
|
# workaround a GCC bug; more like the interior pointer bug?
|
||||||
#if find(q.tok[high(q.tok)].symbol, "\0\x01\x02") > 0:
|
#if find(q.tok[high(q.tok)].symbol, "\0\x01\x02") > 0:
|
||||||
|
|
@ -1538,7 +1543,7 @@ proc dirCodeBlock(p: var RstParser, nimExtension = false): PRstNode =
|
||||||
result = parseDirective(p, {hasArg, hasOptions}, parseLiteralBlock)
|
result = parseDirective(p, {hasArg, hasOptions}, parseLiteralBlock)
|
||||||
var filename = strip(getFieldValue(result, "file"))
|
var filename = strip(getFieldValue(result, "file"))
|
||||||
if filename != "":
|
if filename != "":
|
||||||
var path = p.s.findFile(filename)
|
var path = p.findRelativeFile(filename)
|
||||||
if path == "": rstMessage(p, meCannotOpenFile, filename)
|
if path == "": rstMessage(p, meCannotOpenFile, filename)
|
||||||
var n = newRstNode(rnLiteralBlock)
|
var n = newRstNode(rnLiteralBlock)
|
||||||
add(n, newRstNode(rnLeaf, readFile(path)))
|
add(n, newRstNode(rnLeaf, readFile(path)))
|
||||||
|
|
@ -1590,7 +1595,7 @@ proc dirRawAux(p: var RstParser, result: var PRstNode, kind: RstNodeKind,
|
||||||
contentParser: SectionParser) =
|
contentParser: SectionParser) =
|
||||||
var filename = getFieldValue(result, "file")
|
var filename = getFieldValue(result, "file")
|
||||||
if filename.len > 0:
|
if filename.len > 0:
|
||||||
var path = p.s.findFile(filename)
|
var path = p.findRelativeFile(filename)
|
||||||
if path.len == 0:
|
if path.len == 0:
|
||||||
rstMessage(p, meCannotOpenFile, filename)
|
rstMessage(p, meCannotOpenFile, filename)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -219,20 +219,20 @@ proc processClient(client: AsyncSocket, address: string,
|
||||||
else:
|
else:
|
||||||
await client.sendStatus("417 Expectation Failed")
|
await client.sendStatus("417 Expectation Failed")
|
||||||
|
|
||||||
# Read the body
|
# Read the body
|
||||||
# - Check for Content-length header
|
# - Check for Content-length header
|
||||||
if request.headers.hasKey("Content-Length"):
|
if request.headers.hasKey("Content-Length"):
|
||||||
var contentLength = 0
|
var contentLength = 0
|
||||||
if parseInt(request.headers.getOrDefault("Content-Length"),
|
if parseInt(request.headers.getOrDefault("Content-Length"),
|
||||||
contentLength) == 0:
|
contentLength) == 0:
|
||||||
await request.respond(Http400, "Bad Request. Invalid Content-Length.")
|
await request.respond(Http400, "Bad Request. Invalid Content-Length.")
|
||||||
continue
|
|
||||||
else:
|
|
||||||
request.body = await client.recv(contentLength)
|
|
||||||
assert request.body.len == contentLength
|
|
||||||
else:
|
|
||||||
await request.respond(Http400, "Bad Request. No Content-Length.")
|
|
||||||
continue
|
continue
|
||||||
|
else:
|
||||||
|
request.body = await client.recv(contentLength)
|
||||||
|
assert request.body.len == contentLength
|
||||||
|
else:
|
||||||
|
await request.respond(Http400, "Bad Request. No Content-Length.")
|
||||||
|
continue
|
||||||
|
|
||||||
case request.reqMethod
|
case request.reqMethod
|
||||||
of "get", "post", "head", "put", "delete", "trace", "options",
|
of "get", "post", "head", "put", "delete", "trace", "options",
|
||||||
|
|
|
||||||
|
|
@ -657,7 +657,7 @@ template newSeqWith*(len: int, init: expr): expr =
|
||||||
## seq2D[1][0] = true
|
## seq2D[1][0] = true
|
||||||
## seq2D[0][1] = true
|
## seq2D[0][1] = true
|
||||||
##
|
##
|
||||||
## import math
|
## import random
|
||||||
## var seqRand = newSeqWith(20, random(10))
|
## var seqRand = newSeqWith(20, random(10))
|
||||||
## echo seqRand
|
## echo seqRand
|
||||||
var result {.gensym.} = newSeq[type(init)](len)
|
var result {.gensym.} = newSeq[type(init)](len)
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,8 @@ proc advice*(s: var ThreadPoolState): ThreadPoolAdvice =
|
||||||
inc s.calls
|
inc s.calls
|
||||||
|
|
||||||
when not defined(testing) and isMainModule:
|
when not defined(testing) and isMainModule:
|
||||||
|
import random
|
||||||
|
|
||||||
proc busyLoop() =
|
proc busyLoop() =
|
||||||
while true:
|
while true:
|
||||||
discard random(80)
|
discard random(80)
|
||||||
|
|
|
||||||
|
|
@ -29,21 +29,17 @@ proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
|
||||||
of nnkExprColonExpr:
|
of nnkExprColonExpr:
|
||||||
identDefs.add ident[0]
|
identDefs.add ident[0]
|
||||||
identDefs.add ident[1]
|
identDefs.add ident[1]
|
||||||
of nnkIdent:
|
else:
|
||||||
identDefs.add newIdentNode("i" & $i)
|
identDefs.add newIdentNode("i" & $i)
|
||||||
identDefs.add(ident)
|
identDefs.add(ident)
|
||||||
else:
|
|
||||||
error("Incorrect type list in proc type declaration.")
|
|
||||||
identDefs.add newEmptyNode()
|
identDefs.add newEmptyNode()
|
||||||
formalParams.add identDefs
|
formalParams.add identDefs
|
||||||
of nnkIdent:
|
else:
|
||||||
var identDefs = newNimNode(nnkIdentDefs)
|
var identDefs = newNimNode(nnkIdentDefs)
|
||||||
identDefs.add newIdentNode("i0")
|
identDefs.add newIdentNode("i0")
|
||||||
identDefs.add(p)
|
identDefs.add(p)
|
||||||
identDefs.add newEmptyNode()
|
identDefs.add newEmptyNode()
|
||||||
formalParams.add identDefs
|
formalParams.add identDefs
|
||||||
else:
|
|
||||||
error("Incorrect type list in proc type declaration.")
|
|
||||||
|
|
||||||
result.add formalParams
|
result.add formalParams
|
||||||
result.add newEmptyNode()
|
result.add newEmptyNode()
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,8 @@
|
||||||
## constructor should be used for this purpose. However,
|
## constructor should be used for this purpose. However,
|
||||||
## currently only basic authentication is supported.
|
## currently only basic authentication is supported.
|
||||||
|
|
||||||
import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes, math
|
import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes,
|
||||||
|
math, random
|
||||||
import asyncnet, asyncdispatch
|
import asyncnet, asyncdispatch
|
||||||
import nativesockets
|
import nativesockets
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,6 @@ proc fac*(n: int): int {.noSideEffect.} =
|
||||||
|
|
||||||
when defined(Posix) and not defined(haiku):
|
when defined(Posix) and not defined(haiku):
|
||||||
{.passl: "-lm".}
|
{.passl: "-lm".}
|
||||||
when not defined(js) and not defined(nimscript):
|
|
||||||
import times
|
|
||||||
|
|
||||||
const
|
const
|
||||||
PI* = 3.1415926535897932384626433 ## the circle constant PI (Ludolph's number)
|
PI* = 3.1415926535897932384626433 ## the circle constant PI (Ludolph's number)
|
||||||
|
|
@ -119,30 +117,6 @@ proc sum*[T](x: openArray[T]): T {.noSideEffect.} =
|
||||||
## If `x` is empty, 0 is returned.
|
## If `x` is empty, 0 is returned.
|
||||||
for i in items(x): result = result + i
|
for i in items(x): result = result + i
|
||||||
|
|
||||||
proc random*(max: int): int {.benign.}
|
|
||||||
## Returns a random number in the range 0..max-1. The sequence of
|
|
||||||
## random number is always the same, unless `randomize` is called
|
|
||||||
## which initializes the random number generator with a "random"
|
|
||||||
## number, i.e. a tickcount.
|
|
||||||
|
|
||||||
proc random*(max: float): float {.benign.}
|
|
||||||
## Returns a random number in the range 0..<max. The sequence of
|
|
||||||
## random number is always the same, unless `randomize` is called
|
|
||||||
## which initializes the random number generator with a "random"
|
|
||||||
## number, i.e. a tickcount. This has a 16-bit resolution on windows
|
|
||||||
## and a 48-bit resolution on other platforms.
|
|
||||||
|
|
||||||
when not defined(nimscript):
|
|
||||||
proc randomize*() {.benign.}
|
|
||||||
## Initializes the random number generator with a "random"
|
|
||||||
## number, i.e. a tickcount. Note: Does nothing for the JavaScript target,
|
|
||||||
## as JavaScript does not support this. Nor does it work for NimScript.
|
|
||||||
|
|
||||||
proc randomize*(seed: int) {.benign.}
|
|
||||||
## Initializes the random number generator with a specific seed.
|
|
||||||
## Note: Does nothing for the JavaScript target,
|
|
||||||
## as JavaScript does not support this.
|
|
||||||
|
|
||||||
{.push noSideEffect.}
|
{.push noSideEffect.}
|
||||||
when not defined(JS):
|
when not defined(JS):
|
||||||
proc sqrt*(x: float32): float32 {.importc: "sqrtf", header: "<math.h>".}
|
proc sqrt*(x: float32): float32 {.importc: "sqrtf", header: "<math.h>".}
|
||||||
|
|
@ -239,57 +213,6 @@ when not defined(JS):
|
||||||
proc tgamma*(x: float64): float64 {.importc: "tgamma", header: "<math.h>".}
|
proc tgamma*(x: float64): float64 {.importc: "tgamma", header: "<math.h>".}
|
||||||
## The gamma function
|
## The gamma function
|
||||||
|
|
||||||
# C procs:
|
|
||||||
when defined(vcc) and false:
|
|
||||||
# The "secure" random, available from Windows XP
|
|
||||||
# https://msdn.microsoft.com/en-us/library/sxtz2fa8.aspx
|
|
||||||
# Present in some variants of MinGW but not enough to justify
|
|
||||||
# `when defined(windows)` yet
|
|
||||||
proc rand_s(val: var cuint) {.importc: "rand_s", header: "<stdlib.h>".}
|
|
||||||
# To behave like the normal version
|
|
||||||
proc rand(): cuint = rand_s(result)
|
|
||||||
else:
|
|
||||||
proc srand(seed: cint) {.importc: "srand", header: "<stdlib.h>".}
|
|
||||||
proc rand(): cint {.importc: "rand", header: "<stdlib.h>".}
|
|
||||||
|
|
||||||
when not defined(windows):
|
|
||||||
proc srand48(seed: clong) {.importc: "srand48", header: "<stdlib.h>".}
|
|
||||||
proc drand48(): float {.importc: "drand48", header: "<stdlib.h>".}
|
|
||||||
proc random(max: float): float =
|
|
||||||
result = drand48() * max
|
|
||||||
else:
|
|
||||||
when defined(vcc): # Windows with Visual C
|
|
||||||
proc random(max: float): float =
|
|
||||||
# we are hardcoding this because
|
|
||||||
# importc-ing macros is extremely problematic
|
|
||||||
# and because the value is publicly documented
|
|
||||||
# on MSDN and very unlikely to change
|
|
||||||
# See https://msdn.microsoft.com/en-us/library/296az74e.aspx
|
|
||||||
const rand_max = 4294967295 # UINT_MAX
|
|
||||||
result = (float(rand()) / float(rand_max)) * max
|
|
||||||
proc randomize() = discard
|
|
||||||
proc randomize(seed: int) = discard
|
|
||||||
else: # Windows with another compiler
|
|
||||||
proc random(max: float): float =
|
|
||||||
# we are hardcoding this because
|
|
||||||
# importc-ing macros is extremely problematic
|
|
||||||
# and because the value is publicly documented
|
|
||||||
# on MSDN and very unlikely to change
|
|
||||||
const rand_max = 32767
|
|
||||||
result = (float(rand()) / float(rand_max)) * max
|
|
||||||
|
|
||||||
when not defined(vcc): # the above code for vcc uses `discard` instead
|
|
||||||
# this is either not Windows or is Windows without vcc
|
|
||||||
when not defined(nimscript):
|
|
||||||
proc randomize() =
|
|
||||||
randomize(cast[int](epochTime()))
|
|
||||||
proc randomize(seed: int) =
|
|
||||||
srand(cint(seed)) # rand_s doesn't use srand
|
|
||||||
when declared(srand48): srand48(seed)
|
|
||||||
|
|
||||||
proc random(max: int): int =
|
|
||||||
result = int(rand()) mod max
|
|
||||||
|
|
||||||
proc trunc*(x: float32): float32 {.importc: "truncf", header: "<math.h>".}
|
proc trunc*(x: float32): float32 {.importc: "truncf", header: "<math.h>".}
|
||||||
proc trunc*(x: float64): float64 {.importc: "trunc", header: "<math.h>".}
|
proc trunc*(x: float64): float64 {.importc: "trunc", header: "<math.h>".}
|
||||||
## Truncates `x` to the decimal point
|
## Truncates `x` to the decimal point
|
||||||
|
|
@ -319,17 +242,10 @@ when not defined(JS):
|
||||||
## echo fmod(-2.5, 0.3) ## -0.1
|
## echo fmod(-2.5, 0.3) ## -0.1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
proc mathrandom(): float {.importc: "Math.random", nodecl.}
|
|
||||||
proc floor*(x: float32): float32 {.importc: "Math.floor", nodecl.}
|
proc floor*(x: float32): float32 {.importc: "Math.floor", nodecl.}
|
||||||
proc floor*(x: float64): float64 {.importc: "Math.floor", nodecl.}
|
proc floor*(x: float64): float64 {.importc: "Math.floor", nodecl.}
|
||||||
proc ceil*(x: float32): float32 {.importc: "Math.ceil", nodecl.}
|
proc ceil*(x: float32): float32 {.importc: "Math.ceil", nodecl.}
|
||||||
proc ceil*(x: float64): float64 {.importc: "Math.ceil", nodecl.}
|
proc ceil*(x: float64): float64 {.importc: "Math.ceil", nodecl.}
|
||||||
proc random(max: int): int =
|
|
||||||
result = int(floor(mathrandom() * float(max)))
|
|
||||||
proc random(max: float): float =
|
|
||||||
result = float(mathrandom() * float(max))
|
|
||||||
proc randomize() = discard
|
|
||||||
proc randomize(seed: int) = discard
|
|
||||||
|
|
||||||
proc sqrt*(x: float32): float32 {.importc: "Math.sqrt", nodecl.}
|
proc sqrt*(x: float32): float32 {.importc: "Math.sqrt", nodecl.}
|
||||||
proc sqrt*(x: float64): float64 {.importc: "Math.sqrt", nodecl.}
|
proc sqrt*(x: float64): float64 {.importc: "Math.sqrt", nodecl.}
|
||||||
|
|
@ -398,14 +314,6 @@ proc `mod`*[T: float32|float64](x, y: T): T =
|
||||||
## echo (4.0 mod -3.1) # -2.2
|
## echo (4.0 mod -3.1) # -2.2
|
||||||
result = if y == 0.0: x else: x - y * (x/y).floor
|
result = if y == 0.0: x else: x - y * (x/y).floor
|
||||||
|
|
||||||
proc random*[T](x: Slice[T]): T =
|
|
||||||
## For a slice `a .. b` returns a value in the range `a .. b-1`.
|
|
||||||
result = random(x.b - x.a) + x.a
|
|
||||||
|
|
||||||
proc random*[T](a: openArray[T]): T =
|
|
||||||
## returns a random element from the openarray `a`.
|
|
||||||
result = a[random(a.low..a.len)]
|
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
|
|
@ -440,24 +348,6 @@ proc lcm*[T](x, y: T): T =
|
||||||
x div gcd(x, y) * y
|
x div gcd(x, y) * y
|
||||||
|
|
||||||
when isMainModule and not defined(JS):
|
when isMainModule and not defined(JS):
|
||||||
proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".}
|
|
||||||
|
|
||||||
# Verifies random seed initialization.
|
|
||||||
let seed = gettime(nil)
|
|
||||||
randomize(seed)
|
|
||||||
const SIZE = 10
|
|
||||||
var buf : array[0..SIZE, int]
|
|
||||||
# Fill the buffer with random values
|
|
||||||
for i in 0..SIZE-1:
|
|
||||||
buf[i] = random(high(int))
|
|
||||||
# Check that the second random calls are the same for each position.
|
|
||||||
randomize(seed)
|
|
||||||
for i in 0..SIZE-1:
|
|
||||||
assert buf[i] == random(high(int)), "non deterministic random seeding"
|
|
||||||
|
|
||||||
when not defined(testing):
|
|
||||||
echo "random values equal after reseeding"
|
|
||||||
|
|
||||||
# Check for no side effect annotation
|
# Check for no side effect annotation
|
||||||
proc mySqrt(num: float): float {.noSideEffect.} =
|
proc mySqrt(num: float): float {.noSideEffect.} =
|
||||||
return sqrt(num)
|
return sqrt(num)
|
||||||
|
|
|
||||||
|
|
@ -606,28 +606,31 @@ proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {
|
||||||
var valuei = cint(if value: 1 else: 0)
|
var valuei = cint(if value: 1 else: 0)
|
||||||
setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei)
|
setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei)
|
||||||
|
|
||||||
when defined(posix) or defined(nimdoc):
|
when defined(posix) and not defined(nimdoc):
|
||||||
proc makeUnixAddr(path: string): Sockaddr_un =
|
proc makeUnixAddr(path: string): Sockaddr_un =
|
||||||
result.sun_family = AF_UNIX.toInt
|
result.sun_family = AF_UNIX.toInt
|
||||||
if path.len >= Sockaddr_un_path_length:
|
if path.len >= Sockaddr_un_path_length:
|
||||||
raise newException(ValueError, "socket path too long")
|
raise newException(ValueError, "socket path too long")
|
||||||
copyMem(addr result.sun_path, path.cstring, path.len + 1)
|
copyMem(addr result.sun_path, path.cstring, path.len + 1)
|
||||||
|
|
||||||
|
when defined(posix):
|
||||||
proc connectUnix*(socket: Socket, path: string) =
|
proc connectUnix*(socket: Socket, path: string) =
|
||||||
## Connects to Unix socket on `path`.
|
## Connects to Unix socket on `path`.
|
||||||
## This only works on Unix-style systems: Mac OS X, BSD and Linux
|
## This only works on Unix-style systems: Mac OS X, BSD and Linux
|
||||||
var socketAddr = makeUnixAddr(path)
|
when not defined(nimdoc):
|
||||||
if socket.fd.connect(cast[ptr SockAddr](addr socketAddr),
|
var socketAddr = makeUnixAddr(path)
|
||||||
sizeof(socketAddr).Socklen) != 0'i32:
|
if socket.fd.connect(cast[ptr SockAddr](addr socketAddr),
|
||||||
raiseOSError(osLastError())
|
sizeof(socketAddr).Socklen) != 0'i32:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
proc bindUnix*(socket: Socket, path: string) =
|
proc bindUnix*(socket: Socket, path: string) =
|
||||||
## Binds Unix socket to `path`.
|
## Binds Unix socket to `path`.
|
||||||
## This only works on Unix-style systems: Mac OS X, BSD and Linux
|
## This only works on Unix-style systems: Mac OS X, BSD and Linux
|
||||||
var socketAddr = makeUnixAddr(path)
|
when not defined(nimdoc):
|
||||||
if socket.fd.bindAddr(cast[ptr SockAddr](addr socketAddr),
|
var socketAddr = makeUnixAddr(path)
|
||||||
sizeof(socketAddr).Socklen) != 0'i32:
|
if socket.fd.bindAddr(cast[ptr SockAddr](addr socketAddr),
|
||||||
raiseOSError(osLastError())
|
sizeof(socketAddr).Socklen) != 0'i32:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
when defined(ssl):
|
when defined(ssl):
|
||||||
proc handshake*(socket: Socket): bool
|
proc handshake*(socket: Socket): bool
|
||||||
|
|
@ -1399,7 +1402,7 @@ proc connect*(socket: Socket, address: string, port = Port(0),
|
||||||
if selectWrite(s, timeout) != 1:
|
if selectWrite(s, timeout) != 1:
|
||||||
raise newException(TimeoutError, "Call to 'connect' timed out.")
|
raise newException(TimeoutError, "Call to 'connect' timed out.")
|
||||||
else:
|
else:
|
||||||
when defineSsl:
|
when defineSsl and not defined(nimdoc):
|
||||||
if socket.isSSL:
|
if socket.isSSL:
|
||||||
socket.fd.setBlocking(true)
|
socket.fd.setBlocking(true)
|
||||||
{.warning[Deprecated]: off.}
|
{.warning[Deprecated]: off.}
|
||||||
|
|
|
||||||
|
|
@ -15,21 +15,21 @@
|
||||||
|
|
||||||
## This is an example of how a configuration file may look like:
|
## This is an example of how a configuration file may look like:
|
||||||
##
|
##
|
||||||
## .. include:: doc/mytest.cfg
|
## .. include:: ../../doc/mytest.cfg
|
||||||
## :literal:
|
## :literal:
|
||||||
## The file ``examples/parsecfgex.nim`` demonstrates how to use the
|
## The file ``examples/parsecfgex.nim`` demonstrates how to use the
|
||||||
## configuration file parser:
|
## configuration file parser:
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## :file: examples/parsecfgex.nim
|
## :file: ../../examples/parsecfgex.nim
|
||||||
##
|
##
|
||||||
## Examples
|
## Examples
|
||||||
## --------
|
## --------
|
||||||
##
|
##
|
||||||
## This is an example of a configuration file.
|
## This is an example of a configuration file.
|
||||||
##
|
##
|
||||||
## .. include:: config.ini
|
## ::
|
||||||
##
|
##
|
||||||
## charset = "utf-8"
|
## charset = "utf-8"
|
||||||
## [Package]
|
## [Package]
|
||||||
## name = "hello"
|
## name = "hello"
|
||||||
|
|
@ -38,11 +38,11 @@
|
||||||
## name = "lihf8515"
|
## name = "lihf8515"
|
||||||
## qq = "10214028"
|
## qq = "10214028"
|
||||||
## email = "lihaifeng@wxm.com"
|
## email = "lihaifeng@wxm.com"
|
||||||
##
|
##
|
||||||
## Creating a configuration file.
|
## Creating a configuration file.
|
||||||
## ==============================
|
## ==============================
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
##
|
##
|
||||||
## import parsecfg
|
## import parsecfg
|
||||||
## var dict=newConfig()
|
## var dict=newConfig()
|
||||||
## dict.setSectionKey("","charset","utf-8")
|
## dict.setSectionKey("","charset","utf-8")
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
## dict.setSectionKey("Author","qq","10214028")
|
## dict.setSectionKey("Author","qq","10214028")
|
||||||
## dict.setSectionKey("Author","email","lihaifeng@wxm.com")
|
## dict.setSectionKey("Author","email","lihaifeng@wxm.com")
|
||||||
## dict.writeConfig("config.ini")
|
## dict.writeConfig("config.ini")
|
||||||
##
|
##
|
||||||
## Reading a configuration file.
|
## Reading a configuration file.
|
||||||
## =============================
|
## =============================
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
|
|
@ -66,11 +66,11 @@
|
||||||
## var qq = dict.getSectionValue("Author","qq")
|
## var qq = dict.getSectionValue("Author","qq")
|
||||||
## var email = dict.getSectionValue("Author","email")
|
## var email = dict.getSectionValue("Author","email")
|
||||||
## echo pname & "\n" & name & "\n" & qq & "\n" & email
|
## echo pname & "\n" & name & "\n" & qq & "\n" & email
|
||||||
##
|
##
|
||||||
## Modifying a configuration file.
|
## Modifying a configuration file.
|
||||||
## ===============================
|
## ===============================
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
##
|
##
|
||||||
## import parsecfg
|
## import parsecfg
|
||||||
## var dict = loadConfig("config.ini")
|
## var dict = loadConfig("config.ini")
|
||||||
## dict.setSectionKey("Author","name","lhf")
|
## dict.setSectionKey("Author","name","lhf")
|
||||||
|
|
@ -79,7 +79,7 @@
|
||||||
## Deleting a section key in a configuration file.
|
## Deleting a section key in a configuration file.
|
||||||
## ===============================================
|
## ===============================================
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
##
|
##
|
||||||
## import parsecfg
|
## import parsecfg
|
||||||
## var dict = loadConfig("config.ini")
|
## var dict = loadConfig("config.ini")
|
||||||
## dict.delSectionKey("Author","email")
|
## dict.delSectionKey("Author","email")
|
||||||
|
|
@ -434,7 +434,7 @@ proc loadConfig*(filename: string): Config =
|
||||||
## Load the specified configuration file into a new Config instance.
|
## Load the specified configuration file into a new Config instance.
|
||||||
var dict = newOrderedTable[string, OrderedTableRef[string, string]]()
|
var dict = newOrderedTable[string, OrderedTableRef[string, string]]()
|
||||||
var curSection = "" ## Current section,
|
var curSection = "" ## Current section,
|
||||||
## the default value of the current section is "",
|
## the default value of the current section is "",
|
||||||
## which means that the current section is a common
|
## which means that the current section is a common
|
||||||
var p: CfgParser
|
var p: CfgParser
|
||||||
var fileStream = newFileStream(filename, fmRead)
|
var fileStream = newFileStream(filename, fmRead)
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
## document.
|
## document.
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## :file: examples/htmltitle.nim
|
## :file: ../../examples/htmltitle.nim
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
## Example 2: Retrieve all HTML links
|
## Example 2: Retrieve all HTML links
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
## an HTML document contains.
|
## an HTML document contains.
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## :file: examples/htmlrefs.nim
|
## :file: ../../examples/htmlrefs.nim
|
||||||
##
|
##
|
||||||
|
|
||||||
import
|
import
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
## Matching performance is hopefully competitive with optimized regular
|
## Matching performance is hopefully competitive with optimized regular
|
||||||
## expression engines.
|
## expression engines.
|
||||||
##
|
##
|
||||||
## .. include:: ../doc/pegdocs.txt
|
## .. include:: ../../doc/pegdocs.txt
|
||||||
##
|
##
|
||||||
|
|
||||||
include "system/inclrtl"
|
include "system/inclrtl"
|
||||||
|
|
|
||||||
129
lib/pure/random.nim
Normal file
129
lib/pure/random.nim
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Nim's Runtime Library
|
||||||
|
# (c) Copyright 2016 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
##[Nim's standard random number generator. Based on
|
||||||
|
|
||||||
|
| `http://xoroshiro.di.unimi.it/`_
|
||||||
|
| `http://xoroshiro.di.unimi.it/xoroshiro128plus.c`_
|
||||||
|
]##
|
||||||
|
|
||||||
|
include "system/inclrtl"
|
||||||
|
{.push debugger:off.}
|
||||||
|
|
||||||
|
# XXX Expose RandomGenState
|
||||||
|
when defined(JS):
|
||||||
|
type ui = uint32
|
||||||
|
else:
|
||||||
|
type ui = uint64
|
||||||
|
|
||||||
|
type
|
||||||
|
RandomGenState = object
|
||||||
|
a0, a1: ui
|
||||||
|
|
||||||
|
when defined(JS):
|
||||||
|
var state = RandomGenState(
|
||||||
|
a0: 0x69B4C98Cu32,
|
||||||
|
a1: 0xFED1DD30u32) # global for backwards compatibility
|
||||||
|
else:
|
||||||
|
# racy for multi-threading but good enough for now:
|
||||||
|
var state = RandomGenState(
|
||||||
|
a0: 0x69B4C98CB8530805u64,
|
||||||
|
a1: 0xFED1DD3004688D67CAu64) # global for backwards compatibility
|
||||||
|
|
||||||
|
proc rotl(x, k: ui): ui =
|
||||||
|
result = (x shl k) or (x shr (ui(64) - k))
|
||||||
|
|
||||||
|
proc next(s: var RandomGenState): uint64 =
|
||||||
|
let s0 = s.a0
|
||||||
|
var s1 = s.a1
|
||||||
|
result = s0 + s1
|
||||||
|
s1 = s1 xor s0
|
||||||
|
s.a0 = rotl(s0, 55) xor s1 xor (s1 shl 14) # a, b
|
||||||
|
s.a1 = rotl(s1, 36) # c
|
||||||
|
|
||||||
|
proc skipRandomNumbers(s: var RandomGenState) =
|
||||||
|
## This is the jump function for the generator. It is equivalent
|
||||||
|
## to 2^64 calls to next(); it can be used to generate 2^64
|
||||||
|
## non-overlapping subsequences for parallel computations.
|
||||||
|
when defined(JS):
|
||||||
|
const helper = [0xbeac0467u32, 0xd86b048bu32]
|
||||||
|
else:
|
||||||
|
const helper = [0xbeac0467eba5facbu64, 0xd86b048b86aa9922u64]
|
||||||
|
var
|
||||||
|
s0 = ui 0
|
||||||
|
s1 = ui 0
|
||||||
|
for i in 0..high(helper):
|
||||||
|
for b in 0..< 64:
|
||||||
|
if (helper[i] and (ui(1) shl ui(b))) != 0:
|
||||||
|
s0 = s0 xor s.a0
|
||||||
|
s1 = s1 xor s.a1
|
||||||
|
discard next(s)
|
||||||
|
s.a0 = s0
|
||||||
|
s.a1 = s1
|
||||||
|
|
||||||
|
proc random*(max: int): int {.benign.} =
|
||||||
|
## Returns a random number in the range 0..max-1. The sequence of
|
||||||
|
## random number is always the same, unless `randomize` is called
|
||||||
|
## which initializes the random number generator with a "random"
|
||||||
|
## number, i.e. a tickcount.
|
||||||
|
result = int(next(state) mod uint64(max))
|
||||||
|
|
||||||
|
proc random*(max: float): float {.benign.} =
|
||||||
|
## Returns a random number in the range 0..<max. The sequence of
|
||||||
|
## random number is always the same, unless `randomize` is called
|
||||||
|
## which initializes the random number generator with a "random"
|
||||||
|
## number, i.e. a tickcount.
|
||||||
|
let x = next(state)
|
||||||
|
when defined(JS):
|
||||||
|
result = (float(x) / float(high(uint32))) * max
|
||||||
|
else:
|
||||||
|
let u = (0x3FFu64 shl 52u64) or (x shr 12u64)
|
||||||
|
result = (cast[float](u) - 1.0) * max
|
||||||
|
|
||||||
|
proc random*[T](x: Slice[T]): T =
|
||||||
|
## For a slice `a .. b` returns a value in the range `a .. b-1`.
|
||||||
|
result = random(x.b - x.a) + x.a
|
||||||
|
|
||||||
|
proc random*[T](a: openArray[T]): T =
|
||||||
|
## returns a random element from the openarray `a`.
|
||||||
|
result = a[random(a.low..a.len)]
|
||||||
|
|
||||||
|
proc randomize*(seed: int) {.benign.} =
|
||||||
|
## Initializes the random number generator with a specific seed.
|
||||||
|
state.a0 = ui(seed shr 16)
|
||||||
|
state.a1 = ui(seed and 0xffff)
|
||||||
|
|
||||||
|
when not defined(nimscript):
|
||||||
|
import times
|
||||||
|
|
||||||
|
proc randomize*() {.benign.} =
|
||||||
|
## Initializes the random number generator with a "random"
|
||||||
|
## number, i.e. a tickcount. Note: Does not work for NimScript.
|
||||||
|
when defined(JS):
|
||||||
|
proc getMil(t: Time): int {.importcpp: "getTime", nodecl.}
|
||||||
|
randomize(getMil times.getTime())
|
||||||
|
else:
|
||||||
|
randomize(int times.getTime())
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
proc main =
|
||||||
|
var occur: array[1000, int]
|
||||||
|
|
||||||
|
var x = 8234
|
||||||
|
for i in 0..100_000:
|
||||||
|
x = random(len(occur)) # myrand(x)
|
||||||
|
inc occur[x]
|
||||||
|
for i, oc in occur:
|
||||||
|
if oc < 69:
|
||||||
|
doAssert false, "too few occurances of " & $i
|
||||||
|
elif oc > 130:
|
||||||
|
doAssert false, "too many occurances of " & $i
|
||||||
|
main()
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## Nim support for `substitution expressions`:idx: (`subex`:idx:).
|
## Nim support for `substitution expressions`:idx: (`subex`:idx:).
|
||||||
##
|
##
|
||||||
## .. include:: ../doc/subexes.txt
|
## .. include:: ../../doc/subexes.txt
|
||||||
##
|
##
|
||||||
|
|
||||||
{.push debugger:off .} # the user does not want to trace a part
|
{.push debugger:off .} # the user does not want to trace a part
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,9 @@ when defined(posix) and not defined(JS):
|
||||||
proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {.
|
proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {.
|
||||||
importc: "gettimeofday", header: "<sys/time.h>".}
|
importc: "gettimeofday", header: "<sys/time.h>".}
|
||||||
|
|
||||||
var
|
when not defined(freebsd) and not defined(netbsd) and not defined(openbsd):
|
||||||
timezone {.importc, header: "<time.h>".}: int
|
var timezone {.importc, header: "<time.h>".}: int
|
||||||
|
var
|
||||||
tzname {.importc, header: "<time.h>" .}: array[0..1, cstring]
|
tzname {.importc, header: "<time.h>" .}: array[0..1, cstring]
|
||||||
# we also need tzset() to make sure that tzname is initialized
|
# we also need tzset() to make sure that tzname is initialized
|
||||||
proc tzset() {.importc, header: "<time.h>".}
|
proc tzset() {.importc, header: "<time.h>".}
|
||||||
|
|
@ -416,18 +417,32 @@ when not defined(JS):
|
||||||
|
|
||||||
when not defined(JS):
|
when not defined(JS):
|
||||||
# C wrapper:
|
# C wrapper:
|
||||||
|
when defined(freebsd) or defined(netbsd) or defined(openbsd):
|
||||||
|
type
|
||||||
|
StructTM {.importc: "struct tm", final.} = object
|
||||||
|
second {.importc: "tm_sec".},
|
||||||
|
minute {.importc: "tm_min".},
|
||||||
|
hour {.importc: "tm_hour".},
|
||||||
|
monthday {.importc: "tm_mday".},
|
||||||
|
month {.importc: "tm_mon".},
|
||||||
|
year {.importc: "tm_year".},
|
||||||
|
weekday {.importc: "tm_wday".},
|
||||||
|
yearday {.importc: "tm_yday".},
|
||||||
|
isdst {.importc: "tm_isdst".}: cint
|
||||||
|
gmtoff {.importc: "tm_gmtoff".}: clong
|
||||||
|
else:
|
||||||
|
type
|
||||||
|
StructTM {.importc: "struct tm", final.} = object
|
||||||
|
second {.importc: "tm_sec".},
|
||||||
|
minute {.importc: "tm_min".},
|
||||||
|
hour {.importc: "tm_hour".},
|
||||||
|
monthday {.importc: "tm_mday".},
|
||||||
|
month {.importc: "tm_mon".},
|
||||||
|
year {.importc: "tm_year".},
|
||||||
|
weekday {.importc: "tm_wday".},
|
||||||
|
yearday {.importc: "tm_yday".},
|
||||||
|
isdst {.importc: "tm_isdst".}: cint
|
||||||
type
|
type
|
||||||
StructTM {.importc: "struct tm", final.} = object
|
|
||||||
second {.importc: "tm_sec".},
|
|
||||||
minute {.importc: "tm_min".},
|
|
||||||
hour {.importc: "tm_hour".},
|
|
||||||
monthday {.importc: "tm_mday".},
|
|
||||||
month {.importc: "tm_mon".},
|
|
||||||
year {.importc: "tm_year".},
|
|
||||||
weekday {.importc: "tm_wday".},
|
|
||||||
yearday {.importc: "tm_yday".},
|
|
||||||
isdst {.importc: "tm_isdst".}: cint
|
|
||||||
|
|
||||||
TimeInfoPtr = ptr StructTM
|
TimeInfoPtr = ptr StructTM
|
||||||
Clock {.importc: "clock_t".} = distinct int
|
Clock {.importc: "clock_t".} = distinct int
|
||||||
|
|
||||||
|
|
@ -457,24 +472,47 @@ when not defined(JS):
|
||||||
const
|
const
|
||||||
weekDays: array [0..6, WeekDay] = [
|
weekDays: array [0..6, WeekDay] = [
|
||||||
dSun, dMon, dTue, dWed, dThu, dFri, dSat]
|
dSun, dMon, dTue, dWed, dThu, dFri, dSat]
|
||||||
TimeInfo(second: int(tm.second),
|
when defined(freebsd) or defined(netbsd) or defined(openbsd):
|
||||||
minute: int(tm.minute),
|
TimeInfo(second: int(tm.second),
|
||||||
hour: int(tm.hour),
|
minute: int(tm.minute),
|
||||||
monthday: int(tm.monthday),
|
hour: int(tm.hour),
|
||||||
month: Month(tm.month),
|
monthday: int(tm.monthday),
|
||||||
year: tm.year + 1900'i32,
|
month: Month(tm.month),
|
||||||
weekday: weekDays[int(tm.weekday)],
|
year: tm.year + 1900'i32,
|
||||||
yearday: int(tm.yearday),
|
weekday: weekDays[int(tm.weekday)],
|
||||||
isDST: tm.isdst > 0,
|
yearday: int(tm.yearday),
|
||||||
tzname: if local:
|
isDST: tm.isdst > 0,
|
||||||
if tm.isdst > 0:
|
tzname: if local:
|
||||||
getTzname().DST
|
if tm.isdst > 0:
|
||||||
|
getTzname().DST
|
||||||
|
else:
|
||||||
|
getTzname().nonDST
|
||||||
else:
|
else:
|
||||||
getTzname().nonDST
|
"UTC",
|
||||||
else:
|
# BSD stores in `gmtoff` offset east of UTC in seconds,
|
||||||
"UTC",
|
# but posix systems using west of UTC in seconds
|
||||||
timezone: if local: getTimezone() else: 0
|
timezone: if local: -(tm.gmtoff) else: 0
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
TimeInfo(second: int(tm.second),
|
||||||
|
minute: int(tm.minute),
|
||||||
|
hour: int(tm.hour),
|
||||||
|
monthday: int(tm.monthday),
|
||||||
|
month: Month(tm.month),
|
||||||
|
year: tm.year + 1900'i32,
|
||||||
|
weekday: weekDays[int(tm.weekday)],
|
||||||
|
yearday: int(tm.yearday),
|
||||||
|
isDST: tm.isdst > 0,
|
||||||
|
tzname: if local:
|
||||||
|
if tm.isdst > 0:
|
||||||
|
getTzname().DST
|
||||||
|
else:
|
||||||
|
getTzname().nonDST
|
||||||
|
else:
|
||||||
|
"UTC",
|
||||||
|
timezone: if local: getTimezone() else: 0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
proc timeInfoToTM(t: TimeInfo): StructTM =
|
proc timeInfoToTM(t: TimeInfo): StructTM =
|
||||||
const
|
const
|
||||||
|
|
@ -564,7 +602,14 @@ when not defined(JS):
|
||||||
return ($tzname[0], $tzname[1])
|
return ($tzname[0], $tzname[1])
|
||||||
|
|
||||||
proc getTimezone(): int =
|
proc getTimezone(): int =
|
||||||
return timezone
|
when defined(freebsd) or defined(netbsd) or defined(openbsd):
|
||||||
|
var a = timec(nil)
|
||||||
|
let lt = localtime(addr(a))
|
||||||
|
# BSD stores in `gmtoff` offset east of UTC in seconds,
|
||||||
|
# but posix systems using west of UTC in seconds
|
||||||
|
return -(lt.gmtoff)
|
||||||
|
else:
|
||||||
|
return timezone
|
||||||
|
|
||||||
proc fromSeconds(since1970: float): Time = Time(since1970)
|
proc fromSeconds(since1970: float): Time = Time(since1970)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} =
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
##
|
##
|
||||||
## import math
|
## import math, random
|
||||||
## proc defectiveRobot() =
|
## proc defectiveRobot() =
|
||||||
## randomize()
|
## randomize()
|
||||||
## case random(1..4)
|
## case random(1..4)
|
||||||
|
|
|
||||||
|
|
@ -2514,7 +2514,7 @@ template newException*(exceptn: typedesc, message: string): expr =
|
||||||
e
|
e
|
||||||
|
|
||||||
when hostOS == "standalone":
|
when hostOS == "standalone":
|
||||||
include panicoverride
|
include "$projectpath/panicoverride"
|
||||||
|
|
||||||
when not declared(sysFatal):
|
when not declared(sysFatal):
|
||||||
when hostOS == "standalone":
|
when hostOS == "standalone":
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ discard """
|
||||||
action: run
|
action: run
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import math, strutils
|
import math, random, strutils
|
||||||
const consolePrefix = "jsCallbacks"
|
const consolePrefix = "jsCallbacks"
|
||||||
|
|
||||||
asm """
|
asm """
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
sfml, chipmunk,
|
sfml, chipmunk,
|
||||||
sg_assets, sfml_stuff, keineschweine
|
sg_assets, sfml_stuff, "../keineschweine"
|
||||||
|
|
||||||
|
|
||||||
proc accel*(obj: PVehicle, dt: float) =
|
proc accel*(obj: PVehicle, dt: float) =
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import nake
|
import nake
|
||||||
import httpclient, zip/zipfiles, times, math, sequtils
|
import httpclient, zip/zipfiles, times, random, sequtils
|
||||||
nakeImports
|
nakeImports
|
||||||
|
|
||||||
randomize()
|
randomize()
|
||||||
|
|
@ -145,7 +145,7 @@ task "download", "download game assets":
|
||||||
echo "Extracted the libs dir. Copy the ones you need to this dir."
|
echo "Extracted the libs dir. Copy the ones you need to this dir."
|
||||||
|
|
||||||
task "zip-lib", "zip up the libs dir":
|
task "zip-lib", "zip up the libs dir":
|
||||||
var z: TZipArchive
|
var z: ZipArchive
|
||||||
if not z.open("libs-" & getDateStr() & ".zip", fmReadWrite):
|
if not z.open("libs-" & getDateStr() & ".zip", fmReadWrite):
|
||||||
quit "Could not open zip"
|
quit "Could not open zip"
|
||||||
for file in walkDirRec("libs", {pcFile, pcDir}):
|
for file in walkDirRec("libs", {pcFile, pcDir}):
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
# this file only exists to mark 'main.nim' as the main file
|
# this file only exists to mark 'main.nim' as the main file
|
||||||
|
|
||||||
|
--path:"$projectpath"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
tri_engine/config,
|
../config,
|
||||||
tri_engine/math/vec
|
vec
|
||||||
|
|
||||||
type
|
type
|
||||||
TCircle* = tuple[p: TV2[TR], r: TR]
|
TCircle* = tuple[p: TV2[TR], r: TR]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
macros,
|
macros,
|
||||||
tri_engine/config
|
"../config"
|
||||||
|
|
||||||
type
|
type
|
||||||
TV2*[T:SomeNumber=TR] = array[0..1, T]
|
TV2*[T:SomeNumber=TR] = array[0..1, T]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ discard """
|
||||||
output: "Success"
|
output: "Success"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import math, threadPool
|
import math, random, threadPool
|
||||||
|
|
||||||
# ---
|
# ---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import math
|
import math, random
|
||||||
import unittest
|
import unittest
|
||||||
import sets
|
import sets
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ test "unittest multiple requires":
|
||||||
require(true)
|
require(true)
|
||||||
|
|
||||||
|
|
||||||
import math
|
import math, random
|
||||||
from strutils import parseInt
|
from strutils import parseInt
|
||||||
proc defectiveRobot() =
|
proc defectiveRobot() =
|
||||||
randomize()
|
randomize()
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ discard """
|
||||||
|
|
||||||
# bug #1816
|
# bug #1816
|
||||||
|
|
||||||
from math import random
|
from random import random
|
||||||
from os import sleep
|
from os import sleep
|
||||||
|
|
||||||
type PComm = ptr Channel[int]
|
type PComm = ptr Channel[int]
|
||||||
|
|
|
||||||
16
web/news.txt
16
web/news.txt
|
|
@ -2,7 +2,7 @@
|
||||||
News
|
News
|
||||||
====
|
====
|
||||||
|
|
||||||
2016-XX-XX Version 0.13.1 released
|
2016-XX-XX Version 0.14.0 released
|
||||||
==================================
|
==================================
|
||||||
|
|
||||||
Changes affecting backwards compatibility
|
Changes affecting backwards compatibility
|
||||||
|
|
@ -39,6 +39,12 @@ Changes affecting backwards compatibility
|
||||||
you need that.
|
you need that.
|
||||||
- The ``json.%`` operator is now overloaded for ``object``, ``ref object`` and
|
- The ``json.%`` operator is now overloaded for ``object``, ``ref object`` and
|
||||||
``openarray[T]``.
|
``openarray[T]``.
|
||||||
|
- The procs related to ``random`` number generation in ``math.nim`` have
|
||||||
|
been moved to its own ``random`` module and been reimplemented in pure
|
||||||
|
Nim.
|
||||||
|
- The path handling changed. The project directory is not added to the
|
||||||
|
search path automatically anymore. Add this line to your project's
|
||||||
|
config to get back the old behaviour: ``--path:"$projectdir"``.
|
||||||
|
|
||||||
|
|
||||||
Library Additions
|
Library Additions
|
||||||
|
|
@ -64,11 +70,13 @@ Language Additions
|
||||||
|
|
||||||
- Nim now supports a ``.this`` pragma for more notational convenience.
|
- Nim now supports a ``.this`` pragma for more notational convenience.
|
||||||
- Nim now supports a different ``using`` statement for more convenience.
|
- Nim now supports a different ``using`` statement for more convenience.
|
||||||
- Nim now supports ``partial`` object declarations to mitigate the problems
|
|
||||||
that arise when types are mutually dependent and yet should be kept in
|
|
||||||
different modules.
|
|
||||||
- ``include`` statements are not restricted to top level statements anymore.
|
- ``include`` statements are not restricted to top level statements anymore.
|
||||||
|
|
||||||
|
..
|
||||||
|
- Nim now supports ``partial`` object declarations to mitigate the problems
|
||||||
|
that arise when types are mutually dependent and yet should be kept in
|
||||||
|
different modules.
|
||||||
|
|
||||||
|
|
||||||
2016-01-27 Nim in Action is now available!
|
2016-01-27 Nim in Action is now available!
|
||||||
==========================================
|
==========================================
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ srcdoc2: "impure/re;pure/typetraits"
|
||||||
srcdoc2: "pure/concurrency/threadpool.nim;pure/concurrency/cpuinfo.nim"
|
srcdoc2: "pure/concurrency/threadpool.nim;pure/concurrency/cpuinfo.nim"
|
||||||
srcdoc: "system/threads.nim;system/channels.nim;js/dom"
|
srcdoc: "system/threads.nim;system/channels.nim;js/dom"
|
||||||
srcdoc2: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm"
|
srcdoc2: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm"
|
||||||
srcdoc2: "pure/stats;impure/nre;windows/winlean"
|
srcdoc2: "pure/stats;impure/nre;windows/winlean;pure/random"
|
||||||
srcdoc2: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib;pure/strscans"
|
srcdoc2: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib;pure/strscans"
|
||||||
srcdoc2: "pure/parseopt;pure/parseopt2;pure/hashes;pure/strtabs;pure/lexbase"
|
srcdoc2: "pure/parseopt;pure/parseopt2;pure/hashes;pure/strtabs;pure/lexbase"
|
||||||
srcdoc2: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql"
|
srcdoc2: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue