summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-04-22 10:53:43 +0200
committerAraq <rumpf_a@web.de>2011-04-22 10:53:43 +0200
commit8dda362fa67bcf75a24f2a60b7a124fdea319a64 (patch)
tree7e43b56fd522040989c5c64ddfef9ffab08b8594
parent1985ac69951932d2882b63b13f9dcd853dd80c43 (diff)
downloadNim-8dda362fa67bcf75a24f2a60b7a124fdea319a64.tar.gz
slices are first class citizens
-rwxr-xr-xbuild.bat20
-rwxr-xr-xcompiler/parser.nim41
-rwxr-xr-xcompiler/semexprs.nim28
-rwxr-xr-xcompiler/semstmts.nim19
-rwxr-xr-xcompiler/semtypes.nim42
-rwxr-xr-xcompiler/trees.nim12
-rwxr-xr-xdoc/grammar.txt29
-rwxr-xr-xdoc/manual.txt66
-rwxr-xr-xlib/system.nim27
-rwxr-xr-xlib/wrappers/tcl.nim2
-rw-r--r--tests/accept/compile/ttableconstr.nim16
-rwxr-xr-xtodo.txt2
12 files changed, 177 insertions, 127 deletions
diff --git a/build.bat b/build.bat
index 34086269c..04e48bea8 100755
--- a/build.bat
+++ b/build.bat
@@ -65,8 +65,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/streams.c -o build/1_1/streams.o
 %CC% %COMP_FLAGS% -Ibuild -c build/1_1/streams.c -o build/1_1/streams.o

 ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/wordrecg.c -o build/1_1/wordrecg.o

 %CC% %COMP_FLAGS% -Ibuild -c build/1_1/wordrecg.c -o build/1_1/wordrecg.o

-ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/scanner.c -o build/1_1/scanner.o

-%CC% %COMP_FLAGS% -Ibuild -c build/1_1/scanner.c -o build/1_1/scanner.o

+ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/lexer.c -o build/1_1/lexer.o

+%CC% %COMP_FLAGS% -Ibuild -c build/1_1/lexer.c -o build/1_1/lexer.o

 ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/lexbase.c -o build/1_1/lexbase.o

 %CC% %COMP_FLAGS% -Ibuild -c build/1_1/lexbase.c -o build/1_1/lexbase.o

 ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/llstream.c -o build/1_1/llstream.o

@@ -77,16 +77,16 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/main.c -o build/1_1/main.o
 %CC% %COMP_FLAGS% -Ibuild -c build/1_1/main.c -o build/1_1/main.o

 ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/syntaxes.c -o build/1_1/syntaxes.o

 %CC% %COMP_FLAGS% -Ibuild -c build/1_1/syntaxes.c -o build/1_1/syntaxes.o

-ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/pnimsyn.c -o build/1_1/pnimsyn.o

-%CC% %COMP_FLAGS% -Ibuild -c build/1_1/pnimsyn.c -o build/1_1/pnimsyn.o

+ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/parser.c -o build/1_1/parser.o

+%CC% %COMP_FLAGS% -Ibuild -c build/1_1/parser.c -o build/1_1/parser.o

 ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/pbraces.c -o build/1_1/pbraces.o

 %CC% %COMP_FLAGS% -Ibuild -c build/1_1/pbraces.c -o build/1_1/pbraces.o

-ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/ptmplsyn.c -o build/1_1/ptmplsyn.o

-%CC% %COMP_FLAGS% -Ibuild -c build/1_1/ptmplsyn.c -o build/1_1/ptmplsyn.o

-ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/rnimsyn.c -o build/1_1/rnimsyn.o

-%CC% %COMP_FLAGS% -Ibuild -c build/1_1/rnimsyn.c -o build/1_1/rnimsyn.o

 ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/filters.c -o build/1_1/filters.o

 %CC% %COMP_FLAGS% -Ibuild -c build/1_1/filters.c -o build/1_1/filters.o

+ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/renderer.c -o build/1_1/renderer.o

