p[] instead of p^
This commit is contained in:
parent
fc6cc79273
commit
3d696c3da5
12 changed files with 64 additions and 52 deletions
|
|
@ -932,8 +932,9 @@ untraced references are *unsafe*. However for certain low-level operations
|
||||||
Traced references are declared with the **ref** keyword, untraced references
|
Traced references are declared with the **ref** keyword, untraced references
|
||||||
are declared with the **ptr** keyword.
|
are declared with the **ptr** keyword.
|
||||||
|
|
||||||
The ``^`` operator can be used to derefer a reference, the ``addr`` procedure
|
An empty subscript ``[]`` notation can be used to derefer a reference,
|
||||||
returns the address of an item. An address is always an untraced reference.
|
the ``addr`` procedure returns the address of an item. An address is always
|
||||||
|
an untraced reference.
|
||||||
Thus the usage of ``addr`` is an *unsafe* feature.
|
Thus the usage of ``addr`` is an *unsafe* feature.
|
||||||
|
|
||||||
The ``.`` (access a tuple/object field operator)
|
The ``.`` (access a tuple/object field operator)
|
||||||
|
|
@ -951,7 +952,8 @@ dereferencing operations for reference types:
|
||||||
var
|
var
|
||||||
n: PNode
|
n: PNode
|
||||||
new(n)
|
new(n)
|
||||||
n.data = 9 # no need to write n^ .data
|
n.data = 9
|
||||||
|
# no need to write n[].data; in fact n[].data is highly discouraged!
|
||||||
|
|
||||||
To allocate a new traced object, the built-in procedure ``new`` has to be used.
|
To allocate a new traced object, the built-in procedure ``new`` has to be used.
|
||||||
To deal with untraced memory, the procedures ``alloc``, ``dealloc`` and
|
To deal with untraced memory, the procedures ``alloc``, ``dealloc`` and
|
||||||
|
|
@ -1941,8 +1943,8 @@ above example is equivalent to:
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
proc divmod(a, b: int,
|
proc divmod(a, b: int,
|
||||||
res, remainder: ptr int) =
|
res, remainder: ptr int) =
|
||||||
res^ = a div b
|
res[] = a div b
|
||||||
remainder^ = a mod b
|
remainder[] = a mod b
|
||||||
|
|
||||||
var
|
var
|
||||||
x, y: int
|
x, y: int
|
||||||
|
|
@ -2070,6 +2072,7 @@ The `for`:idx: statement is an abstract mechanism to iterate over the elements
|
||||||
of a container. It relies on an `iterator`:idx: to do so. Like ``while``
|
of a container. It relies on an `iterator`:idx: to do so. Like ``while``
|
||||||
statements, ``for`` statements open an `implicit block`:idx:, so that they
|
statements, ``for`` statements open an `implicit block`:idx:, so that they
|
||||||
can be left with a ``break`` statement. The ``for`` loop declares
|
can be left with a ``break`` statement. The ``for`` loop declares
|
||||||
|
|
||||||
iteration variables (``x`` in the example) - their scope reaches until the
|
iteration variables (``x`` in the example) - their scope reaches until the
|
||||||
end of the loop body. The iteration variables' types are inferred by the
|
end of the loop body. The iteration variables' types are inferred by the
|
||||||
return type of the iterator.
|
return type of the iterator.
|
||||||
|
|
@ -2581,6 +2584,7 @@ The `procvar`:idx: pragma is used to mark a proc that it can be passed to a
|
||||||
procedural variable.
|
procedural variable.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
compileTime pragma
|
compileTime pragma
|
||||||
------------------
|
------------------
|
||||||
The `compileTime`:idx: pragma is used to mark a proc to be used at compile
|
The `compileTime`:idx: pragma is used to mark a proc to be used at compile
|
||||||
|
|
|
||||||
|
|
@ -1183,9 +1183,9 @@ untraced references are *unsafe*. However for certain low-level operations
|
||||||
Traced references are declared with the **ref** keyword, untraced references
|
Traced references are declared with the **ref** keyword, untraced references
|
||||||
are declared with the **ptr** keyword.
|
are declared with the **ptr** keyword.
|
||||||
|
|
||||||
The ``^`` operator can be used to *derefer* a reference, meaning to retrieve
|
The empty ``[]`` subscript notation can be used to *derefer* a reference,
|
||||||
the item the reference points to. The ``addr`` procedure returns the address
|
meaning to retrieve the item the reference points to. The ``addr`` procedure
|
||||||
of an item. An address is always an untraced reference:
|
returns the address of an item. An address is always an untraced reference:
|
||||||
``addr`` is an *unsafe* feature.
|
``addr`` is an *unsafe* feature.
|
||||||
|
|
||||||
The ``.`` (access a tuple/object field operator)
|
The ``.`` (access a tuple/object field operator)
|
||||||
|
|
@ -1200,7 +1200,8 @@ dereferencing operations for reference types:
|
||||||
var
|
var
|
||||||
n: PNode
|
n: PNode
|
||||||
new(n)
|
new(n)
|
||||||
n.data = 9 # no need to write n^ .data
|
n.data = 9
|
||||||
|
# no need to write n[].data; in fact n[].data is highly discouraged!
|
||||||
|
|
||||||
(As a convention, reference types use a 'P' prefix.)
|
(As a convention, reference types use a 'P' prefix.)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1204,7 +1204,7 @@ proc unaryExpression(p: var TParser): PNode =
|
||||||
of pxPlusPlus: result = incdec(p, "inc")
|
of pxPlusPlus: result = incdec(p, "inc")
|
||||||
of pxMinusMinus: result = incdec(p, "dec")
|
of pxMinusMinus: result = incdec(p, "dec")
|
||||||
of pxAmp: result = unaryOp(p, nkAddr)
|
of pxAmp: result = unaryOp(p, nkAddr)
|
||||||
of pxStar: result = unaryOp(p, nkDerefExpr)
|
of pxStar: result = unaryOp(p, nkBracketExpr)
|
||||||
of pxPlus: result = prefixCall(p, "+")
|
of pxPlus: result = prefixCall(p, "+")
|
||||||
of pxMinus: result = prefixCall(p, "-")
|
of pxMinus: result = prefixCall(p, "-")
|
||||||
of pxTilde: result = prefixCall(p, "not")
|
of pxTilde: result = prefixCall(p, "not")
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,9 @@ type
|
||||||
warnCannotWriteMO2, warnCannotReadMO2, warnDeprecated,
|
warnCannotWriteMO2, warnCannotReadMO2, warnDeprecated,
|
||||||
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
||||||
warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored,
|
warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored,
|
||||||
warnXisPassedToProcVar, warnUser, hintSuccess, hintSuccessX,
|
warnXisPassedToProcVar, warnDerefDeprecated,
|
||||||
|
warnUser,
|
||||||
|
hintSuccess, hintSuccessX,
|
||||||
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
||||||
hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
|
hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
|
||||||
hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath, hintUser
|
hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath, hintUser
|
||||||
|
|
@ -319,6 +321,7 @@ const
|
||||||
warnLanguageXNotSupported: "language \'$1\' not supported [LanguageXNotSupported]",
|
warnLanguageXNotSupported: "language \'$1\' not supported [LanguageXNotSupported]",
|
||||||
warnCommentXIgnored: "comment \'$1\' ignored [CommentXIgnored]",
|
warnCommentXIgnored: "comment \'$1\' ignored [CommentXIgnored]",
|
||||||
warnXisPassedToProcVar: "\'$1\' is passed to a procvar; deprecated [XisPassedToProcVar]",
|
warnXisPassedToProcVar: "\'$1\' is passed to a procvar; deprecated [XisPassedToProcVar]",
|
||||||
|
warnDerefDeprecated: "p^ is deprecated; use p[] instead [DerefDeprecated]",
|
||||||
warnUser: "$1 [User]",
|
warnUser: "$1 [User]",
|
||||||
hintSuccess: "operation successful [Success]",
|
hintSuccess: "operation successful [Success]",
|
||||||
hintSuccessX: "operation successful ($1 lines compiled; $2 sec total) [SuccessX]",
|
hintSuccessX: "operation successful ($1 lines compiled; $2 sec total) [SuccessX]",
|
||||||
|
|
@ -336,11 +339,11 @@ const
|
||||||
hintUser: "$1 [User]"]
|
hintUser: "$1 [User]"]
|
||||||
|
|
||||||
const
|
const
|
||||||
WarningsToStr*: array[0..14, string] = ["CannotOpenFile", "OctalEscape",
|
WarningsToStr*: array[0..15, string] = ["CannotOpenFile", "OctalEscape",
|
||||||
"XIsNeverRead", "XmightNotBeenInit", "CannotWriteMO2", "CannotReadMO2",
|
"XIsNeverRead", "XmightNotBeenInit", "CannotWriteMO2", "CannotReadMO2",
|
||||||
"Deprecated", "SmallLshouldNotBeUsed", "UnknownMagic",
|
"Deprecated", "SmallLshouldNotBeUsed", "UnknownMagic",
|
||||||
"RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported",
|
"RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported",
|
||||||
"CommentXIgnored", "XisPassedToProcVar", "User"]
|
"CommentXIgnored", "XisPassedToProcVar", "DerefDeprecated", "User"]
|
||||||
|
|
||||||
HintsToStr*: array[0..13, string] = ["Success", "SuccessX", "LineTooLong",
|
HintsToStr*: array[0..13, string] = ["Success", "SuccessX", "LineTooLong",
|
||||||
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
||||||
|
|
|
||||||
|
|
@ -436,7 +436,7 @@ proc primary(p: var TParser): PNode =
|
||||||
parMessage(p, errIdentifierExpected, $p.tok)
|
parMessage(p, errIdentifierExpected, $p.tok)
|
||||||
of pxHat:
|
of pxHat:
|
||||||
var a = result
|
var a = result
|
||||||
result = newNodeP(nkDerefExpr, p)
|
result = newNodeP(nkBracketExpr, p)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
getTok(p)
|
getTok(p)
|
||||||
of pxBracketLe:
|
of pxBracketLe:
|
||||||
|
|
|
||||||
|
|
@ -629,7 +629,7 @@ proc makeDeref(n: PNode): PNode =
|
||||||
t = skipTypes(t.sons[0], {tyGenericInst})
|
t = skipTypes(t.sons[0], {tyGenericInst})
|
||||||
if t.kind in {tyPtr, tyRef}:
|
if t.kind in {tyPtr, tyRef}:
|
||||||
var a = result
|
var a = result
|
||||||
result = newNodeIT(nkDerefExpr, n.info, t.sons[0])
|
result = newNodeIT(nkHiddenDeref, n.info, t.sons[0])
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
|
|
||||||
proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
|
|
@ -745,8 +745,23 @@ proc buildOverloadedSubscripts(n: PNode, inAsgn: bool): PNode =
|
||||||
# now we know the operator
|
# now we know the operator
|
||||||
result.sons[0] = newIdentNode(getIdent(opr), n.info)
|
result.sons[0] = newIdentNode(getIdent(opr), n.info)
|
||||||
|
|
||||||
|
proc semDeref(c: PContext, n: PNode): PNode =
|
||||||
|
checkSonsLen(n, 1)
|
||||||
|
n.sons[0] = semExprWithType(c, n.sons[0])
|
||||||
|
result = n
|
||||||
|
var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar})
|
||||||
|
case t.kind
|
||||||
|
of tyRef, tyPtr: n.typ = t.sons[0]
|
||||||
|
else: GlobalError(n.sons[0].info, errCircumNeedsPointer)
|
||||||
|
result = n
|
||||||
|
|
||||||
proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
## returns nil if not a built-in subscript operator;
|
## returns nil if not a built-in subscript operator;
|
||||||
|
if sonsLen(n) == 1:
|
||||||
|
var x = semDeref(c, n)
|
||||||
|
result = newNodeIT(nkDerefExpr, x.info, x.typ)
|
||||||
|
result.add(x[0])
|
||||||
|
return
|
||||||
checkMinSonsLen(n, 2)
|
checkMinSonsLen(n, 2)
|
||||||
n.sons[0] = semExprWithType(c, n.sons[0], flags - {efAllowType})
|
n.sons[0] = semExprWithType(c, n.sons[0], flags - {efAllowType})
|
||||||
var arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyPtr, tyRef})
|
var arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyPtr, tyRef})
|
||||||
|
|
@ -1041,14 +1056,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
of nkBracket: result = semArrayConstr(c, n)
|
of nkBracket: result = semArrayConstr(c, n)
|
||||||
of nkLambda: result = semLambda(c, n)
|
of nkLambda: result = semLambda(c, n)
|
||||||
of nkDerefExpr:
|
of nkDerefExpr:
|
||||||
checkSonsLen(n, 1)
|
Message(n.info, warnDerefDeprecated)
|
||||||
n.sons[0] = semExprWithType(c, n.sons[0])
|
result = semDeref(c, n)
|
||||||
result = n
|
|
||||||
var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar})
|
|
||||||
case t.kind
|
|
||||||
of tyRef, tyPtr: n.typ = t.sons[0]
|
|
||||||
else: GlobalError(n.sons[0].info, errCircumNeedsPointer)
|
|
||||||
result = n
|
|
||||||
of nkAddr:
|
of nkAddr:
|
||||||
result = n
|
result = n
|
||||||
checkSonsLen(n, 1)
|
checkSonsLen(n, 1)
|
||||||
|
|
@ -1056,7 +1065,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
if isAssignable(n.sons[0]) != arLValue:
|
if isAssignable(n.sons[0]) != arLValue:
|
||||||
GlobalError(n.info, errExprHasNoAddress)
|
GlobalError(n.info, errExprHasNoAddress)
|
||||||
n.typ = makePtrType(c, n.sons[0].typ)
|
n.typ = makePtrType(c, n.sons[0].typ)
|
||||||
of nkHiddenAddr, nkHiddenDeref:
|
of nkHiddenAddr, nkHiddenDeref:
|
||||||
checkSonsLen(n, 1)
|
checkSonsLen(n, 1)
|
||||||
n.sons[0] = semExpr(c, n.sons[0], flags)
|
n.sons[0] = semExpr(c, n.sons[0], flags)
|
||||||
of nkCast: result = semCast(c, n)
|
of nkCast: result = semCast(c, n)
|
||||||
|
|
|
||||||
|
|
@ -535,7 +535,7 @@ proc indirectAccess(a, b: PSym): PNode =
|
||||||
# returns a^ .b as a node
|
# returns a^ .b as a node
|
||||||
var x = newSymNode(a)
|
var x = newSymNode(a)
|
||||||
var y = newSymNode(b)
|
var y = newSymNode(b)
|
||||||
var deref = newNodeI(nkDerefExpr, x.info)
|
var deref = newNodeI(nkHiddenDeref, x.info)
|
||||||
deref.typ = x.typ.sons[0]
|
deref.typ = x.typ.sons[0]
|
||||||
addSon(deref, x)
|
addSon(deref, x)
|
||||||
result = newNodeI(nkDotExpr, x.info)
|
result = newNodeI(nkDotExpr, x.info)
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,5 @@
|
||||||
This directory contains the test cases.
|
This directory contains the test cases.
|
||||||
Each test must have a filename of the form: ``t*.nim``
|
Each test must have a filename of the form: ``t*.nim``
|
||||||
|
|
||||||
The testcases may contain the directives ``#ERROR``, ``#ERROR_IN``,
|
Each test can contain a spec in ``"""``.
|
||||||
``#ERROR_MSG`` or ``#OUT``.
|
|
||||||
``#ERROR`` is used to indicate that the compiler should report
|
|
||||||
an error in the marked line (the line that contains the ``#ERROR``
|
|
||||||
directive.)
|
|
||||||
The format for ``#ERROR_IN`` is::
|
|
||||||
|
|
||||||
#ERROR_IN filename linenumber
|
|
||||||
|
|
||||||
You can omit the extension of the filename (``.nim`` is then assumed).
|
|
||||||
The format for ``#ERROR_MSG`` is::
|
|
||||||
|
|
||||||
#ERROR_MSG message
|
|
||||||
|
|
||||||
This directive specifies the error message Nimrod shall produce.
|
|
||||||
|
|
||||||
Tests which contain none of the ``#ERROR*`` directives should compile.
|
|
||||||
Thus they are executed after successful compilation and their output
|
|
||||||
is compared to the expected results (specified with the ``#OUT``
|
|
||||||
directive). Tests which require user interaction are currently not
|
|
||||||
possible.
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,11 @@ const
|
||||||
resultsFile = "testresults.html"
|
resultsFile = "testresults.html"
|
||||||
|
|
||||||
type
|
type
|
||||||
|
TTestAction = enum
|
||||||
|
actionCompile, actionRun, actionReject
|
||||||
TSpec {.pure.} = object
|
TSpec {.pure.} = object
|
||||||
file: string
|
action: TTestAction
|
||||||
|
file, cmd: string
|
||||||
outp: string
|
outp: string
|
||||||
line: int
|
line: int
|
||||||
msg: string
|
msg: string
|
||||||
|
|
@ -72,13 +75,21 @@ proc parseSpec(filename: string): TSpec =
|
||||||
result.err = true
|
result.err = true
|
||||||
result.msg = ""
|
result.msg = ""
|
||||||
result.outp = ""
|
result.outp = ""
|
||||||
|
result.cmd = cmdTemplate
|
||||||
parseSpecAux:
|
parseSpecAux:
|
||||||
case normalize(e.key)
|
case normalize(e.key)
|
||||||
|
of "action":
|
||||||
|
case e.value.normalize
|
||||||
|
of "compile": result.action = actionCompile
|
||||||
|
of "run": result.action = actionRun
|
||||||
|
of "reject": result.action = actionReject
|
||||||
|
else: echo ignoreMsg(p, e)
|
||||||
of "file": result.file = e.value
|
of "file": result.file = e.value
|
||||||
of "line": discard parseInt(e.value, result.line)
|
of "line": discard parseInt(e.value, result.line)
|
||||||
of "output": result.outp = e.value
|
of "output": result.outp = e.value
|
||||||
of "errormsg", "msg": result.msg = e.value
|
of "errormsg", "msg": result.msg = e.value
|
||||||
of "disabled": result.disabled = parseCfgBool(e.value)
|
of "disabled": result.disabled = parseCfgBool(e.value)
|
||||||
|
of "cmd": result.cmd = e.value
|
||||||
else: echo ignoreMsg(p, e)
|
else: echo ignoreMsg(p, e)
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
@ -92,7 +103,7 @@ var
|
||||||
pegSuccess = peg"'Hint: operation successful'.*"
|
pegSuccess = peg"'Hint: operation successful'.*"
|
||||||
pegOfInterest = pegLineError / pegOtherError / pegSuccess
|
pegOfInterest = pegLineError / pegOtherError / pegSuccess
|
||||||
|
|
||||||
proc callCompiler(filename, options: string): TSpec =
|
proc callCompiler(cmdTemplate, filename, options: string): TSpec =
|
||||||
var c = parseCmdLine(cmdTemplate % [options, filename])
|
var c = parseCmdLine(cmdTemplate % [options, filename])
|
||||||
var a: seq[string] = @[] # slicing is not yet implemented :-(
|
var a: seq[string] = @[] # slicing is not yet implemented :-(
|
||||||
for i in 1 .. c.len-1: add(a, c[i])
|
for i in 1 .. c.len-1: add(a, c[i])
|
||||||
|
|
@ -192,7 +203,7 @@ proc reject(r: var TResults, dir, options: string) =
|
||||||
r.addResult(t, "", "", reIgnored)
|
r.addResult(t, "", "", reIgnored)
|
||||||
inc(r.skipped)
|
inc(r.skipped)
|
||||||
else:
|
else:
|
||||||
var given = callCompiler(test, options)
|
var given = callCompiler(expected.cmd, test, options)
|
||||||
cmpMsgs(r, expected, given, t)
|
cmpMsgs(r, expected, given, t)
|
||||||
|
|
||||||
proc compile(r: var TResults, pattern, options: string) =
|
proc compile(r: var TResults, pattern, options: string) =
|
||||||
|
|
@ -200,7 +211,7 @@ proc compile(r: var TResults, pattern, options: string) =
|
||||||
var t = extractFilename(test)
|
var t = extractFilename(test)
|
||||||
inc(r.total)
|
inc(r.total)
|
||||||
echo t
|
echo t
|
||||||
var given = callCompiler(test, options)
|
var given = callCompiler(cmdTemplate, test, options)
|
||||||
r.addResult(t, given.msg, if given.err: reFailure else: reSuccess)
|
r.addResult(t, given.msg, if given.err: reFailure else: reSuccess)
|
||||||
if not given.err: inc(r.passed)
|
if not given.err: inc(r.passed)
|
||||||
|
|
||||||
|
|
@ -214,7 +225,7 @@ proc run(r: var TResults, dir, options: string) =
|
||||||
r.addResult(t, "", "", reIgnored)
|
r.addResult(t, "", "", reIgnored)
|
||||||
inc(r.skipped)
|
inc(r.skipped)
|
||||||
else:
|
else:
|
||||||
var given = callCompiler(test, options)
|
var given = callCompiler(expected.cmd, test, options)
|
||||||
if given.err:
|
if given.err:
|
||||||
r.addResult(t, "", given.msg, reFailure)
|
r.addResult(t, "", given.msg, reFailure)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
3
todo.txt
3
todo.txt
|
|
@ -4,8 +4,6 @@
|
||||||
add --deadlock_prevention:on|off switch
|
add --deadlock_prevention:on|off switch
|
||||||
- built-in serialization
|
- built-in serialization
|
||||||
|
|
||||||
- deprecate ^ and make it available as operator
|
|
||||||
|
|
||||||
|
|
||||||
High priority (version 0.9.0)
|
High priority (version 0.9.0)
|
||||||
=============================
|
=============================
|
||||||
|
|
@ -14,6 +12,7 @@ High priority (version 0.9.0)
|
||||||
- fix the streams implementation so that it uses methods
|
- fix the streams implementation so that it uses methods
|
||||||
- fix overloading resolution
|
- fix overloading resolution
|
||||||
- wrong co-/contravariance
|
- wrong co-/contravariance
|
||||||
|
- deprecate ^ and make it available as operator; new other notation: p[]
|
||||||
|
|
||||||
|
|
||||||
Bugs
|
Bugs
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,10 @@ Changes affecting backwards compatibility
|
||||||
if both ``$#`` and ``$i`` are involved.
|
if both ``$#`` and ``$i`` are involved.
|
||||||
- The ``pegs`` and ``re`` modules distinguish between ``replace``
|
- The ``pegs`` and ``re`` modules distinguish between ``replace``
|
||||||
and ``replacef`` operations.
|
and ``replacef`` operations.
|
||||||
|
- The pointer dereference operation ``p^`` is deprecated and might become
|
||||||
|
``^p`` in later versions or be dropped entirely since it is rarely used.
|
||||||
|
Use the new notation ``p[]`` to dereference a pointer.
|
||||||
|
|
||||||
|
|
||||||
Additions
|
Additions
|
||||||
---------
|
---------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue