Skip to content

Commit fb44c52

Browse files
author
Daniil Yarancev
authored
Merge pull request #1 from nim-lang/devel
upstream
2 parents ccf99fa + e23ea64 commit fb44c52

File tree

819 files changed

+89401
-42046
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

819 files changed

+89401
-42046
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@ dist/
5757
# Private directories and files (IDEs)
5858
.*/
5959
~*
60+
61+
# testament cruft
62+
testresults/
63+
test.txt

.travis.yml

+4
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,7 @@ script:
4646
- tests/testament/tester --pedantic all -d:nimCoroutines
4747
- ./koch web
4848
- ./koch csource
49+
- ./koch nimsuggest
50+
# - nim c -r nimsuggest/tester
51+
- ( ! grep -F '.. code-block' -l -r --include '*.html' --exclude contributing.html --exclude docgen.html --exclude tut2.html )
52+
- ( ! grep -F '..code-block' -l -r --include '*.html' --exclude contributing.html --exclude docgen.html --exclude tut2.html )

changelog.md

+185-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,191 @@
22

33
### Changes affecting backwards compatibility
44

5-
- Removed basic2d/basic3d out of the stdlib and into Nimble packages.
6-
These packages deprecated however, use the ``glm``, ``arraymancer``, ``neo``
7-
or another package.
5+
86
- Arrays of char cannot be converted to ``cstring`` anymore, pointers to
97
arrays of char can! This means ``$`` for arrays can finally exist
108
in ``system.nim`` and do the right thing.
11-
- JSON: Deprecated `getBVal`, `getFNum`, and `getNum` in favour to
12-
`getBool`, `getFloat`, `getBiggestInt`. Also `getInt` procedure was added.
9+
- ``echo`` now works with strings that contain ``\0`` (the binary zero is not
10+
shown) and ``nil`` strings are equal to empty strings.
11+
- JSON: Deprecated `getBVal`, `getFNum`, and `getNum` in favour to
12+
`getBool`, `getFloat`, `getBiggestInt`. Also `getInt` procedure was added.
13+
- `reExtended` is no longer default for the `re` constructor in the `re`
14+
module.
15+
- The overloading rules changed slightly so that constrained generics are
16+
preferred over unconstrained generics. (Bug #6526)
17+
- It is now possible to forward declare object types so that mutually
18+
recursive types can be created across module boundaries. See
19+
[package level objects](https://nim-lang.org/docs/manual.html#package-level-objects)
20+
for more information.
21+
- The **unary** ``<`` is now deprecated, for ``.. <`` use ``..<`` for other usages
22+
use the ``pred`` proc.
23+
- We changed how array accesses "from backwards" like ``a[^1]`` or ``a[0..^1]`` are
24+
implemented. These are now implemented purely in ``system.nim`` without compiler
25+
support. There is a new "heterogenous" slice type ``system.HSlice`` that takes 2
26+
generic parameters which can be ``BackwardsIndex`` indices. ``BackwardsIndex`` is
27+
produced by ``system.^``.
28+
This means if you overload ``[]`` or ``[]=`` you need to ensure they also work
29+
with ``system.BackwardsIndex`` (if applicable for the accessors).
30+
- ``mod`` and bitwise ``and`` do not produce ``range`` subtypes anymore. This
31+
turned out to be more harmful than helpful and the language is simpler
32+
without this special typing rule.
33+
- Added ``algorithm.rotateLeft``.
34+
- ``rationals.toRational`` now uses an algorithm based on continued fractions.
35+
This means its results are more precise and it can't run into an infinite loop
36+
anymore.
37+
- Added ``typetraits.$`` as an alias for ``typetraits.name``.
38+
- ``os.getEnv`` now takes an optional ``default`` parameter that tells ``getEnv``
39+
what to return if the environment variable does not exist.
40+
- Bodies of ``for`` loops now get their own scope:
41+
42+
```nim
43+
# now compiles:
44+
for i in 0..4:
45+
let i = i + 1
46+
echo i
47+
```
48+
49+
- The parsing rules of ``if`` expressions were changed so that multiple
50+
statements are allowed in the branches. We found few code examples that
51+
now fail because of this change, but here is one:
52+
53+
```nim
54+
t[ti] = if exp_negative: '-' else: '+'; inc(ti)
55+
```
56+
57+
This now needs to be written as:
58+
59+
```nim
60+
t[ti] = (if exp_negative: '-' else: '+'); inc(ti)
61+
```
62+
63+
- To make Nim even more robust the system iterators ``..`` and ``countup``
64+
now only accept a single generic type ``T``. This means the following code
65+
doesn't die with an "out of range" error anymore:
66+
67+
```nim
68+
var b = 5.Natural
69+
var a = -5
70+
for i in a..b:
71+
echo i
72+
```
73+
74+
- ``formatFloat``/``formatBiggestFloat`` now support formatting floats with zero
75+
precision digits. The previous ``precision = 0`` behavior (default formatting)
76+
is now available via ``precision = -1``.
77+
- The ``nim doc`` command is now an alias for ``nim doc2``, the second version of
78+
the documentation generator. The old version 1 can still be accessed
79+
via the new ``nim doc0`` command.
80+
- Added ``system.getStackTraceEntries`` that allows you to access the stack
81+
trace in a structured manner without string parsing.
82+
- Added ``sequtils.mapLiterals`` for easier construction of array and tuple
83+
literals.
84+
- Added ``parseutils.parseSaturatedNatural``.
85+
- ``atomic`` and ``generic`` are no longer keywords in Nim. ``generic`` used to be
86+
an alias for ``concept``, ``atomic`` was not used for anything.
87+
- Moved from stdlib into Nimble packages:
88+
- [``basic2d``](https://github.com/nim-lang/basic2d)
89+
_deprecated: use ``glm``, ``arraymancer``, ``neo``, or another package instead_
90+
- [``basic3d``](https://github.com/nim-lang/basic3d)
91+
_deprecated: use ``glm``, ``arraymancer``, ``neo``, or another package instead_
92+
- [``gentabs``](https://github.com/lcrees/gentabs)
93+
- [``libuv``](https://github.com/lcrees/libuv)
94+
- [``numeric``](https://github.com/lcrees/polynumeric)
95+
- [``poly``](https://github.com/lcrees/polynumeric)
96+
- [``pdcurses``](https://github.com/lcrees/pdcurses)
97+
- [``romans``](https://github.com/lcrees/romans)
98+
99+
- Added ``system.runnableExamples`` to make examples in Nim's documentation easier
100+
to write and test. The examples are tested as the last step of
101+
``nim doc``.
102+
- Nim's ``rst2html`` command now supports the testing of code snippets via an RST
103+
extension that we called ``:test:``::
104+
105+
```rst
106+
.. code-block:: nim
107+
:test:
108+
# shows how the 'if' statement works
109+
if true: echo "yes"
110+
```
111+
- The ``[]`` proc for strings now raises an ``IndexError`` exception when
112+
the specified slice is out of bounds. See issue
113+
[#6223](https://github.com/nim-lang/Nim/issues/6223) for more details.
114+
You can use ``substr(str, start, finish)`` to get the old behaviour back,
115+
see [this commit](https://github.com/nim-lang/nimbot/commit/98cc031a27ea89947daa7f0bb536bcf86462941f) for an example.
116+
- ``strutils.split`` and ``strutils.rsplit`` with an empty string and a
117+
separator now returns that empty string.
118+
See issue [#4377](https://github.com/nim-lang/Nim/issues/4377).
119+
- The experimental overloading of the dot ``.`` operators now take
120+
an ``untyped``` parameter as the field name, it used to be
121+
a ``static[string]``. You can use ``when defined(nimNewDot)`` to make
122+
your code work with both old and new Nim versions.
123+
See [special-operators](https://nim-lang.org/docs/manual.html#special-operators)
124+
for more information.
125+
- Added ``macros.unpackVarargs``.
126+
- The memory manager now uses a variant of the TLSF algorithm that has much
127+
better memory fragmentation behaviour. According
128+
to [http://www.gii.upv.es/tlsf/](http://www.gii.upv.es/tlsf/) the maximum
129+
fragmentation measured is lower than 25%. As a nice bonus ``alloc`` and
130+
``dealloc`` became O(1) operations.
131+
- The behavior of ``$`` has been changed for all standard library collections. The
132+
collection-to-string implementations now perform proper quoting and escaping of
133+
strings and chars.
134+
- The ``random`` procs in ``random.nim`` have all been deprecated. Instead use
135+
the new ``rand`` procs. The module now exports the state of the random
136+
number generator as type ``Rand`` so multiple threads can easily use their
137+
own random number generators that do not require locking. For more information
138+
about this rename see issue [#6934](https://github.com/nim-lang/Nim/issues/6934)
139+
- The compiler is now more consistent in its treatment of ambiguous symbols:
140+
Types that shadow procs and vice versa are marked as ambiguous (bug #6693).
141+
- ``yield`` (or ``await`` which is mapped to ``yield``) never worked reliably
142+
in an array, seq or object constructor and is now prevented at compile-time.
143+
- For string formatting / interpolation a new module
144+
called [strformat](https://nim-lang.org/docs/strformat.html) has been added
145+
to the stdlib.
146+
- codegenDecl pragma now works for the JavaScript backend. It returns an empty string for
147+
function return type placeholders.
148+
- Asynchronous programming for the JavaScript backend using the `asyncjs` module.
149+
- Extra semantic checks for procs with noreturn pragma: return type is not allowed,
150+
statements after call to noreturn procs are no longer allowed.
151+
- Noreturn proc calls and raising exceptions branches are now skipped during common type
152+
deduction in if and case expressions. The following code snippets now compile:
153+
```nim
154+
import strutils
155+
let str = "Y"
156+
let a = case str:
157+
of "Y": true
158+
of "N": false
159+
else: raise newException(ValueError, "Invalid boolean")
160+
let b = case str:
161+
of nil, "": raise newException(ValueError, "Invalid boolean")
162+
elif str.startsWith("Y"): true
163+
elif str.startsWith("N"): false
164+
else: false
165+
let c = if str == "Y": true
166+
elif str == "N": false
167+
else:
168+
echo "invalid bool"
169+
quit("this is the end")
170+
```
171+
- Proc [toCountTable](https://nim-lang.org/docs/tables.html#toCountTable,openArray[A]) now produces a `CountTable` with values correspoding to the number of occurrences of the key in the input. It used to produce a table with all values set to `1`.
172+
173+
Counting occurrences in a sequence used to be:
174+
175+
```nim
176+
let mySeq = @[1, 2, 1, 3, 1, 4]
177+
var myCounter = initCountTable[int]()
178+
179+
for item in mySeq:
180+
myCounter.inc item
181+
```
182+
183+
Now, you can simply do:
184+
185+
```nim
186+
let
187+
mySeq = @[1, 2, 1, 3, 1, 4]
188+
myCounter = mySeq.toCountTable()
189+
```
190+
191+
- Added support for casting between integers of same bitsize in VM (compile time and nimscript).
192+
This allow to among other things to reinterpret signed integers as unsigned.

compiler/aliases.nim

+7-1
Original file line numberDiff line numberDiff line change
@@ -179,5 +179,11 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
179179
result = isPartOf(a[0], b)
180180
if result == arNo: result = arMaybe
181181
else: discard
182+
of nkObjConstr:
183+
result = arNo
184+
for i in 1..<b.len:
185+
let res = isPartOf(a, b[i][1])
186+
if res != arNo:
187+
result = res
188+
if res == arYes: break
182189
else: discard
183-

compiler/ast.nim

+37-22
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ type
6262
nkTripleStrLit, # a triple string literal """
6363
nkNilLit, # the nil literal
6464
# end of atoms
65-
nkMetaNode_Obsolete, # difficult to explain; represents itself
66-
# (used for macros)
65+
nkComesFrom, # "comes from" template/macro information for
66+
# better stack trace generation
6767
nkDotCall, # used to temporarily flag a nkCall node;
6868
# this is used
6969
# for transforming ``s.len`` to ``len(s)``
@@ -639,7 +639,8 @@ type
639639
mEqIdent, mEqNimrodNode, mSameNodeType, mGetImpl,
640640
mNHint, mNWarning, mNError,
641641
mInstantiationInfo, mGetTypeInfo, mNGenSym,
642-
mNimvm, mIntDefine, mStrDefine
642+
mNimvm, mIntDefine, mStrDefine, mRunnableExamples,
643+
mException
643644

644645
# things that we can evaluate safely at compile time, even if not asked for it:
645646
const
@@ -744,6 +745,8 @@ type
744745
OnUnknown, # location is unknown (stack, heap or static)
745746
OnStatic, # in a static section
746747
OnStack, # location is on hardware stack
748+
OnStackShadowDup, # location is on the stack but also replicated
749+
# on the shadow stack
747750
OnHeap # location is on heap or global
748751
# (reference counting needed)
749752
TLocFlags* = set[TLocFlag]
@@ -753,6 +756,7 @@ type
753756
flags*: TLocFlags # location's flags
754757
lode*: PNode # Node where the location came from; can be faked
755758
r*: Rope # rope value of location (code generators)
759+
dup*: Rope # duplicated location for precise stack scans
756760

757761
# ---------------- end of backend information ------------------------------
758762

@@ -1017,16 +1021,11 @@ proc add*(father, son: PNode) =
10171021

10181022
type Indexable = PNode | PType
10191023

1020-
template `[]`*(n: Indexable, i: int): Indexable =
1021-
n.sons[i]
1024+
template `[]`*(n: Indexable, i: int): Indexable = n.sons[i]
1025+
template `[]=`*(n: Indexable, i: int; x: Indexable) = n.sons[i] = x
10221026

1023-
template `-|`*(b, s: untyped): untyped =
1024-
(if b >= 0: b else: s.len + b)
1025-
1026-
# son access operators with support for negative indices
1027-
template `{}`*(n: Indexable, i: int): untyped = n[i -| n]
1028-
template `{}=`*(n: Indexable, i: int, s: Indexable) =
1029-
n.sons[i -| n] = s
1027+
template `[]`*(n: Indexable, i: BackwardsIndex): Indexable = n[n.len - i.int]
1028+
template `[]=`*(n: Indexable, i: BackwardsIndex; x: Indexable) = n[n.len - i.int] = x
10301029

10311030
when defined(useNodeIds):
10321031
const nodeIdToDebug* = -1 # 299750 # 300761 #300863 # 300879
@@ -1036,9 +1035,9 @@ proc newNode*(kind: TNodeKind): PNode =
10361035
new(result)
10371036
result.kind = kind
10381037
#result.info = UnknownLineInfo() inlined:
1039-
result.info.fileIndex = int32(- 1)
1040-
result.info.col = int16(- 1)
1041-
result.info.line = int16(- 1)
1038+
result.info.fileIndex = int32(-1)
1039+
result.info.col = int16(-1)
1040+
result.info.line = int16(-1)
10421041
when defined(useNodeIds):
10431042
result.id = gNodeId
10441043
if result.id == nodeIdToDebug:
@@ -1392,6 +1391,14 @@ proc skipTypes*(t: PType, kinds: TTypeKinds): PType =
13921391
result = t
13931392
while result.kind in kinds: result = lastSon(result)
13941393

1394+
proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType =
1395+
result = t
1396+
var i = maxIters
1397+
while result.kind in kinds:
1398+
result = lastSon(result)
1399+
dec i
1400+
if i == 0: return nil
1401+
13951402
proc skipTypesOrNil*(t: PType, kinds: TTypeKinds): PType =
13961403
## same as skipTypes but handles 'nil'
13971404
result = t
@@ -1405,7 +1412,7 @@ proc isGCedMem*(t: PType): bool {.inline.} =
14051412

14061413
proc propagateToOwner*(owner, elem: PType) =
14071414
const HaveTheirOwnEmpty = {tySequence, tyOpt, tySet, tyPtr, tyRef, tyProc}
1408-
owner.flags = owner.flags + (elem.flags * {tfHasMeta})
1415+
owner.flags = owner.flags + (elem.flags * {tfHasMeta, tfTriggersCompileTime})
14091416
if tfNotNil in elem.flags:
14101417
if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvocation}:
14111418
owner.flags.incl tfNotNil
@@ -1420,15 +1427,12 @@ proc propagateToOwner*(owner, elem: PType) =
14201427
owner.flags.incl tfHasMeta
14211428

14221429
if tfHasAsgn in elem.flags:
1423-
let o2 = elem.skipTypes({tyGenericInst, tyAlias})
1430+
let o2 = owner.skipTypes({tyGenericInst, tyAlias})
14241431
if o2.kind in {tyTuple, tyObject, tyArray,
14251432
tySequence, tyOpt, tySet, tyDistinct}:
14261433
o2.flags.incl tfHasAsgn
14271434
owner.flags.incl tfHasAsgn
14281435

1429-
if tfTriggersCompileTime in elem.flags:
1430-
owner.flags.incl tfTriggersCompileTime
1431-
14321436
if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
14331437
tyGenericInvocation, tyPtr}:
14341438
let elemB = elem.skipTypes({tyGenericInst, tyAlias})
@@ -1442,6 +1446,10 @@ proc rawAddSon*(father, son: PType) =
14421446
add(father.sons, son)
14431447
if not son.isNil: propagateToOwner(father, son)
14441448

1449+
proc rawAddSonNoPropagationOfTypeFlags*(father, son: PType) =
1450+
if isNil(father.sons): father.sons = @[]
1451+
add(father.sons, son)
1452+
14451453
proc addSonNilAllowed*(father, son: PNode) =
14461454
if isNil(father.sons): father.sons = @[]
14471455
add(father.sons, son)
@@ -1604,10 +1612,10 @@ proc hasPattern*(s: PSym): bool {.inline.} =
16041612
result = isRoutine(s) and s.ast.sons[patternPos].kind != nkEmpty
16051613

16061614
iterator items*(n: PNode): PNode =
1607-
for i in 0.. <n.safeLen: yield n.sons[i]
1615+
for i in 0..<n.safeLen: yield n.sons[i]
16081616

16091617
iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
1610-
for i in 0.. <n.len: yield (i, n.sons[i])
1618+
for i in 0..<n.len: yield (i, n.sons[i])
16111619

16121620
proc isAtom*(n: PNode): bool {.inline.} =
16131621
result = n.kind >= nkNone and n.kind <= nkNilLit
@@ -1663,3 +1671,10 @@ when false:
16631671
if n.isNil: return true
16641672
for i in 0 ..< n.safeLen:
16651673
if n[i].containsNil: return true
1674+
1675+
template hasDestructor*(t: PType): bool = tfHasAsgn in t.flags
1676+
template incompleteType*(t: PType): bool =
1677+
t.sym != nil and {sfForward, sfNoForward} * t.sym.flags == {sfForward}
1678+
1679+
template typeCompleted*(s: PSym) =
1680+
incl s.flags, sfNoForward

compiler/canonicalizer.nim

+3-3
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ proc hashTree(c: var MD5Context, n: PNode) =
102102
of nkStrLit..nkTripleStrLit:
103103
c &= n.strVal
104104
else:
105-
for i in 0.. <n.len: hashTree(c, n.sons[i])
105+
for i in 0..<n.len: hashTree(c, n.sons[i])
106106

107107
proc hashType(c: var MD5Context, t: PType) =
108108
# modelled after 'typeToString'
@@ -151,13 +151,13 @@ proc hashType(c: var MD5Context, t: PType) =
151151
c.hashType(t.sons[0])
152152
of tyProc:
153153
c &= (if tfIterator in t.flags: "iterator " else: "proc ")
154-
for i in 0.. <t.len: c.hashType(t.sons[i])
154+
for i in 0..<t.len: c.hashType(t.sons[i])
155155
md5Update(c, cast[cstring](addr(t.callConv)), 1)
156156

157157
if tfNoSideEffect in t.flags: c &= ".noSideEffect"
158158
if tfThread in t.flags: c &= ".thread"
159159
else:
160-
for i in 0.. <t.len: c.hashType(t.sons[i])
160+
for i in 0..<t.len: c.hashType(t.sons[i])
161161
if tfNotNil in t.flags: c &= "not nil"
162162

163163
proc canonConst(n: PNode): TUid =

0 commit comments

Comments
 (0)