Merge branch 'devel' of github.com:nim-lang/Nim into devel

This commit is contained in:
Araq 2018-03-12 09:02:21 +01:00
commit 8683c8a389
15 changed files with 258 additions and 104 deletions

View file

@ -22,6 +22,14 @@
### Tool changes ### 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 ### Compiler changes
### Bugfixes ### 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)

View file

@ -617,8 +617,10 @@ proc scanCppGenericSlot(pat: string, cursor, outIdx, outStars: var int): bool =
return false return false
proc resolveStarsInCppType(typ: PType, idx, stars: int): PType = proc resolveStarsInCppType(typ: PType, idx, stars: int): PType =
# XXX: we should catch this earlier and report it as a semantic error # Make sure the index refers to one of the generic params of the type.
if idx >= typ.len: internalError "invalid apostrophe type parameter index" # 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] result = typ.sons[idx]
for i in 1..stars: 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) let typeInSlot = resolveStarsInCppType(origTyp, idx + 1, stars)
if typeInSlot == nil or typeInSlot.kind == tyVoid: if typeInSlot == nil or typeInSlot.kind == tyVoid:
result.add(~"void") result.add(~"void")
elif typeInSlot.kind == tyStatic:
internalAssert typeInSlot.n != nil
result.add typeInSlot.n.renderTree
else: else:
result.add getTypeDescAux(m, typeInSlot, check) result.add getTypeDescAux(m, typeInSlot, check)
else: else:

View file

@ -210,14 +210,14 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) =
gCmd = cmdRst2tex gCmd = cmdRst2tex
loadConfigs(DocTexConfig, cache) loadConfigs(DocTexConfig, cache)
commandRst2TeX() commandRst2TeX()
of "jsondoc": of "jsondoc0":
wantMainModule() wantMainModule()
gCmd = cmdDoc gCmd = cmdDoc
loadConfigs(DocConfig, cache) loadConfigs(DocConfig, cache)
wantMainModule() wantMainModule()
defineSymbol("nimdoc") defineSymbol("nimdoc")
commandJson() commandJson()
of "jsondoc2": of "jsondoc2", "jsondoc":
gCmd = cmdDoc gCmd = cmdDoc
loadConfigs(DocConfig, cache) loadConfigs(DocConfig, cache)
wantMainModule() wantMainModule()

View file

@ -255,69 +255,61 @@ proc semCase(c: PContext, n: PNode): PNode =
result.typ = typ result.typ = typ
proc semTry(c: PContext, n: PNode): PNode = 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 result = n
inc c.p.inTryStmt inc c.p.inTryStmt
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2)
var typ = commonTypeBegin var typ = commonTypeBegin
n.sons[0] = semExprBranchScope(c, n.sons[0]) n[0] = semExprBranchScope(c, n[0])
typ = commonType(typ, n.sons[0].typ) typ = commonType(typ, n[0].typ)
var check = initIntSet()
var last = sonsLen(n) - 1 var last = sonsLen(n) - 1
for i in countup(1, last): for i in countup(1, last):
var a = n.sons[i] let a = n.sons[i]
checkMinSonsLen(a, 1) checkMinSonsLen(a, 1)
var length = sonsLen(a)
openScope(c) openScope(c)
if a.kind == nkExceptBranch: 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. if a.len == 2 and a[0].kind == nkBracket:
for j in countup(0, length-2): # rewrite ``except [a, b, c]: body`` -> ```except a, b, c: body```
var typeNode = a.sons[j] # e.g. `Exception` a.sons[0..0] = a[0].sons
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]
# Resolve the type ident into a PType. if a.len == 2 and a[0].isInfixAs():
var typ = semTypeNode(c, typeNode, nil).toObject() # support ``except Exception as ex: body``
if typ.kind != tyObject: a[0][1] = semExceptBranchType(a[0][1])
localError(a.sons[j].info, errExprCannotBeRaised)
let newTypeNode = newNodeI(nkType, typeNode.info) let symbol = newSymG(skLet, a[0][2], c)
newTypeNode.typ = typ symbol.typ = a[0][1].typ.toRef()
if symbolNode.isNil: addDecl(c, symbol)
a.sons[j] = newTypeNode # Overwrite symbol in AST with the symbol in the symbol table.
else: a[0][2] = newSymNode(symbol, a[0][2].info)
a.sons[j].sons[1] = newTypeNode
# Add the exception ident to the symbol table. else:
let symbol = newSymG(skLet, symbolNode, c) # support ``except KeyError, ValueError, ... : body``
symbol.typ = typ.toRef() for j in 0..a.len-2:
addDecl(c, symbol) a[j] = semExceptBranchType(a[j])
# 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)
elif a.kind != nkFinally: elif a.kind != nkFinally:
illFormedAst(n) illFormedAst(n)
# last child of an nkExcept/nkFinally branch is a statement: # last child of an nkExcept/nkFinally branch is a statement:
a.sons[length-1] = semExprBranchScope(c, a.sons[length-1]) a[^1] = semExprBranchScope(c, a[^1])
if a.kind != nkFinally: typ = commonType(typ, a.sons[length-1].typ) if a.kind != nkFinally: typ = commonType(typ, a[^1])
else: dec last else: dec last
closeScope(c) closeScope(c)
dec c.p.inTryStmt 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]) discardCheck(c, n.sons[0])
for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon) for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon)
if typ == enforceVoidContext: if typ == enforceVoidContext:

View file

@ -632,16 +632,18 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
else: else:
typ = semTypeNode(c, n.sons[length-2], nil) typ = semTypeNode(c, n.sons[length-2], nil)
propagateToOwner(rectype, typ) 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): for i in countup(0, sonsLen(n)-3):
var f = semIdentWithPragma(c, skField, n.sons[i], {sfExported}) var f = semIdentWithPragma(c, skField, n.sons[i], {sfExported})
suggestSym(n.sons[i].info, f, c.graph.usageSym) suggestSym(n.sons[i].info, f, c.graph.usageSym)
f.typ = typ f.typ = typ
f.position = pos f.position = pos
if (rec != nil) and ({sfImportc, sfExportc} * rec.flags != {}) and if fieldOwner != nil and
(f.loc.r == nil): {sfImportc, sfExportc} * fieldOwner.flags != {} and
f.loc.r == nil:
f.loc.r = rope(f.name.s) 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) inc(pos)
if containsOrIncl(check, f.name.id): if containsOrIncl(check, f.name.id):
localError(n.sons[i].info, errAttemptToRedefine, f.name.s) localError(n.sons[i].info, errAttemptToRedefine, f.name.s)

View file

@ -7,7 +7,6 @@ Advanced commands:
//rst2html convert a reStructuredText file to HTML //rst2html convert a reStructuredText file to HTML
//rst2tex convert a reStructuredText file to TeX //rst2tex convert a reStructuredText file to TeX
//jsondoc extract the documentation to a json file //jsondoc extract the documentation to a json file
//jsondoc2 extract the documentation to a json file (uses doc2)
//ctags create a tags file //ctags create a tags file
//buildIndex build an index for the whole documentation //buildIndex build an index for the whole documentation
//run run the project (with Tiny C backend; buggy!) //run run the project (with Tiny C backend; buggy!)

View file

