p[] instead of p^

This commit is contained in:
Araq
2011-04-11 21:42:28 +02:00
parent fc6cc79273
commit 3d696c3da5
12 changed files with 64 additions and 52 deletions

View File

@@ -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

View File

@@ -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.)

View File

@@ -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")

View File

@@ -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",

View File

@@ -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:

View File

@@ -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)

View File

@@ -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)

View File

@@ -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.

View File

@@ -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:

View File

@@ -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

View File

@@ -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
---------