+%CC% %COMP_FLAGS% -Ibuild -c build/1_1/renderer.c -o build/1_1/renderer.o

+ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/filter_tmpl.c -o build/1_1/filter_tmpl.o

+%CC% %COMP_FLAGS% -Ibuild -c build/1_1/filter_tmpl.c -o build/1_1/filter_tmpl.o

 ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodread.c -o build/1_1/rodread.o

 %CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodread.c -o build/1_1/rodread.o

 ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodwrite.c -o build/1_1/rodwrite.o

@@ -152,8 +152,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/transf.c -o build/1_1/transf.o
 ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/parseopt.c -o build/1_1/parseopt.o

 %CC% %COMP_FLAGS% -Ibuild -c build/1_1/parseopt.c -o build/1_1/parseopt.o

 

-ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe  build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/rodutils.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/scanner.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/pnimsyn.o build/1_1/pbraces.o build/1_1/ptmplsyn.o build/1_1/rnimsyn.o build/1_1/filters.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/semtypinst.o build/1_1/sigmatch.o build/1_1/suggest.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o

-%LINKER% %LINK_FLAGS% -o bin\nimrod.exe  build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/rodutils.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/scanner.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/pnimsyn.o build/1_1/pbraces.o build/1_1/ptmplsyn.o build/1_1/rnimsyn.o build/1_1/filters.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/semtypinst.o build/1_1/sigmatch.o build/1_1/suggest.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o

+ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe  build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/rodutils.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/lexer.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/parser.o build/1_1/pbraces.o build/1_1/filters.o build/1_1/renderer.o build/1_1/filter_tmpl.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/semtypinst.o build/1_1/sigmatch.o build/1_1/suggest.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o

+%LINKER% %LINK_FLAGS% -o bin\nimrod.exe  build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/rodutils.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/lexer.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/parser.o build/1_1/pbraces.o build/1_1/filters.o build/1_1/renderer.o build/1_1/filter_tmpl.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/semtypinst.o build/1_1/sigmatch.o build/1_1/suggest.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o

 

 ECHO SUCCESS

 

diff --git a/compiler/parser.nim b/compiler/parser.nim
index b579d20be..c7e9cbac7 100755
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -123,7 +123,8 @@ proc newIntNodeP(kind: TNodeKind, intVal: BiggestInt, p: TParser): PNode =
   result = newNodeP(kind, p)
   result.intVal = intVal
 
-proc newFloatNodeP(kind: TNodeKind, floatVal: BiggestFloat, p: TParser): PNode = 
+proc newFloatNodeP(kind: TNodeKind, floatVal: BiggestFloat, 
+                   p: TParser): PNode =
   result = newNodeP(kind, p)
   result.floatVal = floatVal
 
@@ -147,16 +148,18 @@ proc getPrecedence(tok: PToken): int =
   case tok.tokType
   of tkOpr: 
     case tok.ident.s[0]
-    of '$', '^': result = 7
-    of '*', '%', '/', '\\': result = 6
-    of '+', '-', '~', '|': result = 5
-    of '&': result = 4
-    of '=', '<', '>', '!': result = 3
-    else: result = 0
-  of tkDiv, tkMod, tkShl, tkShr: result = 6
-  of tkIn, tkNotIn, tkIs, tkIsNot: result = 3
-  of tkAnd: result = 2
-  of tkOr, tkXor: result = 1
+    of '$', '^': result = 9
+    of '*', '%', '/', '\\': result = 8
+    of '+', '-', '~', '|': result = 7
+    of '&': result = 6
+    of '=', '<', '>', '!': result = 4
+    of '.': result = 5
+    else: result = 1
+  of tkDiv, tkMod, tkShl, tkShr: result = 8
+  of tkIn, tkNotIn, tkIs, tkIsNot, tkNot: result = 4
+  of tkDotDot: result = 5
+  of tkAnd: result = 3
+  of tkOr, tkXor: result = 2
   else: result = - 10
   
 proc isOperator(tok: PToken): bool = 