@ -84,51 +84,72 @@ Document Types
HTML HTML
---- ----
Generation of HTML documents is done via both the ``doc`` and ``doc2`` Generation of HTML documents is done via the ``doc`` command. This command
commands. These command take either a single .nim file, outputting a single takes either a single .nim file, outputting a single .html file with the same
.html file with the same base filename, or multiple .nim files, outputting base filename, or multiple .nim files, outputting multiple .html files and,
multiple .html files and, optionally, an index file. optionally, an index file.
The ``doc`` command:: The ``doc`` command::
nim doc sample 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:: Partial Output::
... ...
proc helloWorld(times: int) {.raises: [], tags: [].} proc helloWorld(times: int) {.raises: [], tags: [].}
... ...
The full output can be seen here: `docgen_sample2.html <docgen_sample2.html>`_. 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 The older version of the ``doc`` command, now renamed ``doc0`` runs before
implicitly by the compiler. This type of information is not available from semantic checking which means it lacks some of the things ``doc`` will output.
looking at the AST (Abstract Syntax Tree) prior to semantic checking, as the
``doc`` command does. 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 JSON
---- ----
Generation of JSON documents is done via the ``jsondoc`` command. This command 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. takes in a .nim file, and outputs a .json file with the same base filename. Note
Note that this tool is built off of the ``doc`` command, and therefore is that this tool is built off of the ``doc`` command (previously ``doc2``), and
performed before semantic checking. contains the same information.
The ``jsondoc`` command:: The ``jsondoc`` command::
nim jsondoc sample 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 &quot;hello world!&quot;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:: 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 Related Options
=============== ===============

View file

@ -11,11 +11,23 @@
## It supports one convenience iterator over all command line options and some ## It supports one convenience iterator over all command line options and some
## lower-level features. ## lower-level features.
## ##
## Supported syntax: ## Supported syntax with default empty ``shortNoVal``/``longNoVal``:
## ##
## 1. short options - ``-abcd``, where a, b, c, d are names ## 1. short options - ``-abcd``, where a, b, c, d are names
## 2. long option - ``--foo:bar``, ``--foo=bar`` or ``--foo`` ## 2. long option - ``--foo:bar``, ``--foo=bar`` or ``--foo``
## 3. argument - everything else ## 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.} {.push debugger: off.}
@ -32,9 +44,11 @@ type
cmdShortOption ## a short option ``-c`` detected cmdShortOption ## a short option ``-c`` detected
OptParser* = OptParser* =
object of RootObj ## this object implements the command line parser object of RootObj ## this object implements the command line parser
cmd: string cmd*: string # cmd,pos exported so caller can catch "--" as..
pos: int pos*: int # ..empty key or subcmd cmdArg & handle specially
inShortState: bool inShortState: bool
shortNoVal: set[char]
longNoVal: seq[string]
kind*: CmdLineKind ## the dected command line token kind*: CmdLineKind ## the dected command line token
key*, val*: TaintedString ## key and value pair; ``key`` is the option key*, val*: TaintedString ## key and value pair; ``key`` is the option
## or the argument, ``value`` is not "" if ## 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 # we cannot provide this for NimRtl creation on Posix, because we can't
# access the command line arguments then! # 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 ## 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.pos = 0
result.inShortState = false result.inShortState = false
result.shortNoVal = shortNoVal
result.longNoVal = longNoVal
if cmdline != "": if cmdline != "":
result.cmd = cmdline result.cmd = cmdline
else: else:
@ -94,15 +116,19 @@ when declared(os.paramCount):
result.key = TaintedString"" result.key = TaintedString""
result.val = 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 ## 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.pos = 0
result.inShortState = false result.inShortState = false
result.shortNoVal = shortNoVal
result.longNoVal = longNoVal
result.cmd = "" result.cmd = ""
if cmdline.len != 0: if cmdline.len != 0:
for i in 0..<cmdline.len: for i in 0..<cmdline.len:
result.cmd.add quote(cmdline[i]) result.cmd.add quote(cmdline[i].string)
result.cmd.add ' ' result.cmd.add ' '
else: else:
for i in countup(1, paramCount()): for i in countup(1, paramCount()):
@ -121,8 +147,9 @@ proc handleShortOption(p: var OptParser) =
while p.cmd[i] in {'\x09', ' '}: while p.cmd[i] in {'\x09', ' '}:
inc(i) inc(i)
p.inShortState = false p.inShortState = false
if p.cmd[i] in {':', '='}: if p.cmd[i] in {':', '='} or card(p.shortNoVal) > 0 and p.key.string[0] notin p.shortNoVal:
inc(i) if p.cmd[i] in {':', '='}:
inc(i)
p.inShortState = false p.inShortState = false
while p.cmd[i] in {'\x09', ' '}: inc(i) while p.cmd[i] in {'\x09', ' '}: inc(i)
i = parseWord(p.cmd, i, p.val.string) i = parseWord(p.cmd, i, p.val.string)
@ -146,12 +173,13 @@ proc next*(p: var OptParser) {.rtl, extern: "npo$1".} =
of '-': of '-':
inc(i) inc(i)
if p.cmd[i] == '-': if p.cmd[i] == '-':
p.kind = cmdLongoption p.kind = cmdLongOption
inc(i) inc(i)
i = parseWord(p.cmd, i, p.key.string, {'\0', ' ', '\x09', ':', '='}) i = parseWord(p.cmd, i, p.key.string, {'\0', ' ', '\x09', ':', '='})
while p.cmd[i] in {'\x09', ' '}: inc(i) while p.cmd[i] in {'\x09', ' '}: inc(i)
if p.cmd[i] in {':', '='}: if p.cmd[i] in {':', '='} or len(p.longNoVal) > 0 and p.key.string notin p.longNoVal:
inc(i) if p.cmd[i] in {':', '='}:
inc(i)
while p.cmd[i] in {'\x09', ' '}: inc(i) while p.cmd[i] in {'\x09', ' '}: inc(i)
p.pos = parseWord(p.cmd, i, p.val.string) p.pos = parseWord(p.cmd, i, p.val.string)
else: else:
@ -172,7 +200,7 @@ iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key, val: TaintedSt
## Example: ## Example:
## ##
## .. code-block:: nim ## .. 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(): ## for kind, key, val in p.getopt():
## case kind ## case kind
## of cmdArgument: ## of cmdArgument:
@ -192,17 +220,30 @@ iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key, val: TaintedSt
yield (p.kind, p.key, p.val) yield (p.kind, p.key, p.val)
when declared(initOptParser): when declared(initOptParser):
iterator getopt*(): tuple[kind: CmdLineKind, key, val: TaintedString] = iterator getopt*(cmdline: seq[TaintedString] = commandLineParams(),
## This is an convenience iterator for iterating over the command line arguments. shortNoVal: set[char]={}, longNoVal: seq[string] = @[]):
## This create a new OptParser object. tuple[kind: CmdLineKind, key, val: TaintedString] =
## See above for a more detailed example ## 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 ## .. code-block:: nim
## for kind, key, val in getopt(): ## for kind, key, val in getopt(shortNoVal = { 'l' },
## # this will iterate over all arguments passed to the cmdline. ## longNoVal = @[ "left" ]):
## continue ## 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: while true:
next(p) next(p)
if p.kind == cmdEnd: break if p.kind == cmdEnd: break

View file

@ -1250,7 +1250,7 @@ proc wordWrap*(s: string, maxLineWidth = 80,
if len(word) > spaceLeft: if len(word) > spaceLeft:
if splitLongWords and len(word) > maxLineWidth: if splitLongWords and len(word) > maxLineWidth:
result.add(substr(word, 0, spaceLeft-1)) result.add(substr(word, 0, spaceLeft-1))
var w = spaceLeft+1 var w = spaceLeft
var wordLeft = len(word) - spaceLeft var wordLeft = len(word) - spaceLeft
while wordLeft > 0: while wordLeft > 0:
result.add(newLine) result.add(newLine)
@ -2514,6 +2514,11 @@ when isMainModule:
outp = " this is a\nlong text\n--\nmuchlongerthan10chars\nand here\nit goes" outp = " this is a\nlong text\n--\nmuchlongerthan10chars\nand here\nit goes"
doAssert wordWrap(inp, 10, false) == outp 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, -1) == "1234.567000"
doAssert formatBiggestFloat(1234.567, ffDecimal, 0) == "1235." doAssert formatBiggestFloat(1234.567, ffDecimal, 0) == "1235."
doAssert formatBiggestFloat(1234.567, ffDecimal, 1) == "1234.6" doAssert formatBiggestFloat(1234.567, ffDecimal, 1) == "1234.6"

View file

@ -1461,9 +1461,9 @@ when defined(nodejs):
programResult = 0 programResult = 0
else: else:
var programResult* {.exportc: "nim_program_result".}: int var programResult* {.exportc: "nim_program_result".}: int
## modify this variable to specify the exit code of the program ## modify this variable to specify the exit code of the program
## under normal circumstances. When the program is terminated ## under normal circumstances. When the program is terminated
## prematurely using ``quit``, this value is ignored. ## prematurely using ``quit``, this value is ignored.
when defined(nimdoc): when defined(nimdoc):
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn.} proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn.}

View file

@ -32,3 +32,11 @@ proc testTryAsExpr(i: int) =
test[Exception]() test[Exception]()
test2() test2()
testTryAsExpr(5) testTryAsExpr(5)
# see bug #7115
doAssert(not compiles(
try:
echo 1
except [KeyError as ex1, ValueError as ex2]:
echo 2
))

View file

@ -9,6 +9,17 @@ kind: cmdLongOption key:val -- left:
kind: cmdLongOption key:val -- debug:3 kind: cmdLongOption key:val -- debug:3
kind: cmdShortOption key:val -- l:4 kind: cmdShortOption key:val -- l:4
kind: cmdShortOption key:val -- r:2 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 parseopt2
first round first round
kind: cmdLongOption key:val -- left: kind: cmdLongOption key:val -- left:
@ -39,6 +50,15 @@ block:
for kind, key, val in parseopt.getopt(p): for kind, key, val in parseopt.getopt(p):
echo "kind: ", kind, "\tkey:val -- ", key, ":", val 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: block:
echo "parseopt2" echo "parseopt2"
for kind, key, val in parseopt2.getopt(): for kind, key, val in parseopt2.getopt():

View 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

View file

@ -10,7 +10,7 @@ _nim()
if [ $COMP_CWORD -eq 1 ] ; then if [ $COMP_CWORD -eq 1 ] ; then
# first item - suggest commands # 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 ) ) COMPREPLY=( $( compgen -W "${kw}" -- $cur ) )
return 0 return 0
fi fi

View file

@ -5,7 +5,6 @@ _nim() {
':command:(( ':command:((
{compile,c}\:compile\ project\ with\ default\ code\ generator\ C {compile,c}\:compile\ project\ with\ default\ code\ generator\ C
doc\:generate\ the\ documentation\ for\ inputfile doc\:generate\ the\ documentation\ for\ inputfile
doc2\:generate\ the\ documentation\ for\ inputfile
{compileToC,cc}\:compile\ project\ with\ C\ code\ generator {compileToC,cc}\:compile\ project\ with\ C\ code\ generator
{compileToCpp,cpp}\:compile\ project\ to\ C++\ code {compileToCpp,cpp}\:compile\ project\ to\ C++\ code
{compileToOC,objc}\:compile\ project\ to\ Objective\ C\ code {compileToOC,objc}\:compile\ project\ to\ Objective\ C\ code
@ -14,7 +13,6 @@ _nim() {
rst2html\:convert\ a\ reStructuredText\ file\ to\ HTML rst2html\:convert\ a\ reStructuredText\ file\ to\ HTML
rst2tex\:convert\ a\ reStructuredText\ file\ to\ TeX rst2tex\:convert\ a\ reStructuredText\ file\ to\ TeX
jsondoc\:extract\ the\ documentation\ to\ a\ json\ file 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 buildIndex\:build\ an\ index\ for\ the\ whole\ documentation
genDepend\:generate\ a\ DOT\ file\ containing\ the\ module\ dependency\ graph genDepend\:generate\ a\ DOT\ file\ containing\ the\ module\ dependency\ graph
dump\:dump\ all\ defined\ conditionals\ and\ search\ paths dump\:dump\ all\ defined\ conditionals\ and\ search\ paths