mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-11 22:28:12 +00:00
Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
@@ -22,6 +22,14 @@
|
||||
|
||||
### Tool changes
|
||||
|
||||
- ``jsondoc2`` has been renamed ``jsondoc``, similar to how ``doc2`` was renamed
|
||||
``doc``. The old ``jsondoc`` can still be invoked with ``jsondoc0``.
|
||||
|
||||
### Compiler changes
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- The `importcpp` pragma now allows importing the listed fields of generic
|
||||
C++ types. Support for numeric parameters have also been added through
|
||||
the use of `static[T]` types.
|
||||
(#6415)
|
||||
|
||||
@@ -617,8 +617,10 @@ proc scanCppGenericSlot(pat: string, cursor, outIdx, outStars: var int): bool =
|
||||
return false
|
||||
|
||||
proc resolveStarsInCppType(typ: PType, idx, stars: int): PType =
|
||||
# XXX: we should catch this earlier and report it as a semantic error
|
||||
if idx >= typ.len: internalError "invalid apostrophe type parameter index"
|
||||
# Make sure the index refers to one of the generic params of the type.
|
||||
# XXX: we should catch this earlier and report it as a semantic error.
|
||||
if idx >= typ.len:
|
||||
internalError "invalid apostrophe type parameter index"
|
||||
|
||||
result = typ.sons[idx]
|
||||
for i in 1..stars:
|
||||
@@ -820,6 +822,9 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||
let typeInSlot = resolveStarsInCppType(origTyp, idx + 1, stars)
|
||||
if typeInSlot == nil or typeInSlot.kind == tyVoid:
|
||||
result.add(~"void")
|
||||
elif typeInSlot.kind == tyStatic:
|
||||
internalAssert typeInSlot.n != nil
|
||||
result.add typeInSlot.n.renderTree
|
||||
else:
|
||||
result.add getTypeDescAux(m, typeInSlot, check)
|
||||
else:
|
||||
|
||||
@@ -210,14 +210,14 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) =
|
||||
gCmd = cmdRst2tex
|
||||
loadConfigs(DocTexConfig, cache)
|
||||
commandRst2TeX()
|
||||
of "jsondoc":
|
||||
of "jsondoc0":
|
||||
wantMainModule()
|
||||
gCmd = cmdDoc
|
||||
loadConfigs(DocConfig, cache)
|
||||
wantMainModule()
|
||||
defineSymbol("nimdoc")
|
||||
commandJson()
|
||||
of "jsondoc2":
|
||||
of "jsondoc2", "jsondoc":
|
||||
gCmd = cmdDoc
|
||||
loadConfigs(DocConfig, cache)
|
||||
wantMainModule()
|
||||
|
||||
@@ -255,69 +255,61 @@ proc semCase(c: PContext, n: PNode): PNode =
|
||||
result.typ = typ
|
||||
|
||||
proc semTry(c: PContext, n: PNode): PNode =
|
||||
|
||||
var check = initIntSet()
|
||||
template semExceptBranchType(typeNode: PNode): PNode =
|
||||
let typ = semTypeNode(c, typeNode, nil).toObject()
|
||||
if typ.kind != tyObject:
|
||||
localError(typeNode.info, errExprCannotBeRaised)
|
||||
if containsOrIncl(check, typ.id):
|
||||
localError(typeNode.info, errExceptionAlreadyHandled)
|
||||
newNodeIT(nkType, typeNode.info, typ)
|
||||
|
||||
result = n
|
||||
inc c.p.inTryStmt
|
||||
checkMinSonsLen(n, 2)
|
||||
|
||||
var typ = commonTypeBegin
|
||||
n.sons[0] = semExprBranchScope(c, n.sons[0])
|
||||
typ = commonType(typ, n.sons[0].typ)
|
||||
n[0] = semExprBranchScope(c, n[0])
|
||||
typ = commonType(typ, n[0].typ)
|
||||
|
||||
var check = initIntSet()
|
||||
var last = sonsLen(n) - 1
|
||||
for i in countup(1, last):
|
||||
var a = n.sons[i]
|
||||
let a = n.sons[i]
|
||||
checkMinSonsLen(a, 1)
|
||||
var length = sonsLen(a)
|
||||
openScope(c)
|
||||
if a.kind == nkExceptBranch:
|
||||
# so that ``except [a, b, c]`` is supported:
|
||||
if length == 2 and a.sons[0].kind == nkBracket:
|
||||
a.sons[0..0] = a.sons[0].sons
|
||||
length = a.sonsLen
|
||||
|
||||
# Iterate through each exception type in the except branch.
|
||||
for j in countup(0, length-2):
|
||||
var typeNode = a.sons[j] # e.g. `Exception`
|
||||
var symbolNode: PNode = nil # e.g. `foobar`
|
||||
# Handle the case where the `Exception as foobar` syntax is used.
|
||||
if typeNode.isInfixAs():
|
||||
typeNode = a.sons[j].sons[1]
|
||||
symbolNode = a.sons[j].sons[2]
|
||||
if a.len == 2 and a[0].kind == nkBracket:
|
||||
# rewrite ``except [a, b, c]: body`` -> ```except a, b, c: body```
|
||||
a.sons[0..0] = a[0].sons
|
||||
|
||||
if a.len == 2 and a[0].isInfixAs():
|
||||
# support ``except Exception as ex: body``
|
||||
a[0][1] = semExceptBranchType(a[0][1])
|
||||
|
||||
# Resolve the type ident into a PType.
|
||||
var typ = semTypeNode(c, typeNode, nil).toObject()
|
||||
if typ.kind != tyObject:
|
||||
localError(a.sons[j].info, errExprCannotBeRaised)
|
||||
let symbol = newSymG(skLet, a[0][2], c)
|
||||
symbol.typ = a[0][1].typ.toRef()
|
||||
addDecl(c, symbol)
|
||||
# Overwrite symbol in AST with the symbol in the symbol table.
|
||||
a[0][2] = newSymNode(symbol, a[0][2].info)
|
||||
|
||||
let newTypeNode = newNodeI(nkType, typeNode.info)
|
||||
newTypeNode.typ = typ
|
||||
if symbolNode.isNil:
|
||||
a.sons[j] = newTypeNode
|
||||
else:
|
||||
a.sons[j].sons[1] = newTypeNode
|
||||
# Add the exception ident to the symbol table.
|
||||
let symbol = newSymG(skLet, symbolNode, c)
|
||||
symbol.typ = typ.toRef()
|
||||
addDecl(c, symbol)
|
||||
# Overwrite symbol in AST with the symbol in the symbol table.
|
||||
let symNode = newNodeI(nkSym, typeNode.info)
|
||||
symNode.sym = symbol
|
||||
a.sons[j].sons[2] = symNode
|
||||
|
||||
if containsOrIncl(check, typ.id):
|
||||
localError(a.sons[j].info, errExceptionAlreadyHandled)
|
||||
else:
|
||||
# support ``except KeyError, ValueError, ... : body``
|
||||
for j in 0..a.len-2:
|
||||
a[j] = semExceptBranchType(a[j])
|
||||
|
||||
elif a.kind != nkFinally:
|
||||
illFormedAst(n)
|
||||
|
||||
# last child of an nkExcept/nkFinally branch is a statement:
|
||||
a.sons[length-1] = semExprBranchScope(c, a.sons[length-1])
|
||||
if a.kind != nkFinally: typ = commonType(typ, a.sons[length-1].typ)
|
||||
a[^1] = semExprBranchScope(c, a[^1])
|
||||
if a.kind != nkFinally: typ = commonType(typ, a[^1])
|
||||
else: dec last
|
||||
closeScope(c)
|
||||
|
||||
dec c.p.inTryStmt
|
||||
if isEmptyType(typ) or typ.kind == tyNil:
|
||||
if isEmptyType(typ) or typ.kind in {tyNil, tyExpr}:
|
||||
discardCheck(c, n.sons[0])
|
||||
for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon)
|
||||
if typ == enforceVoidContext:
|
||||
|
||||
@@ -632,16 +632,18 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||
else:
|
||||
typ = semTypeNode(c, n.sons[length-2], nil)
|
||||
propagateToOwner(rectype, typ)
|
||||
let rec = rectype.sym
|
||||
var fieldOwner = if c.inGenericContext > 0: c.getCurrOwner
|
||||
else: rectype.sym
|
||||
for i in countup(0, sonsLen(n)-3):
|
||||
var f = semIdentWithPragma(c, skField, n.sons[i], {sfExported})
|
||||
suggestSym(n.sons[i].info, f, c.graph.usageSym)
|
||||
f.typ = typ
|
||||
f.position = pos
|
||||
if (rec != nil) and ({sfImportc, sfExportc} * rec.flags != {}) and
|
||||
(f.loc.r == nil):
|
||||
if fieldOwner != nil and
|
||||
{sfImportc, sfExportc} * fieldOwner.flags != {} and
|
||||
f.loc.r == nil:
|
||||
f.loc.r = rope(f.name.s)
|
||||
f.flags = f.flags + ({sfImportc, sfExportc} * rec.flags)
|
||||
f.flags = f.flags + ({sfImportc, sfExportc} * fieldOwner.flags)
|
||||
inc(pos)
|
||||
if containsOrIncl(check, f.name.id):
|
||||
localError(n.sons[i].info, errAttemptToRedefine, f.name.s)
|
||||
|
||||
@@ -7,7 +7,6 @@ Advanced commands:
|
||||
//rst2html convert a reStructuredText file to HTML
|
||||
//rst2tex convert a reStructuredText file to TeX
|
||||
//jsondoc extract the documentation to a json file
|
||||
//jsondoc2 extract the documentation to a json file (uses doc2)
|
||||
//ctags create a tags file
|
||||
//buildIndex build an index for the whole documentation
|
||||
//run run the project (with Tiny C backend; buggy!)
|
||||
|
||||
@@ -84,51 +84,72 @@ Document Types
|
||||
HTML
|
||||
----
|
||||
|
||||
Generation of HTML documents is done via both the ``doc`` and ``doc2``
|
||||
commands. These command take either a single .nim file, outputting a single
|
||||
.html file with the same base filename, or multiple .nim files, outputting
|
||||
multiple .html files and, optionally, an index file.
|
||||
Generation of HTML documents is done via the ``doc`` command. This command
|
||||
takes either a single .nim file, outputting a single .html file with the same
|
||||
base filename, or multiple .nim files, outputting multiple .html files and,
|
||||
optionally, an index file.
|
||||
|
||||
The ``doc`` command::
|
||||
nim doc sample
|
||||
|
||||
Partial Output::
|
||||
...
|
||||
proc helloWorld*(times: int)
|
||||
...
|
||||
|
||||
Output can be viewed in full here: `docgen_sample.html <docgen_sample.html>`_.
|
||||
The next command, called ``doc2``, is very similar to the ``doc`` command, but
|
||||
will be run after the compiler performs semantic checking on the input nim
|
||||
module(s), which allows it to process macros.
|
||||
|
||||
The ``doc2`` command::
|
||||
nim doc2 sample
|
||||
|
||||
Partial Output::
|
||||
...
|
||||
proc helloWorld(times: int) {.raises: [], tags: [].}
|
||||
...
|
||||
|
||||
The full output can be seen here: `docgen_sample2.html <docgen_sample2.html>`_.
|
||||
As you can see, the tool has extracted additional information provided to it by
|
||||
the compiler beyond what the ``doc`` command provides, such as pragmas attached
|
||||
implicitly by the compiler. This type of information is not available from
|
||||
looking at the AST (Abstract Syntax Tree) prior to semantic checking, as the
|
||||
``doc`` command does.
|
||||
|
||||
The older version of the ``doc`` command, now renamed ``doc0`` runs before
|
||||
semantic checking which means it lacks some of the things ``doc`` will output.
|
||||
|
||||
The ``doc0`` command::
|
||||
nim doc0 sample
|
||||
|
||||
Partial Output::
|
||||
...
|
||||
proc helloWorld*(times: int)
|
||||
...
|
||||
|
||||
Output can be viewed in full here: `docgen_sample.html <docgen_sample.html>`_.
|
||||
As you can see, the tool has extracted less information than what the ``doc``
|
||||
command provides, such as pragmas attached implicitly by the compiler. This type
|
||||
of information is not available from looking at the AST (Abstract Syntax Tree)
|
||||
prior to semantic checking, which is why ``doc0`` doesn't show it.
|
||||
|
||||
|
||||
JSON
|
||||
----
|
||||
|
||||
Generation of JSON documents is done via the ``jsondoc`` command. This command
|
||||
takes in a .nim file, and outputs a .json file with the same base filename.
|
||||
Note that this tool is built off of the ``doc`` command, and therefore is
|
||||
performed before semantic checking.
|
||||
takes in a .nim file, and outputs a .json file with the same base filename. Note
|
||||
that this tool is built off of the ``doc`` command (previously ``doc2``), and
|
||||
contains the same information.
|
||||
|
||||
The ``jsondoc`` command::
|
||||
nim jsondoc sample
|
||||
|
||||
Output::
|
||||
{
|
||||
"orig": "docgen_sample.nim",
|
||||
"nimble": "",
|
||||
"entries": [
|
||||
{
|
||||
"name": "helloWorld",
|
||||
"type": "skProc",
|
||||
"line": 5,
|
||||
"col": 0,
|
||||
"description": "Takes an integer and outputs as many "hello world!"s",
|
||||
"code": "proc helloWorld(times: int) {.raises: [], tags: [].}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Similarly to the old ``doc`` command the old ``jsondoc`` command has been
|
||||
renamed ``jsondoc0``.
|
||||
|
||||
The ``jsondoc0`` command::
|
||||
nim jsondoc0 sample
|
||||
|
||||
Output::
|
||||
[
|
||||
{
|
||||
@@ -142,6 +163,8 @@ Output::
|
||||
}
|
||||
]
|
||||
|
||||
Note that the ``jsondoc`` command outputs it's JSON without pretty-printing it,
|
||||
while ``jsondoc0`` outputs pretty-printed JSON.
|
||||
|
||||
Related Options
|
||||
===============
|
||||
|
||||
@@ -11,11 +11,23 @@
|
||||
## It supports one convenience iterator over all command line options and some
|
||||
## lower-level features.
|
||||
##
|
||||
## Supported syntax:
|
||||
## Supported syntax with default empty ``shortNoVal``/``longNoVal``:
|
||||
##
|
||||
## 1. short options - ``-abcd``, where a, b, c, d are names
|
||||
## 2. long option - ``--foo:bar``, ``--foo=bar`` or ``--foo``
|
||||
## 3. argument - everything else
|
||||
##
|
||||
## When ``shortNoVal``/``longNoVal`` are non-empty then the ':' and '=' above
|
||||
## are still accepted, but become optional. Note that these option key sets
|
||||
## must be updated along with the set of option keys taking no value, but
|
||||
## keys which do take values need no special updates as their set evolves.
|
||||
##
|
||||
## When option values begin with ':' or '=' they need to be doubled up (as in
|
||||
## ``--delim::``) or alternated (as in ``--delim=:``).
|
||||
##
|
||||
## The common ``--`` non-option argument delimiter appears as an empty string
|
||||
## long option key. ``OptParser.cmd``, ``OptParser.pos``, and
|
||||
## ``os.parseCmdLine`` may be used to complete parsing in that case.
|
||||
|
||||
{.push debugger: off.}
|
||||
|
||||
@@ -32,9 +44,11 @@ type
|
||||
cmdShortOption ## a short option ``-c`` detected
|
||||
OptParser* =
|
||||
object of RootObj ## this object implements the command line parser
|
||||
cmd: string
|
||||
pos: int
|
||||
cmd*: string # cmd,pos exported so caller can catch "--" as..
|
||||
pos*: int # ..empty key or subcmd cmdArg & handle specially
|
||||
inShortState: bool
|
||||
shortNoVal: set[char]
|
||||
longNoVal: seq[string]
|
||||
kind*: CmdLineKind ## the dected command line token
|
||||
key*, val*: TaintedString ## key and value pair; ``key`` is the option
|
||||
## or the argument, ``value`` is not "" if
|
||||
@@ -78,11 +92,19 @@ when declared(os.paramCount):
|
||||
# we cannot provide this for NimRtl creation on Posix, because we can't
|
||||
# access the command line arguments then!
|
||||
|
||||
proc initOptParser*(cmdline = ""): OptParser =
|
||||
proc initOptParser*(cmdline = "", shortNoVal: set[char]={},
|
||||
longNoVal: seq[string] = @[]): OptParser =
|
||||
## inits the option parser. If ``cmdline == ""``, the real command line
|
||||
## (as provided by the ``OS`` module) is taken.
|
||||
## (as provided by the ``OS`` module) is taken. If ``shortNoVal`` is
|
||||
## provided command users do not need to delimit short option keys and
|
||||
## values with a ':' or '='. If ``longNoVal`` is provided command users do
|
||||
## not need to delimit long option keys and values with a ':' or '='
|
||||
## (though they still need at least a space). In both cases, ':' or '='
|
||||
## may still be used if desired. They just become optional.
|
||||
result.pos = 0
|
||||
result.inShortState = false
|
||||
result.shortNoVal = shortNoVal
|
||||
result.longNoVal = longNoVal
|
||||
if cmdline != "":
|
||||
result.cmd = cmdline
|
||||
else:
|
||||
@@ -94,15 +116,19 @@ when declared(os.paramCount):
|
||||
result.key = TaintedString""
|
||||
result.val = TaintedString""
|
||||
|
||||
proc initOptParser*(cmdline: seq[string]): OptParser =
|
||||
proc initOptParser*(cmdline: seq[TaintedString], shortNoVal: set[char]={},
|
||||
longNoVal: seq[string] = @[]): OptParser =
|
||||
## inits the option parser. If ``cmdline.len == 0``, the real command line
|
||||
## (as provided by the ``OS`` module) is taken.
|
||||
## (as provided by the ``OS`` module) is taken. ``shortNoVal`` and
|
||||
## ``longNoVal`` behavior is the same as for ``initOptParser(string,...)``.
|
||||
result.pos = 0
|
||||
result.inShortState = false
|
||||
result.shortNoVal = shortNoVal
|
||||
result.longNoVal = longNoVal
|
||||
result.cmd = ""
|
||||
if cmdline.len != 0:
|
||||
for i in 0..<cmdline.len:
|
||||
result.cmd.add quote(cmdline[i])
|
||||
result.cmd.add quote(cmdline[i].string)
|
||||
result.cmd.add ' '
|
||||
else:
|
||||
for i in countup(1, paramCount()):
|
||||
@@ -121,8 +147,9 @@ proc handleShortOption(p: var OptParser) =
|
||||
while p.cmd[i] in {'\x09', ' '}:
|
||||
inc(i)
|
||||
p.inShortState = false
|
||||
if p.cmd[i] in {':', '='}:
|
||||
inc(i)
|
||||
if p.cmd[i] in {':', '='} or card(p.shortNoVal) > 0 and p.key.string[0] notin p.shortNoVal:
|
||||
if p.cmd[i] in {':', '='}:
|
||||
inc(i)
|
||||
p.inShortState = false
|
||||
while p.cmd[i] in {'\x09', ' '}: inc(i)
|
||||
i = parseWord(p.cmd, i, p.val.string)
|
||||
@@ -146,12 +173,13 @@ proc next*(p: var OptParser) {.rtl, extern: "npo$1".} =
|
||||
of '-':
|
||||
inc(i)
|
||||
if p.cmd[i] == '-':
|
||||
p.kind = cmdLongoption
|
||||
p.kind = cmdLongOption
|
||||
inc(i)
|
||||
i = parseWord(p.cmd, i, p.key.string, {'\0', ' ', '\x09', ':', '='})
|
||||
while p.cmd[i] in {'\x09', ' '}: inc(i)
|
||||
if p.cmd[i] in {':', '='}:
|
||||
inc(i)
|
||||
if p.cmd[i] in {':', '='} or len(p.longNoVal) > 0 and p.key.string notin p.longNoVal:
|
||||
if p.cmd[i] in {':', '='}:
|
||||
inc(i)
|
||||
while p.cmd[i] in {'\x09', ' '}: inc(i)
|
||||
p.pos = parseWord(p.cmd, i, p.val.string)
|
||||
else:
|
||||
@@ -172,7 +200,7 @@ iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key, val: TaintedSt
|
||||
## Example:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
## var p = initOptParser("--left --debug:3 -l=4 -r:2")
|
||||
## var p = initOptParser("--left --debug:3 -l -r:2")
|
||||
## for kind, key, val in p.getopt():
|
||||
## case kind
|
||||
## of cmdArgument:
|
||||
@@ -192,17 +220,30 @@ iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key, val: TaintedSt
|
||||
yield (p.kind, p.key, p.val)
|
||||
|
||||
when declared(initOptParser):
|
||||
iterator getopt*(): tuple[kind: CmdLineKind, key, val: TaintedString] =
|
||||
## This is an convenience iterator for iterating over the command line arguments.
|
||||
## This create a new OptParser object.
|
||||
## See above for a more detailed example
|
||||
iterator getopt*(cmdline: seq[TaintedString] = commandLineParams(),
|
||||
shortNoVal: set[char]={}, longNoVal: seq[string] = @[]):
|
||||
tuple[kind: CmdLineKind, key, val: TaintedString] =
|
||||
## This is an convenience iterator for iterating over command line arguments.
|
||||
## This creates a new OptParser. See the above ``getopt(var OptParser)``
|
||||
## example for using default empty ``NoVal`` parameters. This example is
|
||||
## for the same option keys as that example but here option key-value
|
||||
## separators become optional for command users:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
## for kind, key, val in getopt():
|
||||
## # this will iterate over all arguments passed to the cmdline.
|
||||
## continue
|
||||
## for kind, key, val in getopt(shortNoVal = { 'l' },
|
||||
## longNoVal = @[ "left" ]):
|
||||
## case kind
|
||||
## of cmdArgument:
|
||||
## filename = key
|
||||
## of cmdLongOption, cmdShortOption:
|
||||
## case key
|
||||
## of "help", "h": writeHelp()
|
||||
## of "version", "v": writeVersion()
|
||||
## of cmdEnd: assert(false) # cannot happen
|
||||
## if filename == "":
|
||||
## writeHelp()
|
||||
##
|
||||
var p = initOptParser()
|
||||
var p = initOptParser(cmdline, shortNoVal=shortNoVal, longNoVal=longNoVal)
|
||||
while true:
|
||||
next(p)
|
||||
if p.kind == cmdEnd: break
|
||||
|
||||
@@ -1250,7 +1250,7 @@ proc wordWrap*(s: string, maxLineWidth = 80,
|
||||
if len(word) > spaceLeft:
|
||||
if splitLongWords and len(word) > maxLineWidth:
|
||||
result.add(substr(word, 0, spaceLeft-1))
|
||||
var w = spaceLeft+1
|
||||
var w = spaceLeft
|
||||
var wordLeft = len(word) - spaceLeft
|
||||
while wordLeft > 0:
|
||||
result.add(newLine)
|
||||
@@ -2514,6 +2514,11 @@ when isMainModule:
|
||||
outp = " this is a\nlong text\n--\nmuchlongerthan10chars\nand here\nit goes"
|
||||
doAssert wordWrap(inp, 10, false) == outp
|
||||
|
||||
let
|
||||
longInp = """ThisIsOneVeryLongStringWhichWeWillSplitIntoEightSeparatePartsNow"""
|
||||
longOutp = "ThisIsOn\neVeryLon\ngStringW\nhichWeWi\nllSplitI\nntoEight\nSeparate\nPartsNow"
|
||||
doAssert wordWrap(longInp, 8, true) == longOutp
|
||||
|
||||
doAssert formatBiggestFloat(1234.567, ffDecimal, -1) == "1234.567000"
|
||||
doAssert formatBiggestFloat(1234.567, ffDecimal, 0) == "1235."
|
||||
doAssert formatBiggestFloat(1234.567, ffDecimal, 1) == "1234.6"
|
||||
|
||||
@@ -1461,9 +1461,9 @@ when defined(nodejs):
|
||||
programResult = 0
|
||||
else:
|
||||
var programResult* {.exportc: "nim_program_result".}: int
|
||||
## modify this variable to specify the exit code of the program
|
||||
## under normal circumstances. When the program is terminated
|
||||
## prematurely using ``quit``, this value is ignored.
|
||||
## modify this variable to specify the exit code of the program
|
||||
## under normal circumstances. When the program is terminated
|
||||
## prematurely using ``quit``, this value is ignored.
|
||||
|
||||
when defined(nimdoc):
|
||||
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn.}
|
||||
|
||||
@@ -32,3 +32,11 @@ proc testTryAsExpr(i: int) =
|
||||
test[Exception]()
|
||||
test2()
|
||||
testTryAsExpr(5)
|
||||
|
||||
# see bug #7115
|
||||
doAssert(not compiles(
|
||||
try:
|
||||
echo 1
|
||||
except [KeyError as ex1, ValueError as ex2]:
|
||||
echo 2
|
||||
))
|
||||
|
||||
@@ -9,6 +9,17 @@ kind: cmdLongOption key:val -- left:
|
||||
kind: cmdLongOption key:val -- debug:3
|
||||
kind: cmdShortOption key:val -- l:4
|
||||
kind: cmdShortOption key:val -- r:2
|
||||
parseoptNoVal
|
||||
kind: cmdLongOption key:val -- left:
|
||||
kind: cmdLongOption key:val -- debug:3
|
||||
kind: cmdShortOption key:val -- l:
|
||||
kind: cmdShortOption key:val -- r:2
|
||||
kind: cmdLongOption key:val -- debug:2
|
||||
kind: cmdLongOption key:val -- debug:1
|
||||
kind: cmdShortOption key:val -- r:1
|
||||
kind: cmdShortOption key:val -- r:0
|
||||
kind: cmdShortOption key:val -- l:
|
||||
kind: cmdShortOption key:val -- r:4
|
||||
parseopt2
|
||||
first round
|
||||
kind: cmdLongOption key:val -- left:
|
||||
@@ -39,6 +50,15 @@ block:
|
||||
for kind, key, val in parseopt.getopt(p):
|
||||
echo "kind: ", kind, "\tkey:val -- ", key, ":", val
|
||||
|
||||
block:
|
||||
echo "parseoptNoVal"
|
||||
# test NoVal mode with custom cmdline arguments
|
||||
var argv = "--left --debug:3 -l -r:2 --debug 2 --debug=1 -r1 -r=0 -lr4"
|
||||
var p = parseopt.initOptParser(argv,
|
||||
shortNoVal = {'l'}, longNoVal = @["left"])
|
||||
for kind, key, val in parseopt.getopt(p):
|
||||
echo "kind: ", kind, "\tkey:val -- ", key, ":", val
|
||||
|
||||
block:
|
||||
echo "parseopt2"
|
||||
for kind, key, val in parseopt2.getopt():
|
||||
|
||||
53
tests/statictypes/tstaticimportcpp.nim
Normal file
53
tests/statictypes/tstaticimportcpp.nim
Normal file
@@ -0,0 +1,53 @@
|
||||
discard """
|
||||
targets: "cpp"
|
||||
output: "[0, 0, 10, 0]\n5\n1.2\n15\ntest"
|
||||
"""
|
||||
|
||||
{.emit: """
|
||||
|
||||
template <int N, class T>
|
||||
struct GenericIntType {
|
||||
T data[N];
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct GenericTType {
|
||||
T field;
|
||||
};
|
||||
|
||||
struct SimpleStruct {
|
||||
int field;
|
||||
};
|
||||
|
||||
|
||||
""" .}
|
||||
|
||||
type
|
||||
GenericIntType {.importcpp: "GenericIntType<'0, '1>".} [N: static[int]; T] = object
|
||||
data: array[N, T]
|
||||
|
||||
GenericTType {.importcpp: "GenericTType<'0>".} [T] = object
|
||||
field: T
|
||||
|
||||
GenInt4 = GenericIntType[4, int]
|
||||
|
||||
SimpleStruct {.importcpp: "SimpleStruct"} = object
|
||||
field: int
|
||||
|
||||
var
|
||||
a = GenInt4()
|
||||
b = SimpleStruct()
|
||||
c = GenericTType[float]()
|
||||
d = SimpleStruct(field: 15)
|
||||
e = GenericTType[string](field: "test")
|
||||
|
||||
a.data[2] = 10
|
||||
b.field = 5
|
||||
c.field = 1.2
|
||||
|
||||
echo a.data
|
||||
echo b.field
|
||||
echo c.field
|
||||
echo d.field
|
||||
echo e.field
|
||||
|
||||
@@ -10,7 +10,7 @@ _nim()
|
||||
|
||||
if [ $COMP_CWORD -eq 1 ] ; then
|
||||
# first item - suggest commands
|
||||
kw="compile c doc doc2 compileToC cc compileToCpp cpp compileToOC objc js e rst2html rst2tex jsondoc jsondoc2 buildIndex genDepend dump check"
|
||||
kw="compile c doc compileToC cc compileToCpp cpp compileToOC objc js e rst2html rst2tex jsondoc buildIndex genDepend dump check"
|
||||
COMPREPLY=( $( compgen -W "${kw}" -- $cur ) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -5,7 +5,6 @@ _nim() {
|
||||
':command:((
|
||||
{compile,c}\:compile\ project\ with\ default\ code\ generator\ C
|
||||
doc\:generate\ the\ documentation\ for\ inputfile
|
||||
doc2\:generate\ the\ documentation\ for\ inputfile
|
||||
{compileToC,cc}\:compile\ project\ with\ C\ code\ generator
|
||||
{compileToCpp,cpp}\:compile\ project\ to\ C++\ code
|
||||
{compileToOC,objc}\:compile\ project\ to\ Objective\ C\ code
|
||||
@@ -14,7 +13,6 @@ _nim() {
|
||||
rst2html\:convert\ a\ reStructuredText\ file\ to\ HTML
|
||||
rst2tex\:convert\ a\ reStructuredText\ file\ to\ TeX
|
||||
jsondoc\:extract\ the\ documentation\ to\ a\ json\ file
|
||||
jsondoc2\:extract\ documentation\ to\ a\ json\ file\ using\ doc2
|
||||
buildIndex\:build\ an\ index\ for\ the\ whole\ documentation
|
||||
genDepend\:generate\ a\ DOT\ file\ containing\ the\ module\ dependency\ graph
|
||||
dump\:dump\ all\ defined\ conditionals\ and\ search\ paths
|
||||
|
||||
Reference in New Issue
Block a user