diff --git a/compiler/docgen.nim b/compiler/docgen.nim
index cd7d459fd5..fc019790a2 100755
--- a/compiler/docgen.nim
+++ b/compiler/docgen.nim
@@ -339,7 +339,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
of tokKeywordLow..tokKeywordHigh:
dispA(result, "$1", "\\spanKeyword{$1}",
[toRope(literal)])
- of tkOpr, tkHat:
+ of tkOpr:
dispA(result, "$1", "\\spanOperator{$1}",
[toRope(esc(literal))])
of tkStrLit..tkTripleStrLit:
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index 2174a696fb..7d65039295 100755
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -49,7 +49,7 @@ type
tkCurlyDotLe, tkCurlyDotRi, # {. and .}
tkParDotLe, tkParDotRi, # (. and .)
tkComma, tkSemiColon, tkColon, tkColonColon, tkEquals, tkDot, tkDotDot,
- tkHat, tkOpr, tkComment, tkAccent, tkInd, tkSad,
+ tkOpr, tkComment, tkAccent, tkInd, tkSad,
tkDed, # pseudo token types used by the source renderers:
tkSpaces, tkInfixOpr, tkPrefixOpr, tkPostfixOpr
TTokTypes* = set[TTokType]
@@ -74,7 +74,7 @@ const
"tkTripleStrLit", "tkGStrLit", "tkGTripleStrLit", "tkCharLit", "(",
")", "[", "]", "{", "}", "[.", ".]", "{.", ".}", "(.", ".)", ",", ";",
":", "::",
- "=", ".", "..", "^", "tkOpr", "tkComment", "`", "[new indentation]",
+ "=", ".", "..", "tkOpr", "tkComment", "`", "[new indentation]",
"[same indentation]", "[dedentation]", "tkSpaces", "tkInfixOpr",
"tkPrefixOpr", "tkPostfixOpr"]
diff --git a/compiler/parser.nim b/compiler/parser.nim
index 42dc0b64bd..aca891863e 100755
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -450,11 +450,6 @@ proc primary(p: var TParser): PNode =
optInd(p, result)
addSon(result, parseSymbol(p))
result = parseGStrLit(p, result)
- of tkHat:
- var a = result
- result = newNodeP(nkDerefExpr, p)
- addSon(result, a)
- getTok(p)
of tkBracketLe:
result = indexExprList(p, result)
else: break
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 8dc629eb41..3c2e766943 100755
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -819,7 +819,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
gsub(g, n.sons[1])
of nkDerefExpr:
gsub(g, n.sons[0])
- putWithSpace(g, tkHat, "^")
+ putWithSpace(g, tkOpr, "^")
# unfortunately this requires a space, because ^. would be only one operator
of nkAccQuoted:
put(g, tkAccent, "`")
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 8f84d665d8..879a42d819 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -237,8 +237,8 @@ proc changeType(n: PNode, newType: PType) =
of nkPar:
if newType.kind != tyTuple:
InternalError(n.info, "changeType: no tuple type for constructor")
- if newType.n == nil: InternalError(n.info, "changeType: no tuple fields")
- if (sonsLen(n) > 0) and (n.sons[0].kind == nkExprColonExpr):
+ if newType.n == nil: nil
+ elif (sonsLen(n) > 0) and (n.sons[0].kind == nkExprColonExpr):
for i in countup(0, sonsLen(n) - 1):
var m = n.sons[i].sons[0]
if m.kind != nkSym:
diff --git a/compiler/semthreads.nim b/compiler/semthreads.nim
index 5e52aea72a..7355c3bfc6 100755
--- a/compiler/semthreads.nim
+++ b/compiler/semthreads.nim
@@ -286,9 +286,9 @@ proc analyseOp(c: PProcCtx, n: PNode): TThreadOwner =
proc analyse(c: PProcCtx, n: PNode): TThreadOwner =
case n.kind
- of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand,
+ of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand,
nkCallStrLit, nkHiddenCallConv:
- result = analyseOp(c, n)
+ result = analyseOp(c, n)
of nkAsgn, nkFastAsgn:
analyseAssign(c, n)
result = toVoid
@@ -299,9 +299,9 @@ proc analyse(c: PProcCtx, n: PNode): TThreadOwner =
of nkDotExpr, nkBracketExpr, nkDerefExpr, nkHiddenDeref:
# field access:
# pointer deref or array access:
- result = analyse(c, n.sons[0])
+ result = analyse(c, n.sons[0])
of nkBind: result = analyse(c, n.sons[0])
- of nkPar, nkCurly, nkBracket:
+ of nkPar, nkCurly, nkBracket, nkRange:
# container construction:
result = toNil # nothing until later
for i in 0..n.len-1: aggregateOwner(result, analyse(c, n[i]))
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index b55f13ae90..47d0fa3fc5 100755
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -32,7 +32,7 @@ type
wShl, wShr, wTemplate, wTry, wTuple, wType, wVar, wWhen, wWhile, wWith,
wWithout, wXor, wYield,
- wColon, wColonColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus,
+ wColon, wColonColon, wEquals, wDot, wDotDot, wStar, wMinus,
wMagic, wThread, wFinal, wProfiler, wObjChecks,
wImportCompilerProc,
wImportc, wExportc, wExtern,
@@ -65,7 +65,7 @@ type
const
oprLow* = ord(wColon)
- oprHigh* = ord(wHat)
+ oprHigh* = ord(wDotDot)
specialWords*: array[low(TSpecialWord)..high(TSpecialWord), string] = ["",
"addr", "and", "as", "asm", "atomic",
@@ -79,7 +79,7 @@ const
"try", "tuple", "type", "var", "when", "while", "with", "without", "xor",
"yield",
- ":", "::", "=", ".", "..", "^", "*", "-",
+ ":", "::", "=", ".", "..", "*", "-",
"magic", "thread", "final", "profiler", "objchecks",
"importcompilerproc", "importc", "exportc", "extern",
"align", "nodecl", "pure", "volatile", "register", "sideeffect",
diff --git a/doc/grammar.txt b/doc/grammar.txt
index 2348a1a7ce..91d334715a 100755
--- a/doc/grammar.txt
+++ b/doc/grammar.txt
@@ -33,7 +33,6 @@ primaryPrefix ::= (prefixOperator | 'bind') optInd
primarySuffix ::= '.' optInd symbol [generalizedLit]
| '(' optInd namedExprList optPar ')'
| '[' optInd [indexExpr (comma indexExpr)* [comma]] optPar ']'
- | '^'
| pragma
primary ::= primaryPrefix* (symbol [generalizedLit] |
diff --git a/tests/accept/compile/tmandelbrot.nim b/tests/accept/compile/tmandelbrot.nim
new file mode 100644
index 0000000000..54724d247b
--- /dev/null
+++ b/tests/accept/compile/tmandelbrot.nim
@@ -0,0 +1,53 @@
+# -*- nimrod -*-
+
+import math
+import os
+import strutils
+
+type TComplex = tuple[re, im: float]
+
+proc `+` (a, b: TComplex): TComplex =
+ return (a.re + b.re, a.im + b.im)
+
+proc `*` (a, b: TComplex): TComplex =
+ result.re = a.re * b.re - a.im * b.im
+ result.im = a.re * b.im + a.im * b.re
+
+proc abs2 (a: TComplex): float =
+ return a.re * a.re + a.im * a.im
+
+var size = parseInt (paramStr (1))
+var bit = 128
+var byteAcc = 0
+
+stdout.writeln ("P4")
+stdout.write ($size)
+stdout.write (" ")
+stdout.writeln ($size)
+
+var fsize = float (size)
+for y in 0 .. size-1:
+ var fy = 2.0 * float (y) / fsize - 1.0
+ for x in 0 .. size-1:
+ var z = (0.0, 0.0)
+ var c = (float (2*x) / fsize - 1.5, fy)
+
+ block iter:
+ for i in 0 .. 49:
+ z = z*z + c
+ if abs2 (z) >= 4.0:
+ break iter
+ byteAcc = byteAcc + bit
+
+ if bit > 1:
+ bit = bit div 2
+ else:
+ stdout.write (chr (byteAcc))
+ bit = 128
+ byteAcc = 0
+
+ if bit != 128:
+ stdout.write (chr (byteAcc))
+ bit = 128
+ byteAcc = 0
+
diff --git a/tests/accept/run/tanontuples.nim b/tests/accept/run/tanontuples.nim
new file mode 100644
index 0000000000..a2babf038b
--- /dev/null
+++ b/tests/accept/run/tanontuples.nim
@@ -0,0 +1,15 @@
+discard """
+ output: "61, 125"
+"""
+
+proc `^` (a, b: int): int =
+ result = 1
+ for i in 1..b: result = result * a
+
+var m = (0, 5)
+var n = (56, 3)
+
+m = (n[0] + m[1], m[1] ^ n[1])
+
+echo m[0], ", ", m[1]
+
diff --git a/todo.txt b/todo.txt
index 4ac2a57033..a21e320dd2 100755
--- a/todo.txt
+++ b/todo.txt
@@ -4,7 +4,6 @@ Version 0.8.14
- ``var T`` as a return type; easy to prove that location does not escape its
stack frame
- document Nimrod's two phase symbol lookup for generics
-- make ^ available as operator
- optional indentation for 'case' statement
- make threadvar efficient again on linux after testing
- test the sort implementation again
diff --git a/web/news.txt b/web/news.txt
index 06d915b262..51e8319d6a 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -25,6 +25,8 @@ Changes affecting backwards compatibility
``osproc.executeCommand``.
- Removed deprecated ``parseopt.init``, ``parseopt.getRestOfCommandLine``.
- Moved ``strutils.validEmailAddress`` to ``matchers.validEmailAddress``.
+- The pointer dereference operator ``^`` has been removed, so that ``^``
+ can now be a user-defined operator.
Language Additions