Merge branch 'devel' of https://github.com/Araq/Nim into devel
This commit is contained in:
commit
2b4e233510
18 changed files with 192 additions and 54 deletions
|
|
@ -796,8 +796,8 @@ type
|
||||||
# for enum types a list of symbols
|
# for enum types a list of symbols
|
||||||
# for tyInt it can be the int literal
|
# for tyInt it can be the int literal
|
||||||
# for procs and tyGenericBody, it's the
|
# for procs and tyGenericBody, it's the
|
||||||
# the body of the user-defined type class
|
|
||||||
# formal param list
|
# formal param list
|
||||||
|
# for concepts, the concept body
|
||||||
# else: unused
|
# else: unused
|
||||||
owner*: PSym # the 'owner' of the type
|
owner*: PSym # the 'owner' of the type
|
||||||
sym*: PSym # types have the sym associated with them
|
sym*: PSym # types have the sym associated with them
|
||||||
|
|
|
||||||
|
|
@ -385,18 +385,11 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
|
||||||
inc j
|
inc j
|
||||||
inc i
|
inc i
|
||||||
of '\'':
|
of '\'':
|
||||||
inc i
|
var idx, stars: int
|
||||||
let stars = i
|
if scanCppGenericSlot(pat, i, idx, stars):
|
||||||
while pat[i] == '*': inc i
|
var t = resolveStarsInCppType(typ, idx, stars)
|
||||||
if pat[i] in Digits:
|
|
||||||
let j = pat[i].ord - '0'.ord
|
|
||||||
var t = typ.sons[j]
|
|
||||||
for k in 1..i-stars:
|
|
||||||
if t != nil and t.len > 0:
|
|
||||||
t = if t.kind == tyGenericInst: t.sons[1] else: t.elemType
|
|
||||||
if t == nil: result.add(~"void")
|
if t == nil: result.add(~"void")
|
||||||
else: result.add(getTypeDesc(p.module, t))
|
else: result.add(getTypeDesc(p.module, t))
|
||||||
inc i
|
|
||||||
else:
|
else:
|
||||||
let start = i
|
let start = i
|
||||||
while i < pat.len:
|
while i < pat.len:
|
||||||
|
|
|
||||||
|
|
@ -495,6 +495,33 @@ proc getTupleDesc(m: BModule, typ: PType, name: Rope,
|
||||||
else: add(result, desc)
|
else: add(result, desc)
|
||||||
add(result, "};" & tnl)
|
add(result, "};" & tnl)
|
||||||
|
|
||||||
|
proc scanCppGenericSlot(pat: string, cursor, outIdx, outStars: var int): bool =
|
||||||
|
# A helper proc for handling cppimport patterns, involving numeric
|
||||||
|
# placeholders for generic types (e.g. '0, '**2, etc).
|
||||||
|
# pre: the cursor must be placed at the ' symbol
|
||||||
|
# post: the cursor will be placed after the final digit
|
||||||
|
# false will returned if the input is not recognized as a placeholder
|
||||||
|
inc cursor
|
||||||
|
let begin = cursor
|
||||||
|
while pat[cursor] == '*': inc cursor
|
||||||
|
if pat[cursor] in Digits:
|
||||||
|
outIdx = pat[cursor].ord - '0'.ord
|
||||||
|
outStars = cursor - begin
|
||||||
|
inc cursor
|
||||||
|
return true
|
||||||
|
else:
|
||||||
|
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"
|
||||||
|
|
||||||
|
result = typ.sons[idx]
|
||||||
|
for i in 1..stars:
|
||||||
|
if result != nil and result.len > 0:
|
||||||
|
result = if result.kind == tyGenericInst: result.sons[1]
|
||||||
|
else: result.elemType
|
||||||
|
|
||||||
proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope =
|
proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope =
|
||||||
# returns only the type's name
|
# returns only the type's name
|
||||||
var t = getUniqueType(typ)
|
var t = getUniqueType(typ)
|
||||||
|
|
@ -597,11 +624,33 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope =
|
||||||
if isImportedCppType(t) and typ.kind == tyGenericInst:
|
if isImportedCppType(t) and typ.kind == tyGenericInst:
|
||||||
# for instantiated templates we do not go through the type cache as the
|
# for instantiated templates we do not go through the type cache as the
|
||||||
# the type cache is not aware of 'tyGenericInst'.
|
# the type cache is not aware of 'tyGenericInst'.
|
||||||
result = getTypeName(t) & "<"
|
let cppName = getTypeName(t)
|
||||||
for i in 1 .. typ.len-2:
|
var i = 0
|
||||||
if i > 1: result.add(", ")
|
var chunkStart = 0
|
||||||
result.add(getTypeDescAux(m, typ.sons[i], check))
|
while i < cppName.data.len:
|
||||||
result.add("> ")
|
if cppName.data[i] == '\'':
|
||||||
|
var chunkEnd = <i
|
||||||
|
var idx, stars: int
|
||||||
|
if scanCppGenericSlot(cppName.data, i, idx, stars):
|
||||||
|
result.add cppName.data.substr(chunkStart, chunkEnd)
|
||||||
|
chunkStart = i
|
||||||
|
|
||||||
|
let typeInSlot = resolveStarsInCppType(typ, idx + 1, stars)
|
||||||
|
if typeInSlot == nil or typeInSlot.kind == tyEmpty:
|
||||||
|
result.add(~"void")
|
||||||
|
else:
|
||||||
|
result.add getTypeDescAux(m, typeInSlot, check)
|
||||||
|
else:
|
||||||
|
inc i
|
||||||
|
|
||||||
|
if chunkStart != 0:
|
||||||
|
result.add cppName.data.substr(chunkStart)
|
||||||
|
else:
|
||||||
|
result = cppName & "<"
|
||||||
|
for i in 1 .. typ.len-2:
|
||||||
|
if i > 1: result.add(", ")
|
||||||
|
result.add(getTypeDescAux(m, typ.sons[i], check))
|
||||||
|
result.add("> ")
|
||||||
# always call for sideeffects:
|
# always call for sideeffects:
|
||||||
assert t.kind != tyTuple
|
assert t.kind != tyTuple
|
||||||
discard getRecordDesc(m, t, result, check)
|
discard getRecordDesc(m, t, result, check)
|
||||||
|
|
|
||||||
|
|
@ -827,6 +827,9 @@ proc localError*(info: TLineInfo, msg: TMsgKind, arg = "") =
|
||||||
proc localError*(info: TLineInfo, arg: string) =
|
proc localError*(info: TLineInfo, arg: string) =
|
||||||
liMessage(info, errGenerated, arg, doNothing)
|
liMessage(info, errGenerated, arg, doNothing)
|
||||||
|
|
||||||
|
proc localError*(info: TLineInfo, format: string, params: openarray[string]) =
|
||||||
|
localError(info, format % params)
|
||||||
|
|
||||||
proc message*(info: TLineInfo, msg: TMsgKind, arg = "") =
|
proc message*(info: TLineInfo, msg: TMsgKind, arg = "") =
|
||||||
liMessage(info, msg, arg, doNothing)
|
liMessage(info, msg, arg, doNothing)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,8 @@ proc getPrecedence(tok: TToken, strongSpaces: bool): int =
|
||||||
let relevantChar = tok.ident.s[0]
|
let relevantChar = tok.ident.s[0]
|
||||||
|
|
||||||
# arrow like?
|
# arrow like?
|
||||||
if L > 1 and tok.ident.s[L-1] == '>': return considerStrongSpaces(1)
|
if L > 1 and tok.ident.s[L-1] == '>' and
|
||||||
|
tok.ident.s[L-2] in {'-', '~', '='}: return considerStrongSpaces(1)
|
||||||
|
|
||||||
template considerAsgn(value: expr) =
|
template considerAsgn(value: expr) =
|
||||||
result = if tok.ident.s[L-1] == '=': 1 else: value
|
result = if tok.ident.s[L-1] == '=': 1 else: value
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,9 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
|
||||||
of tyIter: result = mapTypeToBracket("iter", t, info)
|
of tyIter: result = mapTypeToBracket("iter", t, info)
|
||||||
of tyProxy: result = atomicType"error"
|
of tyProxy: result = atomicType"error"
|
||||||
of tyBuiltInTypeClass: result = mapTypeToBracket("builtinTypeClass", t, info)
|
of tyBuiltInTypeClass: result = mapTypeToBracket("builtinTypeClass", t, info)
|
||||||
of tyUserTypeClass: result = mapTypeToBracket("userTypeClass", t, info)
|
of tyUserTypeClass:
|
||||||
|
result = mapTypeToBracket("concept", t, info)
|
||||||
|
result.add t.n.copyTree
|
||||||
of tyCompositeTypeClass: result = mapTypeToBracket("compositeTypeClass", t, info)
|
of tyCompositeTypeClass: result = mapTypeToBracket("compositeTypeClass", t, info)
|
||||||
of tyAnd: result = mapTypeToBracket("and", t, info)
|
of tyAnd: result = mapTypeToBracket("and", t, info)
|
||||||
of tyOr: result = mapTypeToBracket("or", t, info)
|
of tyOr: result = mapTypeToBracket("or", t, info)
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ Numerical constants are of a single type and have the form::
|
||||||
INT32_LIT = INT_LIT ['\''] ('i' | 'I') '32'
|
INT32_LIT = INT_LIT ['\''] ('i' | 'I') '32'
|
||||||
INT64_LIT = INT_LIT ['\''] ('i' | 'I') '64'
|
INT64_LIT = INT_LIT ['\''] ('i' | 'I') '64'
|
||||||
|
|
||||||
UINT8_LIT = INT_LIT ['\''] ('u' | 'U')
|
UINT_LIT = INT_LIT ['\''] ('u' | 'U')
|
||||||
UINT8_LIT = INT_LIT ['\''] ('u' | 'U') '8'
|
UINT8_LIT = INT_LIT ['\''] ('u' | 'U') '8'
|
||||||
UINT16_LIT = INT_LIT ['\''] ('u' | 'U') '16'
|
UINT16_LIT = INT_LIT ['\''] ('u' | 'U') '16'
|
||||||
UINT32_LIT = INT_LIT ['\''] ('u' | 'U') '32'
|
UINT32_LIT = INT_LIT ['\''] ('u' | 'U') '32'
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,6 @@ Associativity
|
||||||
Binary operators whose first character is ``^`` are right-associative, all
|
Binary operators whose first character is ``^`` are right-associative, all
|
||||||
other binary operators are left-associative.
|
other binary operators are left-associative.
|
||||||
|
|
||||||
Operators ending in ``>`` but longer than a single character are
|
|
||||||
called `arrow like`:idx:.
|
|
||||||
|
|
||||||
|
|
||||||
Precedence
|
Precedence
|
||||||
|
|
@ -33,9 +31,12 @@ as ``(@x).abc`` whereas ``$x.abc`` is parsed as ``$(x.abc)``.
|
||||||
For binary operators that are not keywords the precedence is determined by the
|
For binary operators that are not keywords the precedence is determined by the
|
||||||
following rules:
|
following rules:
|
||||||
|
|
||||||
|
Operators ending in either ``->``, ``~>`` or ``=>`` are called
|
||||||
|
`arrow like`:idx:, and have the lowest precedence of all operators.
|
||||||
|
|
||||||
If the operator ends with ``=`` and its first character is none of
|
If the operator ends with ``=`` and its first character is none of
|
||||||
``<``, ``>``, ``!``, ``=``, ``~``, ``?``, it is an *assignment operator* which
|
``<``, ``>``, ``!``, ``=``, ``~``, ``?``, it is an *assignment operator* which
|
||||||
has the lowest precedence.
|
has the second lowest precedence.
|
||||||
|
|
||||||
Otherwise precedence is determined by the first character.
|
Otherwise precedence is determined by the first character.
|
||||||
|
|
||||||
|
|
@ -43,14 +44,14 @@ Otherwise precedence is determined by the first character.
|
||||||
Precedence level Operators First character Terminal symbol
|
Precedence level Operators First character Terminal symbol
|
||||||
================ =============================================== ================== ===============
|
================ =============================================== ================== ===============
|
||||||
10 (highest) ``$ ^`` OP10
|
10 (highest) ``$ ^`` OP10
|
||||||
9 ``* / div mod shl shr %`` ``* % \ /`` OP9
|
9 ``* / div mod shl shr %`` ``* % \ /`` OP9
|
||||||
8 ``+ -`` ``+ ~ |`` OP8
|
8 ``+ -`` ``+ - ~ |`` OP8
|
||||||
7 ``&`` ``&`` OP7
|
7 ``&`` ``&`` OP7
|
||||||
6 ``..`` ``.`` OP6
|
6 ``..`` ``.`` OP6
|
||||||
5 ``== <= < >= > != in notin is isnot not of`` ``= < > !`` OP5
|
5 ``== <= < >= > != in notin is isnot not of`` ``= < > !`` OP5
|
||||||
4 ``and`` OP4
|
4 ``and`` OP4
|
||||||
3 ``or xor`` OP3
|
3 ``or xor`` OP3
|
||||||
2 ``@ : ?`` OP2
|
2 ``@ : ?`` OP2
|
||||||
1 *assignment operator* (like ``+=``, ``*=``) OP1
|
1 *assignment operator* (like ``+=``, ``*=``) OP1
|
||||||
0 (lowest) *arrow like operator* (like ``->``, ``=>``) OP0
|
0 (lowest) *arrow like operator* (like ``->``, ``=>``) OP0
|
||||||
================ =============================================== ================== ===============
|
================ =============================================== ================== ===============
|
||||||
|
|
@ -67,7 +68,7 @@ is still parsed as ``1 + (3 * 4)``, but ``1+3 * 4`` is parsed as ``(1+3) * 4``:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
#! strongSpaces
|
#! strongSpaces
|
||||||
if foo+4 * 4 == 8 and b&c | 9 ++
|
if foo+4 * 4 == 8 and b&c | 9 ++
|
||||||
bar:
|
bar:
|
||||||
echo ""
|
echo ""
|
||||||
# is parsed as
|
# is parsed as
|
||||||
|
|
|
||||||
21
doc/nimc.txt
21
doc/nimc.txt
|
|
@ -506,7 +506,7 @@ For example:
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
|
|
||||||
type Input {.importcpp: "System::Input".} = object
|
type Input {.importcpp: "System::Input".} = object
|
||||||
proc getSubsystem*[T](): ptr T {.importcpp: "SystemManager::getSubsystem<'*0>()".}
|
proc getSubsystem*[T](): ptr T {.importcpp: "SystemManager::getSubsystem<'*0>()", nodecl.}
|
||||||
|
|
||||||
let x: ptr Input = getSubsystem[Input]()
|
let x: ptr Input = getSubsystem[Input]()
|
||||||
|
|
||||||
|
|
@ -596,6 +596,25 @@ Produces:
|
||||||
x[6] = 91.4;
|
x[6] = 91.4;
|
||||||
|
|
||||||
|
|
||||||
|
- If more precise control is needed, the apostrophe ``'`` can be used in the
|
||||||
|
supplied pattern to denote the concrete type parameters of the generic type.
|
||||||
|
See the usage of the apostrophe operator in proc patterns for more details.
|
||||||
|
|
||||||
|
.. code-block:: nim
|
||||||
|
|
||||||
|
type
|
||||||
|
VectorIterator {.importcpp: "std::vector<'0>::iterator".} [T] = object
|
||||||
|
|
||||||
|
var x: VectorIterator[cint]
|
||||||
|
|
||||||
|
|
||||||
|
Produces:
|
||||||
|
|
||||||
|
.. code-block:: C
|
||||||
|
|
||||||
|
std::vector<int>::iterator x;
|
||||||
|
|
||||||
|
|
||||||
ImportObjC pragma
|
ImportObjC pragma
|
||||||
-----------------
|
-----------------
|
||||||
Similar to the `importc pragma for C <manual.html#importc-pragma>`_, the
|
Similar to the `importc pragma for C <manual.html#importc-pragma>`_, the
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,9 @@ type
|
||||||
ntyBigNum,
|
ntyBigNum,
|
||||||
ntyConst, ntyMutable, ntyVarargs,
|
ntyConst, ntyMutable, ntyVarargs,
|
||||||
ntyIter,
|
ntyIter,
|
||||||
ntyError
|
ntyError,
|
||||||
|
ntyBuiltinTypeClass, ntyConcept, ntyConceptInst, ntyComposite,
|
||||||
|
ntyAnd, ntyOr, ntyNot
|
||||||
|
|
||||||
TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
|
TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
|
||||||
NimSymKind* = enum
|
NimSymKind* = enum
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,11 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
## Regular expression support for Nim. Consider using the pegs module
|
## Regular expression support for Nim. Consider using the pegs module instead.
|
||||||
## instead.
|
##
|
||||||
|
## There is an alternative regular expressions library with a more unified API:
|
||||||
|
## `nre <https://github.com/flaviut/nre>`_. It may be added to the standard
|
||||||
|
## library in the future, instead of `re`.
|
||||||
##
|
##
|
||||||
## **Note:** The 're' proc defaults to the **extended regular expression
|
## **Note:** The 're' proc defaults to the **extended regular expression
|
||||||
## syntax** which lets you use whitespace freely to make your regexes readable.
|
## syntax** which lets you use whitespace freely to make your regexes readable.
|
||||||
|
|
@ -413,22 +416,28 @@ proc escapeRe*(s: string): string =
|
||||||
result.add(toHex(ord(c), 2))
|
result.add(toHex(ord(c), 2))
|
||||||
|
|
||||||
const ## common regular expressions
|
const ## common regular expressions
|
||||||
reIdentifier* = r"\b[a-zA-Z_]+[a-zA-Z_0-9]*\b" ## describes an identifier
|
reIdentifier* {.deprecated.} = r"\b[a-zA-Z_]+[a-zA-Z_0-9]*\b"
|
||||||
reNatural* = r"\b\d+\b" ## describes a natural number
|
## describes an identifier
|
||||||
reInteger* = r"\b[-+]?\d+\b" ## describes an integer
|
reNatural* {.deprecated.} = r"\b\d+\b"
|
||||||
reHex* = r"\b0[xX][0-9a-fA-F]+\b" ## describes a hexadecimal number
|
## describes a natural number
|
||||||
reBinary* = r"\b0[bB][01]+\b" ## describes a binary number (example: 0b11101)
|
reInteger* {.deprecated.} = r"\b[-+]?\d+\b"
|
||||||
reOctal* = r"\b0[oO][0-7]+\b" ## describes an octal number (example: 0o777)
|
## describes an integer
|
||||||
reFloat* = r"\b[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\b"
|
reHex* {.deprecated.} = r"\b0[xX][0-9a-fA-F]+\b"
|
||||||
|
## describes a hexadecimal number
|
||||||
|
reBinary* {.deprecated.} = r"\b0[bB][01]+\b"
|
||||||
|
## describes a binary number (example: 0b11101)
|
||||||
|
reOctal* {.deprecated.} = r"\b0[oO][0-7]+\b"
|
||||||
|
## describes an octal number (example: 0o777)
|
||||||
|
reFloat* {.deprecated.} = r"\b[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\b"
|
||||||
## describes a floating point number
|
## describes a floating point number
|
||||||
reEmail* = r"\b[a-zA-Z0-9!#$%&'*+/=?^_`{|}~\-]+(?:\. &" &
|
reEmail* {.deprecated.} = r"\b[a-zA-Z0-9!#$%&'*+/=?^_`{|}~\-]+(?:\. &" &
|
||||||
r"[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)" &
|
r"[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@" &
|
||||||
r"*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+" &
|
r"(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+" &
|
||||||
r"(?:[a-zA-Z]{2}|com|org|" &
|
r"(?:[a-zA-Z]{2}|com|org|net|gov|mil|biz|" &
|
||||||
r"net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\b"
|
r"info|mobi|name|aero|jobs|museum)\b"
|
||||||
## describes a common email address
|
## describes a common email address
|
||||||
reURL* = r"\b(http(s)?|ftp|gopher|telnet|file|notes|ms\-help):" &
|
reURL* {.deprecated.} = r"\b(http(s)?|ftp|gopher|telnet|file|notes|ms-help)" &
|
||||||
r"((//)|(\\\\))+[\w\d:#@%/;$()~_?\+\-\=\\\.\&]*\b"
|
r":((//)|(\\\\))+[\w\d:#@%/;$()~_?\+\-\=\\\.\&]*\b"
|
||||||
## describes an URL
|
## describes an URL
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
|
|
||||||
|
|
@ -564,7 +564,7 @@ proc fixupEmbeddedRef(n, a, b: PRstNode) =
|
||||||
|
|
||||||
proc parsePostfix(p: var TRstParser, n: PRstNode): PRstNode =
|
proc parsePostfix(p: var TRstParser, n: PRstNode): PRstNode =
|
||||||
result = n
|
result = n
|
||||||
if isInlineMarkupEnd(p, "_"):
|
if isInlineMarkupEnd(p, "_") or isInlineMarkupEnd(p, "__"):
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
if p.tok[p.idx-2].symbol == "`" and p.tok[p.idx-3].symbol == ">":
|
if p.tok[p.idx-2].symbol == "`" and p.tok[p.idx-3].symbol == ">":
|
||||||
var a = newRstNode(rnInner)
|
var a = newRstNode(rnInner)
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ proc terminate*(p: Process) {.rtl, extern: "nosp$1", tags: [].}
|
||||||
proc kill*(p: Process) {.rtl, extern: "nosp$1", tags: [].}
|
proc kill*(p: Process) {.rtl, extern: "nosp$1", tags: [].}
|
||||||
## Kill the process `p`. On Posix OSes the procedure sends ``SIGKILL`` to
|
## Kill the process `p`. On Posix OSes the procedure sends ``SIGKILL`` to
|
||||||
## the process. On Windows ``kill()`` is simply an alias for ``terminate()``.
|
## the process. On Windows ``kill()`` is simply an alias for ``terminate()``.
|
||||||
|
|
||||||
proc running*(p: Process): bool {.rtl, extern: "nosp$1", tags: [].}
|
proc running*(p: Process): bool {.rtl, extern: "nosp$1", tags: [].}
|
||||||
## Returns true iff the process `p` is still running. Returns immediately.
|
## Returns true iff the process `p` is still running. Returns immediately.
|
||||||
|
|
||||||
|
|
@ -666,7 +666,7 @@ elif not defined(useNimRtl):
|
||||||
data.workingDir = workingDir
|
data.workingDir = workingDir
|
||||||
|
|
||||||
|
|
||||||
when declared(posix_spawn) and not defined(useFork) and
|
when declared(posix_spawn) and not defined(useFork) and
|
||||||
not defined(useClone) and not defined(linux):
|
not defined(useClone) and not defined(linux):
|
||||||
pid = startProcessAuxSpawn(data)
|
pid = startProcessAuxSpawn(data)
|
||||||
else:
|
else:
|
||||||
|
|
@ -823,7 +823,7 @@ elif not defined(useNimRtl):
|
||||||
discard execvp(data.sysCommand, data.sysArgs)
|
discard execvp(data.sysCommand, data.sysArgs)
|
||||||
else:
|
else:
|
||||||
when defined(uClibc):
|
when defined(uClibc):
|
||||||
# uClibc environment (OpenWrt included) doesn't have the full execvpe
|
# uClibc environment (OpenWrt included) doesn't have the full execvpe
|
||||||
discard execve(data.sysCommand, data.sysArgs, data.sysEnv)
|
discard execve(data.sysCommand, data.sysArgs, data.sysEnv)
|
||||||
else:
|
else:
|
||||||
discard execvpe(data.sysCommand, data.sysArgs, data.sysEnv)
|
discard execvpe(data.sysCommand, data.sysArgs, data.sysEnv)
|
||||||
|
|
@ -864,9 +864,9 @@ elif not defined(useNimRtl):
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
|
|
||||||
proc kill(p: Process) =
|
proc kill(p: Process) =
|
||||||
if kill(p.id, SIGKILL) != 0'i32:
|
if kill(p.id, SIGKILL) != 0'i32:
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
|
|
||||||
proc waitForExit(p: Process, timeout: int = -1): int =
|
proc waitForExit(p: Process, timeout: int = -1): int =
|
||||||
#if waitPid(p.id, p.exitCode, 0) == int(p.id):
|
#if waitPid(p.id, p.exitCode, 0) == int(p.id):
|
||||||
# ``waitPid`` fails if the process is not running anymore. But then
|
# ``waitPid`` fails if the process is not running anymore. But then
|
||||||
|
|
@ -883,7 +883,7 @@ elif not defined(useNimRtl):
|
||||||
var ret = waitpid(p.id, p.exitCode, WNOHANG)
|
var ret = waitpid(p.id, p.exitCode, WNOHANG)
|
||||||
var b = ret == int(p.id)
|
var b = ret == int(p.id)
|
||||||
if b: result = -1
|
if b: result = -1
|
||||||
if p.exitCode == -3: result = -1
|
if not WIFEXITED(p.exitCode): result = -1
|
||||||
else: result = p.exitCode.int shr 8
|
else: result = p.exitCode.int shr 8
|
||||||
|
|
||||||
proc createStream(stream: var Stream, handle: var FileHandle,
|
proc createStream(stream: var Stream, handle: var FileHandle,
|
||||||
|
|
@ -907,7 +907,7 @@ elif not defined(useNimRtl):
|
||||||
createStream(p.errStream, p.errHandle, fmRead)
|
createStream(p.errStream, p.errHandle, fmRead)
|
||||||
return p.errStream
|
return p.errStream
|
||||||
|
|
||||||
proc csystem(cmd: cstring): cint {.nodecl, importc: "system",
|
proc csystem(cmd: cstring): cint {.nodecl, importc: "system",
|
||||||
header: "<stdlib.h>".}
|
header: "<stdlib.h>".}
|
||||||
|
|
||||||
proc execCmd(command: string): int =
|
proc execCmd(command: string): int =
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ when someGcc and hasThreadSupport:
|
||||||
|
|
||||||
proc atomicCompareExchange*[T: TAtomType](p, expected, desired: ptr T,
|
proc atomicCompareExchange*[T: TAtomType](p, expected, desired: ptr T,
|
||||||
weak: bool, success_memmodel: AtomMemModel, failure_memmodel: AtomMemModel): bool {.
|
weak: bool, success_memmodel: AtomMemModel, failure_memmodel: AtomMemModel): bool {.
|
||||||
importc: "__atomic_compare_exchange_n ", nodecl.}
|
importc: "__atomic_compare_exchange", nodecl.}
|
||||||
## This proc implements the generic version of atomic_compare_exchange.
|
## This proc implements the generic version of atomic_compare_exchange.
|
||||||
## The proc is virtually identical to atomic_compare_exchange_n, except the desired
|
## The proc is virtually identical to atomic_compare_exchange_n, except the desired
|
||||||
## value is also a pointer.
|
## value is also a pointer.
|
||||||
|
|
|
||||||
22
tests/cpp/get_subsystem.nim
Normal file
22
tests/cpp/get_subsystem.nim
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nim cpp $file"
|
||||||
|
"""
|
||||||
|
|
||||||
|
{.emit: """
|
||||||
|
|
||||||
|
namespace System {
|
||||||
|
struct Input {};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SystemManager {
|
||||||
|
template <class T>
|
||||||
|
static T* getSubsystem() { return new T; }
|
||||||
|
};
|
||||||
|
|
||||||
|
""".}
|
||||||
|
|
||||||
|
type Input {.importcpp: "System::Input".} = object
|
||||||
|
proc getSubsystem*[T](): ptr T {.importcpp: "SystemManager::getSubsystem<'*0>()".}
|
||||||
|
|
||||||
|
let input: ptr Input = getSubsystem[Input]()
|
||||||
|
|
||||||
19
tests/cpp/vector_iterator.nim
Normal file
19
tests/cpp/vector_iterator.nim
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nim cpp $file"
|
||||||
|
"""
|
||||||
|
|
||||||
|
{.emit: """
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct Vector {
|
||||||
|
struct Iterator {};
|
||||||
|
};
|
||||||
|
|
||||||
|
""".}
|
||||||
|
|
||||||
|
type
|
||||||
|
Vector {.importcpp: "Vector".} [T] = object
|
||||||
|
VectorIterator {.importcpp: "Vector<'0>::Iterator".} [T] = object
|
||||||
|
|
||||||
|
var x: VectorIterator[void]
|
||||||
|
|
||||||
|
|
@ -15,6 +15,10 @@ true
|
||||||
tester args
|
tester args
|
||||||
all
|
all
|
||||||
all args
|
all args
|
||||||
|
19
|
||||||
|
-3
|
||||||
|
false
|
||||||
|
-2
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -67,3 +71,13 @@ const
|
||||||
echo tester & " " & args|"all"
|
echo tester & " " & args|"all"
|
||||||
echo "all" | tester & " " & args
|
echo "all" | tester & " " & args
|
||||||
echo "all"|tester & " " & args
|
echo "all"|tester & " " & args
|
||||||
|
|
||||||
|
# Test arrow like operators. See also tests/macros/tclosuremacro.nim
|
||||||
|
proc `+->`(a, b: int): int = a + b*4
|
||||||
|
template `===>`(a, b: int): expr = a - b shr 1
|
||||||
|
|
||||||
|
echo 3 +-> 2 + 2 and 4
|
||||||
|
var arrowed = 3+->2 + 2 and 4 # arrowed = 4
|
||||||
|
echo arrowed ===> 15
|
||||||
|
echo (2 * 3+->2) == (2*3 +-> 2)
|
||||||
|
echo arrowed ===> 2 + 3+->2
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,10 @@ News
|
||||||
should be used instead.
|
should be used instead.
|
||||||
- ``nim idetools`` has been replaced by a separate tool `nimsuggest`_.
|
- ``nim idetools`` has been replaced by a separate tool `nimsuggest`_.
|
||||||
- *arrow like* operators are not right associative anymore.
|
- *arrow like* operators are not right associative anymore.
|
||||||
|
- *arrow like* operators are now required to end with either ``->``, ``~>`` or
|
||||||
|
``=>``, not just ``>``. Examples of operators still considered arrow like:
|
||||||
|
``->``, ``==>``, ``+=>``. On the other hand, the following operators are now
|
||||||
|
considered regular operators again: ``|>``, ``-+>``, etc.
|
||||||
- Typeless parameters are now only allowed in templates and macros. The old
|
- Typeless parameters are now only allowed in templates and macros. The old
|
||||||
way turned out to be too error-prone.
|
way turned out to be too error-prone.
|
||||||
- The 'addr' and 'type' operators are now parsed as unary function
|
- The 'addr' and 'type' operators are now parsed as unary function
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue