mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-10 06:54:16 +00:00
p[] instead of p^
This commit is contained in:
@@ -932,8 +932,9 @@ untraced references are *unsafe*. However for certain low-level operations
|
||||
Traced references are declared with the **ref** keyword, untraced references
|
||||
are declared with the **ptr** keyword.
|
||||
|
||||
The ``^`` operator can be used to derefer a reference, the ``addr`` procedure
|
||||
returns the address of an item. An address is always an untraced reference.
|
||||
An empty subscript ``[]`` notation can be used to derefer a 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.
|
||||
|
||||
The ``.`` (access a tuple/object field operator)
|
||||
@@ -951,7 +952,8 @@ dereferencing operations for reference types:
|
||||
var
|
||||
n: PNode
|
||||
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 deal with untraced memory, the procedures ``alloc``, ``dealloc`` and
|
||||
@@ -1941,8 +1943,8 @@ above example is equivalent to:
|
||||
.. code-block:: nimrod
|
||||
proc divmod(a, b: int,
|
||||
res, remainder: ptr int) =
|
||||
res^ = a div b
|
||||
remainder^ = a mod b
|
||||
res[] = a div b
|
||||
remainder[] = a mod b
|
||||
|
||||
var
|
||||
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``
|
||||
statements, ``for`` statements open an `implicit block`:idx:, so that they
|
||||
can be left with a ``break`` statement. The ``for`` loop declares
|
||||
|
||||
iteration variables (``x`` in the example) - their scope reaches until the
|
||||
end of the loop body. The iteration variables' types are inferred by the
|
||||
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.
|
||||
|
||||
|
||||
|
||||
compileTime pragma
|
||||
------------------
|
||||
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
|
||||
are declared with the **ptr** keyword.
|
||||
|
||||
The ``^`` operator can be used to *derefer* a reference, meaning to retrieve
|
||||
the item the reference points to. The ``addr`` procedure returns the address
|
||||
of an item. An address is always an untraced reference:
|
||||
The empty ``[]`` subscript notation can be used to *derefer* a reference,
|
||||
meaning to retrieve the item the reference points to. The ``addr`` procedure
|
||||
returns the address of an item. An address is always an untraced reference:
|
||||
``addr`` is an *unsafe* feature.
|
||||
|
||||
The ``.`` (access a tuple/object field operator)
|
||||
@@ -1200,7 +1200,8 @@ dereferencing operations for reference types:
|
||||
var
|
||||
n: PNode
|
||||
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.)
|
||||
|
||||
|
||||
@@ -1204,7 +1204,7 @@ proc unaryExpression(p: var TParser): PNode =
|
||||
of pxPlusPlus: result = incdec(p, "inc")
|
||||
of pxMinusMinus: result = incdec(p, "dec")
|
||||
of pxAmp: result = unaryOp(p, nkAddr)
|
||||
of pxStar: result = unaryOp(p, nkDerefExpr)
|
||||
of pxStar: result = unaryOp(p, nkBracketExpr)
|
||||
of pxPlus: result = prefixCall(p, "+")
|
||||
of pxMinus: result = prefixCall(p, "-")
|
||||
of pxTilde: result = prefixCall(p, "not")
|
||||
|
||||
@@ -90,7 +90,9 @@ type
|
||||
warnCannotWriteMO2, warnCannotReadMO2, warnDeprecated,
|
||||
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
||||
warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored,
|
||||
warnXisPassedToProcVar, warnUser, hintSuccess, hintSuccessX,
|
||||
warnXisPassedToProcVar, warnDerefDeprecated,
|
||||
warnUser,
|
||||
hintSuccess, hintSuccessX,
|
||||
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
||||
hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
|
||||
hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath, hintUser
|
||||
@@ -319,6 +321,7 @@ const
|
||||
warnLanguageXNotSupported: "language \'$1\' not supported [LanguageXNotSupported]",
|
||||
warnCommentXIgnored: "comment \'$1\' ignored [CommentXIgnored]",
|
||||
warnXisPassedToProcVar: "\'$1\' is passed to a procvar; deprecated [XisPassedToProcVar]",
|
||||
warnDerefDeprecated: "p^ is deprecated; use p[] instead [DerefDeprecated]",
|
||||
warnUser: "$1 [User]",
|
||||
hintSuccess: "operation successful [Success]",
|
||||
hintSuccessX: "operation successful ($1 lines compiled; $2 sec total) [SuccessX]",
|
||||
@@ -336,11 +339,11 @@ const
|
||||
hintUser: "$1 [User]"]
|
||||
|
||||
const
|
||||
WarningsToStr*: array[0..14, string] = ["CannotOpenFile", "OctalEscape",
|
||||
WarningsToStr*: array[0..15, string] = ["CannotOpenFile", "OctalEscape",
|
||||
"XIsNeverRead", "XmightNotBeenInit", "CannotWriteMO2", "CannotReadMO2",
|
||||
"Deprecated", "SmallLshouldNotBeUsed", "UnknownMagic",
|
||||
"RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported",
|
||||
"CommentXIgnored", "XisPassedToProcVar", "User"]
|
||||
"CommentXIgnored", "XisPassedToProcVar", "DerefDeprecated", "User"]
|
||||
|
||||
HintsToStr*: array[0..13, string] = ["Success", "SuccessX", "LineTooLong",
|
||||
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
||||
|
||||
@@ -436,7 +436,7 @@ proc primary(p: var TParser): PNode =
|
||||
parMessage(p, errIdentifierExpected, $p.tok)
|
||||
of pxHat:
|
||||
var a = result
|
||||
result = newNodeP(nkDerefExpr, p)
|
||||
result = newNodeP(nkBracketExpr, p)
|
||||
addSon(result, a)
|
||||
getTok(p)
|
||||
of pxBracketLe:
|
||||
|
||||
@@ -629,7 +629,7 @@ proc makeDeref(n: PNode): PNode =
|
||||
t = skipTypes(t.sons[0], {tyGenericInst})
|
||||
if t.kind in {tyPtr, tyRef}:
|
||||
var a = result
|
||||
result = newNodeIT(nkDerefExpr, n.info, t.sons[0])
|
||||
result = newNodeIT(nkHiddenDeref, n.info, t.sons[0])
|
||||
addSon(result, a)
|
||||
|
||||
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
|
||||
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 =
|
||||
## 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)
|
||||
n.sons[0] = semExprWithType(c, n.sons[0], flags - {efAllowType})
|
||||
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 nkLambda: result = semLambda(c, n)
|
||||
of nkDerefExpr:
|
||||
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
|
||||
Message(n.info, warnDerefDeprecated)
|
||||
result = semDeref(c, n)
|
||||
of nkAddr:
|
||||
result = n
|
||||
checkSonsLen(n, 1)
|
||||
@@ -1056,7 +1065,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
if isAssignable(n.sons[0]) != arLValue:
|
||||
GlobalError(n.info, errExprHasNoAddress)
|
||||
n.typ = makePtrType(c, n.sons[0].typ)
|
||||
of nkHiddenAddr, nkHiddenDeref:
|
||||
of nkHiddenAddr, nkHiddenDeref:
|
||||
checkSonsLen(n, 1)
|
||||
n.sons[0] = semExpr(c, n.sons[0], flags)
|
||||
of nkCast: result = semCast(c, n)
|
||||
|
||||
@@ -535,7 +535,7 @@ proc indirectAccess(a, b: PSym): PNode =
|
||||
# returns a^ .b as a node
|
||||
var x = newSymNode(a)
|
||||
var y = newSymNode(b)
|
||||
var deref = newNodeI(nkDerefExpr, x.info)
|
||||
var deref = newNodeI(nkHiddenDeref, x.info)
|
||||
deref.typ = x.typ.sons[0]
|
||||
addSon(deref, x)
|
||||
result = newNodeI(nkDotExpr, x.info)
|
||||
|
||||
@@ -1,24 +1,5 @@
|
||||
This directory contains the test cases.
|
||||
Each test must have a filename of the form: ``t*.nim``
|
||||
|
||||
The testcases may contain the directives ``#ERROR``, ``#ERROR_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::
|
||||
Each test can contain a spec in ``"""``.
|
||||
|
||||
#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"
|
||||
|
||||
type
|
||||
TTestAction = enum
|
||||
actionCompile, actionRun, actionReject
|
||||
TSpec {.pure.} = object
|
||||
file: string
|
||||
action: TTestAction
|
||||
file, cmd: string
|
||||
outp: string
|
||||
line: int
|
||||
msg: string
|
||||
@@ -72,13 +75,21 @@ proc parseSpec(filename: string): TSpec =
|
||||
result.err = true
|
||||
result.msg = ""
|
||||
result.outp = ""
|
||||
result.cmd = cmdTemplate
|
||||
parseSpecAux:
|
||||
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 "line": discard parseInt(e.value, result.line)
|
||||
of "output": result.outp = e.value
|
||||
of "errormsg", "msg": result.msg = e.value
|
||||
of "disabled": result.disabled = parseCfgBool(e.value)
|
||||
of "cmd": result.cmd = e.value
|
||||
else: echo ignoreMsg(p, e)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
@@ -92,7 +103,7 @@ var
|
||||
pegSuccess = peg"'Hint: operation successful'.*"
|
||||
pegOfInterest = pegLineError / pegOtherError / pegSuccess
|
||||
|
||||
proc callCompiler(filename, options: string): TSpec =
|
||||
proc callCompiler(cmdTemplate, filename, options: string): TSpec =
|
||||
var c = parseCmdLine(cmdTemplate % [options, filename])
|
||||
var a: seq[string] = @[] # slicing is not yet implemented :-(
|
||||
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)
|
||||
inc(r.skipped)
|
||||
else:
|
||||
var given = callCompiler(test, options)
|
||||
var given = callCompiler(expected.cmd, test, options)
|
||||
cmpMsgs(r, expected, given, t)
|
||||
|
||||
proc compile(r: var TResults, pattern, options: string) =
|
||||
@@ -200,7 +211,7 @@ proc compile(r: var TResults, pattern, options: string) =
|
||||
var t = extractFilename(test)
|
||||
inc(r.total)
|
||||
echo t
|
||||
var given = callCompiler(test, options)
|
||||
var given = callCompiler(cmdTemplate, test, options)
|
||||
r.addResult(t, given.msg, if given.err: reFailure else: reSuccess)
|
||||
if not given.err: inc(r.passed)
|
||||
|
||||
@@ -214,7 +225,7 @@ proc run(r: var TResults, dir, options: string) =
|
||||
r.addResult(t, "", "", reIgnored)
|
||||
inc(r.skipped)
|
||||
else:
|
||||
var given = callCompiler(test, options)
|
||||
var given = callCompiler(expected.cmd, test, options)
|
||||
if given.err:
|
||||
r.addResult(t, "", given.msg, reFailure)
|
||||
else:
|
||||
|
||||
3
todo.txt
3
todo.txt
@@ -4,8 +4,6 @@
|
||||
add --deadlock_prevention:on|off switch
|
||||
- built-in serialization
|
||||
|
||||
- deprecate ^ and make it available as operator
|
||||
|
||||
|
||||
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 overloading resolution
|
||||
- wrong co-/contravariance
|
||||
- deprecate ^ and make it available as operator; new other notation: p[]
|
||||
|
||||
|
||||
Bugs
|
||||
|
||||
@@ -37,6 +37,10 @@ Changes affecting backwards compatibility
|
||||
if both ``$#`` and ``$i`` are involved.
|
||||
- The ``pegs`` and ``re`` modules distinguish between ``replace``
|
||||
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
|
||||
---------
|
||||
|
||||
Reference in New Issue
Block a user