@@ -202,7 +205,7 @@ proc parseSymbol(p: var TParser): PNode =
       addSon(result, newIdentNodeP(getIdent("()"), p))
       getTok(p)
       eat(p, tkParRi)
-    of tokKeywordLow..tokKeywordHigh, tkSymbol, tkOpr: 
+    of tokKeywordLow..tokKeywordHigh, tkSymbol, tkOpr, tkDotDot: 
       var id = p.tok.ident
       getTok(p)
       if p.tok.tokType == tkEquals: 
@@ -494,7 +497,7 @@ proc identOrLiteral(p: var TParser): PNode =
 
 proc primary(p: var TParser): PNode = 
   # prefix operator?
-  if (p.tok.tokType == tkNot) or (p.tok.tokType == tkOpr): 
+  if isOperator(p.tok):
     result = newNodeP(nkPrefix, p)
     var a = newIdentNodeP(p.tok.ident, p)
     addSon(result, a)
@@ -553,18 +556,8 @@ proc lowestExprAux(p: var TParser, v: var PNode, limit: int): PToken =
     opPrec = getPrecedence(nextop)
   result = op                 # return first untreated operator
   
-proc otherExpr(p: var TParser): PNode = 
-  discard lowestExprAux(p, result, - 1)
-
 proc lowestExpr(p: var TParser): PNode = 
-  result = otherExpr(p)
-  while p.tok.tokType == tkDotDot:
-    getTok(p)
-    optInd(p, result)
-    var a = result
-    result = newNodeP(nkRange, p)
-    addSon(result, a)
-    addSon(result, otherExpr(p))
+  discard lowestExprAux(p, result, - 1)
 
 proc parseIfExpr(p: var TParser): PNode = 
   result = newNodeP(nkIfExpr, p)
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 8f8a1dc17..56de998f5 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -828,15 +828,20 @@ proc semSetConstr(c: PContext, n: PNode): PNode =
     # only semantic checking for all elements, later type checking:
     var typ: PType = nil
     for i in countup(0, sonsLen(n) - 1): 
-      if n.sons[i].kind == nkRange: 
-        checkSonsLen(n.sons[i], 2)
-        n.sons[i].sons[0] = semExprWithType(c, n.sons[i].sons[0])
+      if isRange(n.sons[i]): 
+        checkSonsLen(n.sons[i], 3)
         n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1])
+        n.sons[i].sons[2] = semExprWithType(c, n.sons[i].sons[2])
         if typ == nil: 
+          typ = skipTypes(n.sons[i].sons[1].typ, 
+                          {tyGenericInst, tyVar, tyOrdinal})
+        n.sons[i].typ = n.sons[i].sons[2].typ # range node needs type too
+      elif n.sons[i].kind == nkRange:
+        # already semchecked
+        if typ == nil:
           typ = skipTypes(n.sons[i].sons[0].typ, 
                           {tyGenericInst, tyVar, tyOrdinal})
-        n.sons[i].typ = n.sons[i].sons[1].typ # range node needs type too
-      else: 
+      else:
         n.sons[i] = semExprWithType(c, n.sons[i])
         if typ == nil: 
           typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyOrdinal})
@@ -848,11 +853,12 @@ proc semSetConstr(c: PContext, n: PNode): PNode =
     addSon(result.typ, typ)
     for i in countup(0, sonsLen(n) - 1): 
       var m: PNode
-      if n.sons[i].kind == nkRange: 
+      if isRange(n.sons[i]):
         m = newNodeI(nkRange, n.sons[i].info)
-        addSon(m, fitNode(c, typ, n.sons[i].sons[0]))
         addSon(m, fitNode(c, typ, n.sons[i].sons[1]))
-      else: 
+        addSon(m, fitNode(c, typ, n.sons[i].sons[2]))
+      elif n.sons[i].kind == nkRange: m = n.sons[i] # already semchecked
+      else:
         m = fitNode(c, typ, n.sons[i])
       addSon(result, m)
 
@@ -1086,7 +1092,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
     checkMinSonsLen(n, 2)
   of nkSymChoice: 
     GlobalError(n.info, errExprXAmbiguous, renderTree(n, {renderNoComments}))
-  else: 
-    #InternalError(n.info, nodeKindToStr[n.kind]);
-    GlobalError(n.info, errInvalidExpressionX, renderTree(n, {renderNoComments}))
+  else:
+    GlobalError(n.info, errInvalidExpressionX, 
+                renderTree(n, {renderNoComments}))
   incl(result.flags, nfSem)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 71d523540..0a3daf79c 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -339,11 +339,11 @@ proc semConst(c: PContext, n: PNode): PNode =
     if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil)
     var def = semAndEvalConstExpr(c, a.sons[2]) 
     # check type compability between def.typ and typ:
-    if (typ != nil): 
+    if typ != nil:
       def = fitRemoveHiddenConv(c, typ, def)
-    else: 
+    else:
       typ = def.typ
-    if not typeAllowed(typ, skConst): 
+    if not typeAllowed(typ, skConst):
       GlobalError(a.info, errXisNoType, typeToString(typ))
     v.typ = typ
     v.ast = def               # no need to copy
@@ -423,25 +423,12 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
   var b = newNodeI(nkBreakStmt, n.info)
   b.add(ast.emptyNode)
   stmts.add(b)
-  
-proc createCountupNode(c: PContext, rangeNode: PNode): PNode = 
-  # convert ``in 3..5`` to ``in countup(3, 5)``
-  checkSonsLen(rangeNode, 2)
-  result = newNodeI(nkCall, rangeNode.info)
-  var countUp = StrTableGet(magicsys.systemModule.Tab, getIdent"countup")
-  if countUp == nil: GlobalError(rangeNode.info, errSystemNeeds, "countup")
-  newSons(result, 3)
-  result.sons[0] = newSymNode(countup)
-  result.sons[1] = rangeNode.sons[0]
-  result.sons[2] = rangeNode.sons[1]
 
 proc semFor(c: PContext, n: PNode): PNode = 
   result = n
   checkMinSonsLen(n, 3)
   var length = sonsLen(n)
   openScope(c.tab)
-  if n.sons[length-2].kind == nkRange:
-    n.sons[length-2] = createCountupNode(c, n.sons[length-2])
   n.sons[length-2] = semExprWithType(c, n.sons[length-2], {efWantIterator})
   var call = n.sons[length-2]
   if call.kind != nkCall or call.sons[0].kind != nkSym or
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index bb0bcdf93..ed9b9f4d5 100755
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -116,14 +116,14 @@ proc semDistinct(c: PContext, n: PNode, prev: PType): PType =
   else: GlobalError(n.info, errXExpectsOneTypeParam, "distinct")
   
 proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = 
-  if (n.kind != nkRange): InternalError(n.info, "semRangeAux")
-  checkSonsLen(n, 2)
+  assert IsRange(n)
+  checkSonsLen(n, 3)
   result = newOrPrevType(tyRange, prev, c)
   result.n = newNodeI(nkRange, n.info)
-  if (n.sons[0].kind == nkEmpty) or (n.sons[1].kind == nkEmpty): 
+  if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty): 
     GlobalError(n.Info, errRangeIsEmpty)
-  var a = semConstExpr(c, n.sons[0])
-  var b = semConstExpr(c, n.sons[1])
+  var a = semConstExpr(c, n[1])
+  var b = semConstExpr(c, n[2])
   if not sameType(a.typ, b.typ): GlobalError(n.info, errPureTypeMismatch)
   if not (a.typ.kind in
       {tyInt..tyInt64, tyEnum, tyBool, tyChar, tyFloat..tyFloat128}): 
@@ -138,7 +138,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
 proc semRange(c: PContext, n: PNode, prev: PType): PType = 
   result = nil
   if sonsLen(n) == 2: 
-    if n.sons[1].kind == nkRange: result = semRangeAux(c, n.sons[1], prev)
+    if isRange(n[1]): result = semRangeAux(c, n[1], prev)
     else: GlobalError(n.sons[0].info, errRangeExpected)
   else: 
     GlobalError(n.info, errXExpectsOneTypeParam, "range")
@@ -148,7 +148,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
   result = newOrPrevType(tyArray, prev, c)
   if sonsLen(n) == 3: 
     # 3 = length(array indx base)
-    if n.sons[1].kind == nkRange: indx = semRangeAux(c, n.sons[1], nil)
+    if isRange(n[1]): indx = semRangeAux(c, n[1], nil)
     else: indx = semTypeNode(c, n.sons[1], nil)
     addSon(result, indx)
     if indx.kind == tyGenericInst: indx = lastSon(indx)
@@ -276,26 +276,26 @@ proc checkForOverlap(c: PContext, t, ex: PNode, branchIndex: int) =
       if overlap(t.sons[i].sons[j], ex): 
         LocalError(ex.info, errDuplicateCaseLabel)
   
-proc semBranchExpr(c: PContext, t: PNode, ex: var PNode) = 
-  ex = semConstExpr(c, ex)
+proc semBranchExpr(c: PContext, t, e: PNode): PNode = 
+  result = semConstExpr(c, e)
   checkMinSonsLen(t, 1)
-  if (cmpTypes(t.sons[0].typ, ex.typ) <= isConvertible): 
-    typeMismatch(ex, t.sons[0].typ, ex.typ)
+  if cmpTypes(t.sons[0].typ, result.typ) <= isConvertible: 
+    typeMismatch(result, t.sons[0].typ, result.typ)
 
 proc SemCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, 
                    covered: var biggestInt) = 
   for i in countup(0, sonsLen(branch) - 2): 
     var b = branch.sons[i]
-    if b.kind == nkRange: 
-      checkSonsLen(b, 2)
-      semBranchExpr(c, t, b.sons[0])
-      semBranchExpr(c, t, b.sons[1])
-      if emptyRange(b.sons[0], b.sons[1]): 
-        #MessageOut(renderTree(t));
-        GlobalError(b.info, errRangeIsEmpty)
-      covered = covered + getOrdValue(b.sons[1]) - getOrdValue(b.sons[0]) + 1
-    else: 
-      semBranchExpr(c, t, branch.sons[i]) # NOT: `b`, because of var-param!
+    if isRange(b): 
+      checkSonsLen(b, 3)
+      var r = newNodeI(nkRange, b.info)
+      r.add(semBranchExpr(c, t, b.sons[1]))
+      r.add(semBranchExpr(c, t, b.sons[2]))
+      if emptyRange(r[0], r[1]): GlobalError(b.info, errRangeIsEmpty)
+      covered = covered + getOrdValue(r[1]) - getOrdValue(r[0]) + 1
+      branch.sons[i] = r
+    else:
+      branch.sons[i] = semBranchExpr(c, t, b)
       inc(covered)
     checkForOverlap(c, t, branch.sons[i], branchIndex)
 
diff --git a/compiler/trees.nim b/compiler/trees.nim
index 54f688103..3c8775b87 100755
--- a/compiler/trees.nim
+++ b/compiler/trees.nim
@@ -1,7 +1,7 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2008 Andreas Rumpf
+#        (c) Copyright 2011 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -10,7 +10,7 @@
 # tree helper routines
 
 import 
-  ast, astalgo, lexer, msgs, strutils
+  ast, astalgo, lexer, msgs, strutils, wordrecg
 
 proc getMagic*(op: PNode): TMagic
 
@@ -106,7 +106,8 @@ proc getOpSym(op: PNode): PSym =
   
 proc getMagic(op: PNode): TMagic = 
   case op.kind
-  of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit: 
+  of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit, nkPrefix, nkPostfix,
+     nkInfix: 
     case op.sons[0].Kind
     of nkSym: result = op.sons[0].sym.magic
     else: result = mNone
@@ -138,3 +139,8 @@ proc SwapOperands(op: PNode) =
   var tmp = op.sons[1]
   op.sons[1] = op.sons[2]
   op.sons[2] = tmp
+
+proc IsRange*(n: PNode): bool {.inline.} = 
+  result = n.kind == nkInfix and n[0].kind == nkIdent and 
+    n[0].ident.id == ord(wDotDot)
+
diff --git a/doc/grammar.txt b/doc/grammar.txt
index 4ab5845a8..837a93003 100755
--- a/doc/grammar.txt
+++ b/doc/grammar.txt
@@ -1,26 +1,27 @@
 module ::= ([COMMENT] [SAD] stmt)*
 
 comma ::= ',' [COMMENT] [IND]
-operator ::= OP0 | OR | XOR | AND | OP3 | OP4 | OP5 | OP6 | OP7
+operator ::= OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9
+           | 'or' | 'xor' | 'and'
            | 'is' | 'isnot' | 'in' | 'notin'
-           | 'div' | 'mod' | 'shl' | 'shr' | 'not'
+           | 'div' | 'mod' | 'shl' | 'shr' | 'not' | '..'
 
-prefixOperator ::= OP0 | OP3 | OP4 | OP5 | OP6 | OP7 | 'not'
+prefixOperator ::= operator
 
 optInd ::= [COMMENT] [IND]
 optPar ::= [IND] | [SAD]
 
-lowestExpr ::= otherExpr ('..' optInd otherExpr)*
-otherExpr ::= orExpr (OP0 optInd orExpr)*
-orExpr ::= andExpr (OR | 'xor' optInd andExpr)*
-andExpr ::= cmpExpr ('and' optInd cmpExpr)*
-cmpExpr ::= ampExpr (OP3 | 'is' | 'isnot' | 'in' | 'notin' optInd ampExpr)*
-ampExpr ::= plusExpr (OP4 optInd plusExpr)*
-plusExpr ::= mulExpr (OP5 optInd mulExpr)*
-mulExpr ::= dollarExpr (OP6 | 'div' | 'mod' | 'shl' | 'shr' optInd dollarExpr)*
-dollarExpr ::= primary (OP7 optInd primary)*
+lowestExpr ::= orExpr (OP1 optInd orExpr)*
+orExpr ::= andExpr (OP2 optInd andExpr)*
+andExpr ::= cmpExpr (OP3 optInd cmpExpr)*
+cmpExpr ::= sliceExpr (OP4 optInd sliceExpr)*
+sliceExpr ::= ampExpr (OP5 optInd ampExpr)*
+ampExpr ::= plusExpr (OP6 optInd plusExpr)*
+plusExpr ::= mulExpr (OP7 optInd mulExpr)*
+mulExpr ::= dollarExpr (OP8 optInd dollarExpr)*
+dollarExpr ::= primary (OP9 optInd primary)*
 
-indexExpr ::= '..' [expr] | expr ['=' expr]
+indexExpr ::= expr ['=' expr]
 
 castExpr ::= 'cast' '[' optInd typeDesc optPar ']' '(' optInd expr optPar ')'
 addrExpr ::= 'addr' '(' optInd expr optPar ')'
@@ -120,7 +121,7 @@ caseStmt ::= 'case' expr [':'] ('of' exprList ':' stmt)*
                                ('elif' expr ':' stmt)*
                                ['else' ':' stmt]
 whileStmt ::= 'while' expr ':' stmt
-forStmt ::= 'for' symbol (comma symbol)* 'in' expr ['..' expr] ':' stmt
+forStmt ::= 'for' symbol (comma symbol)* 'in' expr ':' stmt
 exceptList ::= [qualifiedIdent (comma qualifiedIdent)*]
 
 tryStmt ::= 'try' ':' stmt
diff --git a/doc/manual.txt b/doc/manual.txt
index f9c1fe333..e230861fb 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -346,29 +346,38 @@ notation:
 ``0B0_10001110100_0000101001000111101011101111111011000101001101001001'f64``

 is approximately 1.72826e35 according to the IEEE floating point standard.

 

+
+Operators
+---------
+
+In Nimrod one can define his own operators. An `operator`:idx: is any

+combination of the following characters::

+

+       =     +     -     *     /     <     >

+       @     $     ~     &     %     |

+       !     ?     ^     .     :     \

 

+These keywords are also operators:

+``and or not xor shl shr div mod in notin is isnot``.
+
+`=`:tok:, `:`:tok:, `::`:tok: are not available as general operators; they
+are used for other notational purposes. 
+
+``*:`` is as a special case the two tokens `*`:tok: and `:`:tok:
+(to support ``var v*: T``).

+
 

 Other tokens

 ------------

 

 The following strings denote other tokens::

 

-       (     )     {     }     [     ]     ,  ;   [.    .]  {.   .}  (.  .)

-       :     =     ^     ..    `

-

-`..`:tok: takes precedence over other tokens that contain a dot: `{..}`:tok: are

-the three tokens `{`:tok:, `..`:tok:, `}`:tok: and not the two tokens

-`{.`:tok:, `.}`:tok:.

-

-In Nimrod one can define his own operators. An `operator`:idx: is any

-combination of the following characters that is not listed above::

-

-       +     -     *     /     <     >

-       =     @     $     ~     &     %

-       !     ?     ^     .     |     \

-

-These keywords are also operators:

-``and or not xor shl shr div mod in notin is isnot``.

+    `   (     )     {     }     [     ]     ,  ;   [.    .]  {.   .}  (.  .)

+
+
+The `slice`:idx: operator `..`:tok: takes precedence over other tokens that 
+contain a dot: `{..}`:tok: are the three tokens `{`:tok:, `..`:tok:, `}`:tok: 
+and not the two tokens `{.`:tok:, `.}`:tok:.

 

 

 Syntax

@@ -378,7 +387,7 @@ This section lists Nimrod's standard syntax in ENBF. How the parser receives
 indentation tokens is already described in the `Lexical Analysis`_ section.

 

 Nimrod allows user-definable operators.

-Binary operators have 8 different levels of precedence. For user-defined

+Binary operators have 9 different levels of precedence. For user-defined

 operators, the precedence depends on the first character the operator consists

 of. All binary operators are left-associative, except binary operators starting

 with (or only consisting of) ``^``.

@@ -386,14 +395,15 @@ with (or only consisting of) ``^``.
 ================  ==============================================  ==================  ===============

 Precedence level    Operators                                     First characters    Terminal symbol

 ================  ==============================================  ==================  ===============

-  7 (highest)                                                     ``$  ^``            OP7

-  6               ``*    /    div   mod   shl  shr  %``           ``* % \  /``        OP6

-  5               ``+    -``                                      ``+  ~  |``         OP5

-  4               ``&``                                           ``&``               OP4

-  3               ``==  <= < >= > !=  in  not_in  is  isnot``     ``= <  > !``        OP3

-  2               ``and``                                                             OP2

-  1               ``or xor``                                                          OP1

-  0 (lowest)                                                      ``? @  ` : .``      OP0

+  9 (highest)                                                     ``$  ^``            OP9

+  8               ``*    /    div   mod   shl  shr  %``           ``* % \  /``        OP8

+  7               ``+    -``                                      ``+  ~  |``         OP7

+  6               ``&``                                           ``&``               OP6
+  5               ``..``                                          ``.``               OP5

+  4               ``==  <= < >= > !=  in not_in is isnot not``    ``= <  > !``        OP4

+  3               ``and``                                                             OP3

+  2               ``or xor``                                                          OP2

+  1 (lowest)                                                      `` @  : ? ``        OP1

 ================  ==============================================  ==================  ===============

 

 

@@ -2948,7 +2958,11 @@ string expressions in general:
   proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}

 

 **Note**: Patterns like ``libtcl(|8.5|8.4).so`` are only supported in constant

-strings, because they are precompiled.

+strings, because they are precompiled.
+
+**Note**: Passing variables to the ``dynlib`` pragma will fail at runtime 
+because of order of initialization problems.
+

 

 Dynlib pragma for export

 ------------------------

diff --git a/lib/system.nim b/lib/system.nim
index 46ca5b61d..f5757d475 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -115,6 +115,26 @@ type
   seq*{.magic: "Seq".}[T]  ## Generic type to construct sequences.
   set*{.magic: "Set".}[T]  ## Generic type to construct bit sets.
 
+type
+  TSlice* {.final, pure.}[T] = object ## builtin slice type
+    a*, b*: T                         ## the bounds
+
+proc `..`*[T](a, b: T): TSlice[T] {.noSideEffect, inline.} =
+  ## `slice`:idx: operator that constructs an interval ``[a, b]``, both `a`
+  ## and `b` are inclusive. Slices can also be used in the set constructor
+  ## and in ordinal case statements, but then they are special-cased by the
+  ## compiler.
+  result.a = a
+  result.b = b
+
+proc `..`*[T](b: T): TSlice[T] {.noSideEffect, inline.} =
+  ## `slice`:idx: operator that constructs an interval ``[low(T), b]``
+  result.a = low(b)
+  result.b = b
+
+proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} = 
+  result = value >= s.a and value <= s.b
+
 when not defined(EcmaScript) and not defined(NimrodVM):
   type
     TGenericSeq {.compilerproc, pure.} = object
@@ -1040,6 +1060,13 @@ iterator countup*[S, T](a: S, b: T, step = 1): T {.inline.} =
     yield res
     inc(res, step)
 
+iterator `..`*[S, T](a: S, b: T): T {.inline.} =
+  ## An alias for `countup`.
+  var res: T = a
+  while res <= b:
+    yield res
+    inc res
+
 proc min*(x, y: int): int {.magic: "MinI", noSideEffect.}
 proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.}
 proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.}
diff --git a/lib/wrappers/tcl.nim b/lib/wrappers/tcl.nim
index 6f0368574..8836a4296 100755
--- a/lib/wrappers/tcl.nim
+++ b/lib/wrappers/tcl.nim
@@ -42,7 +42,7 @@ elif defined(macosx):
     dllName = "libtcl(8.5|8.4|8.3|8.2|8.1).dylib"
 else: 
   const 
-    dllName = "libtcl(8.5|8.4|8.3|8.2|8.1).so.(1|0)"
+    dllName = "libtcl(8.5|8.4|8.3|8.2|8.1).so(|.1|.0)"
 const 
   TCL_DESTROYED* = 0xDEADDEAD
   TCL_OK* = 0
diff --git a/tests/accept/compile/ttableconstr.nim b/tests/accept/compile/ttableconstr.nim
new file mode 100644
index 000000000..9433e9985
--- /dev/null
+++ b/tests/accept/compile/ttableconstr.nim
@@ -0,0 +1,16 @@
+# Test if the new table constructor syntax works:
+
+template ignoreExpr(e: expr): stmt =
+  nil
+
+# test first class '..' syntactical citizen:  
+ignoreExpr x <> 2..4
+# test table constructor:
+ignoreExpr({:})
+ignoreExpr({2: 3, "key": "value"})
+
+# NEW:
+assert 56 in 50..100
+
+assert 56 in ..60
+
diff --git a/todo.txt b/todo.txt
index e26f613f9..96818da7d 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,4 +1,5 @@
 - clean up the tests!
+- fake-consts and semantic checking for table constructor
 
 
 High priority (version 0.9.0)
@@ -28,7 +29,6 @@ To implement
 
 * hash tables and sets; count tables; ordered dicts
 * distinct types for array/seq indexes
-* constant sequences
 
 * implement closures for the C code generator
 * GC: marker procs for native Nimrod GC and Boehm GC