Compare commits

...

3328 Commits

Author SHA1 Message Date
narimiran
7e83adff84 bump Nim version to 1.2.0 2020-04-03 14:17:15 +02:00
Alexander Ivanov
920add5880 sourcemaps for the JS codegen (#7508) 2020-04-03 12:06:23 +02:00
Andreas Rumpf
2b3b24a804 make bootstrapping more robust for people who have Nim inside /usr/bin (#13855) 2020-04-03 10:25:15 +02:00
itsumura-h
87e6b88f3b fix #7241 (#13779)
finalize() should run in insert()
2020-04-03 09:38:05 +02:00
Timothee Cour
93cd98dd14 move tinyc to a separate repo and allow installing external dependencency (eg tinyc) from koch / library code (#13850)
* remove tinyc
* installDeps
* update tinyc paths
2020-04-03 09:10:45 +02:00
flywind
6b9ffc7fad fix asynchttpserver content-length header (#13846) 2020-04-03 09:05:43 +02:00
Timothee Cour
d23371fdd7 std/byaddr => std/decls (#13847) 2020-04-03 09:03:13 +02:00
narimiran
7d17cd34b8 create a changelog for v1.2.0 2020-04-02 16:28:01 +02:00
Araq
8ee0771b5a return types must not be Natural for reasons I won't outline here 2020-04-02 15:01:14 +02:00
Araq
d01fca974d added an .assert pragma and mentioned the pragmas in the changelog 2020-04-02 12:57:32 +02:00
Dean Eigenmann
df8e0e7f0c feature/count (#13837) 2020-04-02 12:09:29 +02:00
Andreas Rumpf
d01245e501 renamed new std/pragmas.nim to std/byaddr.nim (#13844)
* renamed new std/pragmas.nim to std/byaddr.nim

* minor code cleanup
2020-04-02 11:52:31 +02:00
Timothee Cour
68539a2926 fix last remaining warning when building nim (intVal should be Int128) + minor cleanups (#13841) 2020-04-02 08:53:52 +02:00
Juan Carlos
c167261735 Deprecate PHP (#13838) 2020-04-02 08:48:09 +02:00
Juan Carlos
160d5fe589 Jsconsole update (#12448)
* Improve jsconsole adding the rest of the stable api as documented on the standard at https://developer.mozilla.org/docs/Web/API/Console

* Improve jsconsole, add runnableexamples
* Simplify jsconsole
2020-04-02 08:47:45 +02:00
Juan Carlos
46ca19ff18 Deprecate DCE:on (#13839) 2020-04-02 02:58:43 +02:00
Juan Carlos
afd0afe0a3 Deprecate when declared(echo):echo (#13840) 2020-04-02 02:56:18 +02:00
Juan Carlos
9102ac8c7d Documentation and Code Style inotify (#13836) 2020-04-02 01:05:55 +02:00
Juan Carlos
9599757068 Add browsers.openDefaultBrowser without URL, implements IETF RFC-6694 Section-3 (#13835) 2020-04-01 15:46:47 -04:00
Andreas Rumpf
bc37668c5a fixes #13782 (#13834) 2020-04-01 20:30:28 +02:00
Juan Carlos
4816984726 Documentation, add more examples (#13825) 2020-04-01 19:39:58 +02:00
Andreas Rumpf
484548c784 revert stdlib changes which are not required anymore 2020-04-01 19:38:44 +02:00
Zahary Karadjov
66f18037b3 Fix tests/types/tparameterizedparent0 2020-04-01 19:38:44 +02:00
Zahary Karadjov
08afa03075 The raises list can now use expressions referencing the generic params 2020-04-01 19:38:44 +02:00
Zahary Karadjov
be95f8fdfa Turn some of the errors back into warnings 2020-04-01 19:38:44 +02:00
Zahary Karadjov
ce9a4ed124 Replace tfHasRequiresInit with a more accurate mechanism
The new mechanism can deal with more complex scenarios such as
not nil field appearing in a non-default case object branch or
a field within a generic object that may depend on a when branch.

The commit also plugs another hole: the user is no longer able
to create illegal default values through seq.setLen(N).
2020-04-01 19:38:44 +02:00
Zahary Karadjov
d374c6373b Fix tests/parallel/tguard2.nim 2020-04-01 19:38:44 +02:00
Zahary Karadjov
2b66d66567 Fix a CI failure during koch doc 2020-04-01 19:38:44 +02:00
Zahary Karadjov
e63b673ce2 Fix https://github.com/nim-lang/Nim/issues/4907 2020-04-01 19:38:44 +02:00
Zahary Karadjov
06438ed143 Close https://github.com/nim-lang/Nim/issues/11428 2020-04-01 19:38:44 +02:00
Zahary Karadjov
4f3d309fb0 Perform nil checks during object construction and within compiles()
Close https://github.com/nim-lang/Nim/issues/6494
2020-04-01 19:38:44 +02:00
Zahary Karadjov
7b7e42be54 More precise error messages for uninitialized fields in the presence of inheritance 2020-04-01 19:38:44 +02:00
Zahary Karadjov
0521f98486 Hrm, the new errors highlighted some code that seems to be broken
New issue: since `Table[A, B]` allocates its backing storage with
`newSeq[KeyValuePair[A, B]]`, it's no longer legal to create a table
with `not nil` types used as either keys or values.
2020-04-01 19:38:44 +02:00
Zahary Karadjov
f3be5a716f not nil types are illegal to construct through default(T) 2020-04-01 19:38:44 +02:00
Zahary Karadjov
1b570f2b18 Turn the warning for uninitialized (result) variables into errors 2020-04-01 19:38:44 +02:00
Zahary Karadjov
e0bb78553a Fix tests/notnil/tnotnil_in_objconstr.nim 2020-04-01 19:38:44 +02:00
Zahary Karadjov
54f06427c8 Enable the requiresInit checks only for objects 2020-04-01 19:38:44 +02:00
Zahary Karadjov
8ae48292ff Plug another hole: default(T) forbidden for objects requiring initialization 2020-04-01 19:38:44 +02:00
Zahary Karadjov
05a0ec4adb Don't allow 'var x: T' for objects that require initialization 2020-04-01 19:38:44 +02:00
Zahary Karadjov
7652aede41 More sophistication; Allow requiresInit to be specified per-field 2020-04-01 19:38:44 +02:00
Zahary Karadjov
a8b6222c86 First steps, the compiler can boot with enforced requiresInit 2020-04-01 19:38:44 +02:00
Timothee Cour
216fd59c44 make usage of foo is a user-defined error more informative (#13833) 2020-04-01 17:49:29 +02:00
Timothee Cour
d3020af44d fix open file leak when running --debugger:native (#13832) 2020-04-01 17:48:17 +02:00
Araq
c2d29eb3e0 updated the changelog 2020-04-01 14:10:47 +02:00
Araq
48213c7428 encodeMIME should be encodeMime by our coding guidelines 2020-04-01 14:10:27 +02:00
Timothee Cour
fd202136b4 fix #13829 (#13831) 2020-04-01 12:46:59 +01:00
Clyybber
515b6d661e Small typo (#13824) 2020-03-31 22:59:43 +02:00
lbartoletti
567af54baf Add arm/arm64 for FreeBSD (#13822)
* Add arm and arm64 for FreeBSD

* Add arm64 with aarch64 and reorder to avoid conflict with arm
2020-03-31 22:55:25 +02:00
Andreas Rumpf
9ffec79300 DrNim (Nim compiler with Z3 integration) (#13743)
* code cleanups and feature additions
* added basic test and koch/CI integration
* make it build on Unix
* DrNim: now buildable on Unix, only takes 10 minutes, enjoy
* added basic documentation for DrNim which can also be seen as the RFC we're following
* drnim: change the build setup so that drnim.exe ends up in bin/
* makes simple floating point ranges work
* added basic float range check
* drnim: teach Z3 about Nim's range types plus code refactoring
* drnim: make unsigned numbers work
* added and fixed index checking under setLen
* first implementation of .ensures, .invariant and .assume (.requires still missing and so is proc type compatibility checking
* drnim: .requires checking implemented
* drnim: implemented .ensures properly
* more impressive test involving min()
* drnim: check for proc type compatibility and base method compatibility wrt .requires and .ensures
* testament: support for 'pattern <directory>
* koch: uses new <directory> feature of testament
* drnim: added tiny musings about 'old'
* Make testament work with old SSL versions
* koch: add support for 'koch drnim -d:release'
* drnim: preparations for the param.old notation
2020-03-31 22:54:48 +02:00
Juan Carlos
dd44701728 Tiny fix on browsers.openDefaultBrowser (#13818) 2020-03-31 21:22:24 +02:00
Juan Carlos
c6586322ba Fix a 'See XXX' on documentation, clean out (#13820) 2020-03-31 21:21:49 +02:00
cooldome
c70b3952ff fixes #13810 (#13821)
Co-authored-by: cooldome <ariabushenko@bk.ru>
2020-03-31 21:15:06 +02:00
Andreas Rumpf
9134bb9cfb macros for proc types, macros for types (#13778)
* new minor feature: macros for proc types, to be documented

* Finished the implementation and added tests

* [skip ci] Describe the new custom pragmas in the manual and the changelog

Co-authored-by: Zahary Karadjov <zahary@gmail.com>
2020-03-31 21:14:05 +02:00
alaviss
40898871a9 workflows/ci_docs: fix documentation deployment (#13819)
* workflows/ci_docs: fix docs publishing

It turns out that github.ref is the full ref name, so we have to be a
bit more specific.

See https://developer.github.com/v3/activity/events/types/#pushevent

Also fixed a silly typo :)

* workflows/ci_docs: run CI when there are changes to the workflow
2020-03-31 19:36:37 +02:00
c-blake
b1aa3b1eea Unwind just the "pseudorandom probing" part of recent sets,tables changes (#13816)
* Unwind just the "pseudorandom probing" (whole hash-code-keyed variable
stride double hashing) part of recent sets & tables changes (which has
still been causing bugs over a month later (e.g., two days ago
https://github.com/nim-lang/Nim/issues/13794) as well as still having
several "figure this out" implementation question comments in them (see
just diffs of this PR).

This topic has been discussed in many places:
  https://github.com/nim-lang/Nim/issues/13393
  https://github.com/nim-lang/Nim/pull/13418
  https://github.com/nim-lang/Nim/pull/13440
  https://github.com/nim-lang/Nim/issues/13794

Alternative/non-mandatory stronger integer hashes (or vice-versa opt-in
identity hashes) are a better solution that is more general (no illusion
of one hard-coded sequence solving all problems) while retaining the
virtues of linear probing such as cache obliviousness and age-less tables
under delete-heavy workloads (still untested after a month of this change).

The only real solution for truly adversarial keys is a hash keyed off of
data unobservable to attackers.  That all fits better with a few families
of user-pluggable/define-switchable hashes which can be provided in a
separate PR more about `hashes.nim`.

This PR carefully preserves the better (but still hard coded!) probing
of the  `intsets` and other recent fixes like `move` annotations, hash
order invariant tests, `intsets.missingOrExcl` fixing, and the move of
`rightSize` into `hashcommon.nim`.

* Fix `data.len` -> `dataLen` problem.
2020-03-31 19:18:45 +02:00
Euan
7abeba6aeb #13806 - getApplFreebsd might lose data (#13807)
* #13806 - first call sysctl with a null buffer to get the length, then alloc buffer and call again

* Use csize_t rather than csize

* Suggestions from @Clyybber

Co-authored-by: Euan Torano <euan.torano@bluesky-wireless.co.uk>
2020-03-31 15:50:24 +02:00
alaviss
5621ff6d09 workflows/ci_docs: lots of goodies (#13809)
* workflows/ci_docs: publish documentation to Github Pages

This should be a complete replacement for our current Travis CI setup.

* workflows/ci_docs: run docgen upon modification to the css on push

So that any changes regarding the stylesheets would be reflected on the
published docs.

* workflows/ci_docs: build the compiler in release mode

* workflows/ci_docs: set branch name for the generated docs

This makes the "Source" links work correctly.

* workflows/ci_docs: run docgen on windows and osx too

Only deploy the Linux-generated version.

* workflows/ci_docs: cache csources compiler

This should cut the time spent building csources, which is about 1-2mins
depending on OS.
2020-03-31 15:48:56 +02:00
Juan Carlos
42d2c3088e Add Documentation (#13811)
* Add more Docs and runnableExamples
2020-03-31 15:47:57 +02:00
Timothee Cour
1e4093d949 refs #13797 (#13812) 2020-03-31 15:43:35 +02:00
Huy Doan
119b0ce66f Fix telebot test failed, closes ba0f3/telebot.nim#49 [ref #13812] (#13814)
I was update telebot to version 1.0.0, update folder structure follow `nimble` guideline
2020-03-31 11:25:12 +02:00
Timothee Cour
19cab9fa51 stacktraces can now show custom runtime msgs per frame (#13351)
* stacktraces can now show custom runtime msgs
* improve tests/stdlib/tstackframes.nim
* fix test for --gc:arc
* test --stacktraceMsgs:on and --stacktraceMsgs:off
* --stacktracemsgs:off by default
2020-03-30 13:45:32 +02:00
Miran
8088633250 faster CIs (#13803)
* ttables: smaller table, 5x speedup

* thavlak: less iterations, less loops; 30% speedup

* tasyncclosestall: shorter timeout; 35% speedup

* gcleak4: less iterations, 2x speedup

* ttimes: remove deprecated stuff

* tdangerisrelease: remove cpp backend, 3x speedup

* tfrexp1: smaller range, 2x speedup

* trtree: fix warnings, less iterations, 6x speedup

* tasyncawait_cyclebreaker: smaller swarm size; 2x speedup

* trealloc: smaller number of iterations; 10x speedup

* towned_binary_tree: less iterations, 4x speedup

* tclosure: remove unused code, less iterations; 2x speedup

* twaitany: less durations; 1.4x speedup

* tasync_misc: less iterations, 2x speedup

* t8535: smaller sleep, 1.5x speedup

* tmanyjoin: smaller sleep, 2x speedup

* t12221: shorter sleeps, removed two slower tests; 1.6x speedup

* tfuturestream: smaller sleep; 1.5x speedup

* growobjcrash: less iterations; 2x speedup

* ttryrecv: smaller sleep; 1.5x speedup

* treusetvar: less threads; 2x speedup

* delete tthreadanalysis2, basically a duplicate of tthreadanalysis

* t7758: less iterations, 1.5x speedup

* tasyncawait: smaller swarm, less messages; 1.5x speedup

* tjsandnativeasync: smaller sleep, 1.5x speedup

* tpendingcheck: smaller sleep, 1.5x speedup

* remove rodfiles test category

* move tseq from its own category to 'collections' category

* remove unneeded tests and helpers from 'assert' category

* stdlib: merge tbitops2 into tbitops

* remove 'trepr2' from 'stdlib' cat

* merge 'tstreams' into one file

* remove 'tinefficient_const_table' from 'ccbugs' cat

* merge 'tcollections_to_string' into 'tcollections'

* tblocking_channel: smaller sleep, small speedup

* tconvexhull: less iterartions; 1.2x speedup

* merge 'tdeepcopy2' into 'tdeepcopy'

* merge 'tdisjoint_slice2' into 'tdisjoint_slice1'

* tmissing_deepcopy: smaller sequence

* tsendtwice: smaller arrays; 5x speedup

* remove 'tindexerrorformatbounds'

* disable multimethod tests

* remove 'gc:none' and 'refc' without 'd:useRealtimeGC' from gc tests

* koch.nim: bootstrap just with '-d:release', no need for 'csource'

* add github workflow for documentation

* testament: no need for 8 sub-second decimals
2020-03-30 13:18:12 +02:00
Andreas Rumpf
2a278f6eba '.push raises: []' now also affects proc types (#13776)
* '.push raises: []' now also affects proc types

* fixes the regression

* less disruptive bugfix

* another attempt
2020-03-29 22:00:18 +02:00
Timothee Cour
06f8c5cb6f fix #13794 HashSet leak (#13800) 2020-03-29 18:08:50 +02:00
Juan Carlos
8c719fce54 Fix #13631 (#13789) 2020-03-29 14:39:58 +02:00
Timothee Cour
cfa1a827dc fix #13730 (#13787) 2020-03-28 08:51:16 +01:00
Timothee Cour
95ab9ab75d [CI] fix recent freebsd systematic failure (#13788) 2020-03-28 01:45:22 -04:00
Andreas Rumpf
0a49fe5fad fixes #13763 (#13777) 2020-03-27 12:14:57 +01:00
alaviss
0eaacbc2c4 More fixes for Haiku (#13774)
* osproc: move fork-based code path under the when conditional

* osproc: avoid using the environ global on Haiku

* osenv: import environ from stdlib.h on Haiku

Haiku's environ is declared in `<stdlib.h>` by default, differing from
POSIX and/or Linux. Import it from there to avoid collision with anyone
importing `<stdlib.h>` from Nim.
2020-03-27 09:08:13 +01:00
Arne Döring
142c59fc37 fix typos and deprecation warnings for tconvariancerules.nim (#13772) 2020-03-27 08:36:21 +01:00
cooldome
289b31ee75 make nim_temp compile with --gc:arc --sinkInference:off (#13769)
* make nim_temp compiler with --gc:arc

* trigger build

Co-authored-by: cooldome <ariabushenko@bk.ru>
2020-03-26 20:15:38 +01:00
Clyybber
2925a47ae6 Fix vm.nim for --gc:arc (#13741)
* koch boot --gc:arc now passes the nim stage

... but generates invalid C code

* Move it closer to where its used

* Try something else

* Poor mans var

* Use UncheckedArray instead
2020-03-26 15:18:45 +00:00
alaviss
6162da812a ssl_certs: add Haiku support (#13761) 2020-03-26 14:47:15 +01:00
alaviss
2da438c33b asyncdispatch: fix erroneous set construction (#13765)
These constants were defined as `cint`. They can be huge on certain
systems, such as Haiku, and trigger out-of-bounds errors in
asyncdispatch.

Ref #13764.
2020-03-26 09:26:56 +01:00
zah
e50441ab33 Fix typeSym.getImpl for ref types (#13752)
* Fix typeSym.getImpl for ref types

* Fix a codegen issue affecting the test suite of nim-beacon-chain

* Fix tests/stdlib/tjsonmacro

To understand the fix better it may help to take a look
at the history of the replaced code.

The nil check that is removed in this commit was introduced
in another fix that failed to identify the root cause of the
issue - namely that we allow an object type to exist for which
no ast is present:

https://github.com/nim-lang/Nim/pull/9601/files

The original intention of the code is more obvious here:

https://github.com/nim-lang/Nim/pull/9538/files
2020-03-26 09:26:19 +01:00
Euan
1b31e08917 import macros rather than import std/macros. (#13762) 2020-03-26 09:11:32 +01:00
Timothee Cour
98753da331 distinctBase overload for values (#13746) 2020-03-25 21:47:03 +01:00
cooldome
764a81ca25 Continue bool conversion fixing (#13751)
* continue fixing #13744

* improve style

* improve test

Co-authored-by: cooldome <ariabushenko@bk.ru>
2020-03-25 21:36:22 +01:00
Miran
e1e062197e bump copyright year to 2020 (#13753) 2020-03-25 21:28:16 +01:00
Rory O’Kane
a8a464810e [ci skip] docs: make the syntax for generics easy to look up (#13754) 2020-03-25 21:09:23 +01:00
Rory O’Kane
febd48f343 [skip ci] docs: reword Part 3 link to communicate that it exists (#13755) 2020-03-25 21:08:24 +01:00
Rory O’Kane
84b378b94f docs: say that nil can be used as a value (#13756)
and improve wording in other ways

Showing that `nil` can be assigned helps to warn readers that variables can be `nil` even after being assigned a value.
2020-03-25 19:42:34 +01:00
Miran
5b55aa52d0 fix deprecations and other warnings (#13748) 2020-03-25 19:15:34 +01:00
cooldome
182d3c16e3 fixes #13744 (#13749)
* fixes #13744

* improve style

Co-authored-by: cooldome <ariabushenko@gmail.ru>
2020-03-25 13:44:52 +00:00
Timothee Cour
46c827be6a fix #13737 (#13738) 2020-03-24 10:14:49 +01:00
Araq
5300baae06 use nimEmulateOverflowChecks for ARM/ARM64 2020-03-24 09:46:54 +01:00
Euan
c0dbcffca6 __stderrp and friends are only on FreeBSD & DragonFlyBSD. (#13735) 2020-03-23 21:39:40 +01:00
Miran
4fb7f076d8 fix #13731, ambiguous repr of pointers (#13732) 2020-03-23 20:03:07 +01:00
Andreas Rumpf
fc5dd11b3d fixes #13722 (#13729)
* fixes #13722

* better fix
2020-03-23 15:47:10 +01:00
Araq
e05fd1d00f hotfix: make 'nim doc nimhcr' work on all platforms 2020-03-23 13:05:29 +01:00
Araq
bcccb74429 trees.nim: compare floating points by their bitpatterns because NaN comparisions are always false (WORST design in the history of computing!) 2020-03-23 12:06:33 +01:00
Araq
ee440df02d disable even more of scope based destruction handling; fixes #13709 2020-03-23 12:05:59 +01:00
Araq
28a755dc80 trees.nim: compare floating points by their bitpatterns because NaN comparisions are always false (WORST design in the history of computing!) 2020-03-23 12:05:59 +01:00
Timothee Cour
913bc95964 new syntax for lvalue references: var b {.byaddr.} = expr (#13508)
* new syntax for lvalue references: `var b {.byaddr.} = expr`
* on type mismatch, `???(0, 0)` not shown anymore
* * compiler now lowers `var a: {.foo.}: MyType = expr` to foo(a, MyType, expr)
* new pragmas.byaddr defined in pure library code exploiting this lowering
* skip `template foo() {.pragma.}`
2020-03-23 11:15:45 +01:00
Andy Davidoff
fa06203e90 add error for missing commandLineParams (#13719)
* add error for missing commandLineParams

* fixup

* rewrite
2020-03-23 11:08:37 +01:00
Andreas Rumpf
7ee08b8cf6 Revert "fix #13417 (#13712)" (#13728)
This reverts commit a5f02cac85.
2020-03-23 09:57:17 +01:00
Christian Ulrich
0ac9c7bb64 introduce getPeerCertificates, fixes #13299 (#13650)
* make i2d_X509 and d2i_X509 always available

i2d_X509 and d2i_X509 have been available in all versions of OpenSSL, so
make them available even if nimDisableCertificateValidation is set.

* introduce getPeerCertificates, fixes #13299

getPeerCertificates retrieves the verified certificate chain of the peer
we are connected to through an SSL-wrapped Socket/AsyncSocket. This
introduces the new type Certificate which stores a DER-encoded X509 certificate.
2020-03-22 21:00:37 +01:00
Araq
ef2566218e better error messages for Nim's effect system 2020-03-22 20:45:03 +01:00
Araq
4c1fdc2e8f Windows API callbacks cannot raise exceptions 2020-03-22 20:45:03 +01:00
Arne Döring
a5f02cac85 fix #13417 (#13712)
* fix #13417

* add test
2020-03-22 20:03:51 +01:00
Arne Döring
64ffa17f0f fixes #13715 (#13716)
* fixes #13715

* fix test
2020-03-22 20:01:01 +01:00
Araq
474dd98125 typo 2020-03-22 19:45:02 +01:00
Arne Döring
047d3af6da fix #13720 (#13721) 2020-03-22 19:35:55 +01:00
Hiroki Noda
86b9435138 Add EPOLLEXCLUSIVE (#13718) 2020-03-21 22:52:44 +01:00
cooldome
586ebb090b fixes #13708 (#13711)
* fixes #13708
* differentiate between arc and rest of GC

Co-authored-by: cooldome <ariabushenko@bk.ru>
2020-03-21 07:12:10 +01:00
narimiran
b6e04eafce [ci skip] add back unintentionally removed line 2020-03-20 17:15:48 +01:00
Federico Ceratto
5b85444244 SSL certificate verify GitHub action (#13697)
* Implement SSL/TLS certificate checking #782

* SSL: Add nimDisableCertificateValidation

Remove NIM_SSL_CERT_VALIDATION env var
tests/untestable/thttpclient_ssl.nim ran successfully on Linux with libssl 1.1.1d

* SSL: update integ test to skip flapping tests

* Revert .travis.yml change

* nimDisableCertificateValidation disable imports

Prevent loading symbols that are not defined on older SSL libs

* SSL: disable verification in net.nim

..when nimDisableCertificateValidation is set

* Update changelog

* Fix peername type

* Add define check for windows

* Disable test on windows

* Add exprimental GitHub action CI for SSL

* Test nimDisableCertificateValidation
2020-03-20 17:11:39 +01:00
Timothee Cour
1d665adecd [RFC] 'walkDir' now has a new 'checkDir' flag, to mimic behaviour of other languages (#13642)
Co-authored-by: narimiran
2020-03-20 16:39:55 +01:00
Araq
8215c57666 threadpool.nim: allow control over MaxThreadPoolSize and MaxDistinguishedThread; refs #10584 2020-03-20 15:07:11 +01:00
Joey
0f2377ebef Revert –#13658 for nim-gdb.bat. Fixes #13705 (#13707) 2020-03-20 14:38:33 +01:00
Andreas Rumpf
253e1b9e96 fixes #13698 (#13706) 2020-03-20 14:35:45 +01:00
Hayden
f4dbdd311f Detect Ubuntu by checking release() and uname() (#13704)
This will improve detection of Ubuntu when running on Ubuntu on WSL. #13703
2020-03-20 10:59:05 +01:00
Araq
dae9865b14 fight the code bloat in base64.nim 2020-03-20 10:46:58 +01:00
Araq
12ab5059a0 make 'nim check' more robust for illdefined constants 2020-03-20 10:46:40 +01:00
Juan Carlos
70d93636cb Add Base64 safe (#13672)
* Implement RFC-4648 Section-7
* https://github.com/nim-lang/Nim/pull/13672#issuecomment-600993466
2020-03-20 10:21:42 +01:00
Timothee Cour
dd362ab4c0 fix #13538 sigmatch errors are now sorted (#13701)
* fix #13538 sigmatch now sorted and has reliable order

* re-enable tests that were disabled because of that bug

* fix remaining tests and un-disable 2 other tests that were affected by this bug
2020-03-20 09:28:03 +01:00
Juan Carlos
55d3780b7b Remove 2 old deprecated files (#13702) 2020-03-20 09:24:35 +01:00
Jasper Jenkins
1037318e68 fix nimsuggest warning (#13699) 2020-03-20 09:24:04 +01:00
Jasper Jenkins
28b6b1c3fb fix nimpretty warning (#13700) 2020-03-20 09:22:40 +01:00
Andreas Rumpf
35fb38629f cycle breaker (#13593)
* cycle breaking as an alternative to cycle detection
2020-03-19 22:58:16 +01:00
Juan Carlos
705e283fef Clean 1 old deprecated empty file (#13696) 2020-03-19 20:40:52 +01:00
cooldome
b3176b8817 Attempt to finish off araq cpp exceptions (#13695)
* config update
* disable a questionable test
* remove c++ exception handling IDs, new impl doesn't require it anymore
* C++ based exceptions finally work
* fixes bootstrapping problem in C++ mode
* teach GCC it's 2020 now
* more bugfixes for C++ based exception handling
* apply cooldome's patch
* another attempt to enable C++11
* bug fix

Co-authored-by: Araq <rumpf_a@web.de>
Co-authored-by: cooldome <ariabushenko@bk.ru>
2020-03-19 20:38:25 +01:00
Andreas Rumpf
034dad8e32 fixes #13691 (#13694) 2020-03-19 12:57:45 +01:00
Timothee Cour
1f2042411a fix #13412 nim now recompiles for stdin input; SuccessX now configurable; can show whether it recompiled (#13506)
* fix #13412 nim now recompiles for stdin input; SuccessX now indicates whether it recompiled
2020-03-19 10:39:18 +01:00
Timothee Cour
a17e87b516 fix #11458 oswalkdir (#13689)
* fix #11458 oswalkdir

* changelog
2020-03-19 10:23:05 +01:00
Andreas Rumpf
ba6e7c6365 added a switch -d:nimEmulateOverflowChecks for broken or old GCC versions (#13692) 2020-03-19 09:56:30 +01:00
Miran
b5c9881a30 add move to tables to prevent warnings when compiled with --gc:arc (#13684) 2020-03-19 09:09:01 +01:00
alaviss
b33335d7fd httpcore: deprecate ==(string, HttpCode) (#13682)
According to [RFC7230], the reason phrase attached to the status line is
optional and clients should not rely on it. This in turn causes the proc
to be practically useless, as clients should only inspect the return
code.

Ref #13680.

[RFC7230]: https://tools.ietf.org/html/rfc7230#section-3.1.2
2020-03-19 09:07:44 +01:00
Andreas Rumpf
c74cee4e6a gc.rst that doesn't lie (#13686) 2020-03-19 06:41:54 +01:00
Andreas Rumpf
15ba765ebd enable --tlsEmulation:on for --gc:arc (#13685)
* enable --tlsEmulation:on for --gc:arc
* make -d:useMalloc work with --gc:arc --threads:on
2020-03-18 23:52:49 +01:00
Juan Carlos
a0ccfd16a7 Documentation GC (#13109)
* Update Documentation about GC, add ARC based on code observations and https://forum.nim-lang.org/t/5734#35562

* Rephrase 'Garbage Collector' on documentation, see #13331

* Peer Review Feedbacks

* When the body of a documentation section is all for garbage collector details then add 'for garbage collectors' to the title to identify they may not apply for ARC

* Change 'GC' for 'garbage collector'.

* Move 'Memory Management Strategies' at the top, without changes

* Move the info for RefC GC from 'Introduction' to 'RefC' section without changes, make 'Introduction' about Nims 'Multi-paradigm Memory Management Strategies'.
2020-03-18 22:55:39 +01:00
Arne Döring
88566cc651 allow category nimble-packages to test a single package (#13576) 2020-03-18 21:36:48 +01:00
Andreas Rumpf
fb641483f0 arc optimizations (#13325)
* scope based destructors
* handle 'or' and 'and' expressions properly, see the new test arc/tcontrolflow.nim
* make this branch mergable, logic is disabled for now
2020-03-18 16:57:34 +01:00
Araq
a96842aaeb removed .gitattributes as it only causes trouble for me 2020-03-18 14:43:39 +01:00
Andreas Rumpf
3f29911a94 new feature: --staticBoundChecks:on to enforce static array index checking (#10965) 2020-03-18 14:25:10 +01:00
Timothee Cour
ed263e174e fix #13524 astToStr now works inside generics (#13681) 2020-03-18 13:43:32 +01:00
Andreas Rumpf
a87062393a fixes #13622 (#13679) 2020-03-18 13:42:33 +01:00
Araq
3f1a85b7f0 fixes hash(HashSet) which was wrong as it didn't respect tombstones; refs #13649 2020-03-18 10:47:58 +01:00
Andreas Rumpf
5f6997794e fixes #13671 [backport] (#13678) 2020-03-18 10:37:36 +01:00
Jasper Jenkins
51bd442b88 fix when statements in inheritable generic objects (#13667) [backport] 2020-03-17 23:44:32 +01:00
Jasper Jenkins
122751aa52 add nnkMacroDef to RoutineNodes (#13676) 2020-03-17 23:41:07 +01:00
Andreas Rumpf
fe7b1dfb2a rewritten goto based exception handling; much cleaner implementation;… (#13677)
* rewritten goto based exception handling; much cleaner implementation; fixes #13668
2020-03-17 23:18:43 +01:00
Araq
b737bb4be0 fixes a bug for 'dup' and 'with'; they can now handle nested statement lists that can result from macros 2020-03-17 18:00:11 +01:00
cooldome
35d14095ed Fixes #13659 (#13674)
* fixes #13659

Co-authored-by: cooldome <ariabushenko@bk.ru>
2020-03-17 16:36:38 +01:00
Timothee Cour
af9c852701 fix nim doc subdir/foo which was generating broken css; + other fixes (#13647)
* docgen: minor refactoring via docOutDir
* fix css for `nim doc subdir/foo` without --outdir nor -o
* tcompilesetting.nim: keep `git status` clean
* re-enable pkg nimgame2 that got fixed upstream
2020-03-17 13:44:37 +01:00
Jasper Jenkins
6a23452bf4 fix sets of scoped imported enums (#13666) 2020-03-17 10:47:27 +01:00
Andreas Rumpf
bec0522fca updated builds.sr.ht script according to their email (#13669) 2020-03-17 08:49:26 +01:00
Leorize
e5adaeed20 workflows/ci: disable
Since we got Azure Pipelines running, this will be a fallback pipeline.

Activate by removing the `.disabled` suffix
2020-03-17 08:48:42 +01:00
Leorize
5017320e7b gitattributes: fix tests for windows
Nim-generated files used in tests all end in LF, so we tell git to not
touch them. Should allow a Windows user to clone and run tests without
having to tweak their git settings
2020-03-17 08:48:42 +01:00
alaviss
6e4cd3e5bf .github/workflows: new CI pipeline (#13656)
* .github/workflows: new CI pipeline

As Azure Pipelines went offline, this will be our (temporary?)
replacement. This pipeline covers everything that Azure Pipelines does.

* workflows/ci: disable pipeline

* workflows/ci: properly disable the pipeline

* gitattributes: .txt used in tests should be LF-terminated

This avoids test failures when the compiler was cloned on an OS where
git attempts to convert LF->CRLF.

We target only .txt in tests/ as the minimum required to keep tests
running correctly.

* workflows/ci: re-enable for testing
2020-03-16 23:02:50 +01:00
Andreas Rumpf
955b31a7d9 fixes #13654 2020-03-16 23:00:43 +01:00
Araq
d375120c42 rename sfAlwaysReturn to sfNeverRaises 2020-03-16 19:05:33 +01:00
Andreas Rumpf
5ba5b5202a fixes #13661 (#13664) [backport] 2020-03-16 18:40:17 +01:00
Araq
b9b53b6ca1 fixes #13645 2020-03-16 16:24:50 +01:00
Andy Davidoff
0f672378ab fix .deprecated. object typedef crash (#13643)
* fix .deprecated. object typedef crash
* fixup a test that i don't understand
* disable the test rather than debug ci
2020-03-16 15:08:38 +01:00
Araq
a102eb5ef6 fixes #13646 2020-03-16 14:55:58 +01:00
Araq
3a6b470412 minor code style change 2020-03-16 14:55:58 +01:00
Araq
7205c3ebe2 minor code style changes 2020-03-16 14:55:58 +01:00
cooldome
613ea6e85e fixes #12747 [backport] (#13651)
* fixes #12747
* fix tests
* improve code style

Co-authored-by: cooldome <ariabushenko@bk.ru>
2020-03-16 13:40:40 +01:00
Kartik Saranathan
fe53f6ef4f fix typo (#13660) [ci skip] 2020-03-16 09:07:10 +01:00
Joey
fd3583803e Fix gdb scripts (#13658)
* Fix nim-gdb and rename to nim-gdb.bash
* Add symlink to nim-gdb.bash
* Fix windows debug script
* Add PR suggestions
* Make readlink check easier to maintain/understand
* Swap symlinks
2020-03-16 08:59:16 +01:00
alaviss
ae5094e143 azure-pipelines: walkaround issues with triggers (#13657)
See https://status.dev.azure.com/_event/179641421
2020-03-15 23:44:07 +01:00
Timothee Cour
6e0c06f50e fix #13218: avoid some irrelevant warnings for nim doc,rst2html,--app:lib, + other fixes (#13550)
* fix #13218: avoid some irrelevant warnings for nim doc,rst2html
* suppress warnRedefinitionOfLabel for nim doc
* lots of fixes for UnusedImport warnings
2020-03-13 20:42:41 +01:00
Timothee Cour
380a505507 azure-pipelines: use OSX 10.15 (was just enabled upstream) (#13546) 2020-03-13 14:02:47 +01:00
Araq
9eeb514dda disable nimgame2 for now 2020-03-13 11:50:39 +01:00
Andreas Rumpf
a6682de004 catchable defects (#13626)
* allow defects to be caught even for --exceptions:goto (WIP)
* implemented the new --panics:on|off switch; refs https://github.com/nim-lang/RFCs/issues/180
* new implementation for integer overflow checking
* produce a warning if a user-defined exception type inherits from Exception directly
* applied Timothee's suggestions; improved the documentation and replace the term 'checked runtime check' by 'panic'
* fixes #13627
* don't inherit from Exception directly
2020-03-12 23:44:33 +01:00
Miran
14b2354b7d rename lenTuple and lenVarargs (#13639)
* rename 'lenTuple' to 'tupleLen'

Rationale:
`lenTuple` is a tuple consisting of lengths (e.g. `(1, 5, 0)`),
`tupleLen` is a length of a tuple (e.g. `tupleLen((1, 5, 0) == 3`)

* rename 'lenVarargs' to 'varargsLen'

The same rationale as a previous commit. Consistency.
2020-03-12 20:07:02 +01:00
Clyybber
f0cd50f9c4 Change order of forwarded koch boot command line options, so as to be able to overwrite the nimcache location (#13637) 2020-03-12 16:15:46 +01:00
Timothee Cour
60a3e036f6 fix #13633 fix koch boot crashing regression (#13635) 2020-03-12 11:39:10 +01:00
Clyybber
2bb0ada797 Amend fix for #13633 (#13636) 2020-03-12 11:20:08 +01:00
Clyybber
d84c4bba9b Fix #13633 2020-03-12 11:01:03 +01:00
genotrance
bbc231f8e0 Fix #12676 (#13634) 2020-03-12 08:53:11 +01:00
Kaushal Modi
64995db4fd unicode.split: Fix the splitting when a Rune separator is used [backport] (#13629)
* unicode.split: Fix the splitting when a Rune separator is used [backport]

- Fixes https://github.com/nim-lang/Nim/issues/13628
- Ref https://irclogs.nim-lang.org/11-03-2020.html#20:01:34

* unicode.split: Remove the sepLen based logic.. resulted in wrong jumps
2020-03-12 00:41:45 +01:00
treeform
f2c7152770 Add more JS stuff to dom.nim (#13483)
* Add more JS stuff to dom.nim

* Make all links to docs doc comments.

* Fix minor textContent * space.

* Remove Selection object.

* More work on docs.

* Fixing links.

* Made the links be "see <docs>".
2020-03-11 23:24:56 +00:00
Clyybber
6b3098c378 Make listCmd honor hint:cc:off (#13606)
* Make listCmd honor hint:cc:off

* Tiny cleanup

* Tiny tiny cleanup

* VERY IMPORTANT: --hint:cc:on will overwrite --verbosity:0 :p

* Tiny cleanup

* Stupid

* Move displayProgressCC to where its required

* Tiny cleanup
2020-03-11 23:04:33 +01:00
Miran
70bd41dae0 fix #13310, Deque misbehaves on VM (#13625)
* fix #13310, Deque misbehaves on VM
* use 'when nimVM'
2020-03-11 17:30:36 +01:00
Timothee Cour
281e02fc79 fixes #13558: toDateTime buggy on 29th, 30th and 31th of each month; breaking change: do not use now to compute result, was undocumented and non-sensical (#13565) 2020-03-11 09:47:34 +01:00
Araq
f5f9243cc0 disable chronos testing for now 2020-03-11 09:28:10 +01:00
Araq
3aed8ff432 fixes async regression 2020-03-11 09:26:57 +01:00
Araq
60f8fdcdab fixes #13240 2020-03-11 09:26:57 +01:00
Araq
861a5340fe fixes #13519 2020-03-11 09:26:57 +01:00
Araq
b0684ec425 fixes #12757 2020-03-11 09:26:57 +01:00
Arne Döring
f95eef99a9 add expectIdent to macros (#12778)
* add expectIdent to macros

* apply feedback

* Update lib/core/macros.nim

Co-Authored-By: Clyybber <darkmine956@gmail.com>

* Update texpectIdent2.nim

* Update texpectIdent1.nim

Co-authored-by: Clyybber <darkmine956@gmail.com>
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2020-03-11 08:27:31 +01:00
めぐみ発動機 (isVowel / GreenWing)
8e3a349561 fixed to jsonArrayEnd comment. (#13624)
typo: start → end
2020-03-11 08:26:10 +01:00
Arne Döring
2f557652d4 fix operators containing percent for VM usage (#13536)
* fixes #13513
* merge tarithmetics in tarithm
2020-03-11 01:01:25 +01:00
Timothee Cour
e64f1c7ee4 koch --nim:pathto/nim boot and koch boot --hint:cc:off now work (#13516)
* `koch boot --hint:cc:off` now works

* `koch --nim:pathto/nim boot` now works; code cleanup
2020-03-11 00:31:34 +01:00
Araq
3b7b017798 fixes #13607 2020-03-10 16:01:13 +01:00
Araq
9e2bce2a8c hotfix: make --useVersion:1.0 work 2020-03-10 16:01:13 +01:00
genotrance
ab5d962b50 Revert "Support cross compiling from host to host (#12859)" (#13591)
This reverts commit e4f7656772.
2020-03-10 15:58:27 +01:00
Andreas Rumpf
090ba1e3a3 fixes #13436 (#13615) 2020-03-10 00:52:46 +01:00
narimiran
7d07897a99 travis now only builds devel docs 2020-03-09 21:16:56 +01:00
Andreas Rumpf
ec5cef13cf fixes #13599 (#13614) 2020-03-09 18:12:52 +01:00
Andreas Rumpf
63af8ae53c fixes #13596 (#13612) 2020-03-09 15:32:38 +01:00
Miran
4aecc6b346 fix #12508, unaligned access on sparc64 (#13594) 2020-03-09 14:08:50 +01:00
Andreas Rumpf
dc94c81cb0 fixes #13605 (#13611) 2020-03-09 13:13:54 +01:00
Andy Davidoff
a693ce7765 surgical fix for #13319 (#13604) 2020-03-08 10:55:19 +01:00
Clyybber
eae31a7f8d Only print the link command when listCmd is active; fix docs (#13603) 2020-03-07 23:53:43 +01:00
Juan Carlos
6a5b3811e7 Add isValidFilename (#13561)
* Add os.isValidFilename

* Add os.isValidFilename

* Peer Review Feedbacks https://github.com/nim-lang/Nim/pull/13561#discussion_r388013139

* Peer Review Feedbacks https://github.com/nim-lang/Nim/pull/13561#issuecomment-595259568

* Add since to const

* Update the documentation comment

* Update the changelog

* Update lib/pure/os.nim

Co-Authored-By: Dominik Picheta <dominikpicheta@googlemail.com>

* Update lib/pure/os.nim

Co-Authored-By: Dominik Picheta <dominikpicheta@googlemail.com>

* Peer Review Feedbacks, Add more Tests

Co-authored-by: Dominik Picheta <dominikpicheta@googlemail.com>
2020-03-07 14:10:22 +00:00
Zed
e056298ceb Implement file streaming for httpclient's MultipartData (#12982)
* Add `uploadFile` to POST files by streaming them

* Use constant for \c\L

* Formatting

* Remove uploadFile

* Implement MultipartData file streaming

* Remove unnecessary var annotations

* Call string on TaintedStrings

Fixes #12789

* Move cl constant to httpcore

* Fix `request` inconsistencies

* Update documentaion

* Clean up

* Skip multipart formatting when there's 0 entries

* Remove extraneous `cl` from multipart formatting

* Update MultipartData `$` to match old behaviour

* Update comment

* Address comments
2020-03-06 18:55:45 +00:00
Andrea Ferretti
7ae0811818 Fix #13573 and #13574 (#13575)
* Fix https://github.com/nim-lang/Nim/issues/13573 and https://github.com/nim-lang/Nim/issues/13574

* Restored asynchttpserver
2020-03-06 18:38:56 +00:00
alaviss
4bd388ad58 Revert "nimsuggest: don't add CRLF to replies (#13545)" (#13597)
This reverts commit a974684b14.

The CRLF was to separate between each response, and removing them causes
the responses to not be splitted correctly.

I didn't notice that it was in a loop when I made the #13545.
2020-03-06 19:29:28 +01:00
Dominik Picheta
ec8a17cc86 Revert broken asynchttpserver FutureStream additions.
As discussed in #13394, these changes cannot work. Reverted via

```
git revert --no-commit 5bf571f061
git revert --no-commit abd660c407
git revert --no-commit 955465e5f4
git commit
```
2020-03-06 11:52:30 +01:00
Timothee Cour
b80d293a3f close #12704 by adding a test (tuple codegen error) (#13592)
* close #12704 by adding a test

* move test to tests/metatype/ttypedesc2.nim
2020-03-06 08:55:53 +01:00
Andreas Rumpf
cb0f7c5d9e Removed simpleGetOrDefault (#13590) 2020-03-05 21:03:39 +01:00
Andreas Rumpf
83e715c5b6 fixes #5170 (#13589)
* fixes #5170

* make tests green
2020-03-05 16:02:34 +01:00
Andreas Rumpf
62c113ebc7 fix #13579 joinPath("/foo/", "../a") is now /a (#13586) 2020-03-05 15:31:22 +01:00
Varriount
357edd86b4 fix nightlies builds on Windows (#13587)
Before the files that should have been ignored weren't ignored
because of different dir separator ('\' vs '/') on Windows.
2020-03-04 14:44:42 -05:00
alaviss
a974684b14 nimsuggest: don't add CRLF to replies (#13545)
This is already sent by replTcp after the message is sent.
2020-03-04 15:56:40 +01:00
Andreas Rumpf
a0eca75182 sink parameter inference for types that have destructors (#13544)
* ensure capitalize doesn't take an inferred sink parameter

* sink parameter inference: first version, for now disabled. Changed that sink parameters can be consumed multiple times in order to adhere to our spec.

* sink inference can now be disabled with .nosinks; sometimes for proc type interop this is required

* fixes yet another critical DFA bug

* better implementation that also understands if expressions etc

* document sink parameter inference and allow for global disabling
2020-03-04 14:28:53 +01:00
Andreas Rumpf
614fb7567c std/compilesettings implementation (#13584)
* Implement compileSetting() and compileSettingSeq()
* Change from magic to vmop
* better design for querySetting

Co-authored-by: genotrance <dev@genotrance.com>
2020-03-04 13:46:42 +01:00
Juan Carlos
0809098971 Nimpretty Fix negative indent breaks code (#13580) 2020-03-04 10:27:52 +01:00
Timothee Cour
9fa070b1dc fix hintSuccess: out was wrong for nim doc without -o flag (#13569) 2020-03-04 10:26:56 +01:00
Miran
9961d1f67d fix #13531 by adding a test (#13581) 2020-03-04 10:25:59 +01:00
hlaaftana
34c16f5eca fix #13409: Document as infix operator (#13570) 2020-03-04 07:50:36 +01:00
narimiran
3ca8f0bde6 [ci skip] important_packages: change the order in commented out packages too 2020-03-04 07:15:34 +01:00
Araq
8705ee7015 ARC hotfix; proper destruction of seqs and strings after a move 2020-03-03 23:03:33 +01:00
genotrance
f8175688a3 Fix docgen snippet numbering (#13507) 2020-03-03 20:52:16 +01:00
Miran
e8c057fb27 important_packages: change the order of arguments in the template (#13577)
Leads to a cleaner and less confusing code - an empty command
doesn't mean 'nimble test' anymore.
2020-03-03 16:25:59 +01:00
Arne Döring
eb42f38088 Remove dead magics (#13551) 2020-03-03 12:42:43 +01:00
Timothee Cour
31332bca45 workaround refs #13563 freebsd CI (#13564) 2020-03-02 22:30:41 -05:00
Timothee Cour
451b724c40 make genericParams support static[T] generic params (#13433)
* make genericParams support static[T] generic params

* WrapStatic => StaticParam
2020-03-02 18:05:14 +01:00
Timothee Cour
27241fda23 fix #13528 nimgrep --word now works better with operators (#13537) 2020-03-02 17:55:17 +01:00
PMunch
05e9473f80 Add signatures object to jsondoc for routine types (#13530)
jsondoc is meant to be read by computers, but yet the signatures of
procedures where simply a string of the whole thing. This adds a
signature object that unpacks this information into an object so it's
easier to analyse the documented signatures.
2020-03-02 17:52:42 +01:00
Timothee Cour
653de5f27a fix broken nim CI, disable blscurve (#13555) 2020-03-02 10:26:10 +01:00
Timothee Cour
22d1ba4be7 fixes #13543 and added times.isLeapDay (#13547) 2020-03-01 21:56:20 +01:00
hlaaftana
525ab5a497 Document import/include outside of top level semantics (#13548) 2020-03-01 21:52:29 +01:00
cooldome
0f1a4ac96c make it possible to pass linker options for vcc (#13535) [backport] 2020-02-29 18:57:00 +01:00
cooldome
c79df2fb6a EndsInNoReturn in expressions extension, fixes #13490 (#13520)
* fix #13490
2020-02-28 09:55:06 +00:00
cooldome
25dc5f76e0 fixes #12627 (#13521)
* fixes #12627
2020-02-28 09:54:17 +00:00
Timothee Cour
1056f9ecff properly handle note override logic/verbosity/config/cmdline using modifiedyNotes, cmdlineNotes 2020-02-27 13:22:18 +01:00
Timothee Cour
c1cbf94e2d remove isCmdLine; use passCmd1 2020-02-27 13:22:18 +01:00
Timothee Cour
ce36fdc897 correctly honor cmdline --hint:conf:on/off ; correctly show Conf hints in order 2020-02-27 13:22:18 +01:00
Ganesh Viswanathan
96bffadf60 Fix #9405 - cfg and nims run in sync 2020-02-27 13:22:18 +01:00
Timothee Cour
73f5f1e80c save another 33s of CI for tests/gc/gcleak.nim 2020-02-27 13:19:31 +01:00
Timothee Cour
fdc5925cbd CI tests run faster: save 120s in azure machines, 335s on local OSX 2020-02-27 13:19:31 +01:00
Timothee Cour
9b8c9abead revert changes to tests/gc/gcleak2.nim 2020-02-27 13:19:31 +01:00
Timothee Cour
81b0718a8f make CI tests faster + more precise 2020-02-27 13:19:31 +01:00
solo989
e84e01cb8c Update pegs.nim to work at compiletime. No range errors. (#13459) 2020-02-27 11:08:57 +01:00
Timothee Cour
6a0e87eb38 cleanup Ordinal (#13501) 2020-02-27 10:43:13 +01:00
Timothee Cour
42dad3a836 tables/sharedtables/intsets/etc: fix #13496, #13504, #13505; add lots of tests (#13498) [backport]
* fix #13496 handle tombstones
* add test
* more tests
* fix #13504; add SharedTable tests
* fix #https://github.com/nim-lang/Nim/issues/13505 intsets.missingOrExcl silently gave wrong results sometimes
* add test for tintsets
2020-02-26 22:07:09 +01:00
Miran
9a93f73983 docgen: don't create compiler's docs + cleanup (#13509) 2020-02-26 20:37:27 +01:00
Andreas Rumpf
d55bbefdcc added operateOn to sugar.nim to give Nim the chaining mechanism it de… (#13092)
* implemented the with stdlib module as specified in https://github.com/nim-lang/RFCs/issues/193
* change sugar.outplace to sugar.dup according to https://github.com/nim-lang/RFCs/issues/193
* changelog update
2020-02-26 20:36:06 +01:00
Kaushal Modi
f091b5a0ee xmltree: Make indentation consistent with any num of children nodes (#13482)
Ref: https://forum.nim-lang.org/t/5972
2020-02-26 11:41:44 +01:00
Timothee Cour
0c312ad898 fix #13455 ; joinPath(a,b) now honors trailing slashes in b (or a if b = "") (#13467)
* fix #13455 ; joinPath(a,b) now honors trailing slashes in b (or a if b = "")
* fix test windows
2020-02-26 11:25:27 +01:00
Timothee Cour
11db28bc61 runCI: logs now show CPU/OS/etc info to be self contained (#13486) 2020-02-26 10:44:23 +01:00
Timothee Cour
bd90199a2f fix #8312 --hints:off and --warnings:off now honored everywhere (#13489) 2020-02-26 10:26:47 +01:00
Juan Carlos
94b0d6bb63 Documentation staticRead maximum file size limits (#13485) 2020-02-26 10:01:23 +01:00
Arne Döring
5d2483fb64 fix #13479 (#13503) 2020-02-26 09:51:07 +01:00
Kaushal Modi
e4ed19c12f [backport] tut1: Update the proc overloading examples (#13497) [skip ci] 2020-02-25 21:19:51 +01:00
Timothee Cour
db540a0223 fix #13449 texitcode flaky on windows (#13487) 2020-02-25 17:49:16 +01:00
narimiran
c444ab9a54 make devel green again: tnetdial still doesn't work on Travis 2020-02-25 08:46:08 +01:00
Timothee Cour
1cf5c280e3 only enable linenoise for -d:nimUseLinenoise (#13478)
* only enable linenoise for -d:nimUseLinenoise

* fixup
2020-02-24 11:06:39 +01:00
hlaaftana
84e78b4ffc Minor doc change in macros, future -> sugar (#13475) [ci skip] 2020-02-24 09:57:15 +01:00
Miran
3e8858d694 add more files to the ignore list, hopefully fixes nightlies on windows (#13474) 2020-02-24 09:41:28 +01:00
Andrey Makarov
3dad130034 fix 3 minor bugs in joinPath (see #13455) (#13462) [backport] 2020-02-23 20:22:46 +01:00
hlaaftana
13d292786e Remove genToArray in jsgen, a PHP remnant (#13466) 2020-02-22 20:04:46 +01:00
Lee Matos
c11b91d52d Update advopt.txt to include link to nim cache docs (#13464) 2020-02-22 09:09:04 +01:00
Timothee Cour
a43583f9c8 relativePath("foo", "foo") is now ".", not "" (#13452) 2020-02-22 09:07:53 +01:00
hlaaftana
1276e386fe Consider proc as a pointer type in options (#13460)
* Consider proc as a pointer type in options

* Add version annotation for SomePointer having proc in options

* Log procs as pointers for options in changelog
2020-02-21 23:14:55 +01:00
Andreas Rumpf
0d219d2c67 fixes #13457 (#13458) 2020-02-21 21:06:41 +01:00
Timothee Cour
e05aca8734 make unzip faster: seq[i]=val can be 7X faster than seq.add(elem) (#13448) 2020-02-21 17:26:52 +01:00
Araq
1d90d9816b fixes #13444 2020-02-21 16:58:30 +01:00
Joey
3667fd9f42 Make gdb script work on mac and linux; add windows gdb script (#13453) 2020-02-21 08:53:05 +01:00
genotrance
7a2b623d2a Fix #8648 - use parent streams to avoid hang (#13445) 2020-02-20 23:04:48 +01:00
Kaushal Modi
bb777fef76 Add sequtils.unzip to complement sequtils.zip (#13429) 2020-02-20 19:15:34 +01:00
Manav
479f4ca6a3 Fixed non-working examples in Manual: Exception Handling (#13424) 2020-02-20 15:16:19 +01:00
Clyybber
87dd19453b Remove testutils (#13435) [backport] 2020-02-19 23:02:08 +01:00
Timothee Cour
8c22518d67 [backport] pseudorandom probing for hash collision (#13418) 2020-02-19 17:19:55 +01:00
Timothee Cour
273a93581f fix incorrect lenTuple implementation (#13423) 2020-02-19 11:07:17 +01:00
alaviss
d1f9f11245 manual: documents changes regarding dynlib (#13425)
* manual: documents changes regarding dynlib

Closes #13416

* manual: clean up sentence phrasing
2020-02-18 19:44:54 +01:00
cooldome
046bb0b881 stdlib/system: add sink and move (#13283) 2020-02-18 19:43:26 +01:00
Nな人(N na hito)
8f73753a2d Update LICENSE (#13421) 2020-02-17 18:40:39 +01:00
Ico Doornekamp
73553621a1 Improved assertion error messages on usage of JsonNode iterators on wrong kinds (#13389) 2020-02-17 09:00:25 +01:00
Khronos
006fe4cfc4 Fix vertical tab in JSON. (#13399)
'\v' is not injected in JSON anymore
2020-02-17 00:39:19 +01:00
Juan Carlos
ba25f849a6 Add browsers.osOpen (#12901)
* Add osOpen alias for the operating system specific open command

* Add `--git.devel` option to the documentation
remove unused import (#12900)

fix json regression D20191212T144944 (#12902) [backport]

Peer Review Feedback https://github.com/nim-lang/Nim/pull/12901#issuecomment-565851680

Merge branch 'devel' of https://github.com/nim-lang/Nim into osopen

Peer Review Feedback https://github.com/nim-lang/Nim/pull/12901#issuecomment-565851680

Update lib/pure/browsers.nim

Co-Authored-By: Dominik Picheta <dominikpicheta@googlemail.com>
Peer Review Feedback https://github.com/nim-lang/Nim/pull/12901#discussion_r358492316

allow typed/untyped in magic procs (#12911)

NaN floatFormat with clang_cl  (#12910)

* clang_cl nan floatFormat

* format

add $nimeq for gdb (#12909)

ARC: cycle detector (#12823)

* first implementation of the =trace and =dispose hooks for the cycle collector
* a cycle collector for ARC: progress
* manual: the .acyclic pragma is a thing once again
* gcbench: adaptations for --gc:arc
* enable valgrind tests for the strutils tests
* testament: better valgrind support
* ARC refactoring: growable jumpstacks
* ARC cycle detector: non-recursive algorithm
* moved and renamed core/ files back to system/
* refactoring: --gc:arc vs --gc:orc since 'orc' is even more experimental and we want to ship --gc:arc soonish

Cleanup leftovers of #12911(#12916)

Fix single match output (#12920)

fixes #12899 (#12921)

* fixes #12899

* fixes regression: destroy global variables in reverse declaration order, closureleak test relies on it

Implement NixOS distro check (#12914)

Better case coverage error message for alias and range enum (#12913)

fix error in assertions document (#12925) [backport]

fix cmdline bugs affecting nimBetterRun correctness (#12933) [backport]

fix #12919 tasyncclosestall flaky: Address already in use (#12934)

system.reset is no longer magic (#12937)

It has now means setting x to default for new and old runtime alike
Fix #12785 (#12943)

* Fix #12785 and add test

* better variable name

update documentation for `closureScope` and `capture` (#12886)

fixes #12735 on osx, call dsymutil for debug builds (#12931)

* fix #12735 osx: dsymutil needs to be called for debug builds
* also write dsymutil command to extraCmds in json build file

Auto-initialize deques (#12879)

case coverage error message for `char` (#12948)

lenVarargs: number of varargs elements (#12907)

docs: tiny style improvements

added guidelines for evolving Nim's stdlib

fixes a bug that kept sugar.collect from working with for loop macros [backport]

fixes #12826

fixes a regression

a better bugfix

fixes a test case

fixes a silly regression

fixes the distros.nim regression

ported channels to ARC

ported osproc.nim to ARC

ported re.nim to ARC

ARC: default to a shared heap with --threads:on

osproc: fixes regression

fixes another regression

fixes #12945 (#12959)

minor refactorings

Fixes stackoverflow links in readme (#12963) [backport]

Allow customize Host header
[ci skip] docfix .. < => ..< (#12981) [backport]

parsecfg: retain CRLF line breaks, fixes #12970 (#12971)

generic stack trace overriding mechanism (#12922)

* libbacktrace support

* switch to a generic stack trace overriding mechanism

When "nimStackTraceOverride" is defined, once of the imported modules
can register its own procedure to replace the default stack trace
generation by calling `registerStackTraceOverride(myOwnProc)`.

Tested with `./koch boot -d:release --debugger:native -d:nimStackTraceOverride --import:libbacktrace`
for the compiler itself and `./bin/nim c -r -f --stacktrace:off --debugger:native -d:nimStackTraceOverride --import:libbacktrace foo.nim`
for an external program.

* make the StackTraceOverrideProc {.noinline.}

Added fix for handling TaintedStrings in streams and httpclient (#12969)

* Added fix for taint mode in streams and httpclient

* Removed taintMode export from system.nim

Check pqntuples > 0 in getValue. Fixes #12973 (#12974)

c_fflush() the rawWrite() buffer (#12987)

Stack traces on an unbuffered stderr get out of sync with line-buffered
stdout - usually on Windows terminals or CI logs. This fixes it by
calling C's fflush() on the output buffer in the procedure used for
printing stack traces.
fixes #12989

Revert "fixes #12989"

This reverts commit 928c2fee06.

fixes #12965 (#12991)

fixes #12989 (#12992)

* fixes #12989
* Revert "remove unwanted changes"

This reverts commit 501829732a.

fixes disruptek/nimph#102 multi-level nim.cfg use (#13001) [backport]

--exception:goto switch for deterministic exception handling (#12977)

This implements "deterministic" exception handling for Nim based on goto instead of setjmp. This means raising an exception is much cheaper than in C++'s table based implementations. Supports hard realtime systems. Default for --gc:arc and the C target because it's generally a good idea and arc is all about deterministic behavior.

Note: This implies that fatal runtime traps are not catchable anymore! This needs to be documented.
fix #12985 {.push.} now does not apply to generic instantiations (#12986)

Sink to MemMove optimization in injectdestructors (#13002)

remove default argument for readLines (#12807) [backport]

fixes #12978 (#13012)

Fix typo (#13015) [backport]

fixes #12961 (#13019)

fixes #12956 (#13020)

fix #12988 (#13022)

fix #12988
Fixes #13026 (#13028)

fixes #12964 (#13027)

fixes #13032

VM: support importc var, ptr/pointer types, cast int <=> ptr/pointer (#12877)

* VM: allow certain hardcoded special var variables at CT
* VM: allow all importc var, cast[int](ptr)
* fix tests tests/vm/tstaticprintseq.nim, tests/cpp/t8241.nim
* VM: == works for ptr/pointer nodes
* bugfix: ==, cast now also works for pointer, not just ptr
* VM supports cast PtrLikeKinds <=> PtrLikeKinds / int
* improve cname handling
* fixup + bug fix
* VM: support cast from ref to int
* address comment: opcLdGlobalDeref => opcLdGlobalDerefFFI
* defensive check against typ == nil

fix enumtostr crash for enum-range (#13035)

fixes #13013, reverts previous changes to readLines() (#13036) [backport]

* Revert "remove default argument for readLines (#12807) [backport]"

This reverts commit c949b81efd.

reprjs: style changes

fixes #12996

Rst parser respect `:start-after:` and `:end-before:` in `include` directive (#12972)

* [FEATURE] rst parser respect :start-after: in include

Rst parser now respects `:start-after:` and `:end-before:` attributes
for `include` directive.

* [DOC] include directive parsing proc update

* [TEST] Added unit tests for include rst directive in `rst` module

Allow `-o` option for `buildIndex` (#13037) [backport]

Addressing #12771

This is also included in the docgen documentation [here](https://nim-lang.org/docs/docgen.html) but its not respected as reported in the issue.
[cleanup] remove disabled (and obsolete) ttypetraits; rename ttypetraits2 => ttypetraits (#13041)

* remove disabled (and obsolete) ttypetraits; rename ttypetraits2 => ttypetraits

* D20200105T085828 fix super strange bug that causes CI to fail: builds.sr.ht with: `Error: Settle timed out after 120 attempts`

Continue #13002 (#13021)

testament/important_packages dont run hts (#13052)

Modify the test command for nimly (nimble-package) (#13053)

clean up deprecated stuff and unused imports in tests (#13059)

--styleCheck:hint now works (#13055)

[easy] --hint🔗on now shows link cmd instead of nothing (#13056)

* --hint🔗on now shows link cmd instead of nothing

* update doc for --listCmd

add pqserverVersion,pqconnectionNeedsPassword,pqconnectionUsedPassword (#13060)

basename supports pragmaexpr (#13045)

* basename supports pragmaexpr

* update changelog

distinctBase type trait for distinct types (#13031)

make SuccessX show project file + output file (#13043)

* make SuccessX show project file + output file
* address comments
* fix test and add `result.err = reNimcCrash` otherwise hard to see where reNimcCrash used
* address comments

move entries from the wrong changelog file [ci skip]

fix crash due to errant symbols in nim.cfg (#13073) [backport]

Deleted misplaced separator (#13085) [backport]

Misplaced separator, which was constantly breaking compilation on Haiku OS, was deleted.
take the one good idea from --os:standalone and enable it via -d:StandaloneHeapSize (#13077)

remove all remaining warnings when build nim (with -d:nimHasLibFFI) (#13084)

* cleanup deprecations in evalffi + elsewhere

* remove dead code getOrdValue64

Use '__noinline' instead of 'noinline' for N_NOINLINE gcc attribute, this prevents clashes with systems where 'noinline' might be already defined (#13089)

Fix error check code in osproc (#13090) [backport]

fixes #13072; no test case because it will be added later with more exception handling related bugfixes

fixes #13070

typetraits: fixes #6454; genericParams; added lenTuple; added tuple type get (#13064)

[backport] system/io.nim fix wrong documentation comment [ci skip]

fixes an asyncftpclient bug; refs #13096 [backport]

System cleanup, part 1 (#13069)

* system.nim: mark what every .pop does

* system.nim: un-nest when statements

[backport] fix #12813, fix #13079 (#13099)

Correctly remove a key from CountTable when it is set to zero.
more arc features (#13098)

* config update
* ARC now supports 'repr' and 'new' with finalizers is supported

Remove some unused/disabled OpenSSL functions (#13106)

Add link to posix_utils.html in posix.nim (#13111)

VM FFI: write(stderr, msg) and fprintf(cstderr, msg) now work at CT (#13083)

fix the ftp store function read the local file bug (#13108) [backport]

* Update asyncftpclient.nim

When use newStringOfCap function not have assign memory for the string data,so if use this address the fault is rasise.

* complelete the bugfix

fix rtti sizeof for varargs in global scope (#13125) [backport]

fixes #13122 (#13126)

* fixes #13122

* moved tests to where they belong

fixes #13112 (#13127)

* improve line error information

* fixes #13112

Expose more openSSL methods. (#13131)

fixes #13100 nim doc now treats `export localSymbol` correctly (#13123) [backport]

* fix #13100 nim doc now treats `export localSymbol` correctly
* use owner instead

fixes #13119 (#13128)

* fixes #13119
* fixes a regression

fixes #13105 (#13138)

fixes #10665 (#13141) [backport]

pass platform argument only if vccexe is used (#13078)

* pass platform only if vccexe is used
* fixes #12297

fixes #13104 [backport] (#13142)

fixes #9674 [backport] (#13143)

Fix typo in doc/destructors.rst (#13148)

Added 'ansic' os support for minimal (embedded) targets (#13088)

* os:any implementation
* os:asny: omit flock/funlock calls in echoBinSafe
* Disabled default "unhandled expection" reporting for `--os:any` to reduce
code size. Added unhandledExceptionHook instead which can be used to get
a notification from Nim and handle it from the application.

System cleanup, part 2 (#13155)

* create basic_types, arithmetics, exceptions, comparisons
* create setops.nim
* create memalloc.nim
* create gc_interface.nim
* create iterators_1.nim

export normalizePathEnd (#13152)

successX now correctly shows html output for `nim doc`, `nim jsondoc`; fix #13121 (#13116)

* successX now correctly shows html output for nim doc
* fixes #13121
* fixup hintSuccessX to be less weird

ARC: misc bugfixes (#13156)

* fixes #13102
* closes #13149
* ARC: fixes a move optimizer bug (there are more left regarding array and tuple indexing)
* proper fix; fixes #12957
* fixes yet another case object '=' code generation problem

CI fix timeout error (#13134)

Remove obsolete code from osalloc (#13158)

style fix: change 'JS' to 'js' to make it consistent (#13168)

Working towards arc codegen (#13153)

fixes #13029
fixes #12998 nim doc regression (#13117)

fix tsizeof3 for aarch64 (#13169)

Cleanup DFA (#13173)

Fix docs (#13176)

fixes #13095 (#13181)

* fixes #13095

* fix typo

make case-object transitions explicit, make unknownLineInfo a const, replace a few magic numbers with consts (#13170)

ARC works for async on Windows (#13179)

make sink operator optional (#13068)

* make sink operator optional

* bug fix, add changelog entry

* Trigger build

* fix one regression

* fix test

* Trigger build

* fix typos

Fix docs for subdirs too (#13180)

* Fix doc subdirs
* Extract to helper proc, and fix on windows

followup on #10435 : should be diff, not show (#13162)

fixes #13157

refs #13054 correctly handle {.exportc,dynlib.} and {.exportcpp,dynlib.}  (#13136)

* refs #13054 correctly handle {.exportc,dynlib.} and {.exportcpp,dynlib.}
* put back NIM_EXTERNC for N_LIB_EXPORT; causes issues with compilerproc

fixes #13144 (#13145)

* fixup: genscript now does not copy nimbase.h but uses -I$nim/lib

times: toUnixFloat, fromUnixFloat (#13044)

maybe: allows optional chaining of field access and indexing when LHS i snil (#13023)

* maybe: allows optional chaining
* fix tools/kochdocs.nim
* improve semantics to distinguish valid from invalid values
* for now, wrapnil, isValid, unwrap are not exported

fix docs + API for fieldPairs, fields (#13189)

more on arc codegen (#13178)

* arc codegen for union type

* add more tests

* fix offsetof

* fix tsizeof test

* fix style

Add link to packaging.html (#13194)

Fixes #13186 (#13188)

fixes #13195

revert last commit

Merge branch 'devel' of https://github.com/nim-lang/Nim into devel

Revert "fixes #13195"

This reverts commit cd7904f2b2.

fixes #13110 (#13197)

fixes #13195 (#13198)

* fixes #13195

* extra fix

* fix typo

compiler/ccgtypes: hide exportc proc unless it has dynlib (#13199)

This hides most of stdlib's internal functions from resulting
binaries/libraries, where they aren't needed on *nix. Static libraries
are not affected by this change (visibility doesn't apply to them).
fix range[enum] type conversion (#13204) [backport]

Idxmin & idxmax, continuation (#13208)

* Add idxmin() which returns the index of the minimum value

* Add idxmax() which returns the index of the maximum value

* Add tests for idxmin()

* Add tests for idxmax()

* Remove initialization of result = 0

* Adds overloading for arrays (no enums indexed arrays yet)

* Add support for enum index arrays

* Fix tests with enum

* Fix tests for idxmax

* Change names of the procedures to minIndex and maxIndex

* address Araq's comments:

- remove 'array' versions
- add .since pragma
- return 'int' instead of 'Natural'
- add changelog entry

Co-authored-by: Federico A. Corazza <20555025+Imperator26@users.noreply.github.com>

fix #13211 relativePath("foo", ".") (#13213)

fixes a critical times.nim bug reported on IRC [backport] (#13216)

httpclient, maxredirects to Natural, newHttpClient/newAsyncHttpClient add headers argument instead of hardcoded empty (#13207)

added note to re constructor regarding performance (#13224)

Since I was new to regex I did not know that there is a compilation going on with ``re"[abc]"`` constructor and so I followed the other examples in the docs blindly, that is I just put the constructor directly in the arguments of match, find, etc., which was inside a loop and then wondered why my performance was so bad. Of course putting it outside the loop made it vastly more performant. People like me would benefit from the small note I added I would think :)
[backport] Documentation Fix #12251 (#13226) [ci skip]

[backport] times/getClockStr(): fix mistake in doc (#13229) [ci skip]

new os.isRelativeTo (#13212)

[backport] Fix typo and improve in code-block of 'lib/pure/parseutils.nim' (#13231) [ci skip]

[backport] fix #11440, add docs to isNil for seq types needing nilseq (#13234) [ci skip]

VM: allow overriding MaxLoopIterations without rebuilding nim (#13233)

kochdocs: use a glob instead of hardcoded list; generate docs for compiler/; bugfixes (#13221)

* kochdocs: use a glob instead of hardcoded list; generate docs for compiler/; bugfixes
* fixup after #13212 isRelativeTo got merged

fix lots of bugs with parentDir, refs #8734 (#13236)

Unexport even more symbols (#13214)

* system/gc: don't export markStackAndRegisters

* compiler/cgen: unexport internal symbols

As these functions are Nim-specific walkaround against C's optimization
schemes, they don't serve any purpose being exported.

* compiler/cgen: don't export global var unless marked

* compiler/ccgthreadvars: don't export threadvar unless marked

* tests/dll/visibility: also check for exports

This ensure that these changes don't break manual exports.

* compiler/cgen: hide all variables created for constants

* compiler/ccgtypes: don't export RTTI variables

* compiler/ccgexprs: make all complex const static

* nimbase.h: fix export for windows

* compiler/cgen, ccgthreadvars: export variables correctly

For C/C++ variables, `extern` means that the variable is defined in an
another unit. Added a new N_LIB_EXPORT_VAR to correctly export
variables.

Removed lib/system/allocators.nim. seqs_v2 and strs_v2 now uses allocShared0. (#13190)

* Cleanup, remove lib/system/allocators.nim. seqs_v2 and strs_v2 now use
allocShared0 by default.

* Fixed -d:useMalloc allocShared / reallocShared / deallocShared. These now use the alloc/dealloc/realloc implementation that also takes care of zeroing memory at realloc.

* Removed debug printfs

* Removed unpairedEnvAllocs() from tests/destructor/tnewruntime_misc

* More mmdisp cleanups. The shared allocators do not need to zero memory or throw since the regular ones already do that

* Introduced realloc0 and reallocShared0, these procs are now used by
strs_v2 and seqs_v2. This also allowed the -d:useMalloc allocator to
drop the extra header with allocation length.

* Moved strs_v2/seqs_v2 'allocated' flag into 'cap' field

* Added 'getAllocStats()' to get low level alloc/dealloc counters. Enable with -d:allocStats

* *allocShared implementations for boehm and go allocators now depend on the proper *allocImpl procs

[backport] documentation: Add channels examples (#13202) [ci skip]

[backport] Make all parseutils examples auto-checking (#13238)

- Also fix one example's output (ikString -> ikStr, ikVar instead of ikExpr)
Updated 'nim for embedded systems' section to use --os:any and --gc:arc (#13237)

* Updated 'nim for embedded systems' section to use --os:any and --gc:arc

* Added section about size optimization to embedded systems

Remove name attribute from docutils.nimble (#13239)

Fixes asyncftpclient multiline reading, fixes #4684 (#13242)

Previously, the 4th character of `result` was checked for `'-'` every time, instead of each new line.

Also made it work for taint mode.
Fix typo for literal `[` (#13243)

The literal value for the `tkBracketLe` token was incorrectly set to `]` rather than `[`. I've had a quick glance at the code and it doesn't look like this change will affect anything at all, but I haven't tested yet - let's see if the CI explodes...
Add "origin" to window.location (#13251)

Add "origin" to window location: https://www.w3schools.com/jsref/prop_loc_origin.asp
nim dump: add libpath (#13249)

contributing docs: symbols need package prefix; changed allocStats to nimAllocStats (#13247)

testament/azure: major rewrite (#13246)

This commit features a major rewrite of Azure Pipelines integration,
turning the spaghetti it originally was into something maintainable.

Key changes:
- No longer requires a ton of hooks into testament.
- Results are now cached then bulk-uploaded to prevent throttling from
  Azure Pipelines, avoiding costly timeouts.
- A low timeout is also employed to avoid inflated test time.
- The integration is now documented.
Cleaned up mmdisp.nim, moved implementations into lib/system/mm/ (#13254)

make goto based exceptions available for 'nim cpp' (#13244)

* make goto based exceptions available for 'nim cpp'
* optimize seq.add to be comparable to C++'s emplace_back

ARC: remove unnecessary code

ARC: optimize complete object constructors to use nimNewObjUninit

make nre compile with --gc:arc

Rename isNilOrWhitespace to isEmptyOrWhitespace and make it use allCharsInSet (#13258)

* Rename isNilOrWhitespace to isEmptyOrWhitespace

* Make isEmptyOrWhitespace use allCharsInSet(Whitespace)

Clearer final objects error; fixes #13256 (#13257)

scrollTop must be settable (#13263)

* scrollTop must be assignable

Make scrollTop settable

* add missing export

fixes #13219 (#13272)

fixes #13281 (#13282)

* fixes ##13281

* add comment to test

unittest add resetOutputFormatters proc (#13267)

* add resetOutputFormatters

* remove space

* resolve comments

TlSF Alloctor: use less memory for --gc:arc (#13280)

Tiny since cleanup (#13286)

nimv2 widestring indexing (#13279)

Repr v2 progress (#13268)

* progress on repr_v2

* repr progress

* add ref objects with distrinct

* fix failing tests

refactor htmldocs; gitignore it

removed unused import

fix stdout(etc) for emscripten

csize => csize_t for sysctl

Thread attributes should be destroyed using the pthread_attr_destroy() (#13293)

On some OSes (such as FreeBSD or Solaris), pthread_attr_init allocate
memory. So it is necessary to deallocate that memory by using
pthread_attr_destroy.
fix critical bug discovered by #11591 (#13290) [backport]

miscellaneous bug fixes (#13291)

* fix for emscripten etc

* add testcase for #13290

* replace deprecated isNilOrWhitespace

CT FFI: fix for windows; fix case transition; error msg shows more useful context (#13292)

* evalffi: fix case transition
* evalffi: fix for windows
* evallffi: `cannot import` errmsg now also shows which library it tried to import symbol from

refs #8391 std/os now shows runtime context for raiseOSError exceptions (#13294)

* refs #8391: fix errmsg for setCurrentDir

* raiseOSError calls for copyFile

* refs #8391 std/os now shows runtime context for raiseOSError exceptions

build_all.sh: building csources 5X faster thanks to make -j (#13300)

* build_all.sh: building csources 5X faster thanks to make -j
* fix for freebsd
* use OS-dependent formula to get number of logical cores
* make is an optional dependency

Fix capture for object types (#13315)

* Fix capture for object|tuple|... types

* Add test case

Quote nim executable before executing. (#13316) [backport]

In case nim executable is located in PATH containing spaces.

fixes #13311
ReSync with devel

Make build_all.sh more portable and a bit simpler (#13308)

koch: enable checks in the compiler when running CI (#13323)

fix #13132 tnetdial (#13318)

enable testing -d:nimHasLibFFI mode (#13091)

Fix #10717, fix #13284 (#13307)

Fixed codegen for constant cstring with --gc:arc (#13326)

* Fixed codegen for constant cstring with --gc:arc, fixes  #13321

* Added test for #13321

Option to allow the request body to be processed outside the asynchttpserver library. (#13147)

Allow the request body to be processed outside the asynchttpserver library to break big files into chunks of data. This change does not break anything.

build_all.sh update (#13320)

* Don't overload the system, don't crash when you can't determine the CPU count and don't rely on bash

* Extract to variable

* Limit number of spawned jobs for systems with weak IO

* Use proper arithmetic braces

contributing.rst: Add a special rule for 'outplace'-like features

[backport] -d:danger should imply -d:release (#13336)

nim secret: support linenoise when available (#13328)

fix #13150 `nim doc --project` now works reliably (#13223)

* fix #13150 `nim doc --project` works with duplicate names and with imports below main project file

* add to help; fixup after #13212 isRelativeTo got merged
* fix test tests/compilerapi/tcompilerapi.nim
* remove nimblePkg field; compute on the fly instead
* kochdocs: compiler docs now under compiler/
* --docRoot now has smart default: best among @pkg, @path

make monotimes have zero overhead if you don't use it (#13338) [backport]

fix #13349 regression: isNamedTuple now works with generic tuples (#13350)

fixes #13269 (#13344)

adding sqlite3 backup functions (#13346)

* adding sqlite3 backup functions

* changing sleep to sqlite3_sleep to prevent clashes

Added a basic example how to handle a Post request. (#13339)

* Added a basic example how to handle a Post request.

They were also made minor cosmetic changes.

* Minor fixes suggested by Yardanico

* Fixed a wrong value in chunkSize constant.

* Re-added the request.body for compatibility!

replace old problematic isNamedTuple implementation by TypeTrait isNamedTuple in dollars.nim (#13347)

* replace old problematic isNamedTuple implementation by TypeTrait isNamedTuple

* fix for bootstrap

fix #13182: `proc fun(a: varargs[Foo, conv])` now can be overloaded (#13345) [backport]

miscellaneous bug fixes (part 3) (#13304)

* fix deprecation; fix indentation

* git clone: use -q

* fix Warning: pragma before generic parameter list is deprecated; fix typo

* bugfix: sysTypeFromName("float64") was never cached

testament: introduce 'matrix' for testing multiple options (#13343)

printing float values will have one more digit. (#13276) [backport]

* printing float values will have one more digit. Fixes #13196

[backport] fix #13352

[backport] remove 'CountTable.mget' (#13355)

It didn't work, and it was an oversight to be included in v1.0.
fix #6736: templates in unittest now show actual value (#13354)

Revert "printing float values will have one more digit. (#13276) [backport]" (#13363)

This reverts commit b2c6db97f9.
Add sideEffect pragma to importC procs in posix, winlean and time module (#13370)

* Add sideEffect pragma to procs in winlean
* Add sideEffect pragma to procs in posix
* Add test for #13306
* Add sideEffect pragma to procs in times
* Fixes #13306
fixes #3339 by documenting the limitations of case-statement (#13366)

fixes #13314 (#13372)

testament: this now works: "testament r /abspath/to/test.nim" (#13358)

fix `is` with generic types; fix `genericHead(Foo[T])` (#13303)

* fix #9855, fix #9855, fix genericHead
* render TTypeKind via toHumanStr

fix #13255 (#13275) [backport]

remove outplace version of 'merge' for CountTables (#13377)

* remove outplace version of 'merge' for CountTables

* remove 'merge' tests

fix #13374 `nim c -r -` now generates $nimcache/stdinfile (#13380) [backport]

fix #9634 don't crash on execCmdEx/readLine when inside gdb/lldb (#13232)

* fix #9634 debugging a program using execCmdEx now works

* only apply EINTR to c_gets for now

This reverts commit c0f5305b5a0b46983dfd27e3d77ecbf4f8744dcc.

lib.rst: add a link for jsconsole [backport] (#13383)

Make vccexe parse response files (#13329)

expectLen now shows the length that we got (#13387)

fix several bugs with `repr`  (#13386)

fixes #13378 [backport] (#13392)

remove dead code test_nimhcr_integration.(bat,sh) (#13388)

* enable test for osx: import tests/dll/nimhcr_integration

* re-disable osx test

fix linenoise regression (#13395)

* fix nightlies linenoise regression

* fix other installers

Revert "remove dead code test_nimhcr_integration.(bat,sh) (#13388)" (#13396)

This reverts commit 90491ea0a9.
fixes #13368 (#13397)

fix bug in int128 (#13403)

isolate the build process from external config files (#13411)

add ggplotnim to important_packages (#13206)

Fix to asynchttpserver form data/body broken with #13147 (#13394)

* Fix to asynchttpserver form data/body broken with #13147
* New implementation that use a interator instance of future streams
* asynchttpserver now can handle chunks of data.

Merge branch 'devel' of https://github.com/nim-lang/Nim into osopen

Squash Commits; Peer review feedbacks https://github.com/nim-lang/Nim/pull/12901#discussion_r379694384
2020-02-15 22:31:00 +00:00
Clyybber
f3eb0a5970 capture macro now accepts variables of different types (#13356)
* Capture macro can now accept variables of different types

* Add test

* Update examples

* Use let instead of var
2020-02-15 19:53:40 +01:00
Henrique Dias
5bf571f061 Fix to asynchttpserver form data/body broken with #13147 (#13394)
* Fix to asynchttpserver form data/body broken with #13147
* New implementation that use a interator instance of future streams
* asynchttpserver now can handle chunks of data.
2020-02-14 21:59:37 +01:00
Miran
3300e317a4 add ggplotnim to important_packages (#13206) 2020-02-14 21:28:50 +01:00
Ștefan Talpalaru
3d7d06571c isolate the build process from external config files (#13411) 2020-02-14 21:15:52 +01:00
Arne Döring
ccd2e044cb fix bug in int128 (#13403) 2020-02-14 12:33:36 +01:00
cooldome
7dd787b8a3 fixes #13368 (#13397) 2020-02-14 10:13:55 +01:00
Andreas Rumpf
1e303100f8 Revert "remove dead code test_nimhcr_integration.(bat,sh) (#13388)" (#13396)
This reverts commit 90491ea0a9.
2020-02-12 13:22:26 +01:00
Timothee Cour
2b368bcdd7 fix linenoise regression (#13395)
* fix nightlies linenoise regression

* fix other installers
2020-02-12 10:35:00 +01:00
Timothee Cour
90491ea0a9 remove dead code test_nimhcr_integration.(bat,sh) (#13388)
* enable test for osx: import tests/dll/nimhcr_integration

* re-disable osx test
2020-02-12 10:21:32 +01:00
Andreas Rumpf
c446c0f57a fixes #13378 [backport] (#13392) 2020-02-11 23:48:41 +01:00
Timothee Cour
eec07b4e84 fix several bugs with repr (#13386) 2020-02-11 21:33:06 +01:00
Clyybber
f6d45b40a5 expectLen now shows the length that we got (#13387) 2020-02-11 12:31:52 +01:00
Fredrik Høisæther Rasch
8100e2e9cd Make vccexe parse response files (#13329) 2020-02-11 12:05:47 +01:00
Jjp137
84a71dad87 lib.rst: add a link for jsconsole [backport] (#13383) 2020-02-11 10:22:49 +01:00
Timothee Cour
39ba502f87 fix #9634 don't crash on execCmdEx/readLine when inside gdb/lldb (#13232)
* fix #9634 debugging a program using execCmdEx now works

* only apply EINTR to c_gets for now

This reverts commit c0f5305b5a0b46983dfd27e3d77ecbf4f8744dcc.
2020-02-11 10:16:30 +01:00
Timothee Cour
1f7c907e7d fix #13374 nim c -r - now generates $nimcache/stdinfile (#13380) [backport] 2020-02-11 00:37:40 +01:00
Miran
ceb3d5ad68 remove outplace version of 'merge' for CountTables (#13377)
* remove outplace version of 'merge' for CountTables

* remove 'merge' tests
2020-02-10 20:50:55 +01:00
Arne Döring
2fee89f7db fix #13255 (#13275) [backport] 2020-02-09 13:51:36 +01:00
Timothee Cour
7939319379 fix is with generic types; fix genericHead(Foo[T]) (#13303)
* fix #9855, fix #9855, fix genericHead
* render TTypeKind via toHumanStr
2020-02-09 13:48:55 +01:00
Timothee Cour
debe7fffd8 testament: this now works: "testament r /abspath/to/test.nim" (#13358) 2020-02-09 13:44:16 +01:00
Andreas Rumpf
240174dd81 fixes #13314 (#13372) 2020-02-09 00:22:34 +01:00
Miran
038f47e7b9 fixes #3339 by documenting the limitations of case-statement (#13366) 2020-02-08 20:11:20 +01:00
Tomohiro
2a4aa24620 Add sideEffect pragma to importC procs in posix, winlean and time module (#13370)
* Add sideEffect pragma to procs in winlean
* Add sideEffect pragma to procs in posix
* Add test for #13306
* Add sideEffect pragma to procs in times
* Fixes #13306
2020-02-08 20:09:49 +01:00
Timothee Cour
e4415422fe Revert "printing float values will have one more digit. (#13276) [backport]" (#13363)
This reverts commit b2c6db97f9.
2020-02-08 09:30:24 +01:00
Miran
f3117d350e fix #6736: templates in unittest now show actual value (#13354) 2020-02-07 22:04:08 +01:00
Miran
78b15de304 [backport] remove 'CountTable.mget' (#13355)
It didn't work, and it was an oversight to be included in v1.0.
2020-02-07 20:50:44 +01:00
narimiran
36d1ad39d0 [backport] fix #13352 2020-02-07 18:26:08 +01:00
Arne Döring
b2c6db97f9 printing float values will have one more digit. (#13276) [backport]
* printing float values will have one more digit. Fixes #13196
2020-02-07 17:10:25 +01:00
Miran
cdedb86348 testament: introduce 'matrix' for testing multiple options (#13343) 2020-02-07 16:45:49 +01:00
Timothee Cour
1f725f1d7e miscellaneous bug fixes (part 3) (#13304)
* fix deprecation; fix indentation

* git clone: use -q

* fix Warning: pragma before generic parameter list is deprecated; fix typo

* bugfix: sysTypeFromName("float64") was never cached
2020-02-07 16:37:40 +01:00
Timothee Cour
79ec8c2571 fix #13182: proc fun(a: varargs[Foo, conv]) now can be overloaded (#13345) [backport] 2020-02-07 13:29:18 +01:00
Timothee Cour
c0a2e2ed92 replace old problematic isNamedTuple implementation by TypeTrait isNamedTuple in dollars.nim (#13347)
* replace old problematic isNamedTuple implementation by TypeTrait isNamedTuple

* fix for bootstrap
2020-02-07 13:27:28 +01:00
Henrique Dias
abd660c407 Added a basic example how to handle a Post request. (#13339)
* Added a basic example how to handle a Post request.

They were also made minor cosmetic changes.

* Minor fixes suggested by Yardanico

* Fixed a wrong value in chunkSize constant.

* Re-added the request.body for compatibility!
2020-02-07 03:59:28 -05:00
pyloor
bf3f1c3762 adding sqlite3 backup functions (#13346)
* adding sqlite3 backup functions

* changing sleep to sqlite3_sleep to prevent clashes
2020-02-07 01:11:05 -05:00
Andreas Rumpf
c87796180e fixes #13269 (#13344) 2020-02-07 06:58:57 +01:00
Timothee Cour
7481f43753 fix #13349 regression: isNamedTuple now works with generic tuples (#13350) 2020-02-07 06:58:04 +01:00
Andreas Rumpf
e24443f1bc make monotimes have zero overhead if you don't use it (#13338) [backport] 2020-02-06 16:12:54 +01:00
Timothee Cour
7ec7731f82 fix #13150 nim doc --project now works reliably (#13223)
* fix #13150 `nim doc --project` works with duplicate names and with imports below main project file

* add to help; fixup after #13212 isRelativeTo got merged
* fix test tests/compilerapi/tcompilerapi.nim
* remove nimblePkg field; compute on the fly instead
* kochdocs: compiler docs now under compiler/
* --docRoot now has smart default: best among @pkg, @path
2020-02-06 11:17:00 +01:00
Timothee Cour
574f61315d nim secret: support linenoise when available (#13328) 2020-02-05 16:44:19 +01:00
Miran
c6d5f0df8d [backport] -d:danger should imply -d:release (#13336) 2020-02-05 13:41:16 +01:00
Araq
8279da5219 contributing.rst: Add a special rule for 'outplace'-like features 2020-02-05 13:39:08 +01:00
Clyybber
ab525cc48a build_all.sh update (#13320)
* Don't overload the system, don't crash when you can't determine the CPU count and don't rely on bash

* Extract to variable

* Limit number of spawned jobs for systems with weak IO

* Use proper arithmetic braces
2020-02-04 21:26:38 +01:00
Henrique Dias
955465e5f4 Option to allow the request body to be processed outside the asynchttpserver library. (#13147)
Allow the request body to be processed outside the asynchttpserver library to break big files into chunks of data. This change does not break anything.
2020-02-04 21:13:25 +01:00
Ico Doornekamp
bfe96e069b Fixed codegen for constant cstring with --gc:arc (#13326)
* Fixed codegen for constant cstring with --gc:arc, fixes  #13321

* Added test for #13321
2020-02-04 17:39:27 +01:00
genotrance
7cc03b43f8 Fix #10717, fix #13284 (#13307) 2020-02-04 17:38:24 +01:00
Timothee Cour
e70294dff2 enable testing -d:nimHasLibFFI mode (#13091) 2020-02-04 14:08:56 +01:00
Timothee Cour
b20d7e2110 fix #13132 tnetdial (#13318) 2020-02-04 10:31:44 +01:00
alaviss
7e5c070244 koch: enable checks in the compiler when running CI (#13323) 2020-02-04 09:27:54 +01:00
Clyybber
1ab37ccfc6 Make build_all.sh more portable and a bit simpler (#13308) 2020-02-03 02:02:44 +01:00
Fredrik Høisæther Rasch
dfecc3489b Quote nim executable before executing. (#13316) [backport]
In case nim executable is located in PATH containing spaces.

fixes #13311
2020-02-02 13:54:48 +01:00
Clyybber
d43e5bef39 Fix capture for object types (#13315)
* Fix capture for object|tuple|... types

* Add test case
2020-02-02 13:52:21 +01:00
Timothee Cour
45a5c64c9a build_all.sh: building csources 5X faster thanks to make -j (#13300)
* build_all.sh: building csources 5X faster thanks to make -j
* fix for freebsd
* use OS-dependent formula to get number of logical cores
* make is an optional dependency
2020-01-31 20:00:05 +01:00
Timothee Cour
adc52b0039 refs #8391 std/os now shows runtime context for raiseOSError exceptions (#13294)
* refs #8391: fix errmsg for setCurrentDir

* raiseOSError calls for copyFile

* refs #8391 std/os now shows runtime context for raiseOSError exceptions
2020-01-30 11:06:04 +01:00
Timothee Cour
4a747f0250 CT FFI: fix for windows; fix case transition; error msg shows more useful context (#13292)
* evalffi: fix case transition
* evalffi: fix for windows
* evallffi: `cannot import` errmsg now also shows which library it tried to import symbol from
2020-01-30 11:04:06 +01:00
Timothee Cour
bf22b44b1f miscellaneous bug fixes (#13291)
* fix for emscripten etc

* add testcase for #13290

* replace deprecated isNilOrWhitespace
2020-01-30 10:54:50 +01:00
Timothee Cour
81a43791f9 fix critical bug discovered by #11591 (#13290) [backport] 2020-01-29 17:40:03 +01:00
Hiroki Noda
3ab1274231 Thread attributes should be destroyed using the pthread_attr_destroy() (#13293)
On some OSes (such as FreeBSD or Solaris), pthread_attr_init allocate
memory. So it is necessary to deallocate that memory by using
pthread_attr_destroy.
2020-01-29 17:33:21 +01:00
Timothee Cour
2ecef8f779 csize => csize_t for sysctl 2020-01-28 23:36:24 +00:00
Timothee Cour
2e20f5648b fix stdout(etc) for emscripten 2020-01-28 23:36:24 +00:00
Timothee Cour
9657a83698 removed unused import 2020-01-28 23:36:24 +00:00
Timothee Cour
5676912209 refactor htmldocs; gitignore it 2020-01-28 23:36:24 +00:00
cooldome
76ede7c198 Repr v2 progress (#13268)
* progress on repr_v2

* repr progress

* add ref objects with distrinct

* fix failing tests
2020-01-28 20:05:57 +01:00
cooldome
92010becbe nimv2 widestring indexing (#13279) 2020-01-28 20:02:39 +01:00
Clyybber
fb94836bc7 Tiny since cleanup (#13286) 2020-01-28 20:02:07 +01:00
Andreas Rumpf
be795bbf1a TlSF Alloctor: use less memory for --gc:arc (#13280) 2020-01-28 17:09:48 +01:00
cooldome
84e8477b90 unittest add resetOutputFormatters proc (#13267)
* add resetOutputFormatters

* remove space

* resolve comments
2020-01-28 14:16:03 +00:00
cooldome
46bfb590c8 fixes #13281 (#13282)
* fixes ##13281

* add comment to test
2020-01-28 14:55:54 +01:00
Andreas Rumpf
c8418651b1 fixes #13219 (#13272) 2020-01-27 22:50:10 +01:00
Jairo
32f0910f11 scrollTop must be settable (#13263)
* scrollTop must be assignable

Make scrollTop settable

* add missing export
2020-01-27 09:14:56 +01:00
hlaaftana
a71654323d Clearer final objects error; fixes #13256 (#13257) 2020-01-26 18:56:04 +01:00
hlaaftana
e7744b0909 Rename isNilOrWhitespace to isEmptyOrWhitespace and make it use allCharsInSet (#13258)
* Rename isNilOrWhitespace to isEmptyOrWhitespace

* Make isEmptyOrWhitespace use allCharsInSet(Whitespace)
2020-01-26 14:02:07 +01:00
Araq
6900da314c make nre compile with --gc:arc 2020-01-26 13:43:02 +01:00
Araq
a10cc18247 ARC: optimize complete object constructors to use nimNewObjUninit 2020-01-26 13:43:02 +01:00
Araq
ab35f07e77 ARC: remove unnecessary code 2020-01-26 13:43:02 +01:00
Andreas Rumpf
6efac70181 make goto based exceptions available for 'nim cpp' (#13244)
* make goto based exceptions available for 'nim cpp'
* optimize seq.add to be comparable to C++'s emplace_back
2020-01-25 20:00:13 +01:00
Ico Doornekamp
4f3dd33509 Cleaned up mmdisp.nim, moved implementations into lib/system/mm/ (#13254) 2020-01-25 17:14:31 +01:00
alaviss
5124b2e575 testament/azure: major rewrite (#13246)
This commit features a major rewrite of Azure Pipelines integration,
turning the spaghetti it originally was into something maintainable.

Key changes:
- No longer requires a ton of hooks into testament.
- Results are now cached then bulk-uploaded to prevent throttling from
  Azure Pipelines, avoiding costly timeouts.
- A low timeout is also employed to avoid inflated test time.
- The integration is now documented.
2020-01-25 09:32:27 +01:00
Timothee Cour
981ffc912e contributing docs: symbols need package prefix; changed allocStats to nimAllocStats (#13247) 2020-01-25 09:27:29 +01:00
Timothee Cour
4cbeddddcc nim dump: add libpath (#13249) 2020-01-24 20:06:54 +01:00
Jairo
fb74497c99 Add "origin" to window.location (#13251)
Add "origin" to window location: https://www.w3schools.com/jsref/prop_loc_origin.asp
2020-01-24 20:06:17 +01:00
Euan
ccb728a7b0 Fix typo for literal [ (#13243)
The literal value for the `tkBracketLe` token was incorrectly set to `]` rather than `[`. I've had a quick glance at the code and it doesn't look like this change will affect anything at all, but I haven't tested yet - let's see if the CI explodes...
2020-01-24 08:42:03 +00:00
hlaaftana
4656580b54 Fixes asyncftpclient multiline reading, fixes #4684 (#13242)
Previously, the 4th character of `result` was checked for `'-'` every time, instead of each new line.

Also made it work for taint mode.
2020-01-24 00:18:16 +01:00
hlaaftana
caaa8f285f Remove name attribute from docutils.nimble (#13239) 2020-01-23 18:51:25 +01:00
Ico Doornekamp
5dd2fa3e0c Updated 'nim for embedded systems' section to use --os:any and --gc:arc (#13237)
* Updated 'nim for embedded systems' section to use --os:any and --gc:arc

* Added section about size optimization to embedded systems
2020-01-23 17:17:48 +01:00
Kaushal Modi
c4ff4e553e [backport] Make all parseutils examples auto-checking (#13238)
- Also fix one example's output (ikString -> ikStr, ikVar instead of ikExpr)
2020-01-23 17:14:22 +01:00
chr v1.x
aebcbfe5ea [backport] documentation: Add channels examples (#13202) [ci skip] 2020-01-23 14:47:00 +01:00
Ico Doornekamp
b68eb1cad0 Removed lib/system/allocators.nim. seqs_v2 and strs_v2 now uses allocShared0. (#13190)
* Cleanup, remove lib/system/allocators.nim. seqs_v2 and strs_v2 now use
allocShared0 by default.

* Fixed -d:useMalloc allocShared / reallocShared / deallocShared. These now use the alloc/dealloc/realloc implementation that also takes care of zeroing memory at realloc.

* Removed debug printfs

* Removed unpairedEnvAllocs() from tests/destructor/tnewruntime_misc

* More mmdisp cleanups. The shared allocators do not need to zero memory or throw since the regular ones already do that

* Introduced realloc0 and reallocShared0, these procs are now used by
strs_v2 and seqs_v2. This also allowed the -d:useMalloc allocator to
drop the extra header with allocation length.

* Moved strs_v2/seqs_v2 'allocated' flag into 'cap' field

* Added 'getAllocStats()' to get low level alloc/dealloc counters. Enable with -d:allocStats

* *allocShared implementations for boehm and go allocators now depend on the proper *allocImpl procs
2020-01-23 14:25:22 +01:00
alaviss
f500895efe Unexport even more symbols (#13214)
* system/gc: don't export markStackAndRegisters

* compiler/cgen: unexport internal symbols

As these functions are Nim-specific walkaround against C's optimization
schemes, they don't serve any purpose being exported.

* compiler/cgen: don't export global var unless marked

* compiler/ccgthreadvars: don't export threadvar unless marked

* tests/dll/visibility: also check for exports

This ensure that these changes don't break manual exports.

* compiler/cgen: hide all variables created for constants

* compiler/ccgtypes: don't export RTTI variables

* compiler/ccgexprs: make all complex const static

* nimbase.h: fix export for windows

* compiler/cgen, ccgthreadvars: export variables correctly

For C/C++ variables, `extern` means that the variable is defined in an
another unit. Added a new N_LIB_EXPORT_VAR to correctly export
variables.
2020-01-23 13:45:31 +01:00
Timothee Cour
3a5056dc70 fix lots of bugs with parentDir, refs #8734 (#13236) 2020-01-23 13:39:41 +01:00
Timothee Cour
b8a436af93 kochdocs: use a glob instead of hardcoded list; generate docs for compiler/; bugfixes (#13221)
* kochdocs: use a glob instead of hardcoded list; generate docs for compiler/; bugfixes
* fixup after #13212 isRelativeTo got merged
2020-01-23 11:06:28 +01:00
Timothee Cour
b462baed65 VM: allow overriding MaxLoopIterations without rebuilding nim (#13233) 2020-01-23 10:53:30 +01:00
D-Nice
f12bea16ad [backport] fix #11440, add docs to isNil for seq types needing nilseq (#13234) [ci skip] 2020-01-23 07:51:53 +01:00
Mera
4a754ff392 [backport] Fix typo and improve in code-block of 'lib/pure/parseutils.nim' (#13231) [ci skip] 2020-01-23 06:49:27 +01:00
Timothee Cour
7356bc29b7 new os.isRelativeTo (#13212) 2020-01-23 00:45:16 +01:00
Milan
3e843ab335 [backport] times/getClockStr(): fix mistake in doc (#13229) [ci skip] 2020-01-22 18:22:14 +01:00
Juan Carlos
fbd7fe118c [backport] Documentation Fix #12251 (#13226) [ci skip] 2020-01-22 17:56:44 +01:00
whiterock
ef9fb39cdf added note to re constructor regarding performance (#13224)
Since I was new to regex I did not know that there is a compilation going on with ``re"[abc]"`` constructor and so I followed the other examples in the docs blindly, that is I just put the constructor directly in the arguments of match, find, etc., which was inside a loop and then wondered why my performance was so bad. Of course putting it outside the loop made it vastly more performant. People like me would benefit from the small note I added I would think :)
2020-01-22 16:02:16 +01:00
Juan Carlos
2fad7f134f httpclient, maxredirects to Natural, newHttpClient/newAsyncHttpClient add headers argument instead of hardcoded empty (#13207) 2020-01-21 19:34:47 +01:00
Andreas Rumpf
bdb7c82c6a fixes a critical times.nim bug reported on IRC [backport] (#13216) 2020-01-21 16:49:59 +01:00
Timothee Cour
b355ef2a72 fix #13211 relativePath("foo", ".") (#13213) 2020-01-21 15:48:19 +01:00
Miran
bf96d6d316 Idxmin & idxmax, continuation (#13208)
* Add idxmin() which returns the index of the minimum value

* Add idxmax() which returns the index of the maximum value

* Add tests for idxmin()

* Add tests for idxmax()

* Remove initialization of result = 0

* Adds overloading for arrays (no enums indexed arrays yet)

* Add support for enum index arrays

* Fix tests with enum

* Fix tests for idxmax

* Change names of the procedures to minIndex and maxIndex

* address Araq's comments:

- remove 'array' versions
- add .since pragma
- return 'int' instead of 'Natural'
- add changelog entry

Co-authored-by: Federico A. Corazza <20555025+Imperator26@users.noreply.github.com>
2020-01-20 16:57:34 +01:00
Jasper Jenkins
0606b6a44e fix range[enum] type conversion (#13204) [backport] 2020-01-20 16:56:59 +01:00
alaviss
470faa97c6 compiler/ccgtypes: hide exportc proc unless it has dynlib (#13199)
This hides most of stdlib's internal functions from resulting
binaries/libraries, where they aren't needed on *nix. Static libraries
are not affected by this change (visibility doesn't apply to them).
2020-01-20 10:51:21 +01:00
cooldome
da1bddb084 fixes #13195 (#13198)
* fixes #13195

* extra fix

* fix typo
2020-01-20 10:41:12 +01:00
Andreas Rumpf
41555ca86f fixes #13110 (#13197) 2020-01-19 23:30:45 +01:00
Andrii Riabushenko
6f3476d39c Revert "fixes #13195"
This reverts commit cd7904f2b2.
2020-01-19 20:33:23 +00:00
Andrii Riabushenko
e349f7ad21 Merge branch 'devel' of https://github.com/nim-lang/Nim into devel 2020-01-19 20:22:06 +00:00
Andrii Riabushenko
7576387dfe revert last commit 2020-01-19 20:21:26 +00:00
Andrii Riabushenko
cd7904f2b2 fixes #13195 2020-01-19 20:18:04 +00:00
slangmgh
13ddbc46fc Fixes #13186 (#13188) 2020-01-19 14:16:50 +01:00
Federico Ceratto
8d64550b1e Add link to packaging.html (#13194) 2020-01-19 14:15:59 +01:00
cooldome
416b4c3612 more on arc codegen (#13178)
* arc codegen for union type

* add more tests

* fix offsetof

* fix tsizeof test

* fix style
2020-01-19 14:14:26 +01:00
Timothee Cour
bc14453f69 fix docs + API for fieldPairs, fields (#13189) 2020-01-18 13:33:30 +01:00
Timothee Cour
f6ba4e81b0 maybe: allows optional chaining of field access and indexing when LHS i snil (#13023)
* maybe: allows optional chaining
* fix tools/kochdocs.nim
* improve semantics to distinguish valid from invalid values
* for now, wrapnil, isValid, unwrap are not exported
2020-01-18 12:24:56 +01:00
Timothee Cour
e11ecc8266 times: toUnixFloat, fromUnixFloat (#13044) 2020-01-18 01:24:44 +01:00
Timothee Cour
5010bc1af5 fixes #13144 (#13145)
* fixup: genscript now does not copy nimbase.h but uses -I$nim/lib
2020-01-18 01:21:13 +01:00
Timothee Cour
c56612ff96 refs #13054 correctly handle {.exportc,dynlib.} and {.exportcpp,dynlib.} (#13136)
* refs #13054 correctly handle {.exportc,dynlib.} and {.exportcpp,dynlib.}
* put back NIM_EXTERNC for N_LIB_EXPORT; causes issues with compilerproc
2020-01-18 01:19:20 +01:00
Araq
107352f9d7 fixes #13157 2020-01-17 17:52:06 +01:00
Timothee Cour
6c2214b7de followup on #10435 : should be diff, not show (#13162) 2020-01-17 16:56:21 +01:00
Clyybber
451c47634c Fix docs for subdirs too (#13180)
* Fix doc subdirs
* Extract to helper proc, and fix on windows
2020-01-17 16:49:37 +01:00
cooldome
f51613e262 make sink operator optional (#13068)
* make sink operator optional

* bug fix, add changelog entry

* Trigger build

* fix one regression

* fix test

* Trigger build

* fix typos
2020-01-17 11:44:06 +00:00
Andreas Rumpf
7626907401 ARC works for async on Windows (#13179) 2020-01-17 11:14:17 +01:00
Jasper Jenkins
796aafe7e0 make case-object transitions explicit, make unknownLineInfo a const, replace a few magic numbers with consts (#13170) 2020-01-17 10:34:31 +01:00
cooldome
2bf337abae fixes #13095 (#13181)
* fixes #13095

* fix typo
2020-01-17 09:17:18 +01:00
Clyybber
41cf609fc7 Fix docs (#13176) 2020-01-16 22:22:17 +01:00
Clyybber
e3acb2d12c Cleanup DFA (#13173) 2020-01-16 20:15:50 +01:00
Jasper Jenkins
d245d4cf09 fix tsizeof3 for aarch64 (#13169) 2020-01-16 14:21:12 +01:00
Timothee Cour
1b54be7779 fixes #12998 nim doc regression (#13117) 2020-01-16 14:19:58 +01:00
cooldome
5ef0494677 Working towards arc codegen (#13153)
fixes #13029
2020-01-16 14:16:17 +01:00
Miran
352232e62d style fix: change 'JS' to 'js' to make it consistent (#13168) 2020-01-16 14:14:03 +01:00
Ico Doornekamp
54bfd69a27 Remove obsolete code from osalloc (#13158) 2020-01-16 09:11:05 +01:00
Timothee Cour
d5f011d9e6 CI fix timeout error (#13134) 2020-01-15 22:54:04 +01:00
Andreas Rumpf
a5e67071d2 ARC: misc bugfixes (#13156)
* fixes #13102
* closes #13149
* ARC: fixes a move optimizer bug (there are more left regarding array and tuple indexing)
* proper fix; fixes #12957
* fixes yet another case object '=' code generation problem
2020-01-15 22:13:31 +01:00
Timothee Cour
d88b52c0bc successX now correctly shows html output for nim doc, nim jsondoc; fix #13121 (#13116)
* successX now correctly shows html output for nim doc
* fixes #13121
* fixup hintSuccessX to be less weird
2020-01-15 15:18:37 +01:00
Timothee Cour
51c072bd37 export normalizePathEnd (#13152) 2020-01-15 15:03:06 +01:00
Miran
e708d5de75 System cleanup, part 2 (#13155)
* create basic_types, arithmetics, exceptions, comparisons
* create setops.nim
* create memalloc.nim
* create gc_interface.nim
* create iterators_1.nim
2020-01-15 14:42:49 +01:00
Ico Doornekamp
79a326759a Added 'ansic' os support for minimal (embedded) targets (#13088)
* os:any implementation
* os:asny: omit flock/funlock calls in echoBinSafe
* Disabled default "unhandled expection" reporting for `--os:any` to reduce
code size. Added unhandledExceptionHook instead which can be used to get
a notification from Nim and handle it from the application.
2020-01-15 11:06:41 +01:00
Tomohiro
d31e32743f Fix typo in doc/destructors.rst (#13148) 2020-01-14 19:51:58 +01:00
Andreas Rumpf
675ca997fb fixes #9674 [backport] (#13143) 2020-01-14 16:20:48 +01:00
Andreas Rumpf
8b00586488 fixes #13104 [backport] (#13142) 2020-01-14 15:16:36 +01:00
cooldome
b4545f03de pass platform argument only if vccexe is used (#13078)
* pass platform only if vccexe is used
* fixes #12297
2020-01-14 15:02:10 +01:00
Andreas Rumpf
fadbd8f70d fixes #10665 (#13141) [backport] 2020-01-14 13:51:28 +01:00
Andreas Rumpf
9fc04a555c fixes #13105 (#13138) 2020-01-14 12:57:20 +01:00
Andreas Rumpf
d56848878c fixes #13119 (#13128)
* fixes #13119
* fixes a regression
2020-01-14 09:56:08 +01:00
Timothee Cour
49d1822c8f fixes #13100 nim doc now treats export localSymbol correctly (#13123) [backport]
* fix #13100 nim doc now treats `export localSymbol` correctly
* use owner instead
2020-01-13 22:05:38 +01:00
treeform
d9640ed075 Expose more openSSL methods. (#13131) 2020-01-13 22:04:43 +01:00
Andreas Rumpf
eadd1ba9ed fixes #13112 (#13127)
* improve line error information

* fixes #13112
2020-01-13 15:47:17 +01:00
Andreas Rumpf
abea80376a fixes #13122 (#13126)
* fixes #13122

* moved tests to where they belong
2020-01-13 14:11:51 +01:00
Jasper Jenkins
bf2e052e6d fix rtti sizeof for varargs in global scope (#13125) [backport] 2020-01-13 10:17:21 +01:00
perter lee
1f27a2f8ab fix the ftp store function read the local file bug (#13108) [backport]
* Update asyncftpclient.nim

When use newStringOfCap function not have assign memory for the string data,so if use this address the fault is rasise.

* complelete the bugfix
2020-01-13 10:16:19 +01:00
Timothee Cour
ee1563ef33 VM FFI: write(stderr, msg) and fprintf(cstderr, msg) now work at CT (#13083) 2020-01-12 13:44:43 +01:00
Federico Ceratto
1c001fe583 Add link to posix_utils.html in posix.nim (#13111) 2020-01-12 13:36:37 +01:00
treeform
01a89cc473 Remove some unused/disabled OpenSSL functions (#13106) 2020-01-11 10:58:38 +01:00
Andreas Rumpf
767592a3c3 more arc features (#13098)
* config update
* ARC now supports 'repr' and 'new' with finalizers is supported
2020-01-10 23:17:33 +01:00
Miran
c0973d1b47 [backport] fix #12813, fix #13079 (#13099)
Correctly remove a key from CountTable when it is set to zero.
2020-01-10 15:24:33 +01:00
Miran
f7ce4e8705 System cleanup, part 1 (#13069)
* system.nim: mark what every .pop does

* system.nim: un-nest when statements
2020-01-10 10:14:02 +01:00
Andreas Rumpf
3a39ab83ac fixes an asyncftpclient bug; refs #13096 [backport] 2020-01-10 09:42:21 +01:00
narimiran
e9e114058c [backport] system/io.nim fix wrong documentation comment [ci skip] 2020-01-10 08:53:44 +01:00
Timothee Cour
4cd86c0842 typetraits: fixes #6454; genericParams; added lenTuple; added tuple type get (#13064) 2020-01-10 08:51:37 +01:00
Araq
fcd2f305ad fixes #13070 2020-01-10 08:32:30 +01:00
Araq
033da35de1 fixes #13072; no test case because it will be added later with more exception handling related bugfixes 2020-01-10 08:32:30 +01:00
Tomohiro
a33b72af49 Fix error check code in osproc (#13090) [backport] 2020-01-09 18:00:41 +01:00
Ico Doornekamp
bb7273bc47 Use '__noinline' instead of 'noinline' for N_NOINLINE gcc attribute, this prevents clashes with systems where 'noinline' might be already defined (#13089) 2020-01-09 17:27:42 +01:00
Timothee Cour
3f78873898 remove all remaining warnings when build nim (with -d:nimHasLibFFI) (#13084)
* cleanup deprecations in evalffi + elsewhere

* remove dead code getOrdValue64
2020-01-09 13:19:18 +01:00
Andreas Rumpf
852170cc78 take the one good idea from --os:standalone and enable it via -d:StandaloneHeapSize (#13077) 2020-01-09 11:48:37 +01:00
Teashrock
27fee4d8b4 Deleted misplaced separator (#13085) [backport]
Misplaced separator, which was constantly breaking compilation on Haiku OS, was deleted.
2020-01-09 11:48:13 +01:00
Andy Davidoff
56fb909676 fix crash due to errant symbols in nim.cfg (#13073) [backport] 2020-01-08 22:25:25 +01:00
narimiran
5e9ebe9ec1 move entries from the wrong changelog file [ci skip] 2020-01-08 15:20:30 +01:00
Timothee Cour
15043d35b8 make SuccessX show project file + output file (#13043)
* make SuccessX show project file + output file
* address comments
* fix test and add `result.err = reNimcCrash` otherwise hard to see where reNimcCrash used
* address comments
2020-01-08 00:39:07 +01:00
cooldome
871d5e79b1 distinctBase type trait for distinct types (#13031) 2020-01-08 00:36:57 +01:00
b3liever
8bcc7e8b9e basename supports pragmaexpr (#13045)
* basename supports pragmaexpr

* update changelog
2020-01-07 11:25:51 +01:00
Bung
291608045c add pqserverVersion,pqconnectionNeedsPassword,pqconnectionUsedPassword (#13060) 2020-01-07 10:52:02 +01:00
Timothee Cour
e5ae7ceaa3 [easy] --hint🔗on now shows link cmd instead of nothing (#13056)
* --hint🔗on now shows link cmd instead of nothing

* update doc for --listCmd
2020-01-07 10:38:59 +01:00
Timothee Cour
569d4d18f8 --styleCheck:hint now works (#13055) 2020-01-07 09:53:11 +01:00
Miran
1551fff853 clean up deprecated stuff and unused imports in tests (#13059) 2020-01-07 09:49:08 +01:00
loloiccl
6a7a19eb15 Modify the test command for nimly (nimble-package) (#13053) 2020-01-07 06:47:40 +01:00
Brent Pedersen
a019cc52f6 testament/important_packages dont run hts (#13052) 2020-01-07 06:47:18 +01:00
Clyybber
ba4fbb6328 Continue #13002 (#13021) 2020-01-06 11:40:42 +00:00
Timothee Cour
72499a8d7c [cleanup] remove disabled (and obsolete) ttypetraits; rename ttypetraits2 => ttypetraits (#13041)
* remove disabled (and obsolete) ttypetraits; rename ttypetraits2 => ttypetraits

* D20200105T085828 fix super strange bug that causes CI to fail: builds.sr.ht with: `Error: Settle timed out after 120 attempts`
2020-01-05 19:33:33 +01:00
BinHong Lee
2cfa8d8385 Allow -o option for buildIndex (#13037) [backport]
Addressing #12771 

This is also included in the docgen documentation [here](https://nim-lang.org/docs/docgen.html) but its not respected as reported in the issue.
2020-01-05 19:24:29 +01:00
Kamanji
9a5aaadda8 Rst parser respect :start-after: and :end-before: in include directive (#12972)
* [FEATURE] rst parser respect :start-after: in include

Rst parser now respects `:start-after:` and `:end-before:` attributes
for `include` directive.

* [DOC] include directive parsing proc update

* [TEST] Added unit tests for include rst directive in `rst` module
2020-01-05 10:01:21 +01:00
Araq
ae68ff959b fixes #12996 2020-01-05 09:42:44 +01:00
Araq
fdcea66fd9 reprjs: style changes 2020-01-05 09:42:44 +01:00
cooldome
a3df1b55f3 fixes #13013, reverts previous changes to readLines() (#13036) [backport]
* Revert "remove default argument for readLines (#12807) [backport]"

This reverts commit c949b81efd.
2020-01-05 09:22:41 +01:00
Jasper Jenkins
9474a818af fix enumtostr crash for enum-range (#13035) 2020-01-05 09:18:14 +01:00
Timothee Cour
13c08f3ab4 VM: support importc var, ptr/pointer types, cast int <=> ptr/pointer (#12877)
* VM: allow certain hardcoded special var variables at CT
* VM: allow all importc var, cast[int](ptr)
* fix tests tests/vm/tstaticprintseq.nim, tests/cpp/t8241.nim
* VM: == works for ptr/pointer nodes
* bugfix: ==, cast now also works for pointer, not just ptr
* VM supports cast PtrLikeKinds <=> PtrLikeKinds / int
* improve cname handling
* fixup + bug fix
* VM: support cast from ref to int
* address comment: opcLdGlobalDeref => opcLdGlobalDerefFFI
* defensive check against typ == nil
2020-01-05 09:11:29 +01:00
Araq
a1beeb313f fixes #13032 2020-01-04 19:33:49 +01:00
Andreas Rumpf
0f6987a86e fixes #12964 (#13027) 2020-01-04 07:40:02 +01:00
cooldome
47e7b8771c Fixes #13026 (#13028) 2020-01-04 02:33:13 +01:00
rockcavera
89570aa44b fix #12988 (#13022)
fix #12988
2020-01-03 22:41:58 +01:00
Andreas Rumpf
fb1b51f1e3 fixes #12956 (#13020) 2020-01-03 17:36:09 +01:00
Andreas Rumpf
8aadba1a2a fixes #12961 (#13019) 2020-01-03 14:30:54 +01:00
Siegfried Ehret
a577a88c36 Fix typo (#13015) [backport] 2020-01-03 10:23:28 +01:00
Andreas Rumpf
0ecb709cbe fixes #12978 (#13012) 2020-01-03 01:21:45 +01:00
cooldome
c949b81efd remove default argument for readLines (#12807) [backport] 2020-01-02 23:27:37 +01:00
cooldome
002d50f1f0 Sink to MemMove optimization in injectdestructors (#13002) 2020-01-02 22:58:01 +01:00
Timothee Cour
0ff23e696c fix #12985 {.push.} now does not apply to generic instantiations (#12986) 2020-01-02 16:49:57 +01:00
Andreas Rumpf
c3344862b0 --exception:goto switch for deterministic exception handling (#12977)
This implements "deterministic" exception handling for Nim based on goto instead of setjmp. This means raising an exception is much cheaper than in C++'s table based implementations. Supports hard realtime systems. Default for --gc:arc and the C target because it's generally a good idea and arc is all about deterministic behavior.

Note: This implies that fatal runtime traps are not catchable anymore! This needs to be documented.
2020-01-01 10:01:49 +01:00
Andy Davidoff
8a63caca07 fixes disruptek/nimph#102 multi-level nim.cfg use (#13001) [backport] 2019-12-31 22:29:19 +01:00
cooldome
584e8c8283 fixes #12989 (#12992)
* fixes #12989
* Revert "remove unwanted changes"

This reverts commit 501829732a.
2019-12-31 21:13:26 +01:00
Andreas Rumpf
ce40ed18bb fixes #12965 (#12991) 2019-12-31 09:42:18 +01:00
Andrii Riabushenko
9eeff690d5 Revert "fixes #12989"
This reverts commit 928c2fee06.
2019-12-31 00:10:02 +00:00
Andrii Riabushenko
928c2fee06 fixes #12989 2019-12-31 00:07:49 +00:00
Ștefan Talpalaru
defaf3b5a5 c_fflush() the rawWrite() buffer (#12987)
Stack traces on an unbuffered stderr get out of sync with line-buffered
stdout - usually on Windows terminals or CI logs. This fixes it by
calling C's fflush() on the output buffer in the procedure used for
printing stack traces.
2019-12-30 02:13:41 +01:00
Chris Heller
8d1a7db6ea Check pqntuples > 0 in getValue. Fixes #12973 (#12974) 2019-12-29 17:41:18 +01:00
Sam Wang
441cacf70f Added fix for handling TaintedStrings in streams and httpclient (#12969)
* Added fix for taint mode in streams and httpclient

* Removed taintMode export from system.nim
2019-12-29 17:37:22 +01:00
Ștefan Talpalaru
ee9ee297d8 generic stack trace overriding mechanism (#12922)
* libbacktrace support

* switch to a generic stack trace overriding mechanism

When "nimStackTraceOverride" is defined, once of the imported modules
can register its own procedure to replace the default stack trace
generation by calling `registerStackTraceOverride(myOwnProc)`.

Tested with `./koch boot -d:release --debugger:native -d:nimStackTraceOverride --import:libbacktrace`
for the compiler itself and `./bin/nim c -r -f --stacktrace:off --debugger:native -d:nimStackTraceOverride --import:libbacktrace foo.nim`
for an external program.

* make the StackTraceOverrideProc {.noinline.}
2019-12-29 15:46:01 +01:00
Simon Krauter
37e93eab66 parsecfg: retain CRLF line breaks, fixes #12970 (#12971) 2019-12-29 15:39:48 +01:00
Timothee Cour
8c19372690 [ci skip] docfix .. < => ..< (#12981) [backport] 2019-12-29 15:34:36 +01:00
Jack Tang
21ea1094ef Allow customize Host header 2019-12-28 17:26:02 +00:00
King Eca
b67dea7a33 Fixes stackoverflow links in readme (#12963) [backport] 2019-12-27 08:31:01 +00:00
Andreas Rumpf
1917ebf082 minor refactorings 2019-12-27 08:29:40 +01:00
cooldome
649bf326bf fixes #12945 (#12959) 2019-12-24 20:34:14 +01:00
Araq
30162908b0 fixes another regression 2019-12-24 17:33:27 +01:00
Araq
3516947642 osproc: fixes regression 2019-12-24 17:33:27 +01:00
Araq
5aa7b1a44b ARC: default to a shared heap with --threads:on 2019-12-24 17:33:27 +01:00
Araq
bafb4f119c ported re.nim to ARC 2019-12-24 17:33:27 +01:00
Araq
8f17a70fe1 ported osproc.nim to ARC 2019-12-24 17:33:27 +01:00
Araq
9faf00598f ported channels to ARC 2019-12-24 17:33:27 +01:00
Araq
fbb8052e3a fixes the distros.nim regression 2019-12-24 17:33:27 +01:00
Araq
7bcf7696f0 fixes a silly regression 2019-12-24 17:33:27 +01:00
Araq
942db8c5f3 fixes a test case 2019-12-24 17:33:27 +01:00
Araq
6152eb3be3 a better bugfix 2019-12-24 17:33:27 +01:00
Araq
767bd57289 fixes a regression 2019-12-24 17:33:27 +01:00
Araq
d1d017ae85 fixes #12826 2019-12-24 17:33:27 +01:00
Araq
a7b4b2ed54 fixes a bug that kept sugar.collect from working with for loop macros [backport] 2019-12-24 17:33:27 +01:00
Araq
fd5aa89304 added guidelines for evolving Nim's stdlib 2019-12-24 17:33:27 +01:00
Araq
2616a86d4b docs: tiny style improvements 2019-12-24 17:33:27 +01:00
Timothee Cour
a0980c88c9 lenVarargs: number of varargs elements (#12907) 2019-12-23 09:42:32 +01:00
Jasper Jenkins
2e7c9eb6a8 case coverage error message for char (#12948) 2019-12-22 10:10:46 +01:00
Ico Doornekamp
28466ce6fc Auto-initialize deques (#12879) 2019-12-21 21:01:34 +01:00
Timothee Cour
b081166685 fixes #12735 on osx, call dsymutil for debug builds (#12931)
* fix #12735 osx: dsymutil needs to be called for debug builds
* also write dsymutil command to extraCmds in json build file
2019-12-21 20:59:08 +01:00
Judd
e1d79d40f2 update documentation for closureScope and capture (#12886) 2019-12-21 08:06:32 +01:00
RSDuck
9b8afd1dbb Fix #12785 (#12943)
* Fix #12785 and add test

* better variable name
2019-12-21 07:51:19 +01:00
Clyybber
10bd7d8fa0 system.reset is no longer magic (#12937)
It has now means setting x to default for new and old runtime alike
2019-12-19 20:36:59 +01:00
Timothee Cour
e041c184d2 fix #12919 tasyncclosestall flaky: Address already in use (#12934) 2019-12-19 18:50:39 +01:00
Timothee Cour
206a4cee77 fix cmdline bugs affecting nimBetterRun correctness (#12933) [backport] 2019-12-19 14:53:01 +01:00
flywind
cb0a20b9b4 fix error in assertions document (#12925) [backport] 2019-12-18 14:29:45 +01:00
Jasper Jenkins
3c38edf563 Better case coverage error message for alias and range enum (#12913) 2019-12-18 10:29:01 +01:00
Emery Hemingway
148f6d9820 Implement NixOS distro check (#12914) 2019-12-18 08:01:58 +01:00
Andreas Rumpf
3f6df5cc34 fixes #12899 (#12921)
* fixes #12899

* fixes regression: destroy global variables in reverse declaration order, closureleak test relies on it
2019-12-18 07:54:20 +01:00
genotrance
f9f55a23bb Fix single match output (#12920) 2019-12-17 20:26:11 +01:00
Clyybber
18e2ea787e Cleanup leftovers of #12911(#12916) 2019-12-17 17:58:04 +01:00
Andreas Rumpf
83a736a34a ARC: cycle detector (#12823)
* first implementation of the =trace and =dispose hooks for the cycle collector
* a cycle collector for ARC: progress
* manual: the .acyclic pragma is a thing once again
* gcbench: adaptations for --gc:arc
* enable valgrind tests for the strutils tests
* testament: better valgrind support
* ARC refactoring: growable jumpstacks
* ARC cycle detector: non-recursive algorithm
* moved and renamed core/ files back to system/
* refactoring: --gc:arc vs --gc:orc since 'orc' is even more experimental and we want to ship --gc:arc soonish
2019-12-17 17:37:50 +01:00
Arne Döring
5848f0042c add $nimeq for gdb (#12909) 2019-12-17 11:30:01 +01:00
cooldome
7650617448 NaN floatFormat with clang_cl (#12910)
* clang_cl nan floatFormat

* format
2019-12-17 11:25:46 +01:00
Timothee Cour
e8f4586c68 allow typed/untyped in magic procs (#12911) 2019-12-17 11:07:32 +01:00
Timothee Cour
e5ed4c1b7d fix json regression D20191212T144944 (#12902) [backport] 2019-12-15 23:04:06 +01:00
Krzysztof Majk
e4e74a5565 remove unused import (#12900) 2019-12-15 22:59:08 +01:00
BinHong Lee
20a59da401 Add --git.devel option to the documentation 2019-12-15 12:45:57 +00:00
Andreas Rumpf
347a04606b fixes #12885 [backport] (#12895) 2019-12-13 19:20:29 +01:00
Andreas Rumpf
a0aa8fa857 fixes #12874 (#12890)
* fixes #12874

* fixes introduced regressions
2019-12-13 15:36:39 +01:00
cooldome
12d2b980e8 Fixes #12883 (#12894)
* fixes #12883

* fix comment

* add normalize

* fix
2019-12-13 13:30:27 +00:00
cooldome
777c9ad0ef Better clang_cl support (#12896) 2019-12-13 12:12:04 +00:00
cooldome
1e1fd73530 fixes #12882 (#12889)
* fixes #12882
2019-12-13 11:24:05 +00:00
Andreas Rumpf
22b2684608 fixes #12148 [backport] (#12888) 2019-12-12 11:05:18 +01:00
cooldome
94289161f9 invoke createTypeBoundOps for constructors (#12878) 2019-12-11 10:46:20 +00:00
Andreas Rumpf
3524944e21 ARC: fixes cycle detection and move the .cursor attribute into closures (#12872) 2019-12-11 06:57:00 +01:00
Ico Doornekamp
e61d702206 Increased TInstr field sizes: allow long jumps and 65535 VM registers (#12777)
* Increased regBx size from 16 to 24 bits to increase jump range in the VM
from 32K to 8M instructions. Fixes #12727

* Increased VM TInst register field sizes to 16 bits to allow up to 65535 VM registers per proc

* Added test case for >255 VM registers
2019-12-10 19:04:02 +01:00
Andreas Rumpf
b8152b29e8 ARC: yet another bugfix (#12871) 2019-12-10 16:44:54 +01:00
Judd
56cf3403b4 introduce capture macro (#12712)
capture works for more cases than `closureScope`.
2019-12-10 13:16:37 +01:00
PMunch
65fd95bf85 Fix AVR target to define ints properly (#12817)
* Fix AVR target to define ints properly

* Fix more than AVR target

* Test to see how robust not using stdint is

* Fix for namespaces using cstdint

* Fix for pre C++11 compilers when using namespaces
2019-12-10 12:10:33 +01:00
Andreas Rumpf
61d89aae11 completes #12799, fixes #12216 (#12870) 2019-12-10 12:09:48 +01:00
cooldome
13d232ec56 fixes #12827 (#12829) [backport] 2019-12-10 07:08:46 +01:00
Andreas Rumpf
c282cee4db feature dracula themed doc (#12816)
* Implement gorgeous Dracula themed Nim documentation

* Add color for escape sequences

* fixes the test cases

* the big CSS cleanup
2019-12-10 06:48:11 +01:00
cooldome
5929c3da21 fixes #12820 (#12828) 2019-12-09 20:03:23 +01:00
Neelesh Chandola
e4f7656772 Support cross compiling from host to host (#12859) 2019-12-09 13:39:25 +01:00
Neelesh Chandola
7ebb2baa6c Assigning template to var/let/const gives a proper error (#12851)
* Assigning template to var/let/const gives a proper error

* Fix style
2019-12-09 08:19:40 +00:00
Andy Davidoff
a3d45d0c1b add a StringTable.clear that requires no mode specification (#12853)
* add clear overload, test, changelog

* add since annotation
2019-12-09 06:58:36 +01:00
Kevin
a02d043b58 added cstrutils (#12858) [backport]
fixed for 'csuCmpIgnoreStyle' error on hotcodereloading
2019-12-09 06:58:06 +01:00
Neelesh Chandola
ff5ef95414 Fixes #12832 (#12842) [backport]
* Fix #12832
* nimVm -> nimvm in json.nim
* Use suggestSym() instead of markUsed(); Also use styleCheckUse() for finding style violations
2019-12-08 23:27:25 +01:00
Mark
73dd348ddd Manual update: custom exceptions (#12847) [backport]
Said that you can have custom exceptions and showed how to create and raise them.
2019-12-08 21:39:44 +00:00
Elliot Waite
50c1e50184 Add a 32x32 favicon (#12856) 2019-12-08 22:19:35 +01:00
KeepCoolWithCoolidge
ae7b53ec51 Fixes classify function to detect subnormal floating points (#12836)
* Fix classify to test for subnormality.
* Minor fix.
* Modified to maintain existing API.
* Minor change.
* Removed 32-bit case since float is always 64-bit.
2019-12-08 20:17:11 +01:00
Elliot Waite
5da27a891c Removing the mention of using discard for block comments (#12837) [backport]
* Remove mention of using `discard` for block comments

* Add a 32x32 alternate favicon
2019-12-08 20:16:17 +01:00
Mark
0ebc709037 deviated -> derived (#12846) [backport] 2019-12-08 20:15:19 +01:00
Mark
46144a31ab deviated -> derived (#12845) [backport] 2019-12-08 20:14:54 +01:00
Timothee Cour
23fc93fc2d VM: allow ptr setting ptr fields (#12825) 2019-12-06 22:38:53 +01:00
cooldome
7213969901 fixes #12821 (#12822) 2019-12-06 09:56:54 +01:00
Neelesh Chandola
1db21721ec Fixed objects being erroneously zeroed out before object construction (#12814) [backport] 2019-12-05 17:31:51 +01:00
Andreas Rumpf
3fbb3bfd3f ARC related bugfixes and refactorings (#12781) 2019-12-05 16:59:06 +01:00
cooldome
9b0e874687 fixes #12783 [backport] (#12810)
* fixes #12783

* Trigger build
2019-12-05 15:17:45 +01:00
Andrey Makarov
26074f594d nimgrep improvements (#12779)
* fix sticky colors in styledWrite

* nimgrep: context printing, colorthemes and other

* add context printing (lines after and before a match)
* nimgrep: add exclude/include options
* nimgrep: improve error printing & symlink handling
* nimgrep: rename dangerous `-r` argument
* add a `--newLine` style option for starting matching/context
  lines from a new line
* add color themes: 3 new themes besides default `simple`
* enable printing of multi-line matches with line numbers
* proper display of replace when there was another match replaced at
  the same line / context block
* improve cmdline arguments error reporting
2019-12-05 14:42:20 +01:00
Andreas Rumpf
0e7338d65c better support for PROGMEM like annotations for lets/vars; fixes #12216 (#12799) 2019-12-05 13:45:16 +01:00
Clyybber
267fed53ee Fix #12812 2019-12-05 13:22:40 +01:00
itsumura-h
208b018f6b fix db_mysql getRow() when column is null error raised (#12806) [backport]
* fix db_mysql getRow()
* added if y == nil [backport]
2019-12-05 10:28:47 +01:00
cooldome
0987872675 fixes #12804 (#12809) 2019-12-05 07:38:12 +01:00
Araq
de1a283383 fixes #12798 [backport] 2019-12-04 20:38:20 +01:00
Arne Döring
b0c06aa711 fix #12740 (#12774)
* fix #12740

* A different kind of a hack

* proper fix

* fix typo
2019-12-04 07:33:01 +00:00
Timothee Cour
3383985c44 osx: support nanosecond resolution for file stat (eg getLastModificationTime) (#12794) 2019-12-04 08:12:55 +01:00
cooldome
01c7409924 Fix external file recompilation (#12802) 2019-12-03 16:54:42 +01:00
Alex Mitchell
7b562dd43d Update events.nim (#12803)
Removing old username.
2019-12-03 16:54:23 +01:00
genotrance
eed328856f Path substitution for --out and --outdir (#12796)
* Enable pathSubs for --out and --outDir
* Cleanup
2019-12-03 09:26:18 +01:00
Timothee Cour
9e1fd9e46b [minor] fix doc for $(Time) (#12795) [backport] 2019-12-03 09:12:08 +01:00
Tomohiro
378289c6a8 Fixes #12734 (#12784) 2019-12-01 23:21:36 +01:00
Ico Doornekamp
6aade97fe8 Refactored VM registerlayout. The size and location of the registers in (#12775)
the instructions are now all derived from a single definition, allowing
the register layout to be changed.
2019-11-30 13:38:36 +01:00
Jasper Jenkins
0d022622e3 fix nimsuggest deprecation warnings (#12772) 2019-11-30 06:54:15 +01:00
Jasper Jenkins
b6b8d540e3 [backport] always set fileInfoIdx.isKnownFile (#12773) 2019-11-29 22:36:01 +01:00
Euan
c5c6bae2a4 #12103 - CI for FreeBSD (#12179)
* Ref #12103 - adds FreeBSD CI
* Fix getApplFreebsd - length of the string includes the null terminator byte, so minus 1 for result length
* Show last commit in setup task.
* Remove .git from repository URL
* Don't include noisy details showing last commit.
* Add FreeBSD build status badge
* Fix #12182 - disable tconsole on FreeBSD
* Disable tgetaddrinfo on FreebSD as getaddrinfo doesn't support the ICMP protocol.
* Install boehm-gc-threaded
* Use libgc-threaded.so on FreeBSD rather than libgc.so.
* Simplify build failure handling. Update alt text for CI badge.
* Disable test on FreeBSD
* Simplify build config

- use GNU make to build csources
- set PATH variable using the environment key
- remove modification of config to set CC as this is already set

* Install git which seems to be missing from current freebsd images
* Revert change to how path is set
* Add a comment explaining why the length is truncated
* Fix tconsole.
2019-11-29 21:00:54 +01:00
Araq
7e6e399d10 fixes #12669 2019-11-29 19:46:21 +01:00
Araq
b688250202 fixes #12766 2019-11-29 19:46:21 +01:00
Pierre-Jean Grenier
a114a40b57 fix httpclient.lastModified bad pattern in parsing (#12698) 2019-11-29 11:17:10 +01:00
Oscar Nihlgård
5456da3ca9 Fix sequtils.delete bug with out of bounds indexes (#12506) 2019-11-29 11:15:20 +01:00
genotrance
49db2a08ba Fixes #12767 (#12768) 2019-11-29 10:18:44 +01:00
Jasper Jenkins
9ea55eccbb make addQuoted work on nimscript (#12717) [backport] 2019-11-28 23:01:17 +01:00
Araq
0996eb174f fixes #11727 [backport] 2019-11-28 23:00:34 +01:00
Araq
87f0d534d6 fixes #12488 [backport] 2019-11-28 23:00:34 +01:00
Araq
2dea920379 ARC: implemented a simple cycle detector 2019-11-28 23:00:34 +01:00
Clyybber
7e747d11c6 Cosmetic compiler cleanup (#12718)
* Cleanup compiler code base

* Unify add calls

* Unify len invocations

* Unify range operators

* Fix oversight

* Remove {.procvar.} pragma

* initCandidate -> newCandidate where reasonable

* Unify safeLen calls
2019-11-28 17:13:04 +01:00
PMunch
b662842bd0 Fix for 16 bit platforms (#12760) [backend]
This fixes some tiny issues with using Nim on 16-bit platforms. Not
entirely sure why the AVR chip I was compiling for with "cpu = avr" was
detected as 16-bit, but that's probably another issue..
2019-11-28 17:11:56 +01:00
genotrance
010067f3cc Substitute $nimbleDir in --path flags (#12750) 2019-11-28 13:58:38 +01:00
Andreas Rumpf
abe07eb75d VM: improvements for var T/addr (#12667); fixes #12489 2019-11-28 09:56:02 +01:00
Araq
d4cae118dc fixes a flaky test for the realtime GC 2019-11-28 09:33:01 +01:00
3n-k1
0944b0f441 [backport] Fix style issues in lib/, tools/, and testament/. Fixes #12687. (#12754) 2019-11-28 08:32:11 +01:00
Brian Wignall
a7aeabb9d2 [backport] Fix spelling typos (#12755) 2019-11-28 08:30:55 +01:00
Andreas Rumpf
fd85a5ae05 more fixes for --cpu:avr [backport] (#12748) 2019-11-27 16:24:21 +01:00
Araq
80b508d337 test suite: rename tests containing 'fail' for easier search in logs 2019-11-26 16:04:28 +01:00
Araq
72237e2bcf ARC: ported the GC tests over to --gc:arc 2019-11-26 16:04:28 +01:00
Miran
879801c639 increase the timeout for 'tasyncclosestall' (#12744)
This test is very flaky, this change might help reducing the
number of failings (usually solved by restarting the test suite).

Refs https://github.com/nim-lang/Nim/pull/12694#issuecomment-557583790
2019-11-26 14:12:15 +01:00
Timothee Cour
dfe5d115fb fixes #12663 staticRead now creates a dependency for rebuilds (#12731) [backport]
* fix #12663 staticRead
* address comments
2019-11-25 14:44:13 +01:00
Arne Döring
04614a30bd fix in tests/js/tconsole (#12709) 2019-11-25 10:30:22 +01:00
Andy Davidoff
bd8f49cbd3 replace some runtime repr in stdlib for gc:arc (#12716) 2019-11-25 10:13:30 +01:00
tauplus
8debf79837 fix typo in the manual (#12723) 2019-11-25 10:08:22 +01:00
tauplus
bfad0056ab Fix wrong section hierarchy in the manual (#12724) [backport] 2019-11-25 10:06:54 +01:00
Mamy Ratsimbazafy
1f7871ea1c csize_t changes: pinToCpu didn't compile (#12725) 2019-11-25 08:42:19 +01:00
narimiran
015bec6254 Revert "ARC: another critical bugfix; temporary tuples we introduce for tuple unpackaging are not owning the data"
This reverts commit 8b2f8f5430.
2019-11-24 09:50:52 +01:00
Araq
8b2f8f5430 ARC: another critical bugfix; temporary tuples we introduce for tuple unpackaging are not owning the data 2019-11-22 21:41:45 +01:00
Arne Döring
2acf74d458 delete list comprehension (#12392)
The `lc` macro is now part of `graveyard` repository.
2019-11-22 19:57:43 +01:00
Araq
c85e266d1d ARC: yet another silly bugfix 2019-11-22 17:18:11 +01:00
Jack Tang
f0c5d99924 index out of bounds exception when data is empty (#12428) 2019-11-22 15:37:59 +01:00
b3liever
5bb6c67a45 add collect macro (#12708)
* add collect macro

* Add to changelog
2019-11-22 14:40:50 +01:00
Andreas Rumpf
e5478b32a8 fixes #11863 multipart data need $ (#12707)
* fixes #11863
* improved the code; refs #12412
2019-11-22 14:21:03 +01:00
Andreas Rumpf
64e8f050e1 implemented a new localPassc pragma (#12706) 2019-11-22 14:20:15 +01:00
Juan Carlos
c0eeea4f3c Improve head comment on JS (#12548)
* Improve comment on JSGen, replace 12+ concatenations by 1 multiline string

* Peer review feedbacks https://github.com/nim-lang/Nim/pull/12548#discussion_r340051147
2019-11-22 11:37:30 +01:00
Andreas Rumpf
f7ba7c711a added the --asm command line option for inspection of the produced assember code (#12699) 2019-11-21 22:53:51 +01:00
Araq
135774d92b thavlak.nim: more idiomatic code 2019-11-21 20:01:43 +01:00
Araq
d45a736cc8 more thavlak.nim improvements 2019-11-21 16:06:04 +01:00
Araq
f07774d064 more thavlak.nim improvements 2019-11-21 16:03:44 +01:00
Araq
48eed1f522 thavlak.nim test: improved the code style 2019-11-21 15:34:45 +01:00
Jjp137
1b2c1bc64a Remove a stray file (#12697) 2019-11-21 11:19:54 +01:00
Andreas Rumpf
78e02d174d fixes #12670 [backport] (#12693) 2019-11-20 19:08:16 +01:00
Andreas Rumpf
c98e0e22ad conversions to unsigned numbers are not checked anymore; implements /… (#12688) [backport]
* conversions to unsigned numbers are not checked anymore; implements / fixes https://github.com/nim-lang/RFCs/issues/175

* change the spec yet again to be less consistent but to make more sense; updated the changelog
2019-11-20 17:08:43 +01:00
Andreas Rumpf
85ffcd80c0 more arc improvements (#12690)
* ARC: bugfix for =destroy for inherited objects
* added code useful for debugging
2019-11-20 14:34:05 +01:00
c-blake
a88004114d Discussion both in (#12678)
https://github.com/nim-lang/Nim/pull/12600
and in
    https://forum.nim-lang.org/t/5499
indicates that everyone is happy/happier with ``pop``.

This just renames the brand new ``take``s to ``pop`` and installs inline
aliases/wrappers to preserve ``Table.take`` and ``TableRef.take``.

Update apis.rst to try to maintain consistency of remove-and-return procs.
2019-11-20 08:39:45 +01:00
Andreas Rumpf
56a00da34a fixes #12612 [backport] (#12681) 2019-11-19 12:09:36 +01:00
Arne Döring
03fa9a9041 fix regression in align (#12680)
* fix regression in align

* add test typesym without type
2019-11-19 09:58:47 +01:00
Andreas Rumpf
5278cf80eb ARC: closure bugfixes (#12677)
* ARC: closure bugfixes
* progress
* ARC closures: create =hooks for captured parameters
* ARC: always destroy constructions like tuples, arrays properly, even in edge cases
* fixes a regression
2019-11-18 12:33:44 +01:00
Dominik Picheta
bab5351d43 Fixes ambiguity errors when evaluating Nimble files. (#12674) [backport]
When trying to evaluate a Nimble file which imports a Nim module
I was getting the following errors for some reason:

```
/Users/dom/projects/nim/lib/pure/parseopt.nim(229, 46) Error: ambiguous call; both system.paramCount() [declared in /Users/dom/projects/nim/lib/system/nimscript.nim(65, 6)] and os.paramCount() [declared in /Users/dom/projects/nim/lib/pure/os.nim(2613, 8)] match for: ()
```
2019-11-18 09:26:06 +01:00
Andreas Rumpf
223e65e529 attempt to add valgrind support to the CIs and testament (#12646)
* attempt to add valgrind support to the CIs and testament

* valgrind (currently) works only on 64-bit Linux
2019-11-18 09:10:48 +01:00
Andreas Rumpf
58f3e07b1a fixes and changes the recently introduced 'alignas' to be 'align' (#12666)
* fixes and changes the recently introduced 'alignas' to be 'align'

* more improvements
2019-11-15 20:24:14 +01:00
Juan Carlos
9c46526cfa Fix htmlgen html lang (#12668) [backport]
* Fix HTMLGen enable lang on html tag
2019-11-15 20:23:03 +01:00
Gampol T
83b7656c0e fixes #12319 - change exception handling for finish.exe (#12413)
* documented behaviour of recv on bufferd socket

* fixes #12319- check exception using errorCode
2019-11-15 13:28:55 +01:00
Andreas Rumpf
76179cbec2 ARC: fixes leaking new() statement (#12665) 2019-11-15 12:38:11 +01:00
Miran
107b40f097 remove two asserts in int128.nim (#12648) [backport]
Before this PR, `tests/misc/tconv.nim` fails when the compiler
is compiled without `-d:danger` flag.
Bear in mind that even without the asserts, the values outside of
a given range are still checked and a meaningful error message
(from `compiler/semexprs.nim`) is printed.
2019-11-15 12:37:43 +01:00
David Krause
ffca3eefb5 fix documentation of $*(dt: DateTime) (#12660)
(cherry picked from commit 39122ecd93)
2019-11-15 08:06:26 +01:00
Andreas Rumpf
a14abc5708 ARC: solves phase ordering problems (#12654) 2019-11-14 23:19:18 +01:00
Araq
f22d3c75aa ARC: closure inside object constructor now works 2019-11-13 23:29:21 +01:00
Araq
bcab3ed06c ARC: handle closures like tuples consistently 2019-11-13 23:29:21 +01:00
Araq
3020e49b75 ARC: use the new .cursor annotation for 'up' pointers 2019-11-13 23:29:21 +01:00
Andreas Rumpf
6ad0238fd7 make tests green again 2019-11-13 23:29:21 +01:00
Araq
25c724d38b gc:arc: support GC_ref/unref for ref T 2019-11-13 23:29:21 +01:00
Araq
eea0cb07cf async: cleaner solution that avoids GC_ref on strings which doesn't exist for --gc:arc 2019-11-13 23:29:21 +01:00
narimiran
a1e7bf81b3 a better way to test Arraymancer 2019-11-13 16:25:43 +01:00
narimiran
8394c00300 remove long-deprecated 'mapIt' 2019-11-13 14:24:25 +01:00
Arne Döring
0496a666e2 implemented alignas pragma (#12643)
* implemented alignas pragma

* fix bootstrap

* generate c++ compatible syntax for alignas

* Make it work.

* Multiple alignof expressions. Implement top level alignof.
2019-11-13 08:22:41 +00:00
Andreas Rumpf
84861eb48a fixes #12644 2019-11-12 23:56:19 +01:00
Andreas Rumpf
dfb020b174 .cursor implementation (#12637)
* cursors: first implementation
* added currently failing test
* .cursor works for doubly linked lists
* make -d:useMalloc work again
* added code to nil out refs in a destructor
* it's now called --gc:arc
* renderer.nim: render nkBreakState properly
* make simple closure iterators work without leaking
2019-11-12 15:05:36 +01:00
Euan
7e689873e2 Fix #12135 and #12109 (#12137)
* Fix #12135 and fix #12109 - fix OpenBSD type defs

* Fix Mode definition as in #12132
2019-11-11 16:18:08 +01:00
b3liever
0c4d81241a Version of trimZeros without temp strings (#12633) 2019-11-11 12:54:17 +01:00
Araq
a4d43d7d0c --gc:destructors: bugfixes 2019-11-09 20:34:51 +01:00
Araq
e835377d3f inhibit silly warning about moving closure environments for performance 2019-11-09 20:33:23 +01:00
Andreas Rumpf
82e0765fc9 --gc:destructors improvements (#12626)
* do not cache the noDestructors transformation
* liftdestructor: improvements
* undo bugfix
2019-11-09 13:21:55 +01:00
Clyybber
144ad36974 Implemented outplace differently (#12599)
* implemented sugar.outplace; refs #12550
* Different approach, allows for chaining
2019-11-09 12:52:31 +01:00
Miran
6958248efe fix #12519: introduce OrderedTable.take, CountTable.del, CountTable.take (#12600)
* add OrderedTable.take

* add CountTable.del and CountTable.take

* add .since pragma to the introduced public procs

* add changelog entry [ci skip]
2019-11-08 16:35:27 +01:00
cooldome
1e71c13697 fix compilation warning (#12618)
* fix compilation warning

* comments incorporated
2019-11-08 09:16:44 +01:00
Volodymyr Lashko
4e841ab156 Fix crash in terminate handler (#12572) [backport]
* fix undefined behavior in terminate handler

* fix failing unit test

* Revert "fix failing unit test"

This reverts commit 0e5e385fbf.

* Revert "fix undefined behavior in terminate handler"

This reverts commit 2b582871f1.

* do not throw inside terminate handler with msvc < 1923
2019-11-07 22:00:34 +00:00
Andreas Rumpf
135e945ff0 make parsexml compatible with --gc:destructors/newruntime 2019-11-07 18:18:51 +01:00
Yanis Zafirópulos
76085e8a45 added support for openArray's for gcd and lcm (#12621) 2019-11-07 18:06:48 +01:00
Arne Döring
a2d6691af2 fix #12597 (#12604) 2019-11-07 17:16:34 +01:00
Judd
8b1ef8e07e allow random module to be used in standalone: (#12617)
proc randomized*() uses time releated function which is not available on
standalone, so disable this function for standalone.
2019-11-07 14:48:33 +01:00
cooldome
e1b1759439 fixes #5050; fixes #11826 (#12606) [backport] 2019-11-07 14:47:26 +01:00
Arne Döring
94675c2378 backtick and export marker handling in eqIdent (#12574) 2019-11-07 14:40:44 +01:00
Andreas Rumpf
372b01711e added 'since' template for further stdlib additions 2019-11-07 14:20:39 +01:00
Andreas Rumpf
f69ee294c8 bugfix that enables the 'since' template [backport] 2019-11-07 14:20:39 +01:00
Andreas Rumpf
14a0182ca6 pragmas.nim: tiny code formatting 2019-11-07 14:20:39 +01:00
narimiran
0d00bde4ea fix failing test 2019-11-07 11:04:41 +01:00
Andreas Rumpf
166048da5d osproc needs 'import linux' for -d:useClone 2019-11-07 09:51:15 +01:00
Andreas Rumpf
230c618eb9 error message: Nim calls it 'proc' 2019-11-07 09:41:04 +01:00
Dominik Picheta
675189c77f Merge pull request #12613 from nim-lang/miran-unused-imports
Remove unused imports
2019-11-06 22:08:43 +00:00
Andy Davidoff
5544a13236 restore --define🔑val in nim.cfg and fix #12367 (#12611) 2019-11-06 21:26:03 +01:00
Andy Davidoff
738c957e94 add --clearNimblePath; fixes #12601 (#12609) 2019-11-06 20:40:22 +01:00
narimiran
717da9f158 [backport] print more information for the previous commit 2019-11-06 16:14:28 +01:00
narimiran
5381c810a8 [backport] rewrite flaky runnable example 2019-11-06 15:54:21 +01:00
narimiran
c6a451c584 remove unused imports from tests 2019-11-06 14:35:45 +01:00
Tor Arvid Lund
5ccbf7e3cf [backport] doc/tut3.rst: Fix typo in Introduction (#12607) [ci skip]
Derivative of `b*pow(x, 2)` is `2*b*x`, while old version had `2*a*x`
2019-11-06 13:42:39 +01:00
narimiran
cc3e9ca164 remove unused imports 2019-11-06 12:01:00 +01:00
Andy Davidoff
61889c604a export nim.cfg parser (#12602) 2019-11-06 09:59:23 +01:00
Federico Ceratto
59c212607e [backport] Add links to packaging and distro pages (#12603) [ci skip] 2019-11-06 09:03:28 +01:00
Araq
d19206755b async: use $ and not repr in debug mode 2019-11-05 17:10:02 +01:00
Araq
1794cd477d expr -> untyped 2019-11-05 16:55:08 +01:00
jiro
0694bd47b9 Add or detectOs(Manjaro) (#12587) [backport]
Using `pacman` command in Manjaro Linux

(cherry picked from commit 1ff3494dab)
2019-11-05 16:21:28 +01:00
Andreas Rumpf
3ba3307d61 remove deprecated procs (#12535) 2019-11-05 11:05:46 +01:00
Miran
ffa9a7405f fix #8242, fix #12586: fix 'formatFloat' with 'precision = 0' (#12592)
* fix #8242, fix #12586: fix 'formatFloat' with 'precision = 0'

'formatFloat' with 'precision = 0' now gives the same result
(a number without a decimal point) in all backends.
This is compatible with Python's formatters, too.

* fix failing tests

* add changelog entry

* add version switch
2019-11-05 10:31:23 +01:00
Andreas Rumpf
46af8164c0 implement the --useVersion emulation feature 2019-11-04 21:58:26 +01:00
Kaushal Modi
b24560a140 Make sequtils.zip return seq of anonymous tuples (#12575)
* Make sequtils.zip return seq of anonymous tuples

Earlier the tuples had named fields "a" and "b" and that made it
difficult to assign the zip returned seqs to other vars which expected
seqs of tuples with field names other than "a" and "b".

* Make sequtils.zip backwards compatible with Nim 1.0.x
2019-11-04 21:11:43 +01:00
Clyybber
cf5c3f2400 Fixes #12379 (#12591) [backport] 2019-11-04 20:57:14 +01:00
alaviss
558ecd1ca6 compiler/suggest: add variable support to con (#12569)
This allows for the type of a variable to be retrieved.
2019-11-04 18:29:26 +01:00
Miran
ae32d637f7 [backport] fix #12395 (#12590)
'countBits32' is now fixed in the same way that
'countBits64' was already patched earlier (by adding 'u32
where needed).
2019-11-04 15:02:36 +01:00
Arne Döring
992f0a7756 fix conversions to uint in varints.nim (#12564) 2019-11-04 13:06:08 +01:00
Andreas Rumpf
62fc3db9d7 --os:ios needs to imply defined(macosx) [backport] (#12585) 2019-11-04 13:05:03 +01:00
narimiran
bdc2bcc36c NimPatch of devel version should be an odd number because of the earlier hacks 2019-11-03 16:04:21 +01:00
Andreas Rumpf
3f4b9971fc newruntime: only check for dangling refs when 'owned ref T' support is enabled 2019-11-03 09:46:49 +01:00
Juan Carlos
4c9a7e6f00 JS improve indent (#12581)
* JSgen make indent be all spaces, instead of mixed spaces and tabs, for generated JS
2019-11-03 08:03:03 +01:00
Andreas Rumpf
ceda586d88 fixes #12577 [backport] (#12584) 2019-11-03 07:55:55 +01:00
Tomohiro
4e0f12092e Fixes #12536 (#12568) [backport] 2019-11-02 08:21:49 +01:00
Andreas Rumpf
44a27ccfe1 --gc:destructors: simple closures work 2019-11-02 00:39:04 +01:00
Andreas Rumpf
7a4d066102 make renderIds work again 2019-11-01 21:02:44 +01:00
Andreas Rumpf
3761e62fde improve codegen quality for --gc:destructors 2019-11-01 09:59:18 +01:00
Kaushal Modi
d914e9a65f [backport] Add docs to better distinguish among getProjectPath, getCurrentDir and currentSourcePath (#12565)
Fixes https://github.com/nim-lang/Nim/issues/10477.
2019-10-31 21:00:18 +01:00
Arne Döring
99078d80d7 introduce csize_t instead of fixing csize (#12497) 2019-10-31 19:18:12 +01:00
genotrance
0c7b6c9c15 Switch mingw links (#12561) 2019-10-31 11:13:32 +01:00
Andreas Rumpf
79a262d6e9 better testing for nimcrypto; re-enable chronos testing (#12560) 2019-10-31 07:18:45 +01:00
Andreas Rumpf
1746da2d9e --gc:destructors now means Nim uses pure refcounting (#12557) 2019-10-30 16:15:17 +01:00
Juan Carlos
b5bb581642 Improve Math.Trunc code emit on JS, had weird whitespaces and indents (#12549) 2019-10-30 14:12:17 +01:00
Nindaleth
34dbc5699e fix several typos in documentation and comments (#12553) 2019-10-30 09:08:45 +01:00
Araq
1214960a1b fixes #12547 [backport] 2019-10-29 15:07:04 +01:00
zah
de5f6a07c2 Fix newLit for objects having string fields (#12542) [backport] 2019-10-28 22:45:55 +01:00
Araq
44b1ecc287 destructors.rst: added a missing 'var' to the motivating example 2019-10-28 18:15:17 +01:00
Andreas Rumpf
e58c2d261c [backport] fix #12528, fix #12525: incorrect generic type resolution for default values (#12538) 2019-10-28 16:56:38 +01:00
Andreas Rumpf
c52a2c3ab0 proof that refcounting can handle Nim's async (#12533) 2019-10-28 16:13:38 +01:00
Solitude
160c07be00 Fix code style errors (#12545) 2019-10-28 15:21:10 +01:00
Anthon van der Neut
c58aa7705d [backport] fix broken link to non-existing c2nim manual html, fixes #12537 [ci skip] (#12544) 2019-10-28 13:51:43 +01:00
Tomohiro
90376940bb Add a changelog entry related to PR #11748 [ci skip] (#12541) 2019-10-28 13:29:13 +01:00
Jjp137
ee119f7984 colors: fix 'mix' template and make most examples runnable (#12532) [backport]
* colors: fix the 'mix' template
* colors: make most examples runnable
2019-10-28 13:11:11 +01:00
Artem V L
580462c886 splitPath() behavior synchronized with splitFile() (#12481)
* splitPath() behavior synchronized with splitFile() having the expected behavior in all languages

splitPath() docstrings update, tests added for both splitPath() and splitFile()

* Path splitting refined and described
2019-10-28 12:58:02 +01:00
Tomohiro
a9d7796e1c [feature]strformat: add 2 'fmt' macros that use specified characters instead of '{}' (#11748)
* [feature]strformat: add 2 'fmt' macros that use specified chars instead of '{}'

* strformat: revert documentation comments of `&` and 'fmt'

* strformat: removed single open/close char variant of fmt
2019-10-28 12:33:44 +01:00
Arne Döring
5ed99f8d3f Extent json.to testing to VM, add workrounds for VM bugs. (#12493)
fixes #12479
2019-10-28 10:06:16 +01:00
Miran
a2ad7d4883 fix deprecation warnings related to Int128 (#12474)
* semfold: fix deprecation warnings related to Int128

* semmagic: fix deprecation warnings related to Int128

* system/io: remove unneeded conversion of TaintedString to itself
2019-10-28 09:58:39 +01:00
Arne Döring
91af075244 integer literal documentation [ci skip] (#12513)
* integer literal documentation [ci skip]

* apply feedback [ci skip]
2019-10-28 09:52:59 +01:00
Andreas Rumpf
7192b13609 some progress on bug #12443 2019-10-27 17:50:30 +01:00
Andreas Rumpf
cbbc2cc237 fixes #12502 2019-10-27 17:50:30 +01:00
Andreas Rumpf
120829155a development version should be 1.1.0 so that version checking can work properly 2019-10-27 17:50:30 +01:00
Andreas Rumpf
0631d2dccc minor improvements 2019-10-27 17:50:30 +01:00
Tomohiro
f3b56e7ac0 Add /nologo option when nim call cl.exe (#12524) 2019-10-27 11:36:38 +01:00
Arne Döring
3c567bcf20 fixes #12514 (#12520) [backport] 2019-10-27 11:34:33 +01:00
Jjp137
3a62cf29d8 Remove sentences referring to the graphics module (#12522) 2019-10-26 04:28:01 -04:00
Artem V L
60ff41a8da '#' value parcing is explained (disambiguated) (#12476) 2019-10-25 15:22:26 +02:00
Jjp137
1d42108fda sequtils: replace deprecated 'random' call within example (#12515) [backport] 2019-10-25 09:47:34 +02:00
alaviss
5b3571c9a4 compiler/semtypes: improve lineinfo for exported object fields (#12495)
The line info should now points to the `a`, not the `*`, like this:
    a*: string
    ^
Additionally this fixes nimsuggest's highlighting of exported object
fields.
2019-10-25 01:06:53 +02:00
Andreas Rumpf
e0d13abaff VM: fixes register leaks [backport] (#12510) 2019-10-25 00:45:06 +02:00
Tomohiro
8040c84615 Fix Nim specify wrong option to vccexe when vcc.options.always is set (#12490) [backport] 2019-10-24 23:43:59 +02:00
Andreas Rumpf
8a599fb571 fixes #12491 [backport] 2019-10-24 22:51:13 +02:00
alaviss
f827d75804 compiler/semcall: return the correct lineinfo for nkCallStrLit (#12484) 2019-10-24 18:21:37 +02:00
Andreas Rumpf
801a794039 VM: fixes most ran-out-registers problems [backport] (#12485) 2019-10-24 17:29:32 +02:00
Federico Ceratto
9ac062b746 [backport] Add link to posix_utils.html - related to #10723 (#12509) 2019-10-24 14:08:59 +02:00
UNIcodeX
d731646106 [backport] Clarifies experimental / parallel example on manual.rst (#12472)
* Clarifies experimental / parallel on manual.rst

Details:
Calling `useParallel()` in example fails with compiler error
  Error: 'parallel' section without 'spawn'

Adding `spawn` causes error:
  Error: internal error: (filename: "ccgexprs.nim", line: 1032, column: 17)
  No stack traceback available
  To create a stacktrace, rerun compilation with ./koch temp c <file>

Therefore a separate proc, `threadedEcho`, is added for the echo'ing
of the string, which allows the example to build, however, `sync()`
must be added so that the "echo in parallel" strings will actually
be shown on the terminal. Otherwise, the program will spawn of the
threads and exit before they can return to the main thread.

* Fixes and clarifies example for threading in manual.rst

Issue:
Calling useParallel() in example failed with compiler error
`Error: 'parallel' section without 'spawn'`

Adding spawn yielded compiler error:
```bash
Error: internal error: (filename: "ccgexprs.nim", line: 1032, column: 17)
No stack traceback available
To create a stacktrace, rerun compilation with ./koch temp c
```

Proposed Solution:
- Separate proc, threadedEcho, is added for the echo'ing
  of the string, which allows the example to build
- Added the thread number so that it can demonstrate that sometimes
  threads which were started sooner, come back after threads which
  were started later.
2019-10-24 14:08:27 +02:00
Miran
b03de8a4d9 Fix many broken links and prefer relative links within docs (#12463)
* Fix many broken links

Note that contrary to what docgen.rst currently says, the ids have
to match exactly or else most web browsers will not jump to the
intended symbol.

* Prefer relative links for Nim documentation

This is more friendly to those browsing the documentation without
a network connection. The nim-doc package in Debian allows this,
for example.

Also, the domain name being used was not consistent. It could have
been either nim-lang.org or nim-lang.github.io, and those reading
the stable docs could have found themselves suddenly reading the
devel docs instead.

* koch.rst: remove link to nonexistent section

* manual.rst: remove unintended link

cast[T](0) is interpreted as a link to id 0 with text T, so escape
the opening parentheses to display the intended output.

* asyncstreams: replace unintended link with emphasis

* Fix word wrapping
2019-10-24 14:07:43 +02:00
Juan Carlos
8f8916413f [backport] Documentation Math module (#12460) 2019-10-24 14:07:21 +02:00
narimiran
2baa21d461 disable package 'chronos' for now 2019-10-24 13:46:59 +02:00
Araq
a03a8e80ea fixes a regression that caused that Nim devel cannot compile 1.0 anymore 2019-10-24 12:27:34 +02:00
Araq
e506c1e0ea fixes a regression that caused that Nim devel cannot compile 1.0 anymore 2019-10-24 12:27:34 +02:00
Araq
619b997c31 ast.nim: slightly better documentation 2019-10-24 12:27:34 +02:00
Oscar Nihlgård
3d0c756a3c Fix JS bug in std/monotimes (#12499) [backport] 2019-10-24 11:24:26 +02:00
Oscar Nihlgård
4ac100c912 Fix jsgen bug with uninitialized seq (#12500) [backport] 2019-10-24 11:17:01 +02:00
Oscar Nihlgård
9ccfcf5dd2 Fix compiler crash caused by top level return (#12501) 2019-10-24 11:04:04 +02:00
narimiran
822078ed12 add changelog for v1.0.2 2019-10-23 14:35:31 +02:00
Arne Döring
8d3d97aa9b no html comments in issue template [skip ci] (#12496) 2019-10-23 12:08:17 +02:00
narimiran
d5cd5b00b9 disable flaky test on OSX 2019-10-23 11:24:43 +02:00
narimiran
2120fb2777 [backport] package chronos now has dependencies 2019-10-23 11:20:12 +02:00
Arne Döring
fe4a59f12b fixes #12453 (#12475) 2019-10-23 10:29:12 +02:00
narimiran
c90b4ecddc Revert "[ci skip] disable two packages until #11764 is merged"
This reverts commit 48975bb3e7.
2019-10-23 07:09:08 +02:00
Jjp137
3ad48069d3 Fix word wrapping 2019-10-22 17:59:12 -07:00
Jjp137
e6d5379b3b asyncstreams: replace unintended link with emphasis 2019-10-22 17:59:12 -07:00
Jjp137
59c1f7c87f manual.rst: remove unintended link
cast[T](0) is interpreted as a link to id 0 with text T, so escape
the opening parentheses to display the intended output.
2019-10-22 17:59:12 -07:00
Jjp137
79aa58979c koch.rst: remove link to nonexistent section 2019-10-22 17:59:12 -07:00
Jjp137
72147c9ba4 Prefer relative links for Nim documentation
This is more friendly to those browsing the documentation without
a network connection. The nim-doc package in Debian allows this,
for example.

Also, the domain name being used was not consistent. It could have
been either nim-lang.org or nim-lang.github.io, and those reading
the stable docs could have found themselves suddenly reading the
devel docs instead.
2019-10-22 17:59:12 -07:00
Jjp137
93461aee34 Fix many broken links
Note that contrary to what docgen.rst currently says, the ids have
to match exactly or else most web browsers will not jump to the
intended symbol.
2019-10-22 17:59:12 -07:00
Dominik Picheta
6bfa4eb6c5 Merge pull request #12371 from rayman22201/IOSelector_unregister_fix
Test + fix for epoll and kqueue selector modules to properly unregister event handles that have the key type "User"
2019-10-22 11:32:22 -07:00
Dominik Picheta
92fa7e0579 Merge branch 'devel' into IOSelector_unregister_fix 2019-10-22 11:31:38 -07:00
Artem V L
049032432c Docstring refined for the getSectionValue() (#12478) [backport] 2019-10-22 18:20:25 +02:00
Paul Tan
ad3c10022a guards.nim:sameTree(): handle uint literals correctly (#12483) [backport] 2019-10-22 18:18:33 +02:00
Andy Davidoff
2ccd1c3428 tweaked for clarity after editing to fix a typo (#12473) 2019-10-22 13:54:48 +02:00
Andreas Rumpf
38b3590e40 fixes #12310 [backport] (#12470) 2019-10-20 22:37:31 +02:00
Arne Döring
ec20fd3544 fix #12426 (#12462) 2019-10-20 11:52:50 +02:00
ducdetronquito
df4c339cfc Namespace unittest enums to avoid name conflicts (#12468) [backport]
* [backport] Fixes: #12465 - Unittest - Namespace the usage of TestStatus enum to avoid name conflicts.
2019-10-20 08:12:02 +02:00
Araq
0eae2217b6 first implementation of the new --seqsv2 switch 2019-10-20 08:11:07 +02:00
Araq
ed2fb36bc6 refactoring: use the new strings and seqs when optSeqDestructors is active 2019-10-20 08:11:07 +02:00
Araq
61ea85687c refactoring: --newruntime consists of 3 different switches 2019-10-20 08:11:07 +02:00
Ray Imber
91661c16a1 Update changelog.md based on feedback from Dom96 2019-10-19 14:30:10 -07:00
Andreas Rumpf
832b0a0232 fixes #12420 [backport] (#12456) 2019-10-18 22:13:24 +02:00
Tomohiro
6b157e5f73 Fix vcc linker option name (#12422) 2019-10-18 16:20:18 +02:00
Andreas Rumpf
889b745b2b Revert "Fixes #12187 (#12321)" (#12447)
This reverts commit 00c31e8766.
2019-10-18 15:59:22 +02:00
Juan Carlos
f5b4d9a2e5 Fixes #8802 (#12439)
* Fix #8802

* Peer review feedbacks https://github.com/nim-lang/Nim/pull/12439#discussion_r335905397
2019-10-18 14:27:23 +02:00
Juan Carlos
4a0debfe87 Add no-ident for GCC when -d:release (#12454) 2019-10-18 14:13:55 +02:00
Juan Carlos
0a6e0a3f38 Improve htmlgen (#12452) 2019-10-18 12:16:01 +02:00
Miran
a5ab502f08 [backport] fix type's case in random.nim (#12445) 2019-10-17 22:13:00 +02:00
Andreas Rumpf
81125e2029 [backport] add back a check that got accidentically removed; fixes #12379 (#12444) 2019-10-17 20:02:59 +02:00
Juan Carlos
4d1f69c7d2 Fixes #10824 (#12437) 2019-10-17 11:39:01 +02:00
Juan Carlos
2cfd58de48 Fix #10804 (#12438) 2019-10-17 11:37:55 +02:00
Juan Carlos
1ccf1b89c2 Improve jsconsole adding the rest of the stable api as documented on the standard at https://developer.mozilla.org/docs/Web/API/Console (#12440) 2019-10-17 11:37:08 +02:00
Arne Döring
21cbfd72ec Refactor json macro (#12391)
* closes #12316
* make tjsonmacro work at js target
* closes #12289
* closes #11988
* also fixed gdb related stuff
2019-10-17 09:55:41 +02:00
treeform
5ba932e43c About 50% faster base64 implemention. (#12436) 2019-10-17 09:50:00 +02:00
Ray Imber
bec8225448 Updated the changelog 2019-10-16 19:14:18 -07:00
Ray Imber
bef1c4437d fixes based on code review by @dom96
- For clarity: Changed the unregister if statement to use the in operator instead of
the set intersection operator in ioselectors_epoll.nim and
ioselectors_select.nim.

- Fixed unregister of Event.User case on the Android branch.
2019-10-16 14:13:09 -07:00
alaviss
37dfb7ecc6 compiler/options: only check the last folder for a candidate (#12421)
This prevents a nimble file from causing a different project to be
targeted instead of the desired one.
2019-10-16 13:03:11 +02:00
Miran
734da9e1df fixes #11764, faster hashing of (u)int (#12407) 2019-10-15 16:31:07 +02:00
Miran
5f5ac8ce16 [backport] fix #12418, fix random.randomize on JS backend (#12432) 2019-10-15 16:29:32 +02:00
Yuriy Glukhov
1aed455e7c Fixed yield in nkCheckedFieldExpr (#12429) [backport] 2019-10-15 09:16:06 +02:00
narimiran
48975bb3e7 [ci skip] disable two packages until #11764 is merged 2019-10-14 11:51:41 +02:00
Ray Imber
233455a685 Remove unnecessary change to ioselectors_kqueue.nim found by @cheatfate. 2019-10-11 12:24:29 -07:00
Alexander Ivanov
990aadc43c Fixes semCustomPragma when nkSym (#12414) [backport] 2019-10-11 18:05:23 +02:00
alaviss
94c1695be6 compiler/options: improve project file detection (#12404)
The compiler can now correctly find the project file of a nimble package.
The algorithm is based on what used by nim.nvim, which has yielded good
results.
2019-10-11 18:04:52 +02:00
alaviss
f957266574 nimsuggest: add a command that returns the project file (#12411)
This can be used to let nimsuggest users know which project is
nimsuggest being in charge of, so they can know when should a new
nimsuggest instance be spawned.

An additional feature is to debug the project file finding feature.
2019-10-11 18:00:38 +02:00
alaviss
eeffa0163f nimsuggest: add option to force finding the project file (#12409) 2019-10-11 09:55:15 +02:00
Arne Döring
7cf3395d85 refactor illegal iterator assignment detection (#12212)
* refactor illegal iterator assignment detection

* delete crappy test
2019-10-11 08:43:58 +02:00
Jasper Jenkins
245a954b25 ungeneric unsigned ops (#12230)
* ungenericise unsigned ops, remove nimNewShiftOps
* fix/remove tests
* update t6448
* fix line info
* disable on 32bit
* fix different line info
* add changelog entry
2019-10-11 08:38:08 +02:00
genotrance
9e62876647 Fixes #12286 - require explicit disabling of boehm interior pointer checking (#12406) [backport] 2019-10-11 07:39:18 +02:00
Ray Imber
4e6f2b5313 Fix drain to correctly take into account hasPendingOperations and the timeout value 2019-10-10 17:53:44 -07:00
Ray Imber
aa84d35d86 Fix io slector unregister for windows as well. 2019-10-10 16:50:36 -07:00
Euan
45030972b9 #12389: Check working directory for getAppFilename() (#12390)
* Check working directory for exe
* Expand symlinks
* Use expandFilename() to expand symlinks
* Move OpenBSD code to getApplOpenBsd()
2019-10-10 17:28:47 +02:00
Arne Döring
0a29c05a1b fix #12332 (#12402) [backport] 2019-10-10 14:35:26 +02:00
Andreas Rumpf
00e06bba28 minor improvements for htmlgen.nim 2019-10-10 13:47:55 +02:00
Andreas Rumpf
d783c0f7ff fixes a koch regression that made 'koch boot --listcmd' not work anymore [backport] (#12400) 2019-10-10 11:56:01 +02:00
Araq
7f904e2c66 fixes #12244 [backport] 2019-10-10 10:00:57 +02:00
awr1
3b1760df72 [backport] Mention "lambdas" and => in the manual (#12397) [ci skip]
(so that "lambda" can be CTRL+F'd)
2019-10-10 09:28:54 +02:00
Andreas Rumpf
f728614ef8 fixes #12366 [backport] (#12393) 2019-10-09 14:48:42 +02:00
Gampol T
82fe19769a documented behaviour of recv on bufferd socket (#12374) 2019-10-09 10:48:15 +02:00
Nindaleth
84c956d9da fix a few dead links and a missing sentence in documentation (#12387) 2019-10-08 15:24:34 -04:00
Andreas Rumpf
f30da2f266 fixes #12315 [backport]; refs #12314 (#12385) 2019-10-08 20:49:45 +02:00
Clyybber
00c31e8766 Fixes #12187 (#12321)
* Fixes #12187
* Point to fork of compactdict
Since the original repo is now archived / read-only
2019-10-08 14:15:47 +02:00
alaviss
edb24b7ce0 nimsuggest: fix tcp socket leak for epc backend (#12384) [backport]
Same as e9fa4c9b9c, but for the epc
backend which is used by emacs and vscode plugin.

Since the EPC backend only deal with one connection per nimsuggest
instance, only one socket is leaked, thus not as servere as with the tcp
backend.
2019-10-08 14:14:18 +02:00
Ray Imber
7c23522b29 Documentation improvements around the db interface (#12362)
Added more details about the limits and reasoning behind the API.
Came about from this discussion on IRC: https://irclogs.nim-lang.org/04-10-2019.html#16:58:04
2019-10-08 11:24:06 +02:00
Ridho Pratama
7ef4bffa79 renderer letAux fix only for octal literal (#12343)
* renderer letAux fix only for octal literal

* Handle when it's octal -1 for i64

* Added testcases
2019-10-08 11:12:24 +02:00
treeform
dbcffcfccb Easier build instructions for windows - just run build_all.bat. (#12276)
* Easier build instructions for windows.

* title letter

* Update build_all.bat to be like build_all.sh
2019-10-08 11:00:37 +02:00
pietroppeter
89c37fada7 [doc/tut1] removed discard discussion in comments (#12352) 2019-10-08 09:08:38 +02:00
alaviss
e9fa4c9b9c nimsuggest: fix tcp socket leak (#12377) [backport]
A new socket is created for each iteration and leak immediately thanks
to the accept() call replacing the created socket with the client socket.

This commit fixes that.
2019-10-08 08:11:18 +02:00
cooldome
0355c64b92 External file compilation improvement (#12380) 2019-10-08 08:10:55 +02:00
Tomohiro
509f53b782 On windows, os.relativePath returns path as is when roots are different (#12329)
* On windows, os.relativePath returns path as is when roots are different
* Implement os.sameRoot without windows API
* Fix compile error when compiling lib/nimhcr.nim
* Fix compile error when compiling lib/nimhcr.nim on Windows
2019-10-07 19:57:16 +02:00
Ray Imber
b347490f91 lowered the number of events in the test because some CI's have an extremely low FD limit 2019-10-07 10:07:05 -07:00
Federico Ceratto
f9d95fd6a7 Refactor closeEmitter to make it more modular (#12365) 2019-10-07 17:26:27 +02:00
Andreas Rumpf
a60f18d025 fixes #12323 [backport] 2019-10-07 06:47:30 +02:00
Andreas Rumpf
9d000c519a render typeof as typeof 2019-10-07 06:47:30 +02:00
Ray Imber
0338516e70 Additional fix for User key unregister in the KQueue backend 2019-10-06 17:33:58 -07:00
Ray Imber
adc1419499 Test + fix for epoll and kqueue selector modules to properly unregister
event handles that have the key type "User"
2019-10-06 16:02:12 -07:00
Andreas Rumpf
5be8e0b088 VM: no special casing for big endian machines; refs #9690 [backport] (#12364) 2019-10-06 19:28:53 +02:00
Federico Ceratto
a03d8ed4c2 Expose some layouter elements, improve readme (#12361)
Useful for writing linters and static code analysis
2019-10-04 22:43:47 +02:00
Ico Doornekamp
26676066cc added cpuTime to VM (#12346)
* added cpuTime to VM

* Hide VM-time cpuTime() behind --benchmarkVM flag
2019-10-04 19:32:16 +02:00
kraptor
412011eb96 Fix reference to parseSpec proc in readme (#12359) 2019-10-04 19:30:58 +02:00
Hideki Okamoto
294d5fb560 Fixes #12010; Add the description for "cc" option into --fullhelp (#12350) 2019-10-04 19:30:20 +02:00
Miran
2909e41370 [backport] bundle nimpretty on Windows (#12358) 2019-10-04 17:13:04 +02:00
Andreas Rumpf
60d64d1aef use system.move instead of system.shallowCopy if the GC mode requires it 2019-10-04 09:48:45 +02:00
Andreas Rumpf
68ce808db1 minor optimization for asynchttpserver.nim 2019-10-04 09:48:45 +02:00
Andrew Owen
64acc9dbfb [backport] Fix typo in docs (#12356) [ci skip] 2019-10-04 08:40:15 +02:00
Dominik Picheta
4ab9b6146b Change future version number in changelog 2019-10-03 21:26:20 +01:00
Ridho Pratama
678775601a Fixed sizeOf to sizeof (#12347) 2019-10-03 19:38:37 +02:00
Leorize
73c8391fd3 azure: disable failing tests 2019-10-03 18:36:18 +02:00
Leorize
acebcd7899 testament: add azure integration 2019-10-03 18:36:07 +02:00
Leorize
880df4de62 azure-pipelines: add pipelines for linux, mac and win
This is the equivalent to the current AppVeyor + Travis setup.
2019-10-03 18:35:54 +02:00
Andreas Rumpf
c51857f434 fixes #12291 [backport] (#12338) 2019-10-03 07:50:32 +02:00
Ico Doornekamp
982086dbe9 Fixed #12337, leaking pipe after gorge (#12339) 2019-10-03 00:48:31 -04:00
hlaaftana
ba43156363 Sets need copying in JS (#11392)
* Sets need copying in JS
* Fixes #11353
* Add test for #11353
2019-10-02 21:01:59 +02:00
zah
ad13e18c7c system.writeFile has been overloaded to also support openarray[byte] (#12313) 2019-10-02 20:34:03 +02:00
Timothee Cour
2446570350 fixes #12330 (#12331) 2019-10-02 17:57:24 +02:00
Andreas Rumpf
98e76a1058 fixes #12336 [backport] 2019-10-02 17:01:27 +02:00
narimiran
032c3b77db test more packages 2019-10-02 12:35:18 +02:00
Andrew Smith
0d94ee15c0 Updated the code example in the os module to use better grammar. (#12328) 2019-10-02 00:43:38 -04:00
Jasper Jenkins
c20778d2d3 Macro docs additions (#12270)
* small macros doc additions

* more changes

* fixes [ci skip]

* capitalization, couple additions

* nkNodeKind to nnkNodeKind
2019-10-01 08:55:26 -04:00
Clyybber
5f5879dc4c Refactor injectdestructors (#12295)
One improvement over #devel is visible in the transformation of getEnv. With this approach we move to result whenever possible.
2019-10-01 14:09:24 +02:00
Tomohiro
64d5e25821 Fix how relativePath handle case sensitiviy (#12312) [backport] 2019-10-01 09:09:59 +02:00
Andreas Rumpf
6dd4cbc3af fixes #12240 [backport] (#12308) 2019-10-01 05:52:51 +02:00
zah
a4ade43536 macros.newLit now works for ref object types (#12307) 2019-09-30 22:24:57 +02:00
Andreas Rumpf
dd082b6ec8 fixes #12264 [backport] (#12302) 2019-09-30 21:44:24 +02:00
Andreas Rumpf
72acf5de94 fixes #12281 [backport] 2019-09-30 20:42:16 +02:00
Andreas Rumpf
1964589a29 fixes #12294 [backport] 2019-09-30 20:01:25 +02:00
narimiran
5732bb41ef [backport] run nimpretty on the remaining files 2019-09-30 13:58:17 +02:00
narimiran
34d0be2ec1 [backport] run nimpretty on os-related stuff 2019-09-30 13:58:15 +02:00
narimiran
dcf3181bd1 [backport] run nimpretty on string stuff 2019-09-30 13:58:13 +02:00
narimiran
0ca9cc7419 [backport] run nimpretty on web stuff 2019-09-30 13:58:11 +02:00
narimiran
15895ebc3f [backport] run nimpretty on hashes 2019-09-30 13:58:10 +02:00
narimiran
b17ed2ca9c [backport] run nimpretty on parsers 2019-09-30 13:58:08 +02:00
narimiran
6c994b2498 [backport] run nimpretty on numbers stuff 2019-09-30 13:58:05 +02:00
narimiran
aa513d78e7 [backport] run nimpretty on async 2019-09-30 13:57:58 +02:00
Araq
63bcbea700 JS: gensym is stricter for 'this'; refs #12246 [backport] 2019-09-30 13:21:46 +02:00
Araq
c5a1149e00 different fix for #12279 [backport] 2019-09-30 13:11:24 +02:00
Araq
0ecf3806c4 fixes #12298 2019-09-30 12:06:41 +02:00
Araq
86de2cddf6 fixes #12279 [backport] 2019-09-30 10:40:00 +02:00
Clyybber
16c39f9b2e More of StringStream now works at compile time (#12284)
* readLine of StringStream now works at compile time
* Work for js backend only at compile time
* readAll now works at CT
* readAll works in js ct now
* Add test
2019-09-29 22:20:00 +02:00
Clyybber
85db42ad8c Fixes #10514 (#12268)
* Fixes #10514

(cherry picked from commit f6f789bb4d)

* Add comment

* Add changelog entry
2019-09-28 19:50:20 +02:00
Andrey Makarov
5a65243e14 fix nimgrep color on posix #7591 (#12288) 2019-09-28 00:19:57 +02:00
narimiran
f804245087 [backport] fix nimpretty removing space before pragma 2019-09-27 10:36:22 +02:00
narimiran
e0cd52365c [backport] fix #12278, don't expose internal PCRE documentation 2019-09-27 10:13:04 +02:00
narimiran
ce4eb4ac91 Nim now has Patreon account [ci skip] 2019-09-27 08:22:46 +02:00
Federico Ceratto
39290cf88c Fix spellings (#12277) [backport] 2019-09-27 07:02:54 +02:00
Ray Imber
9dd297f613 Locks modules should give a compile error when threads are not enabled. (#12231)
* Locks modules should give a compile error when threads are not enabled.

* fix the compile flags to make the tests pass, or ignore files where necessary.

* Fixed when statement to account for doc builds.
2019-09-26 15:45:50 +02:00
John Paul Adrian Glaubitz
944fcc0e62 Add build support for Linux/hppa (#12271)
* build.sh: Enable CPU detection for hppa
* compiler: Add hppa as target architecture on Linux
* lib/system: Add platform support for hppa
2019-09-26 15:45:05 +02:00
Endeg
657e09e79d Fix #12242, replacing ":" with "@c" in packages [backport] (#12265) 2019-09-25 20:32:36 +02:00
Mathias Stearn
920f9be9aa Explicitly state that trailing underscores are banned (#12257)
It was explicit in the BNF, but the English text implied it was allowed.
2019-09-25 19:12:54 +02:00
Andreas Rumpf
5f44651769 updated the contributing.rst guidelines 2019-09-25 15:01:35 +02:00
narimiran
6b4b329f45 devel version is 1.0.99 [ci skip] 2019-09-25 09:14:38 +02:00
Jjp137
e065e51245 threadpool: fix link in docs [ci skip] (#12258) [backport]
[backport]
2019-09-25 07:12:08 +02:00
treeform
cbefb266bb Fix -d:logGC compile cerror: 'stdout not defined' (#12237) 2019-09-24 12:02:53 +02:00
Jasper Jenkins
b49fb2d90f remove nimnomagic64 (#12243) 2019-09-24 12:02:25 +02:00
Andreas Rumpf
13960066cb fixes the --verbosity:2 regression [backport] 2019-09-24 01:31:03 +02:00
narimiran
f7a8fc46c0 Revert "improvements for httpcore (#12228)"
This reverts commit b865c2a54b.
2019-09-23 19:06:55 +02:00
narimiran
5b43c98897 version 1.0 2019-09-23 14:42:19 +02:00
Andreas Rumpf
f388817a79 update the Nimble version we ship with Nim (#12236) 2019-09-23 14:24:36 +02:00
Andreas Rumpf
b865c2a54b improvements for httpcore (#12228)
* improvements for httpcore
* further improvements, now stable API but needs extensions later on
2019-09-23 12:38:35 +02:00
Ray Imber
6e681b546f fixes #9026 adds a readLineImpl to streams so that FileStreams can be fast (#12234) 2019-09-23 08:25:26 +02:00
PMunch
2565d3d102 Fix issue with long wait for passed timer [bugfix] (#12221)
* Fix issue with long wait for passed timer [bugfix]

This fixes a small issue where a timer that had been completed while
code executed would still wait for more events before being considered
completed. This would in some scenarios incur a 500ms delay to the
completion of a timer.

* Refactor logic into

* Add test case based on original issue

* Use longer timeouts to be more lenient in checking

* Revert to short timeouts, but widen the accepted range

* Widen accepted range further, it is meant to check for a 500ms delay after all

* Increase poll timeout to make it easier to detect mistakes
2019-09-22 07:24:14 +02:00
Andreas Rumpf
39185b46ca living in unix-land, eye to eye, where nothing ever works; fixes #12226 2019-09-21 19:07:25 +02:00
Andreas Rumpf
e0f2b3ba8f documentation updates 2019-09-21 11:53:09 +02:00
Andreas Rumpf
b04ef2973d cleanup importjs implementation 2019-09-21 11:19:09 +02:00
cooldome
be82d11576 fixes #12224 (#12225)
* fixes #12224

* improve test
2019-09-21 06:45:27 +02:00
Andreas Rumpf
c2fced129f makes tests green again 2019-09-21 06:43:37 +02:00
Araq
5abe880469 last stdlib cleanups 2019-09-21 06:43:37 +02:00
Araq
9776f926a2 htmlgen update; don't use deprecated callsite feature 2019-09-21 06:43:37 +02:00
Araq
908b553215 asyndispatch: removed deprecated setEvent proc 2019-09-21 06:43:37 +02:00
Araq
96b3bae99b json: removed deprecatedGet pragma 2019-09-21 06:43:37 +02:00
Araq
a404ec540a updated lib.rst and added some useful missing modules 2019-09-21 06:43:37 +02:00
Araq
dea9e38d26 removed the deprecatedGet pragma 2019-09-21 06:43:37 +02:00
Araq
c623ab62cc updated comment in ast.nim 2019-09-21 06:43:37 +02:00
Araq
f576df2bcc smtp: renamed starttls to startTls 2019-09-21 06:43:37 +02:00
Araq
05e80e1cda lib\pure\htmlgen.nim
avoid callsite for htmlgen
2019-09-21 06:43:37 +02:00
Araq
7839658323 mark events.nim as unstable 2019-09-21 06:43:37 +02:00
Araq
1b20f768c7 lib.rst cleanups and reorderings 2019-09-21 06:43:37 +02:00
Arne Döring
38ab51c445 importjs symbol (#12218)
* importjs symbol
* importjs warning message, minor warning fixes
2019-09-20 20:26:30 +02:00
Andreas Rumpf
7bc5bf8334 consistent floating point output (#12219)
* unify float printing
* makes tests green
2019-09-20 10:41:40 +02:00
Araq
04c803d6df expose more fields of TNimType 2019-09-19 20:54:17 +02:00
Andreas Rumpf
162d74db91 fixes #10981; fixes #7261 (#12217) 2019-09-19 14:34:56 +02:00
treeform
363d0ada50 Update Android and iOS cross compile docs. (#12215)
* Update Cross compilation, add noMain section.

* Small world update, note about XCode clean.
2019-09-19 13:22:07 +02:00
treeform
a948deebb3 Add --os:ios switch and docs. (#12204) 2019-09-18 20:03:51 +02:00
Arne Döring
188ce5f3ee add nodeId proc to macros (#11456)
* add nodeId proc to macros

* add doc comment.

* fix typo
2019-09-18 20:02:30 +02:00
Araq
f8000d4ba1 fixes #12186 2019-09-18 12:16:52 +02:00
Araq
48537fec81 fixes #12209 2019-09-18 12:16:52 +02:00
Arne Döring
638a4d9d9f rename cast opcodes, fix for 32bit cast, fix python pretty printer (#12207) 2019-09-18 09:04:37 +02:00
Vitor Oliveira
93f74e4f93 Fix typo (#12210) [ci skip] 2019-09-18 07:17:38 +02:00
treeform
910ed5888e Add -d:androidNDK to fix echo on Android NDK builds. (#12203)
* Add -d:echoToAndroidLog to fix echo.

* Change to androidNDK and add docs.

* Some word changes to docs.
2019-09-17 23:00:06 +02:00
Miran
618316beb9 fix #12200, cannot 'inc' CountTable by a negative value (#12208)
* fix #12200, cannot 'inc' CountTable by a negative value

* use Positive
2019-09-17 21:29:25 +02:00
Araq
ea8a049af3 fixes the testcase 2019-09-17 15:15:12 +02:00
Araq
c9f3a8b269 added a testcase for #12195; testament now supports a 'timeout' spec field 2019-09-17 15:15:12 +02:00
Araq
f1b7c0494e fixes #12195 2019-09-17 15:15:12 +02:00
Andreas Rumpf
62aa1a3cfe gc:destructors progress 2019-09-16 23:54:31 +02:00
Andreas Rumpf
77c6425e65 gc_common: typo 2019-09-16 23:54:31 +02:00
Andreas Rumpf
754531fff3 make --useVersion's documentation reflect reality 2019-09-16 23:54:31 +02:00
Andreas Rumpf
059a16b34d fixes #12193 (#12199) 2019-09-16 15:38:07 +02:00
Andreas Rumpf
2a59f499e9 some gc:destructors progress 2019-09-16 13:54:58 +02:00
Araq
6c487a6309 fixes #12196 2019-09-16 12:12:44 +02:00
Araq
8b4c17a140 better implementation 2019-09-16 12:12:44 +02:00
Andreas Rumpf
3f87453981 fixes a weird quote do regression 2019-09-16 12:12:44 +02:00
Andreas Rumpf
1c03604ec6 make tests green again 2019-09-13 20:11:01 +02:00
Araq
fd63443419 changed name mangling for generated C files 2019-09-13 19:11:48 +02:00
Araq
5018e7f304 fixes #12172 2019-09-13 18:12:38 +02:00
narimiran
ee6df5bd24 close #7104 by writing a test 2019-09-13 07:59:38 +02:00
narimiran
d79fb77974 close #6731 by writing a test case 2019-09-13 07:46:46 +02:00
Andreas Rumpf
eb241f4241 count 64 bits at a time instead of 8 (#12159)
* count 64 bits at a time

* spacing

* only do 64bts on x86

* add amd64

* use while
2019-09-12 08:20:53 +02:00
Jasper Jenkins
ca7bf3be8b no commas for empty importcpp splat params (#12183) 2019-09-12 08:19:53 +02:00
Brent Pedersen
5b923cd149 use while 2019-09-11 15:40:34 -06:00
Yuriy Glukhov
5783cd67a8 Fixed c filenames mangling (#12161) 2019-09-11 20:47:58 +02:00
Andreas Rumpf
e134a722de fixes #12152 (#12165)
* fixes #12152

* makes test green
2019-09-11 20:28:24 +02:00
Andreas Rumpf
8c81cddf7e fixes #12170 (#12176) 2019-09-11 20:01:09 +02:00
Andreas Rumpf
560eef5bbe fixes #12171 (#12173) 2019-09-11 18:35:13 +02:00
Brent Pedersen
944bab4c3c add amd64 2019-09-11 08:39:33 -06:00
Brent Pedersen
5a520a8454 only do 64bts on x86 2019-09-11 08:35:44 -06:00
Andreas Rumpf
33b8a00aa8 Revert "Refactored injectdestructors.nim (#11926)" (#12169)
This reverts commit 20dec10722.
2019-09-11 15:39:40 +02:00
Arne Döring
c55ceafd9a add tensordsl test (#12166)
* add tensordsl test

* simpler
2019-09-11 13:36:35 +02:00
Araq
99425ff21d fixes #12174 2019-09-11 11:59:12 +02:00
Benny Elgazar
ee36931f26 Fix to the relevant path of the docs. (#12162) 2019-09-10 17:50:03 +02:00
Araq
cf99c9bfb5 fixes #12051 2019-09-10 09:43:37 +02:00
Andreas Rumpf
d363eced3a closureiters.nim: finish the bugfix 2019-09-10 08:50:05 +02:00
Andreas Rumpf
1fa1024ddf typo 2019-09-10 08:36:24 +02:00
Andreas Rumpf
58077450cc parsejson: typo 2019-09-10 08:36:24 +02:00
Yuriy Glukhov
5d9c1544bf Allow ProcTy in addPragma and friends (#12158) 2019-09-10 07:54:51 +02:00
Yuriy Glukhov
60911304b4 Fixed yield in nnkChckRange (#12160) 2019-09-10 07:54:06 +02:00
Brent Pedersen
81c23bba7b spacing 2019-09-09 20:20:35 -06:00
Brent Pedersen
92f2d68802 count 64 bits at a time 2019-09-09 20:00:28 -06:00
Clyybber
ed1d41c51e Small ast.nim cleanup (#12156)
* Remove sonsLen
* Use Indexable
2019-09-09 11:54:15 +02:00
Andreas Rumpf
aa95ae6af9 Merge pull request #12153 from dumjyl/get_type-range
fix range.getType crash
2019-09-08 23:09:41 +02:00
Andreas Rumpf
f915064e07 fix #12130 ; improve naming scheme in fakePackageName (#12149)
* fix #12130 ; improve naming scheme in fakePackageName

* fix tests
2019-09-08 20:33:18 +02:00
Jasper Jenkins
e5139b0662 error for NimNode index kind (#12154) 2019-09-08 20:31:22 +02:00
Araq
18135cc194 proper bugfix 2019-09-08 13:08:41 +02:00
Araq
790f5bac01 added a simple debugging helper 2019-09-08 13:08:41 +02:00
Araq
3255b55266 fixes #11675 2019-09-08 13:08:41 +02:00
Araq
8362d92e47 fixes #12091 2019-09-08 13:08:41 +02:00
Araq
4bbafb47dc streams.nim: indentation change 2019-09-08 13:08:41 +02:00
Timothee Cour
3eb89481cb fix tests 2019-09-06 15:49:25 -07:00
Timothee Cour
4129993689 fix #12130 ; improve naming scheme in fakePackageName 2019-09-06 11:26:48 -07:00
pgkos
5a8fddf29b Fix mode_t posix definitions (fixes #12119) (#12132)
* fixes #12119
2019-09-06 20:15:07 +02:00
Andreas Rumpf
e0f3e8432a fixes a critical --gc:boehm regression 2019-09-06 18:06:08 +02:00
Euan
0e01a5f76c Fix #12133 - use libgc.so.4.0 for OpenBSD (#12134) 2019-09-06 14:31:39 +02:00
Euan
24f52d855c #12141 Define SDL lib name for OpenBSD and FreeBSD (#12143)
* Define SDL lib name for OpenBSD and FreeBSD

* Merge Linux and FreeBSD definitions
2019-09-06 12:57:38 +02:00
Timothee Cour
32769c478b exportc now mangles same as importc, fixes #10578 (#12144)
* fixes #10578
* add tests
* add changelog
* add {.exportcpp.}
2019-09-06 12:54:44 +02:00
Andreas Rumpf
8397554315 fixes #12125 (#12131)
* fixes #12125
2019-09-06 07:23:59 +02:00
Jasper Jenkins
40c5175145 fix range.getType crash 2019-09-05 15:56:44 -07:00
Andreas Rumpf
488f3ed085 fixes yet another gensym regression (#12145) 2019-09-06 00:45:00 +02:00
Araq
0882a09986 fixes a subtle tables.nim regression 2019-09-05 16:45:07 +02:00
Araq
49f63d3aae ic: update to serialize paddingAtEnd 2019-09-05 16:45:07 +02:00
Andreas Rumpf
a5e2db2ac5 allows access to .compileTime vars at runtime (#12128) 2019-09-05 11:56:32 +02:00
Andreas Rumpf
58bcf6cd46 fixes #12121 (#12126) 2019-09-05 08:21:01 +02:00
Andreas Rumpf
c2ba0ee144 Merge pull request #12124 from narimiran/nimsuggest-108
fixes nimsuggest/#108: RangeError with d:release
2019-09-05 00:31:37 +02:00
narimiran
92c012d86d fix commands for testing packages 2019-09-04 14:58:22 +02:00
narimiran
a9c7fb2fcc fixes nimsuggest/#108: RangeError with d:release 2019-09-04 13:31:59 +02:00
Araq
fa5707e7e2 fixes #11713, fixes #1034 2019-09-04 11:20:30 +02:00
Andreas Rumpf
cb0450398a introduce --oldgensym:on rather than --useVersion 2019-09-03 20:15:27 +02:00
Andreas Rumpf
07a986afa1 disable IC and the SQLite dependency for version 1 2019-09-03 18:43:57 +02:00
Andreas Rumpf
ea1a26294f prepare sqlite3 wrapper for static linking 2019-09-03 18:43:23 +02:00
Andreas Rumpf
459fbb9525 appveyor config: don't stop after testing failures; keep testing Nimble packages 2019-09-03 17:24:57 +02:00
Andreas Rumpf
4972d797e4 gcbench: better memory usage report 2019-09-03 12:39:49 +02:00
Chris Heller
35f1519ad6 Add delOutputFormatter proc to unittest.nim (#12032) 2019-09-03 08:14:19 +01:00
Andreas Rumpf
79f1b8592a Merge pull request #12107 from nim-lang/uint-range-checks
Uint range checks
2019-09-03 07:47:56 +02:00
Andreas Rumpf
ac6fcab7a4 Merge branch 'devel' into uint-range-checks 2019-09-02 22:03:10 +02:00
Andreas Rumpf
d70e292571 makes more tests green 2019-09-02 22:03:06 +02:00
Andreas Rumpf
5a03eea518 revert #12100; typeof(nil) is weird enough, don't allow it as the return type 2019-09-02 17:48:06 +02:00
narimiran
545ddf4a4f mark nimprof as used when profiling 2019-09-02 16:00:26 +02:00
Andreas Rumpf
f8f96d816c sink as lvalue (#12108) 2019-09-02 15:49:01 +02:00
Andreas Rumpf
7ef85db9a9 fixes #12020 (#12106) 2019-09-02 15:47:56 +02:00
Araq
18ca1788f0 makes test green again 2019-09-02 14:23:05 +02:00
Araq
fc7fe636e2 improvement for 'unused import' warnings 2019-09-02 12:49:31 +02:00
Araq
23c44f009a weaking unsigned/signed indexing requirements in order to not break too much existing code 2019-09-02 12:07:36 +02:00
Arne Döring
3d4ad9739c fix min/max for float numbers (#12068) 2019-09-02 11:21:26 +02:00
Andrii Riabushenko
ba18c12005 sink as lvalue 2019-09-02 10:11:51 +01:00
Araq
755c4428fe added more tests and updated the changelog 2019-09-02 11:03:08 +02:00
Araq
2396f0ee71 make test green 2019-09-02 10:56:51 +02:00
Araq
e765687646 Merge branch 'devel' into uint-range-checks 2019-09-02 10:27:35 +02:00
Araq
e6ec88d4c3 renamed and moved test 2019-09-02 10:27:33 +02:00
Araq
ad82e65387 gc:destructors progress 2019-09-01 23:28:26 +02:00
Miran
ab48d7901e hashes: implement murmur3 (#12022)
* hashes: implement murmur3
* refactoring; there is only one murmurHash and it works at compile-time via VM hooks
* fixes JS tests
* makes toOpenArrayByte work with C++
* make it bootstrap in C++ mode for 0.20
2019-09-01 00:04:10 +02:00
Oscar Nihlgård
35268c500f Fix int literals and range interaction (#11197)
* Fix int literals and range interaction

* Fix test

* remove float range fix; update changelog
2019-08-31 19:34:08 +02:00
Arne Döring
6e01be34ef fixes #11903 (#11908) 2019-08-31 19:32:59 +02:00
Andreas Rumpf
326a333c8b Merge pull request #12099 from cooldome/destructor_too_late
fixes #12092
2019-08-31 19:25:19 +02:00
Andreas Rumpf
15213028b7 Return typeof(nil) (#12100)
* Allow typeof(nil) as a return type

* $typeof(nil) is now "typeof(nil)", not "nil"
2019-08-31 19:24:44 +02:00
cooldome
2b565aad89 Support iterators returning lent T (#11938)
* lent iterators
* rebase tests
* update changelog
* fix comments, more tests
2019-08-31 19:23:54 +02:00
Albert Safin
a6428657e9 $typeof(nil) is now "typeof(nil)", not "nil" 2019-08-31 10:16:26 +00:00
Albert Safin
efe1bed82e Allow typeof(nil) as a return type 2019-08-31 10:16:26 +00:00
Andrii Riabushenko
a388c35741 support forward declared destructors 2019-08-31 09:56:39 +01:00
Andrii Riabushenko
a055f628f4 fixes #12092 2019-08-31 09:49:47 +01:00
Timothee Cour
9ae0dd611f typeToString can now show (recursively) resolved type aliases; fixes #8569 #8083 #8570 (#11678)
* nested typeToString
* typeToString: preferResolved
* add test
* fix test
* preferMixed
* fix tests
2019-08-31 08:26:45 +02:00
Clyybber
f9600b7207 Remove ENDB (#12095) 2019-08-31 07:44:53 +02:00
Andreas Rumpf
82d5e773e3 make testament a tool we ship with Nim; fixes #12084 (#12088)
* make testament a tool we ship with Nim; fixes #12084
* moved config to fit
* adapt testament tests to use the testament binary
2019-08-30 15:43:07 +02:00
narimiran
25581c796f enable testing of more packages 2019-08-30 08:47:58 +02:00
Clyybber
029dcc6259 fix #12037 (#12089) 2019-08-30 06:41:26 +02:00
Andreas Rumpf
2a3b056314 fixes #12042 (#12083)
* fixes #12042

* make tests green again
2019-08-29 19:09:54 +02:00
Araq
d0e5bd2305 fixes a critical type checking regression 2019-08-29 12:10:31 +02:00
Andreas Rumpf
9203d3a982 fixes 5870 (#11704)
* fixes #5870
* make tclosure test green again
* this check is correct but breaks some Nimble packages
2019-08-29 07:49:58 +02:00
Andreas Rumpf
cd106cf680 fixes #12074 (#12080) 2019-08-29 07:43:35 +02:00
Andreas Rumpf
5f7a6aff06 fixes #11941 (#12079) 2019-08-29 00:35:05 +02:00
Andreas Rumpf
21fc8b4d4d refactor sizealignoffset (#12077)
* small refactoring
* refactor computeObjectOffsetFoldFunction with AccumObject
* refactor packed object offstes fold function
* refactor compute union object offsets fold function
* merge normal/packed object offset fold function
* compiletime offsetof in c++ inheritance objects
* enable c++ inheritance offsetof tests
* correct alignment for big sets/enums on weird 32bit platforms
* uncomputedSize -> unknownSize
* workaround for travis
* fixes win32 alignment problems
2019-08-28 19:36:29 +02:00
Jacek Sieka
42d2e68bca only store finally block in exception stack (#11876) 2019-08-28 12:08:54 +02:00
cooldome
c9f49cbc0a lift destructor for openarray (#12073)
* destroy for sink openarray
2019-08-28 12:07:46 +02:00
Ico Doornekamp
84351da9d8 Fixes #12044 (#12071) 2019-08-28 12:05:07 +02:00
Andreas Rumpf
d4af0554c4 remove unicode.Rune16 without deprecation period; fixes https://github.com/nim-lang/RFCs/issues/151 (#12072) 2019-08-28 10:25:13 +02:00
Clyybber
20dec10722 Refactored injectdestructors.nim (#11926)
One improvement over #devel is visible in the transformation of getEnv. With this approach we move to result whenever possible.
2019-08-28 00:02:48 +02:00
Andreas Rumpf
eaebbfa785 Fix several float range issues (supersedes #11905) (#12067)
* Fix several float range issues

* address the comments
2019-08-27 23:19:41 +02:00
Arne Döring
d564130a3b Fix to int to biggest int (#12066)
* fix to(Biggest)Int
* kill toFloat magics as well
2019-08-27 23:18:46 +02:00
Vindaar
eff0837ff4 fixes #12015 by also checking kind of typeNode (#12016)
* fixes #12015 by also checking kind of `typeNode`

If a tuple field is aliased it'll appear the same as a ref type in a
call to `getType` if only for the kind of the resulting `NimNode` is
checked (that is a `nnkBracketExpr`)

* fix test case due to #12017 and add more realistic test case

Adds an additional test case, which includes generics and is closer to
the real failure I encountered

* remove previous fix and fix differently after all

The previous fix was incomplete, because it failed for generics.

Note that the `of "tuple"` is not actually needed, the
`nnkBracketExpr` branch in the `else` branch would catch it too, but I
decided to introduce it for clarity. However, the latter is actually
needed, because it seems for aliases of `seq` we end up in it.

* update comment about global `%` proc in json test
2019-08-27 22:23:47 +02:00
Andreas Rumpf
00d46ca1c0 fixes #12024 (#12065) 2019-08-27 20:05:40 +02:00
Andreas Rumpf
114da04cbb fixes #12029; finish the 'unused import' feature (#12064) 2019-08-27 19:18:56 +02:00
Artem V L
d8177a3980 Typos fixed, handleRefillChar() described (#12062) 2019-08-27 16:16:32 +02:00
Andreas Rumpf
8df745a42e fixes #12056 (#12063) 2019-08-27 16:15:37 +02:00
narimiran
3f5599b344 disable testing of 'norm' package 2019-08-27 15:03:06 +02:00
narimiran
329e169e96 address the comments 2019-08-27 14:49:32 +02:00
Oscar Nihlgård
def6234903 Fix several float range issues 2019-08-27 14:45:19 +02:00
Jacek Sieka
66a8856152 abort is noreturn (#12061) 2019-08-27 14:27:44 +02:00
Arne Döring
ab8241ad42 minor stuff 2019-08-27 12:28:18 +02:00
Araq
1ccff0324c manual: more precise rules about evaluation order 2019-08-27 12:13:06 +02:00
Araq
ddc155af64 fixes #12040 2019-08-27 10:20:12 +02:00
Andreas Rumpf
b044523c5a fixes 9195 (#12055) 2019-08-27 10:07:42 +02:00
Andreas Rumpf
5a9edb222b unicode.nim: fixed spacing to something sane 2019-08-26 23:30:35 +02:00
Andreas Rumpf
97d77bf37e semtypes.nim: more refactorings for liftParamType 2019-08-26 23:30:35 +02:00
Andreas Rumpf
0c41fd0f50 semtypes.nim: little refactoring for liftParamType 2019-08-26 23:30:35 +02:00
Andreas Rumpf
d8d2a9e985 manual: better documentation for implicit generics 2019-08-26 23:30:35 +02:00
Dominik Picheta
8117a949c5 Remove old and unused parseBody/parseResponse procs in httpclient. (#11949) 2019-08-26 20:27:44 +02:00
Arne Döring
ae9bb4474b fixes #12033 (#12039) 2019-08-26 20:14:21 +02:00
Palash Nigam
88814bbe98 fixes #11832 (#12049) 2019-08-26 20:13:41 +02:00
Andreas Rumpf
931ee0ca82 fixes #7258 (#12054) 2019-08-26 20:12:22 +02:00
Viktor Kirilov
5df7d72afe HCR: tests for the fixes for #11608 and #11996 (#12047)
* tests for #11996 and #11608

* removed unnecessary comment
2019-08-26 20:08:18 +02:00
nc-x
73dd73f961 [ci skip] Add note to nimhcr.nim (#12050) 2019-08-26 19:20:24 +02:00
Andreas Rumpf
ce7f29e8e6 fixes #11833 (#12018) 2019-08-24 06:25:47 +02:00
Viktor Kirilov
f2e8c39e85 - adding _actual as a suffix only for calls to an actual proc and not through a global function pointer - fixes https://github.com/nim-lang/Nim/issues/11996 (#12007)
- adding forward declarations for reloadable functions within a module - fix compilation errors when 2 such functions reference each other - fixes https://github.com/nim-lang/Nim/issues/11608
- preserve permissions of copied executable binaries
2019-08-23 22:50:34 +02:00
Andreas Rumpf
547fcd69c3 rdstdin: remove cruft that shouldn't have been exported or added (#12014) 2019-08-23 21:34:22 +02:00
Andreas Rumpf
c3c5839329 Add build support for FreeBSD/PowerPC64 (#12011)
* Add build support for FreeBSD PowerPC64

* Add build support for FreeBSD PowerPC64

* Add build support for FreeBSD PowerPC64
2019-08-23 18:59:52 +02:00
Andreas Rumpf
fbb2763204 fixes #11958 (#12013) 2019-08-23 18:58:55 +02:00
Andreas Rumpf
b07694cd90 new gensym handling (#11985)
* new .gensym implementation
* make astspec test green again
* introduce a --useVersion switch to group compatibility switches
* fixes #10180
* fixes #11494 
* fixes #11483
* object constructor fields and named parameters are also not gensym'ed
* disabled broken package
2019-08-23 16:15:02 +02:00
lenoil98
2212a90458 Add build support for FreeBSD PowerPC64 2019-08-23 07:56:56 -04:00
lenoil98
e1539c7344 Add build support for FreeBSD PowerPC64 2019-08-23 07:54:02 -04:00
lenoil98
806f3b592f Add build support for FreeBSD PowerPC64 2019-08-23 07:50:50 -04:00
Palash Nigam
f28a47ea7b fixes #11834 (#12000) 2019-08-23 07:42:33 +02:00
Andreas Rumpf
9aad99bdfd closes #7117 2019-08-22 19:08:35 +02:00
Andreas Rumpf
085fbcea6f fixes #10854 2019-08-22 18:57:41 +02:00
Andreas Rumpf
9eee15f668 thavlak: code style changes 2019-08-21 22:03:04 +02:00
Federico Ceratto
170cb4f4cb Update OpenSSL example (#11896)
* Update OpenSSL example

Fix privkey filename.
Bump up RSA key size.
Add ECDSA example.
2019-08-21 20:01:17 +02:00
Arne Döring
a562de2d91 squashed and merged with devel 2019-08-21 19:24:36 +02:00
Timothee Cour
2b2efe3dbe fix compiletimeFFI (#11991) 2019-08-21 09:28:16 +02:00
Arne Döring
5304b16a55 Fix typos. Apply title case. (#11987) 2019-08-21 00:04:01 +02:00
Oscar Nihlgård
4264e9576d Consider range type of runtime discrim [feature] (#11432) 2019-08-20 17:39:49 +02:00
Andreas Rumpf
d00c8febee Nimpretty: fix #11937 (#11978)
* cosmetic improvements

* remove unused imports
* make 'openPars' and 'closedPars' more readable

* nimpretty: fix #11937 (wrong indentation)
2019-08-20 16:03:04 +02:00
Araq
b1b0960c36 fixes #11972 2019-08-20 15:47:04 +02:00
Miran
75baaa5e25 nim check, fix #11927, no more empty strings (#11979) 2019-08-19 22:25:21 +02:00
narimiran
ceb742351a nimpretty: fix #11937 (wrong indentation) 2019-08-19 13:35:10 +02:00
narimiran
cf4390a24a cosmetic improvements
* remove unused imports
* make 'openPars' and 'closedPars' more readable
2019-08-19 13:29:45 +02:00
Andreas Rumpf
742862b847 more enhancements for #11618 (#11976)
* finish the Windows IO layer changes; refs #11618
* added system.getOsFileHandle which is less error-prone on Windows
* make tests green again
2019-08-18 22:57:56 +02:00
nc-x
ac7a365137 Fix HCR crash because certain procs were hcrGetProc'ed before being hcrRegisterProc'ed (#11971) 2019-08-18 14:16:51 +02:00
nc-x
d5840e1e3d Implement isExported for symbols in macros (#11963)
* Implement isExported for macros

* Reimplement isExported using VM callback mechanism

* VM does not support exceptions, use stacktrace() instead.
2019-08-18 11:51:28 +02:00
Andreas Rumpf
7cb31455ee fixes #11618 (#11969) 2019-08-17 21:19:57 +02:00
nc-x
b68380f09b fixes #11872; include now gives a proper error message for all invalid infix operators (#11965) 2019-08-17 19:45:47 +02:00
Andreas Rumpf
db9e27dffd Fixes #11118 (#11964)
* fixes #11118

* Reset closure iter exception before rethrowing
2019-08-17 10:37:38 +02:00
nc-x
cf09ef47b8 Remove duplicate line number from 'invalid forward declaration' error (#11966) 2019-08-17 10:35:25 +02:00
Andreas Rumpf
15e681ce66 fixes 'e' command handling; now only does what advopt.txt claims it does (#11961)
* fixes 'e' command handling; now only does what advopt.txt claims it does
* address Timothee's remark
2019-08-16 18:19:30 +02:00
Yuriy Glukhov
721ca3e830 Reset closure iter exception before rethrowing 2019-08-16 17:26:00 +02:00
Araq
39f4a3e418 fixes #11801 2019-08-16 15:20:39 +02:00
Araq
b9dd972c32 fixes #11770 2019-08-16 14:48:32 +02:00
Araq
7023241aaf fixes #11819 2019-08-16 14:37:52 +02:00
Araq
bebda3851f fixes #1188 2019-08-16 13:29:58 +02:00
Araq
c7e77edecc fixes #11925 2019-08-16 12:33:31 +02:00
Andreas Rumpf
ba577c7e1b better tojsstr (#11954)
* JS: rewrote toJSStr
* JS: don't raise exceptions in primitives
2019-08-16 12:18:51 +02:00
Timothee Cour
cf22dec584 genSym symbols rendered as b1_416049 instead of b1416049 (#11960) 2019-08-16 12:17:20 +02:00
Araq
1fb9a6d946 added destructors.rst spec to the build documentation 2019-08-16 12:14:39 +02:00
Yuriy Glukhov
d31404ac27 Merge branch 'cpp_reraise_fix' into yield-in-try-fix 2019-08-16 10:25:09 +02:00
Timothee Cour
922e2a5098 refs #11956 (#11957) 2019-08-16 07:19:34 +02:00
Timothee Cour
511298242d fixes #10053 (#11951) 2019-08-15 15:55:48 +02:00
pgkos
296dfae8af Fixes splitfile (#11918) [bugfix] 2019-08-15 15:22:14 +02:00
Dominik Picheta
b095203f28 Fixes regression introduced by #11904. (#11948) 2019-08-15 06:05:38 +02:00
Timothee Cour
630e18a6eb refs #11947; FieldError fixed (#11950) 2019-08-15 06:04:38 +02:00
Arne Döring
a25d43ca6b fix warnings in system.nim (#11944) 2019-08-14 17:48:11 +02:00
Arne Döring
65ed2d7fe8 fixes #11942 (#11945) 2019-08-14 17:41:44 +02:00
Clyybber
e6cb7e34ef Make name mangling reversable unambiguously (#11939) [bugfix] 2019-08-14 08:11:50 +02:00
cooldome
5ef62fcb25 newruntime for vcc (#11934) [bugfix] 2019-08-14 08:10:59 +02:00
narimiran
1874b3e786 [nobackport] add a changelog entry for the previous commit 2019-08-13 07:38:07 +02:00
Fabian Keller
83397a69fc Consistent behavior of exec; Improved docs around exec, staticExec, gorgeEx, etc. (#10967)
* improved docs around exec, staticExec, gorgeEx, etc.
* incorporate review comment; made behavior of exec consistent
2019-08-13 07:41:08 +02:00
Andreas Rumpf
433613e267 fixes #11844 (#11935) 2019-08-13 06:37:37 +02:00
Araq
322ce1872f fixes #10689 2019-08-12 14:06:48 +02:00
Araq
289b5e9ef9 fixes #11254 2019-08-12 13:58:35 +02:00
sschwarzer
c9c28bf85e Update documentation on xmltree.items/mitems (#11930)
* Update documentation on `xmltree.items`/`mitems`

So far the documentation on `items` and `mitems` wasn't explicit about whether the iteration recurses down the node's children or not. I assumed recursion, which was wrong.

* Improve wording in comment

Use the more common and shorter word "direct".
2019-08-12 11:12:22 +02:00
Andreas Rumpf
da64c8762f destructors: spec reflects reality, =sink is here to stay 2019-08-11 21:55:47 +02:00
Andreas Rumpf
212ae2f125 fixes #11891 2019-08-10 15:41:24 +02:00
Araq
0e4a8bfb28 fixes 'unused module' feature for 32 bit builds of Nim for good [nobackport] 2019-08-09 16:38:10 +02:00
Araq
da37177ac2 make tests green again on 32bit systems 2019-08-09 10:12:32 +02:00
Andreas Rumpf
3b8f721460 merged #11813 manually [bugfix] 2019-08-08 23:09:27 +02:00
Zachary Carter
082c440f13 Fixes effect error in pure/logging.nim (#11898)
* Fix effect error in pure/logging.nim

Currently calling `logging.log` will produce - `Error: can have an unlisted effect: RootEffect`. Add `RootEffect` to list of tags.

* the only tag necessary is RootEffect since all other Effects are descendants of RootEffect
2019-08-08 22:48:25 +02:00
Andreas Rumpf
81ddc67785 [refactoring] compiler: simplified markUsed 2019-08-08 22:43:58 +02:00
Andreas Rumpf
04708742e7 fixes #11809 2019-08-08 21:41:05 +02:00
Andreas Rumpf
e3c0bf48c5 tiny style change [refactoring] 2019-08-08 18:30:10 +02:00
Andreas Rumpf
0d5bd7e8b5 removed unused imports [refactoring] 2019-08-08 17:03:19 +02:00
Arne Döring
44e7a7b6c2 Lock semchecked ast for macros (#11883) [bugfix]
* reject to modify type checked AST
* add flag to back out
* Introduce legacy feature set.
2019-08-08 16:57:06 +02:00
Timothee Cour
fda51b6ca2 fix crash on sigmatch (#11913) 2019-08-08 14:41:23 +02:00
Dmitry Matveyev
756fabb979 Fix typo (#11910) 2019-08-08 13:17:53 +02:00
Arne Döring
48968f3c84 delete expensive call (#11909) [refactoring] 2019-08-08 09:16:07 +02:00
konradmb
addd7b5e20 Fix issue #10726 - HTTP response without Content-Length is not accessible (#11904)
* Add patch by @xenogenesi

* Async test for HTTP/1.1 without Content-Length

* Apply suggestions from code review

Co-Authored-By: Dominik Picheta <dominikpicheta@googlemail.com>
2019-08-08 08:41:56 +02:00
Andreas Rumpf
c8cffaf420 Incremental compilation (IC): Improvements (#11881)
* IC: C codegen is aware of IC
* manual: minor change to make VSCode's RST plugin render it properly
* IC: minor refactoring
* testament: code refactorings
* rodutils: removed dead code
* IC: always build the compiler with the IC feature
* IC: C codegen improvements
* IC: implement the undocumented -d:nimMustCache option for testing purposes
* IC: added first basic tests
* IC: extensive testing of the deserialization feature
* testament: refactoring; better IC tests
* IC: removes 'nimMustCache' flag; readonly does the same
* testament: minor refactoring
* update Nimble version
* testament: removed dead code and imports; IC: added simple test
* IC: progress
2019-08-08 08:41:05 +02:00
Andreas Rumpf
c0d240b8cd fixes #11807 (#11900)
* fixes #11807
* make tests green again
2019-08-07 22:40:58 +02:00
amzak
f34ae81971 Fixed handling of empty strings for encodings conversions (#11897) 2019-08-07 19:56:42 +02:00
awr1
9321b33cd2 Typeclass/Variant clarification in Manual (#11901)
* [Docs] clarified what type classes do in manual

* [Docs] fixed 'dynamism', added to object variant section
2019-08-07 16:03:32 +02:00
Arne Döring
afbcd1b330 int128 on firstOrd, lastOrd and lengthOrd (#11701)
* fixes #11847
2019-08-07 15:53:16 +02:00
Andy Davidoff
8407a57499 note set[T].len alias in future changelog (#11893)
per comments in #11885
2019-08-06 21:07:26 +02:00
amzak
3d7d5cf121 Fixed utf8<->utf16 conversions on windows (#11888) 2019-08-06 03:30:47 -04:00
Arne Döring
ce148e71ef disallow static in return type (#9686) [nobackport] 2019-08-06 01:26:53 +02:00
Andreas Rumpf
42e83ac24c fixes #11817 (#11889) 2019-08-05 16:48:26 +02:00
Andy Davidoff
d208d7a995 set[T].len is an alias for set[T].card (#11885) [feature] 2019-08-05 14:27:45 +02:00
Araq
61c66abbfe newruntime: make system.delete and friends work with owned ref (bugfix); reported on the forum 2019-08-05 00:14:30 +02:00
Araq
7024bb800c fixes #11844 2019-08-04 23:54:29 +02:00
John Paul Adrian Glaubitz
65d1140d11 Add build support for Linux/ia64 (#11880) [feature]
* compiler: Add ia64 as target architecture on Linux
* build.sh: Enable CPU detection for ia64
2019-08-04 23:16:30 +02:00
Arne Döring
b73d097d36 fixes #9829 (#11849) 2019-08-04 19:31:55 +02:00
Chris Heller
343ace8194 Skip db_postgres.setRow if getRow returns 0 rows (#11859)
Fixes nim-lang/Nim#11821
2019-08-04 19:28:24 +02:00
Leorize
51d998390c tgetaddrinfo: disable ICMP tests for Haiku
They're not supported by Haiku's getaddrinfo()
2019-08-04 12:15:17 +01:00
Leorize
df32c45757 tgetaddrinfo: use sizeof() instead of hardcoding
OS like Haiku have a bigger sockaddr_in struct for legacy(?) reasons.
Using sizeof() should account for the different struct sizes.
2019-08-04 12:15:17 +01:00
Oscar Nihlgård
bcfb540e57 Allow typeof(nil) as generic parameter (#11869) 2019-08-03 10:16:07 +02:00
Oscar Nihlgård
50e921bb94 VM exception fixes (#11868) 2019-08-02 22:59:04 +01:00
Jjp137
a906b3952b random: minor documentation updates (#11831)
Add docs for the sample procs that take in sets, and clean up a
few other minor things.
2019-08-02 02:42:18 -04:00
Oscar Nihlgård
829f719670 Fix VM conversion to var type [bugfix] (#11866) 2019-08-01 17:44:12 +02:00
Arne Döring
803406d07c fix #11854 (#11857) 2019-07-30 17:24:42 +02:00
Dominik Picheta
bb949a75db Fixes subtle SSL recvInto bug.
This resulted in a "value out of range: -1" exception inside `recvInto`
(on the `copyMem` line). Basically readIntoBuf was returning `-1`.
2019-07-27 19:06:56 +01:00
Andreas Rumpf
ceb1a1b688 IR: minor refactoring 2019-07-27 14:01:28 +02:00
Andreas Rumpf
f58d87cb43 IC: some progress 2019-07-27 14:01:28 +02:00
Andreas Rumpf
c9c8fa99cc destructors spec: be more precise about temporaries 2019-07-27 14:01:28 +02:00
Andreas Rumpf
b9c15371a3 nimgrep: introduce the --rex option 2019-07-27 14:01:28 +02:00
Andreas Rumpf
f7c99838e2 nimgrep: fixes the -w option 2019-07-27 14:01:28 +02:00
Andreas Rumpf
25e6c53bb5 makes the -d:nimIncremental compiler mode compile again 2019-07-27 14:01:28 +02:00
Arne Döring
1a77040278 fix #11812 (#11829)
* fixes #11812
* fixes #10899
* fixes #11367
2019-07-27 07:21:47 +02:00
Giovanni Petrantoni
2fdba334da Use proper types according to MSDN and fix clang build of windows dynlib (#11828) 2019-07-26 10:11:21 +02:00
Andrii Riabushenko
4c73139316 revert changes 2019-07-25 23:18:20 +01:00
Andrii Riabushenko
95856ab8d3 add test 2019-07-25 23:07:43 +01:00
Andrii Riabushenko
d7bc4e43a2 fixes #11826 2019-07-25 23:02:04 +01:00
Miran
3bb6d1916e fix #11772, JS random seed was too large (#11820) 2019-07-25 04:53:50 -04:00
narimiran
3ccda773d6 close #11166 by adding a test 2019-07-25 10:05:02 +02:00
narimiran
13190435a6 close #9891 by adding a test 2019-07-25 09:25:18 +02:00
genotrance
44aadd50cf Fix #10630 - fix broken separators in nim doc (#11814) 2019-07-24 14:45:05 +02:00
narimiran
5484352d26 fix asyncftpclient examples [ci skip] 2019-07-24 11:49:06 +02:00
Timothee Cour
8c93c692b9 run runnableExamples in the module scope (#11732) [feature] 2019-07-22 16:22:57 +02:00
narimiran
30f2cec671 fix failing JS tests 2019-07-22 11:41:20 +02:00
Benjamin Summerton
46f2271968 Add opacity to JS Style
I noticed this was missing.  It has cross browser support: https://developer.mozilla.org/en-US/docs/Web/CSS/opacity#Browser_compatibility
2019-07-21 23:15:36 +01:00
cooldome
d563efb719 fixes #11792 (#11793) 2019-07-21 16:53:22 +02:00
Araq
67a6effb7b fixes #11745 2019-07-19 22:38:35 +02:00
Araq
affe1be47c fixes #11790 [nobackport] 2019-07-19 22:24:56 +02:00
Araq
dc38b88f7e bugfix: it should be [UnusedImport] [nobackport] 2019-07-19 19:33:56 +02:00
Araq
1868cbc449 revert the bugfix for #11747 as it really was a new, poorly though-out feature 2019-07-19 19:32:13 +02:00
Araq
5a020d641d style improvements; fixes #11774 2019-07-19 17:25:04 +02:00
Araq
313cc337f2 fixes a 'nim check' regression 2019-07-19 17:09:11 +02:00
Araq
de69e1856f installer: ship nimpretty.exe on Windows 2019-07-19 16:48:27 +02:00
Andreas Rumpf
70e8551e37 async macro: general stability improvements [bugfix] (#11787) 2019-07-19 16:47:38 +02:00
Jörg Wollenschläger
903d06bab8 Fix the range of destroyed elements when shrinking a seq (#11785) 2019-07-19 16:46:47 +02:00
Andreas Rumpf
a5d6080a81 Merge pull request #11766 from nim-lang/araq-detect-unused-imports
[feature] detect unused imports
2019-07-19 01:06:45 +02:00
Andreas Rumpf
fbb0642e27 Merge branch 'devel' into araq-detect-unused-imports 2019-07-18 18:16:32 +02:00
Andreas Rumpf
9852cf804b warn about unused imports; fixes an 'export' regression [nobackport] 2019-07-18 18:16:25 +02:00
Araq
6d8913ee14 nimpretty: fixes #11616 2019-07-18 12:13:22 +02:00
Araq
7deb49e992 nimpretty: fixes #11699 2019-07-18 11:28:25 +02:00
Araq
5b7273b4f8 [refactoring] nimpretty 2019-07-18 11:00:29 +02:00
Andreas Rumpf
4becd5a2a8 Merge pull request #11771 from nim-lang/araq-remove-unused-imports
[refactoring] remove unused imports in the compiler and in some stdli…
2019-07-18 08:48:11 +02:00
Araq
07d465ca42 [refactoring] remove unused imports in the compiler and in some stdlib modules 2019-07-18 00:36:03 +02:00
Araq
4137a4dbf3 [feature] detect unused imports 2019-07-17 22:36:23 +02:00
narimiran
f50e4500c2 update changelogs [ci skip] 2019-07-17 21:20:28 +02:00
Andreas Rumpf
745669ac25 fixes #11758 [nobackport] 2019-07-17 20:06:10 +02:00
Kaushal Modi
d40872bf9b [bugfix] Make std/unicode compile with --styleCheck:error (#11763) 2019-07-17 19:48:15 +02:00
Kaushal Modi
404b224945 [bugfix] Make std/unittest compile with --styleCheck:error (#11762) 2019-07-17 19:47:50 +02:00
Andreas Rumpf
210988c532 [refactoring] don't use 'defer' 2019-07-17 16:36:40 +02:00
Andreas Rumpf
1acb9bae94 Merge pull request #11743 from GULPF/stdlib-monotimes [feature]
Use std/monotimes in the stdlib [feature]
2019-07-17 16:06:34 +02:00
Andreas Rumpf
e11494f1cf Merge pull request #11680 from timotheecour/pr_fix_sigmatch_errmsg
fixes #8305; fixes #7808; fixes #10285; fixes #11061 + other bugs with type mismatch error msgs
2019-07-17 16:01:44 +02:00
Andreas Rumpf
326860e84c Merge pull request #11751 from nim-lang/araq-fixes-11474
fixes #11747
2019-07-17 15:21:07 +02:00
Andreas Rumpf
15d2a92be0 fixes #11747 2019-07-17 15:19:25 +02:00
Andreas Rumpf
bae08d0961 Merge pull request #11753 from kaushalmodi/fix-compilation-warning-in-macros
[bugfix] Fix compilation warning in macros.nim
2019-07-17 15:17:45 +02:00
Andreas Rumpf
43940294c5 fixes a critical 'nim secret' regression 2019-07-17 15:10:02 +02:00
Kaushal Modi
44d80dd863 [bugfix] critbits styleCheck fix: consistent var naming (#11752) 2019-07-16 21:24:09 +02:00
Kaushal Modi
3f7142fcfd [bugfix] openssl styleCheck fix: consistent var naming (#11750) 2019-07-16 21:23:12 +02:00
Kaushal Modi
0b511b15ea styleCheck fix: type naming: s/outType/OutType/ (#11749) 2019-07-16 21:22:34 +02:00
Kaushal Modi
dcbb2d66da Fix compilation warning in macros.nim
Fixes:

> macros.nim(1423, 35) Warning: `typed` will change its meaning in future versions of
  Nim. `void` or no return type declaration at all has the same
  meaning as the current meaning of `typed` as return type declaration. [Deprecated]
2019-07-16 15:03:44 -04:00
Oscar Nihlgård
1f32498a47 Use std/monotimes in the stdlib 2019-07-16 11:05:42 +02:00
Andreas Rumpf
102b71f42e Merge pull request #11740 from nim-lang/araq-fixes-11723
fixes #11723
2019-07-16 09:08:15 +02:00
Tristano Ajmone
8550a8127c Fix Typos in Internal Docs (#11735) [ci skip] 2019-07-15 19:05:23 +02:00
Araq
76f9ddb6ab fixes #11723 2019-07-15 17:22:01 +02:00
Kartik Saranathan
ec9d0ee86d fix broken link (#11736) [ci skip] 2019-07-15 16:05:43 +02:00
Andreas Rumpf
8513f50a8d Add std/monotimes which implements monotonic timestamps (#11712)
* [feature] Added std/monotimes

* [other] Minor optimization in times
2019-07-15 13:47:30 +02:00
Araq
dd7dd1b6dc styleCheck fixes [bugfix] 2019-07-15 13:16:02 +02:00
Araq
ad67a46e5d styleCheck fixes [bugfix] 2019-07-15 12:03:21 +02:00
Araq
52cbd0c558 styleCheck fixes [bugfix] 2019-07-15 10:56:55 +02:00
Araq
edbe02b4e1 newruntime: progress to make 'async' work with --newruntime 2019-07-15 10:56:55 +02:00
Andreas Rumpf
df53c68a36 makes devel green again 2019-07-14 17:14:51 +02:00
Araq
58e0dad371 'nim check' stability improvements 2019-07-14 16:11:42 +02:00
Araq
e06046ab51 makes --styleCheck:error the default for the Nim compiler itself 2019-07-14 16:08:52 +02:00
Araq
fab70e4fe3 minor update for the genode target 2019-07-14 16:08:15 +02:00
Araq
44c12d9d20 make 'koch temp' work again 2019-07-14 16:07:30 +02:00
Araq
9db369063c [refactoring] moves transformation for 'spawn' into its own spawn.nim implementation 2019-07-14 12:13:19 +02:00
alaviss
a59fb5b352 os: confine osErrorMsg example to Linux (#11725)
POSIX does **not** define the exact number for each errors. This caused
a failure in docs building on Haiku.
2019-07-13 16:16:09 +02:00
Jacek Sieka
cf36e4a44a times: use posix constant instead of import (#11692)
* times: use posix constant instead of import

* simplify clock id usage
2019-07-13 08:39:20 +02:00
Andreas Rumpf
de1ede77fe fixes #11715 (#11721) 2019-07-13 07:55:56 +02:00
Araq
d55cc0888d better run also considers the command line; fixes #11719 [feature] 2019-07-12 21:53:46 +02:00
Araq
423e8cca91 newruntime: refchecks:on|off switch 2019-07-12 21:53:46 +02:00
Araq
416ba133ad made --newruntime ready for multi-threading 2019-07-12 21:53:46 +02:00
Araq
bb5ca0772e atomics.nim: minor improvements 2019-07-12 21:53:45 +02:00
Araq
f45a1b927a documented --newruntime switch 2019-07-12 21:53:45 +02:00
Araq
03ded27021 preparations to be able to use atomics in runtime_v2.nim 2019-07-12 21:53:45 +02:00
Andreas Rumpf
2895ad70c8 fixes tcompiletimerange [bugfix] (#11720) 2019-07-12 15:37:54 +02:00
Ico Doornekamp
38b836b49e Moved 'Case statement macros' documentation out of manual into manual_experimental (#11716) 2019-07-12 14:41:54 +02:00
Araq
7606efc0bf [bugfix] VM: finally do inheritance properly 2019-07-12 12:15:30 +02:00
Araq
6d125da93f koch/nim: completion of the 'better run' feature 2019-07-12 10:48:29 +02:00
Araq
13253f4154 document 'nim' defines prefix 2019-07-12 10:48:07 +02:00
Araq
5bf3734984 nimpretty: implement a --maxLineLen command line option 2019-07-12 10:23:21 +02:00
Oscar Nihlgård
974362c98f [other] Minor optimization in times 2019-07-12 10:15:12 +02:00
Oscar Nihlgård
fd24a8923e [feature] Added std/monotimes 2019-07-12 10:15:06 +02:00
Araq
eaf4b42ff9 JS codegen: supports toOpenArray [bugfix] 2019-07-12 10:11:59 +02:00
Araq
511b6ae27c koch temp bugfix 2019-07-12 10:11:34 +02:00
Miran
2f0a50fa51 nimpretty: fix #11700, no extra newlines (#11714) 2019-07-12 09:14:21 +02:00
Andreas Rumpf
3d88d06b32 better run [feature] (#11709)
* track the checksums of all involved Nim files for smarter 'nim c -r' recompiles
* don't recompile unless necessary for 'nim c -r' [feature]
* [feature] koch boot uses a two step process in order to free the RAM before the GCC/Clang invocations
* fixes a serious regression
2019-07-11 21:36:23 +02:00
Dominik Picheta
b8be1ccb85 Give NilAccessError a message (#11706) 2019-07-11 11:14:38 +02:00
Andreas Rumpf
ac458448d8 make async tests green again 2019-07-11 11:09:10 +02:00
Araq
cb3c3c306c minor style changes 2019-07-11 00:28:20 +02:00
Araq
38bdf1cd7f minor style changes 2019-07-10 23:55:56 +02:00
Araq
b2f9447896 make tests green again 2019-07-10 23:32:04 +02:00
Araq
87a2ced1ba there is only one style -- my style 2019-07-10 19:17:06 +02:00
Araq
73cc029fec fixes linter regressions 2019-07-10 18:59:27 +02:00
Araq
dc0bbba3fa make editdistance work with --styleCheck:error 2019-07-10 18:58:59 +02:00
Araq
78174857f8 fixes #10901 2019-07-10 16:10:20 +02:00
Araq
b03421d087 fixes #11683 2019-07-10 16:00:05 +02:00
Araq
bc7733827d make more parts of the stdlib compile with --styleCheck:error 2019-07-10 15:48:30 +02:00
Araq
6663dbbe57 fixes #11691 2019-07-10 15:28:35 +02:00
Huy
e5425b5f2f [feature] add unsafeColumnAt procs, that return unsafe cstring from InstantRow (#11647) 2019-07-10 14:56:09 +02:00
Araq
c94647aeca styleCheck: make the compiler and large parts of the stdlib compatible with --styleCheck:error 2019-07-10 12:42:41 +02:00
Ivan Bobev
96523cdd3e Make public additional types from sha1 module [feature] (#11694)
* Make public additional types from sha1 module

After making public newSha1State, update and finalize methods from the
sha1 module was forgotten to be made public Sha1Digest and Sha1State
types used by the new public methods.

* Update changelog.md with sha1 module changes
2019-07-10 10:20:08 +02:00
Araq
18182e4bfd linter: refactorings 2019-07-10 09:07:03 +02:00
Araq
ff4a9a226f style changes 2019-07-10 09:06:54 +02:00
Araq
bd689849f2 nim styleChecker: implemented all the missing features (bugfix) 2019-07-10 00:29:58 +02:00
Araq
c6c9e30379 minor system.nim style changes 2019-07-10 00:29:58 +02:00
Araq
7a39eb13a5 koch temp: use -d:leanCompiler if possible 2019-07-10 00:29:58 +02:00
Miran
2255d8795b [other] prettify collections (#11695) 2019-07-09 22:45:23 +02:00
Araq
55e8aefbea newruntime: async progress 2019-07-09 20:15:57 +02:00
Araq
73c570d1d9 control flow graph: don't ignore yield statements 2019-07-09 20:15:57 +02:00
Araq
ad58ed344a newruntime: map system.reset to =destroy 2019-07-09 20:15:57 +02:00
Arne Döring
eb059fa848 closes #11551 (#11693) 2019-07-09 19:38:38 +02:00
Araq
a85e20c125 newruntime: 'owned distinct' is a valid construct (required by async) 2019-07-09 15:23:46 +02:00
Araq
fa982b43f0 make tests green again 2019-07-09 13:29:16 +02:00
narimiran
96d49608c0 nimpretty: more comment indentation fixes 2019-07-09 13:15:35 +02:00
Araq
eefcea8892 nimpretty: more improvements 2019-07-09 11:38:01 +02:00
Araq
fc34193483 nimpretty: code cleanups 2019-07-09 11:38:01 +02:00
Araq
0193c8ad2e nimpretty: yet another improvement 2019-07-09 11:38:01 +02:00
Araq
7993d61d00 async: more 'owned' annotations 2019-07-09 11:38:00 +02:00
Araq
2c2f2de614 asyncmacro produces 'owned' types 2019-07-09 11:38:00 +02:00
Araq
f64179e7fe bugfix: allow type conversions between 'owned ref' types 2019-07-09 11:38:00 +02:00
Araq
7c62de0cb7 better error message for invalid types 2019-07-09 11:38:00 +02:00
Arne Döring
11dad688fe Offsetof fixes (#11690)
* first fixes

* more tests and fixes

* code normalization
2019-07-09 09:07:45 +02:00
Timothee Cour
063ae96a66 address comments 2019-07-08 15:24:20 -07:00
Timothee Cour
5ddea6a98f add tests for #8305 #7808 #10285 #11061 + other bugs 2019-07-08 15:24:20 -07:00
Timothee Cour
5fce81edfd make tests/concepts/t3330.nim disabled again: the order of candidates is machine dependent 2019-07-08 15:24:20 -07:00
Timothee Cour
6375df4c53 make tests/concepts/t3330.nim disabled again: the order of candidates is machine dependent 2019-07-08 15:24:20 -07:00
Timothee Cour
b80d70b0f3 fix tests 2019-07-08 15:24:20 -07:00
Timothee Cour
a6526695f0 fix #8305 #7808 #10285 #11061 + other bugs with type mismatch error msgs 2019-07-08 15:24:20 -07:00
Miran
b50ae6817a [other] test more packages (#11687) 2019-07-08 22:22:15 +02:00
Andreas Rumpf
124a584eb2 fixes #11530 2019-07-08 19:40:42 +02:00
Timothee Cour
655cb08461 [refactoring] nimbase.h: remove dead code which was confusing (#11682) 2019-07-08 10:36:02 +02:00
Jacek Sieka
9e7d885f35 dynlib: use posix module (#11623) 2019-07-08 09:14:35 +02:00
Miran
d0616ed115 nimpretty: don't introduce extra spaces after a colon or a comma (#11672) 2019-07-07 20:13:10 +02:00
Araq
085a21ebf4 fixes #11350 2019-07-07 17:17:14 +02:00
Andreas Rumpf
bab1f67971 fixes #11660 (#11677) 2019-07-07 15:25:25 +02:00
awr1
6a7f8e8ab5 [HCR] Added warning for using performCodeReload() in main module (#11667)
* [HCR] Added error for using performCodeReload() in main module

* [HCR] changed this to a warning, clarified usage

* [HCR] fixed typo
2019-07-07 09:18:33 +02:00
Andreas Rumpf
3258c1e2a3 fixes #11671 2019-07-07 00:29:43 +02:00
Andreas Rumpf
465815e894 improved the error message for #11494; closes #11494 2019-07-06 23:59:23 +02:00
Andreas Rumpf
6ce6bce12e fixes a finish.exe regression 2019-07-06 22:48:22 +02:00
Andreas Rumpf
d2684cdfd2 fixes #11447 2019-07-06 21:20:16 +02:00
Andreas Rumpf
cab0c3e544 fixes #3333 2019-07-06 20:38:10 +02:00
Andreas Rumpf
64e1408920 fixes #8316 (#11673) 2019-07-06 20:02:50 +02:00
Andreas Rumpf
2678fa679a fixes #7057 2019-07-06 15:24:14 +02:00
Andreas Rumpf
02b9af2f75 ABI fixes for OSX/BSD; fixes #6860 (#11666) 2019-07-06 13:00:29 +02:00
Juan Carlos
25cd8a5490 Documentation Diff, Typo (#11566)
* Documentation for Diff, add Examples and runnableExamples
2019-07-06 09:45:48 +02:00
Miran
34c09a98c7 nimpretty: improved detection of commas and semicolons (#11661)
* nimpretty: improved detection of commas and semicolons

* address the comments
2019-07-06 00:21:21 +02:00
Arne Döring
7d5d9f7703 introduce internal Int128 type, use it to fix case stmt checks (#11652)
* initial version of int128
* use int128 in case stmt
* fixes #11552
2019-07-05 22:45:32 +02:00
Miran
176eaf5c90 nimpretty: don't touch formatted multiline comments (#11663) 2019-07-05 21:47:01 +02:00
cooldome
d1f6c820dd Fixes #11662: render ops priority (#11664) 2019-07-05 21:25:36 +02:00
narimiran
2c0c0e772c nimpretty: nicer debugging [ci skip] 2019-07-05 10:08:52 +02:00
Miran
96a19ea1b4 nimpretty: relax line length rules when dealing with (inline) comments (#11657) 2019-07-05 09:32:56 +02:00
Timothee Cour
95f2f2396f fix #11651 exportc symbol not exported, leading to link error (#11658) 2019-07-05 07:53:21 +02:00
Andreas Rumpf
28c9c062a4 fixes #11610 (#11659) 2019-07-05 07:26:06 +02:00
Tomohiro
b64dd795b1 manual: document block expression (#11638) 2019-07-05 01:43:14 +02:00
Andreas Rumpf
5f515410af newruntime for async (#11650)
* fixes overloading resolution for passing owned(Future[string]) to Future[T]
* WIP: make --newruntime work with .async
* memtracker: make it compile again
* make Nimble compile again
2019-07-05 01:42:17 +02:00
Ivan Bobev
d914dca513 Make public some sha1 module procedures (#11655) [feature]
Make "newSha1State", "update" and "finalize" procedures from the sha1
module public in order to be possible to compute single sha1 hash of
multiple separate blocks of data.
2019-07-04 22:29:03 +02:00
Akito13
0a501932c2 Corrected example shown in documentation (#11654) [ci skip]
Used template within example was added to imports.
2019-07-04 15:59:29 +02:00
Graeme Cross
dad3c40f55 Fix the broken link in math.nim (#11653) [ci skip] 2019-07-04 13:24:19 +02:00
narimiran
4450fca6fd nimpretty: fix out of bounds error [ci skip] 2019-07-04 12:02:35 +02:00
Araq
a59f0adc50 nimpretty: nimpretty now understands splitting newlines 2019-07-04 11:32:15 +02:00
Araq
7d29f8b1a4 nimpretty: distinguish between the different kinds of newlines in Nim 2019-07-04 10:44:04 +02:00
Timothee Cour
64168d4aea fixes #8405: -d:useNimRtl now works even when {.rtl.} procs are used at compile time; CTFFI now works with {dynlib} (#11635) 2019-07-03 23:57:52 +02:00
Miran
0718d6c2cd [bugfix] fix wrong nimpretty unidents, refs #11616 (#11645) 2019-07-03 18:55:15 +02:00
Andreas Rumpf
045eeab6b4 fixes #11585 2019-07-03 15:38:24 +02:00
Timothee Cour
0ca71dd92c [bugfix] fix mach_absolute_time header; refs #11591 (#11593) 2019-07-03 14:59:07 +02:00
Miran
1e9316e23c [bugfix] fix #11484, acknowledge 'danger' flag (#11486) 2019-07-03 13:01:22 +02:00
Araq
c0db1705dc fixes #11510 2019-07-03 12:54:11 +02:00
Araq
476b4ff372 fixes #11636 2019-07-03 12:54:11 +02:00
Liam Sc
a157c2baef Added 'keys' iterator to JsonNode (#11597) [feature] 2019-07-03 08:06:22 +02:00
Arne Döring
20d0ef8afb [backport] fix #11320 (#11538)
* [backport] fix #11320
* fix test for 32 bit test
2019-07-03 08:00:40 +02:00
Hugo Locurcio
0a1cb631a2 Implement some custom formatting for input fields in the documentation (#11632)
* Implement some custom formatting for input fields in the documentation

Aside of resulting in more consistent appearance across browsers,
this also fixes input form rendering when using Firefox with a
dark system theme on Linux.

* change the expected html in the tests
2019-07-03 07:40:24 +02:00
Graeme Cross
ab6dec6e90 Documentation improvements to the times module (#11639)
* Typo and grammar fixes for the times module
* Minor typo fixes to the times module
2019-07-03 07:39:19 +02:00
Andreas Rumpf
71b7383f12 fixes #11479 (#11641) 2019-07-03 07:22:30 +02:00
Miran
c522a455df [bugfix] nimpretty indents multiline comments correctly (#11607) 2019-07-02 10:52:46 +02:00
Andreas Rumpf
cce8a739da fixes #11633 2019-07-01 23:53:41 +02:00
Andreas Rumpf
766960dc15 fixes #11515 (#11624)
* fixes #11515

* better fix for #11515; make tests green
2019-07-01 18:08:50 +02:00
Andreas Rumpf
9b949855c7 fixes #11618 (#11631) 2019-07-01 14:10:08 +02:00
alaviss
2c10b246ec assertions: fixes #11545 (#11605)
* assertions: properly fix #11545

* tests/assert: enable excessiveStackTrace

* tests/assert: add test case for #11545

* tfailedassert_stacktrace: disable excessiveStackTrace

* assertions: weird workaround for failing tests

This fixes megatest on *nix, but have no idea why
2019-07-01 13:19:07 +02:00
Araq
bd55c862a6 fixes #11617 2019-07-01 13:12:04 +02:00
Araq
c352892232 fixes #11628 2019-07-01 12:34:19 +02:00
Araq
413dff03a0 fixes #11614 2019-07-01 12:29:03 +02:00
Ico Doornekamp
a5686961bd Make repr use 'ptr' for ptr types instead of 'ref' (#11626) 2019-07-01 11:59:27 +02:00
Juan Carlos
d7a7662a7f Remove IO.js compat (long dead vanished project,superseed by NodeJS) (#11627) 2019-07-01 11:59:02 +02:00
Araq
dd39b11b13 [bugfix] make -d:nimSetUtf8CodePage switch work again 2019-07-01 10:35:52 +02:00
Andreas Rumpf
d37c4e44d3 added destructors.rst document 2019-07-01 08:51:47 +02:00
alaviss
e259f80fc7 msgs, ccgstmts: fixes #11572 (#11621)
* [refactor] msgs: toFilename now return just the filename

The C codegen uses just the file name for stacktrace when
excessiveStackTrace is off (see quotedName),
so there aren't any reason for other codegen to not do the same.

The file name is now cached in TFileInfo.shortName, which was introduced
for nimsuggest, and went unused after several refactoring of the
compiler.

A toProjPath() proc has been added for the previous behavior of
toFilename().

* ccgstmt: use quotedFilename() for raiseExceptionEx

This is the same proc used for stacktrace when --stacktrace:on

Fixes #11572

* msgs: handle case where file name is not available
2019-06-30 12:30:37 +02:00
Andreas Rumpf
7113c1e931 [other] additions to the manual 2019-06-29 23:41:25 +02:00
Araq
3606e035f5 fixes #11606 2019-06-28 21:13:03 +02:00
Araq
7ddb31262e fixes #11611 2019-06-28 21:04:49 +02:00
Ivan Bobev
5be5bf0222 Pass additional koch options to the nim compiler (#11615)
Add possibility when "koch tools" command is used, nim compiler options
to be passed. The current options are kept and the new user specified
options will be added to the end of the command line if present.

Example:
> koch --latest tools -d:danger --debugInfo --lineDir:on
bin\nim.exe c -o:bin\nimsuggest.exe -d:release -d:danger -d:danger
 --debugInfo --lineDir:on nimsuggest/nimsuggest.nim
...
bin\nim.exe c -o:bin\nimgrep.exe -d:release -d:danger --debugInfo
 --lineDir:on tools/nimgrep.nim
...
bin\nim.exe c -o:bin\vccexe.exe -d:danger --debugInfo --lineDir:on
 tools/vccexe/vccexe.nim
...
bin\nim.exe c -o:bin\nimpretty.exe -d:release -d:danger --debugInfo
 --lineDir:on nimpretty/nimpretty.nim
...
bin\nim.exe c -o:bin\nimfind.exe -d:release -d:danger --debugInfo
 --lineDir:on tools/nimfind.nim
...
bin\nim.exe c -o:bin\nimble.exe --noNimblePath --nilseqs:on -d:release
 -d:danger --debugInfo --lineDir:on dist\nimble\src\nimble.nim
2019-06-28 18:06:43 +02:00
Araq
284a8cb58a nimpretty: bugfix [bugfix] 2019-06-28 11:45:21 +02:00
Andreas Rumpf
d72edfb14b Merge pull request #11609 from zestyr/xmltree-typo
Fix typo in xmltree docs
2019-06-27 21:36:49 +02:00
Andreas Rumpf
765ff4b67b contributing.rst guide: Make the rules reflect the reality. 2019-06-27 21:28:53 +02:00
Andreas Rumpf
17bbce7c8a manual: typo 2019-06-27 21:25:07 +02:00
Andreas Rumpf
d9604d7d0b manual: document how accessors are resolved; fixes #11514 2019-06-27 21:25:07 +02:00
Zestyr
bab83c4d8b Fix typo in xmltree docs [ci skip] 2019-06-27 20:44:42 +02:00
Araq
f36a61e6d4 make tests green again 2019-06-27 17:10:11 +02:00
Andreas Rumpf
fb878330a9 fixes #11445 2019-06-27 14:46:38 +02:00
Andreas Rumpf
135fdde6a9 fixes #11523 2019-06-26 23:41:20 +02:00
Andreas Rumpf
19b142401c fixes #11525 2019-06-26 23:15:58 +02:00
Andreas Rumpf
48cbf1c496 Merge pull request #11598 from narimiran/fix-sharedtables
[bugfix] fix #11588, don't check if SharedTable is initialized
2019-06-26 23:11:34 +02:00
Andreas Rumpf
ce2777af5a fixes #11600 (#11602) 2019-06-26 23:10:20 +02:00
Miran
f65eaa51f1 [bugfix] fix #11532, nimpretty should ignore source code filters (#11603) 2019-06-26 23:09:57 +02:00
Andreas Rumpf
e083a1533b fixes #11098 2019-06-26 19:34:05 +02:00
narimiran
326e3ad09d [bugfix] fix #11588, don't check if SharedTable is initialized 2019-06-26 17:16:55 +02:00
Araq
b6fb47df77 fixes #11600 2019-06-26 15:55:27 +02:00
Miran
f288e1b11a [bugfix] fix #11469, new rules for a newline in nimpretty (#11512)
* [bugfix] fix #11469, new rules for a newline in nimpretty
* concatenate two lines if they have the same indentation level
2019-06-26 15:36:44 +02:00
Araq
0a81b038fd fixes #11577 2019-06-26 15:33:51 +02:00
alaviss
993b3909a8 [refactor] compiler/[msgs, reorder, semstmts]: use toMsgFilename where appropriate (#11595)
* compiler/msgs: toMsgFilename now operates on FileIndex
* compiler/reorder: use toMsgFilename for compiler messages
* compiler/semstmts: respect listFullPaths for recursive deps error
2019-06-26 14:38:19 +02:00
Toshiyuki-Tega
b7f8031e98 VCC discovery using vswhere (#6540) (#11559) 2019-06-26 10:52:22 +02:00
Juan Carlos
206f2478b8 Documentation highlite (#11596)
* Add Documentation with examples for highlite

* Add Documentation with examples for highlite
2019-06-26 10:28:11 +02:00
Andreas Rumpf
0f868b587b fixes #11563 (#11594) 2019-06-26 06:55:43 +02:00
alaviss
2f1a1b7106 compiler/[msgs, options]: confine --listFullPaths to compiler messages (#11583)
* compiler/[msgs, options]: make toFilename independent of listFullPaths

toFilename is used mainly in codegen, as such it should not follow
--listFullPaths

* compiler/msgs: use toMsgFilename for toFileLineCol

This proc is mainly used for compiler messages, so it should follow
--listFullPaths

* compiler/msgs: remove toFileLine

unused proc

* compiler/msgs: cleanup toMsgFilename

Also improved path choosing logic, /home should now be preferred over
../home on *nix
2019-06-26 02:40:10 +02:00
cooldome
0d50b0c8a7 increase dfa instruction limit (#11579) 2019-06-24 22:34:54 -07:00
Jasper Jenkins
91f0626dcb [bugfix] remove dangling ref (#11576) 2019-06-25 02:04:15 +02:00
Gérôme Fournier
181350f6c9 Fix out of bound access in cgi module (#11578)
When an HTTP request with a zero CONTENT_LENGTH is made,
attempting to access addr(result[0]) raise an exception as the 0 index
is out of bound
2019-06-25 02:03:44 +02:00
WhiteDuke
2a7cf71db3 Fix typo (#11573) 2019-06-25 00:24:51 +02:00
alaviss
403fd3ac43 assertions: make assert follow excessiveStackTrace (#11574) 2019-06-25 00:23:22 +02:00
alaviss
e9a23cee0a nim.cfg: disable excessiveStackTrace on release (#11575) 2019-06-25 00:22:30 +02:00
narimiran
436f570651 [documentation] fix #4630, document unsupported functions for JS 2019-06-24 12:52:54 +02:00
Arne Döring
e90d91f0e4 [refactoring] remove zeroExtend and friends from the compiler builtins. (#11531)
* remove zeroExtend and friends from the compiler builtins.
* fix jssys
2019-06-24 09:19:02 +02:00
Simon Krauter
800bc661b6 Spelling fixes in nimc.rst (#11569) 2019-06-23 15:15:55 -07:00
Juan Carlos
bb9b60604b [other] Documentation NimScript (#11548)
* Documentation of NimScript, update and expand, mention the benefits aside of its limitations, add examples, update the list of usable std lib modules
2019-06-23 20:08:21 +02:00
Giovanni Petrantoni
b81fd958d1 [feature] Add dynlib (required on windows/cpp) to nimCoroutines related gc_common procs (#11567) 2019-06-23 18:05:10 +02:00
Miran
3d50f7e2a1 [bugfix] fix OrderedTable iterators (#11562) 2019-06-22 22:28:45 -07:00
Andreas Rumpf
79c721d418 [bugfix] fixes #11524 2019-06-22 01:52:49 +02:00
Andreas Rumpf
0db3c670ac closes #11533 2019-06-21 20:45:00 +02:00
Andreas Rumpf
35df59b3ce [bugfix] fixes #11556 2019-06-21 20:38:18 +02:00
narimiran
12eebf48b6 [documentation] fix wrong link [ci skip] 2019-06-21 12:04:43 +02:00
Kaushal Modi
a4c613c110 [other] Improve the "tabs are not allowed" error message (#11554) 2019-06-20 22:16:06 +02:00
Miran
23e95dc629 [bugfix] fix delete in strutils and sequtils (#11535) 2019-06-20 21:04:37 +02:00
Miran
d6b0e46ee4 [bugfix] correct 'source' for documentation (#11540) 2019-06-20 21:03:48 +02:00
Miran
45bbf1ef5b [bugfix] fix OrderedTable default initialization (#11549) 2019-06-20 21:03:11 +02:00
Andreas Rumpf
55da84e141 [other] new experimental pragma .nodestroy for easier custom destructors 2019-06-20 19:41:03 +02:00
Andreas Rumpf
f310cf5250 [other] added system.dispose for owned refs 2019-06-20 19:40:18 +02:00
Andreas Rumpf
280193cc07 [bugfix] system.nim: make pop work with --newruntime 2019-06-20 19:39:42 +02:00
Andreas Rumpf
7e4748beee [bugfix] proper destruction for strings/seqs for --newruntime 2019-06-20 19:39:19 +02:00
Andreas Rumpf
bc9fb4885b [bugfix] system.nim: make pop work with --newruntime 2019-06-20 19:38:25 +02:00
Araq
678beb8ef9 [other] newruntime: add a simple closure iterator test 2019-06-20 11:31:21 +02:00
Araq
6adcc09877 [bugfix] newruntime: trivial closure iterator works 2019-06-20 11:31:20 +02:00
Araq
c83914b435 [refactoring] closureiters.nim: style change 2019-06-20 11:31:20 +02:00
Araq
50afafdb38 wip 2019-06-20 11:31:19 +02:00
Andreas Rumpf
af10788dcc WIP: closures for the newruntime [ci skip] 2019-06-20 11:30:42 +02:00
narimiran
16d81fa205 [bugfix] fix #11546, correct link for sequtils 2019-06-20 09:41:06 +02:00
narimiran
96bed814d2 [bugfix] fix #11543, add std/sums to theindex.html 2019-06-20 09:37:21 +02:00
Andreas Rumpf
0adb1c6223 newruntime: added yet another test 2019-06-20 08:38:29 +02:00
Andreas Rumpf
c65a5d754b [bugfix] owned closures (#11544) 2019-06-20 07:40:45 +02:00
Arne Döring
1a074fffa4 change newLit on Seq (#11542) 2019-06-19 20:14:54 +02:00
Araq
ab36ffbeb1 [bugfix] fixes #11517 2019-06-19 17:39:52 +02:00
Araq
ff89f7e33a libffi: style changes 2019-06-19 16:54:34 +02:00
narimiran
de88fdb86e Revert "makes travis OSX green again"
This reverts commit 79a23fe805.
2019-06-19 15:53:42 +02:00
Miran
ae5a4cea98 [other] update homebrew, fix travis fails on OSX (#11541) 2019-06-19 15:54:40 +02:00
narimiran
cf47c2c60c [other] documentation: deprecation comments are now auto-generated 2019-06-19 14:21:46 +02:00
alaviss
24ac13f653 [bugfix] gc_common: export foreign thread gc docs (#11536) 2019-06-19 12:41:22 +02:00
Araq
f67be92512 [feature] cleanup PR, refs #11424 2019-06-19 09:54:01 +02:00
Araq
296c48de5e fixes #11436 2019-06-19 09:48:55 +02:00
Araq
79a23fe805 makes travis OSX green again 2019-06-19 09:48:55 +02:00
Phạm Ngọc Quang Nam
7c637c2faf [bugfix] Fix smtp.nim unhandled exception (#11498) 2019-06-19 00:26:59 +02:00
Jasper Jenkins
8ee0f14ab6 literal array indices (#11424) 2019-06-18 14:16:33 +02:00
Araq
c99ce5051e add HCR document to the tools.rst list 2019-06-18 12:19:14 +02:00
Araq
38f05bb9a3 HCR: better documentation 2019-06-18 12:17:26 +02:00
Benjamin Summerton
a009cbdc2f Add cbrt() bindings for the JS Target (#11528)
`Math.cbrt()` exists:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt

The binding was missing for the JavaScript backend.
2019-06-18 02:26:47 -04:00
yatsen1
c8268330be [feature] Add boehm gc finalizer (#11446) 2019-06-17 20:47:18 +02:00
Miran
ac3449b93b [bugfix] fix #11450, random.initRand crashes in JS backend (#11522) 2019-06-17 20:46:04 +02:00
Miran
6cad5c7861 [bugfix] fix #11482, fix nimsuggest range error (#11519)
The default starting parameters for `line` and `col` were switched.

See line 141: "line starts at 1, column at 0, dirtyfile is optional".
Also, in `TLineInfo` object, `line` is uint16, `col` is int16.
2019-06-17 20:41:41 +02:00
narimiran
b70fd0400e [other] introduce a separate changelog for backports, update
contributing guidelines
2019-06-17 12:15:47 +02:00
Juan Carlos
eb087b3546 [bugfix] Fixes #11434 , Update Tools Documentation (#11449) 2019-06-17 11:17:28 +02:00
Juan Carlos
aa7f23e1ee [bugfix] Fixes #11495 , Remove TinyC from help (#11508) 2019-06-17 11:03:18 +02:00
Phạm Ngọc Quang Nam
9f6187b46c Add starttls for smtp (#11500)
* Add starttls for smtp

* Update smtp.nim
2019-06-16 23:50:56 +01:00
Kaushal Modi
7182922622 [feature] Added os.delEnv; add delEnv support to nimscript too (#11466)
[feature] Fixes https://github.com/nim-lang/Nim/issues/11452.
2019-06-15 11:32:26 +02:00
Andreas Rumpf
eadea343ef [bugfix] fixes https://github.com/nim-lang/Nim/issues/11430
[bugfix] fixes https://github.com/nim-lang/Nim/issues/11430
2019-06-15 11:29:10 +02:00
Charles Blake
6dc6487311 Disambiguate idents now that all 3 rfind's are included in the RTL. 2019-06-15 03:46:21 -04:00
Andreas Rumpf
68cce40510 [bugfix] Add .47 as supported libssl version (#11503) 2019-06-14 23:03:00 +02:00
Kaushal Modi
d1ce86fdc6 [bugfix] Fix the link to "For Loop Macro" section (#11505) 2019-06-14 23:02:30 +02:00
SolitudeSF
e96afd6324 [bugfix] Add .47 as supported libssl version 2019-06-14 20:00:23 +03:00
Kaushal Modi
c656714623 [bugfix] Minor formatting fix in tut2 [ci skip] (#11501)
Monospace `untyped` like elsewhere in the tutorial.
2019-06-14 15:13:44 +02:00
Araq
57a83df745 [bugfix] nimpretty: better alignment; fixes #11467 2019-06-14 11:16:39 +02:00
Juan Carlos
80320c72d3 [bugfix] document the norewrite pragma (#11453)
* fixes #9454
* Peer review feedback, wording, move to experimental manual
2019-06-13 19:37:17 +02:00
Jasper Jenkins
bda9fd149c [refactoring] error instead of quit for basename (#11491) 2019-06-13 19:34:41 +02:00
Charles Blake
e11d582fa1 Merge branch 'devel' of https://github.com/nim-lang/Nim into devel 2019-06-13 10:21:11 -04:00
Charles Blake
e7188cdfa8 Add missing ,int to type signature in doc comment references. 2019-06-13 10:20:43 -04:00
Jasper Jenkins
06ef56ba72 [bugfix] fix quit errormsg in nimvm (#11490) 2019-06-13 15:30:30 +02:00
Simon Krauter
e2f99a2026 Update tut1: -d:release does not turn off *allruntime checks off anymore (#11492)
According to https://nim-lang.org/blog/2019/06/06/version-0200-released.html
"The -d:release switch now does not disable runtime checks anymore. "
2019-06-13 15:16:38 +02:00
Araq
165ea46284 [bugfix] nimpretty: fixes #11470 2019-06-13 10:58:27 +02:00
Araq
af39f26a3a [bugfix] nimpretty: fixes #11468 2019-06-13 10:42:37 +02:00
Araq
b70295c768 [other] nimsuggest: adhere to our style guide 2019-06-13 09:59:03 +02:00
alaviss
08fdffc717 [other] appveyor: use official dlls on nim-lang.org (#11473) 2019-06-12 17:09:36 +02:00
Dominik Picheta
73c44c6e9b [bugfix] Fixes async IO operations stalling even after socket is closed. (#11232) 2019-06-12 17:07:05 +02:00
Charles Blake
bde899d4f8 Attempt to close https://github.com/nim-lang/Nim/issues/11430 2019-06-12 07:44:56 -04:00
Jasper Jenkins
da035e9c83 [bugfix] fix nimpretty for absolute paths (#11480) 2019-06-12 11:59:25 +02:00
Araq
b056d32a79 [refactoring] liftdestructors.nim is callable from lambdalifting; refs #11217 2019-06-12 10:44:45 +02:00
Arne Döring
e4d0f4fee0 fix regression in semfold for old right shift (#11477) 2019-06-12 09:26:30 +02:00
Araq
c07973e313 [refactoring] liftdestructors is now a module of its own 2019-06-12 08:45:47 +02:00
Araq
549d8cc0c6 [other] make typeAllowed easier to debug by using structured programming 2019-06-12 08:45:47 +02:00
Andreas Rumpf
572b7c37a5 [other] preparations for --styleCheck:error for the Nim compiler (#11478) 2019-06-12 08:35:32 +02:00
Arne Döring
c7e1c665a1 [refactoring] refactor the compiler and stdlib to deprecation warnings (#11419) 2019-06-11 16:49:56 +02:00
Juan Carlos
3d13103443 [bugfix] Add .nimf to mimetypes (#11417) 2019-06-11 16:46:15 +02:00
Hitesh Jasani
a9aef65b2d [feature] Enable Oid usage in hashtables (#11472) 2019-06-11 15:06:46 +02:00
Miran
b3d2cd738a [other] better error message for IndexError for empty containers (#11476) 2019-06-11 14:34:21 +02:00
Miran
639e9a7aa9 [other] test 6 more nimble packages (#11464) 2019-06-11 11:43:54 +02:00
Andreas Rumpf
51ac2e67bf newruntime: added a basic table test 2019-06-11 08:58:11 +02:00
jiro
ced0527ae3 streams: change error message of openFileStream (#11438) [feature] 2019-06-10 21:00:55 +02:00
Kaushal Modi
f8c8e319bc Ensure that koch-built nim exe has +x perm for u/g/others [bugfix] (#11444)
Fixes https://github.com/nim-lang/Nim/issues/11427.
2019-06-10 20:52:56 +02:00
Kaushal Modi
2334680b3d Use TMPDIR env var if available to get the temp dir name (#11443) [bugfix]
Additionally, use normalizePathEnd to suffix the dir name with "/" or
"\" as appropriate for the current OS.

Fixes https://github.com/nim-lang/Nim/issues/11439.
2019-06-10 19:59:51 +02:00
Arne Döring
94177f7357 VM can now cast integer type arbitrarily. (#11459) [feature] 2019-06-10 19:58:11 +02:00
Miran
7cf9b522b5 [bugfix] rename Nimrod to Nim, fix #11460 (#11462) 2019-06-10 12:54:43 +02:00
Juan Carlos
3a91a93584 Fixes #11431 (#11451) [bugfix] 2019-06-10 10:53:34 +02:00
Andreas Rumpf
caf93f4355 nimpretty: smart tabs support, fixes #9399 [bugfix] 2019-06-10 10:50:15 +02:00
Juan Carlos
22a1b12038 [documentation] fix #11281, httpclient examples (#11455) 2019-06-10 09:31:57 +02:00
Andreas Rumpf
cb47e49d3b nimpretty: keep a seq of tokens instead of a single string to enable better transformations [refactoring] 2019-06-09 22:22:50 +02:00
Andreas Rumpf
8317de7648 complex.nim: reformating [other] 2019-06-09 22:22:50 +02:00
Kaushal Modi
3c62d41468 Make -d:tempDir switch work once again [bugfix] (#11442)
Fixes https://github.com/nim-lang/Nim/issues/11441.
2019-06-09 08:54:15 +02:00
nc-x
bce908f6ee fix koch docs failing at io.nim with import os in config.nims (#11418) [bugfix] 2019-06-08 00:37:08 +02:00
Miran
bf9f1f7b45 [bugfix] hashes: fix regression for nested containers (#11426)
Move forward declarations earlier.
2019-06-08 00:34:11 +02:00
Andreas Rumpf
bf63d83a97 update the nimc.rst document about the release/danger split [bugfix] 2019-06-08 00:13:57 +02:00
Andreas Rumpf
9f82e07b2d nimpretty: fixes #10156 [bugfix] 2019-06-08 00:00:00 +02:00
Andreas Rumpf
2c03c9f42e updates the contributing guidelines [other] 2019-06-07 16:21:01 +02:00
Arne Döring
99a4fed96b fix for passing tuples as static params to macros (#11423); fixes #10751 [bugfix]
* add vm value preparation proc

* small optimization
2019-06-07 14:34:59 +02:00
Araq
12fc1dfb2c nimpretty: closes #10159 [bugfix] 2019-06-07 13:03:04 +02:00
Araq
667af87e66 nimpretty: fixes #9505 [bugfix] 2019-06-07 12:59:31 +02:00
Araq
790bc5b07b nimpretty: fixes #10177 [bugfix] 2019-06-07 11:50:56 +02:00
Araq
5a37224102 develop version is 0.20.99 [feature] 2019-06-07 10:49:56 +02:00
Araq
447cc1ff09 nimpretty: fixes #10295 2019-06-07 10:37:00 +02:00
Dominik Picheta
554908df0c Create FUNDING.yml 2019-06-06 21:58:25 +01:00
Andreas Rumpf
e7471cebae koch.nim: hotfix for nightly builds 2019-06-06 19:57:54 +02:00
Andreas Rumpf
abaa42fd8a cleanup nimpretty's config 2019-06-06 19:57:42 +02:00
narimiran
7a670a6bc9 more changelog fixes 2019-06-06 08:57:50 +02:00
Arne Döring
cfeb9d2c50 Bit operator names 2 (#11413)
* add bit operator names

* add test for bitop alias
2019-06-06 08:36:20 +02:00
Araq
4296bddccb fixes #11412 2019-06-06 07:56:19 +02:00
Araq
1d23d7472b a new dawn 2019-06-06 07:56:06 +02:00
narimiran
56f79ab0b8 changelog: fix typos, create a changelog for 0.20 2019-06-05 22:57:28 +02:00
Araq
591007878c cleaned up the changelog 2019-06-05 22:48:27 +02:00
Araq
f844891e48 make megatest work with 'koch boot -d:release' too 2019-06-05 22:32:19 +02:00
narimiran
be9c38d265 bump version to 0.20.0 2019-06-05 18:38:45 +02:00
Tristano Ajmone
5a4122dc98 Ignore dochack.js (#11409)
Add to `.gitignore` rule for `/tools/dochack/dochack.js`.

After building locally Nim and running `koch docs`, the `dochack.js`
file was showing up in Git working tree as a new untracked file.

Closes #11374.
2019-06-05 18:26:57 +02:00
Araq
8cc9753285 fixes #11405 2019-06-05 16:26:23 +02:00
Tristano Ajmone
6ebbff0a11 Fix strscans Docs (#11408) [ci skip]
Amend two typos in the documentation of strscans library:

- `a ^* b` instead of `a ^+ b`.
- Remove hyphen from `$w` ASCII identifier `[A-Z-a-z_][A-Za-z_0-9]*`
  (matching `IdentStartChars` definition in parseutils).
2019-06-05 16:20:13 +02:00
andri lim
c16a753822 fix macrocache implementation (#11404)
* macrocache improvements

* fix macrocache implementation
2019-06-05 14:56:45 +02:00
Arne Döring
efbf43d4a9 intVal works now on enum field symbols (#11403)
* intVal works now on enum field symbols

* disable flakey titerators test
2019-06-05 14:55:47 +02:00
Araq
9230862534 koch now ignores the existance of .git and always builds the latest tagged stable release of Nimble unless you use the --latest switch; fixes #11402; fixes #9017 2019-06-05 11:34:09 +02:00
Araq
8ab94cdd45 refs #11402; now koch ships a fixed version of Nimble so that the connection between Nim and Nimble version is obvious when you do 'git checkout v0.20' in Nim's repo 2019-06-05 11:26:10 +02:00
Arne Döring
cb45527e37 pass typedesc as NimNode to macros (#11400)
* change typedesc's design in macros

* Manual and changelog entry.

* add link to RFC
2019-06-05 09:17:04 +02:00
Jasper Jenkins
71388caf2e remove stdlib case transitions (#11401) 2019-06-05 08:04:29 +02:00
Andreas Rumpf
7215341190 make fullpaths the default in error messages and stack traces for mor… (#11385)
* make fullpaths the default in error messages and stack traces for more convenient development
* split up -d:release into -d:release and -d:danger flags
* workaround a Nim config parser bug
* fixes an old nim config parser bug
* make megatest green again
* make nimpretty tests work again
* make nimsuggest green
2019-06-05 08:02:54 +02:00
Jasper Jenkins
fc4f0808c4 parameter runtime discriminators (#11397)
* allow param for runtime discriminator construction
2019-06-04 22:10:39 +02:00
Miran
bfa32e8d99 improve 'marshal' documentation, refs #10330 (#11398) 2019-06-04 20:54:32 +02:00
alaviss
89f6b1b2c5 appveyor: test using nim-lang.org gcc (#11382) 2019-06-04 18:50:32 +02:00
narimiran
6f853a747a use proper mathematical expressions for subsets [ci skip]
Fixes https://github.com/nim-lang/website/issues/46
2019-06-04 14:57:04 +02:00
narimiran
e3ddc6b83a revert unintended changes 2019-06-04 14:33:55 +02:00
narimiran
7f63c1b83d fix c2nim link 2019-06-04 12:37:37 +02:00
narimiran
1f883f6d78 better documentation for the new shr 2019-06-04 12:29:52 +02:00
Araq
5f4e8dc4c9 added a nice test case for macro based lookup tables 2019-06-04 11:16:30 +02:00
Jasper Jenkins
55af21c662 rename (un)likely (#11391) 2019-06-03 20:33:24 +02:00
narimiran
d7d88ae218 disable 3 packages until they merge their pending PRs which fix failures 2019-06-03 17:12:02 +02:00
Dankr4d
9d536b90c1 Fixed "is not GC-safe as it calls 'createThread'" when creating a thread in a thread. (#11390) 2019-06-03 17:13:21 +02:00
ehmry
7072eaad73 Genode compiler configuration for arm64 and riscv64 (#11389)
Add compiler for arm64 and riscv64, remove path to compiler binaries.
2019-06-03 16:30:55 +02:00
Araq
7c5e7a4f6a disable the new CaseTransition warning for the Nim compiler itself 2019-06-03 12:00:28 +02:00
LemonBoy
7d217a71d3 Render deprecated pragmas (#8886)
* Render deprecated pragmas
* fix the expected html
* clean up the documentation regarding deprecations
* fix typo
* fix system.nim
* fix random
2019-06-03 10:15:20 +02:00
Araq
64518380a5 undeprecate system.programResult until we have a good solution at hand 2019-06-03 09:35:04 +02:00
Andreas Rumpf
a68fe3d082 fixes #11364 (#11383) 2019-06-03 08:46:57 +02:00
alaviss
1d1c72dfbb niminst: get rid of LINKER / LD (#11379)
* niminst: get rid of LINKER / LD

They don't seem to be used anywhere, and clashes with *nix `$LD`
2019-06-03 08:45:52 +02:00
John Paul Adrian Glaubitz
5c5df61071 Additional platform definitions for sparc64 (#11387)
* lib/posix: Define SO_REUSEPORT for sparc64 as 0x0200 from kernel ABI

* lib/system: Add platform support for sparc64
2019-06-03 08:20:00 +02:00
John Paul Adrian Glaubitz
4a485cb7ef Add build support for Linux/alpha (#11386)
* compiler: Add alpha as target architecture on Linux

* build.sh: Enable CPU detection for alpha
2019-06-03 08:18:15 +02:00
alaviss
06f251fe4e niminst/makefile: add windows support (#11380) 2019-06-02 14:25:47 +02:00
Andreas Rumpf
5eb47f8ed9 fixes #11369 (#11381) 2019-06-02 14:24:38 +02:00
Andreas Rumpf
c02320e230 sigmatch: use boolean algebra 2019-06-02 08:35:09 +02:00
Jjp137
9ee2ecf0a6 sets: minor documentation fixes [ci skip] (#11377)
Mainly replace a backslash, which was supposed to represent set
difference, with the Unicode symbol for set difference (U+2216).
The backslash did not appear in the output since it is used to
escape characters in reST.

Fix a few typos as well.
2019-06-02 08:29:31 +02:00
genotrance
1255b3c864 Warn about object case transitions at compile time (#11378) 2019-06-02 06:40:07 +02:00
Andreas Rumpf
4a35d2b571 fixes #11375 (#11376) 2019-06-02 06:33:35 +02:00
John Paul Adrian Glaubitz
ec038998f0 Add build support for Linux/m68k (#11366)
* compiler: Add m68k as target architecture on Linux

* build.sh: Enable CPU detection for m68k
2019-06-02 00:20:28 +02:00
John Paul Adrian Glaubitz
af0ae5830f Add build support for Linux/sparc64 (#11365)
* compiler: Add sparc64 as target architecture on Linux

* build.sh: Use getconf for bitness detection on Linux/sparc

The isainfo utility is specific to Solaris and not available
on Linux/sparc. While getconf exists on Solaris as well, it
does not always seem to match the bitness reported by isainfo
on Solaris and isainfo should therefore be preferred on Solaris.
2019-06-01 10:45:44 +02:00
Smittyvb
40c5509a02 Make net module compile with --taintMode:on (#11360) 2019-06-01 10:44:40 +02:00
Jasper Jenkins
6b23b2d7df parseopt fix (#11363) [backport] 2019-06-01 10:44:08 +02:00
Ico Doornekamp
41b74db218 Added 'except X as Y' to section 'except clauses' of manual (#11371) 2019-06-01 10:43:25 +02:00
narimiran
3b73da310c close #9961 by adding a test 2019-05-30 12:34:27 +02:00
narimiran
cb71564785 close #9827 by adding a test 2019-05-30 11:18:17 +02:00
narimiran
4606a00d4e close #8573 by adding a test 2019-05-30 11:13:29 +02:00
alaviss
1d00f7f9d7 travis: cleanup & add 32-bit Linux testing (#11337) 2019-05-30 07:34:54 +02:00
Arne Döring
5b27b263fd Remove immediate pragma (#11308)
* remove immediate from tests
* remove immediate from the compiler
2019-05-29 22:21:51 +02:00
Araq
eb471acffb system.nim: minor fix for the new 'unown' template 2019-05-29 20:49:36 +02:00
Araq
9ecb1aae80 new compiler feature: --expandMacro 2019-05-29 20:47:28 +02:00
Araq
dc5fa90b43 switch should be nimOldShiftRight with the nim prefix 2019-05-29 17:06:39 +02:00
Arne Döring
88b5dd3362 right shift is now by default sign preserving (#11322)
* right shift is now by default sign preserving
* fix hashString and semfold
* enable arithmetic shift right globally for CI
* fix typo
* remove xxx
* use oldShiftRight as flag
* apply feedback
* add changelog entry
2019-05-29 16:48:00 +02:00
narimiran
897e7c90ac fix megatest 2019-05-29 16:42:36 +02:00
Andreas Rumpf
f79b6dee33 fixes excessive newlines in testament's output (#11351) 2019-05-29 15:59:11 +02:00
narimiran
d654383a8e rename a file, so that megatest doesn't complain 2019-05-29 15:44:52 +02:00
narimiran
6f5eba4b94 close #7792 by adding a test 2019-05-29 14:56:39 +02:00
narimiran
a8939686a1 close #8199 by adding a test 2019-05-29 14:47:45 +02:00
narimiran
3845faf85f close #7615 by adding a test 2019-05-29 14:35:05 +02:00
narimiran
d1b4f1082e close #5859 by adding a test 2019-05-29 13:37:55 +02:00
Yuriy Glukhov
6904f323aa Fixed #9762 (#11296) 2019-05-29 12:11:03 +02:00
Araq
13505c3be2 added a -d:nimv019 define for compiling 0.19 code with 0.20 2019-05-29 12:01:43 +02:00
narimiran
4f989b9162 close #5235 by adding a test 2019-05-29 11:52:54 +02:00
Araq
0f4446b861 docgen: do not render the ugly <//> operator; temporary hack until 0.20 has been released 2019-05-29 10:23:39 +02:00
Andreas Rumpf
8951680c05 fixes #10889 2019-05-29 08:00:52 +02:00
Araq
950f2d7c2f fixes #6755; error message could be better but oh well 2019-05-28 22:20:49 +02:00
Andreas Rumpf
e68adca0c9 fixes #6777 (#11347) 2019-05-28 22:00:01 +02:00
Araq
8bb1a6b041 fixes #11205 2019-05-28 21:30:41 +02:00
Araq
bcccc7dec8 docgen.nim: avoid compiler warning 2019-05-28 16:31:57 +02:00
Araq
4a9e6361ce fixes #11344 2019-05-28 16:05:33 +02:00
Arne Döring
35593700fa fix doccomment of macros.get{Size,Align,Offset} [ci skip] (#11346) 2019-05-28 15:57:27 +02:00
Andreas Rumpf
9d8b4d6020 fixes #11057 (#11345) 2019-05-28 15:55:11 +02:00
Zed
1f8c9aff1f Fix and reenable thread tests (#11343) 2019-05-28 15:23:09 +02:00
narimiran
379916c737 make tests green 2019-05-28 07:31:25 +02:00
Araq
781108ffe4 better error message for the object case switch transition period 2019-05-27 22:46:52 +02:00
Araq
84ca1f3bf3 hotfix for 32bit unsigned 'range' checking; incomplete, unknown why some operations produce range checks 2019-05-27 22:38:06 +02:00
narimiran
c644bf399f tsendtwice test: make it arch-independent 2019-05-27 21:51:54 +02:00
narimiran
0fc42fc4f7 tableinstatic test: make it arch-independed 2019-05-27 21:41:24 +02:00
narimiran
2b0ea6b2ae xmltree: use code-block for arch-dependent tests 2019-05-27 21:32:12 +02:00
Araq
af6539b0c3 disable parsetoml package until it's fixed upstream 2019-05-27 21:29:02 +02:00
Araq
dfcd82669b update nimsuggest 2019-05-27 21:29:02 +02:00
Araq
795044ed2b make tests green again 2019-05-27 21:29:02 +02:00
Araq
383147f5cb make json.to work with the more restricted case objects 2019-05-27 21:29:02 +02:00
Andreas Rumpf
49e686ab4e fixes #1286; object case transitions are now sound 2019-05-27 21:29:02 +02:00
narimiran
247fa431de hashes: quickfix one test 2019-05-27 20:46:33 +02:00
Jasper Jenkins
1286ba3452 fix bool and range (#11336) 2019-05-27 07:59:22 +02:00
Jasper Jenkins
f774426095 Smarter variant object construction (#11273) 2019-05-26 21:22:02 +02:00
Andreas Rumpf
16aa10dfe1 fixes #10038; deprecate generic methods, they are unreliable 2019-05-25 23:56:16 +02:00
Andreas Rumpf
36a398d96f C codegen: preparations for better code generation 2019-05-25 20:53:11 +02:00
Oscar Nihlgård
3a06022071 Enable range checking for unsigned integers (#11313)
* Enable range checking for unsigned integers

* Make the tests green
2019-05-25 20:48:13 +02:00
Ico Doornekamp
70fb3a93e9 list available options for --cpu, --os and --cc if the passed option is not found (#11328) 2019-05-25 20:22:57 +02:00
Kaushal Modi
2f610d621f Use the correct HTML file reference in "nim doc" generated idx files (#11326)
* Use the correct HTML file reference in "nim doc" generated idx files

Now "nim doc --out:foo.html --index:on bar.nim" generates "foo.html"
and the generated "bar.idx" contains references to "foo.html".

Fixes https://github.com/nim-lang/Nim/issues/11325.

* Refactor the nim doc tester to extend it for more tests

* Reference the HTML files relative to the outDir, not project dir

* Add test for issues #11312 and #11325

- https://github.com/nim-lang/Nim/issues/11312
- https://github.com/nim-lang/Nim/issues/11325
2019-05-25 20:20:25 +02:00
alaviss
6a94599d66 travis: minor opimizations (#11327)
* travis: use homebrew addon

* travis: parallelize csources building
2019-05-25 08:00:39 +02:00
Andreas Rumpf
7e9cda7dba fixes #10299 (#11324) 2019-05-25 07:33:33 +02:00
Andreas Rumpf
7e53c1c5c5 fixes #11188 (#11319) 2019-05-24 22:50:43 +02:00
Andreas Rumpf
ef8ddef47b fixes #10912 (#11317)
* fixes #10912

* update the tutorial examples
2019-05-24 18:33:53 +02:00
Araq
d67a9f024e fixes #11306 2019-05-24 15:25:09 +02:00
Araq
1a8ef6b491 fixes #11312 2019-05-24 10:34:36 +02:00
Araq
96b2233b71 nimgrep: be less annoying 2019-05-24 10:29:26 +02:00
Araq
03e619349f cleanup keineschweine test; removes unused module 2019-05-24 09:43:33 +02:00
Araq
cacd6d1070 fixes #11294 2019-05-24 09:43:04 +02:00
Andreas Rumpf
39a3dbb16b fixes #11187 (#11315) 2019-05-24 08:19:05 +02:00
Araq
c7de1a252e fixes #11257 2019-05-24 00:44:49 +02:00
Araq
b75ad05267 fixes move analyser; refs #11257 2019-05-24 00:12:36 +02:00
Alvydas Vitkauskas
981f95757c Implement generic fromBin|Oct|Hex in strutils (#11107)
* make parsutils.parseBin generic and improve runnableExamples

* reimplement parseBin/Oct/Hex and improve runnableExamples

* update changelog.md file with parseBin/Oct/Hex and fix a typo

* delete template and code parseBin|Oct|Hex separately

* split definitions between int and other SomeInteger

* make parseBin|Oct|Hex generic and remove rtl pragmas

* remove pragma inline from praseBin|Oct|Hex

* implement families of parse(Bin|Oct|Hex)Int[xx]

* fix typo [skip ci]

* implement generic fromBin|Oct|Hex

* make runnableExamples shorter
2019-05-23 21:34:47 +02:00
Andreas Rumpf
aa4cf92ae8 fixes #11309 (#11310) 2019-05-23 19:32:44 +02:00
Miran
44cc5f6360 fix #8329, allow case insensitive xmltree.findAll (#11305) 2019-05-23 00:14:28 +02:00
Andreas Rumpf
fd16875561 fixes #8568 (#11303)
* fixes #8568

* fixes regression
2019-05-22 20:59:54 +02:00
Andy Davidoff
b62f4b1b0c fix spelling [ci skip] (#11307) 2019-05-22 20:50:44 +02:00
narimiran
6ae74f61f3 remove trailing whitespace [ci skip] 2019-05-22 20:38:08 +02:00
Miran
3e0fac7c20 finish #11292: fix addQuoted and add changelog entry (#11301)
* finish #11292: fix `addQuoted` and add changelog entry

* JS is special
2019-05-22 18:57:52 +02:00
Araq
85ac4bfff6 closes #6076 2019-05-22 15:42:34 +02:00
Araq
279df834ba Nim is not a header file generator anymore; closes #4723 2019-05-22 15:13:26 +02:00
Andreas Rumpf
1e97b420bb fixes #7167 (#11300)
* fixes #7167
* spec: distinct types can be ordinal types
* bootstrapping issue
2019-05-22 11:50:05 +02:00
Araq
57bc8d73b4 fixes subtype relation regression 2019-05-22 07:41:16 +02:00
Araq
1f7f0908ef make bootstrapping work with older Nims 2019-05-22 07:41:16 +02:00
Araq
90e882d55b fixes #11239 2019-05-22 07:41:16 +02:00
Araq
11fca968b2 stdlib: more consistent formatting 2019-05-22 07:41:16 +02:00
Araq
845f89ab54 better default for nimgrep 2019-05-22 07:41:16 +02:00
Andreas Rumpf
23dbc9ad58 fixes #11268 (#11299) 2019-05-22 07:37:25 +02:00
Miran
bab5e30972 fixes #10963, disallow implicit mixing of strings and ints/floats (#11292) 2019-05-21 21:32:37 +02:00
Arne Döring
f94ec363ab Allow void macro result (#11286)
* allow void macro result
* add test for void macro result type
2019-05-21 21:31:40 +02:00
Miran
68b5e3e3fe colors: fix mix, add documentation (#11295) 2019-05-21 21:28:29 +02:00
Miran
1251e1ad16 faster hashing (#11203)
* faster hashing

* multibyte hashing for:
  * string and string slices
  * cstring
  * string, ignoring case
  * string, ignoring style
  * openArray of byte or char

* address the review comments

* use optimized version for all ints
* add more tests
* make it work in VM
* put warnings about differences between CT and runtime
* minor style tweaks
2019-05-21 21:26:27 +02:00
Miran
9bd4347abb fix #10910, optimize squaring and cubing (#11291) 2019-05-21 15:57:33 +02:00
Miran
6586516511 fix #8395, fix #8734: normalize os.tailDir and os.parentDir (#11288) 2019-05-21 15:57:20 +02:00
liuxiaodong
5e552ad3a5 getDateStr and getClockStr takes a default parameter (#11108) 2019-05-21 09:54:09 +02:00
Miran
dc6a4b1d43 fixes #11049, wrong streams.readBool and streams.peekBool (#11284) 2019-05-20 19:39:38 +02:00
treeform
d490bc519a Add force openSSL version with -d:sslVersion=1.0.0 (#11272) 2019-05-20 16:53:24 +02:00
Ico Doornekamp
c01f7bfdaf More specific error message for unsupported recursion in iterators (#11283) 2019-05-20 15:22:42 +02:00
Arne Döring
aeb6ec27de fix for return in macro (#9666); fixes #5874 2019-05-20 12:18:53 +02:00
jcosborn
433ce7bea2 move test for #7632 above import strformat (#11270) 2019-05-20 10:17:56 +02:00
Ștefan Talpalaru
13b3e4af8a fixes #11275 (#11276) 2019-05-20 09:29:13 +02:00
Miran
a63c2a25d0 fix changing case for Unicode characters which change size (#11271)
Some Unicode characters don't have the same byte length
in their upper- and lower-case variants.
2019-05-20 09:18:47 +02:00
jiro
468599c654 db_sqlite: Update documentation (#10330) (#11266) 2019-05-19 20:27:12 +02:00
Dominik Picheta
f1a8edc14d Merge pull request #11263 from jrfondren/asyncstreams-fix-immediately-vs-soon
fix unnecessary poll() (and default 500ms delay) in some uses of async
2019-05-16 23:24:53 +01:00
Miran
9d4190a5cc fixes #11139 (re.nim memory leak) (#11265)
Use the same PCRE function for freeing up the memory as nre.nim does.
2019-05-16 21:06:31 +02:00
Miran
8f198db2ca fixes #10952, UNC paths (#11260) 2019-05-16 21:06:04 +02:00
Jasper Jenkins
90ed904c4d range/case fixes (#11264) 2019-05-16 16:36:40 +02:00
Julian Fondren
22b4cf192d fix for unnecessary poll() in some uses of async 2019-05-15 19:57:45 -05:00
Andreas Rumpf
e26545797e fixes #7816 (#11261) 2019-05-15 21:12:07 +02:00
Clyybber
4e0e706cfe Correct global destructor injections for js backend (#11240) 2019-05-15 19:16:32 +02:00
Araq
791abfbc16 selectors: exceptions are for errors, not for bugs 2019-05-15 18:19:17 +02:00
Araq
a470ba673b manual_experiments: clarifications 2019-05-15 18:16:45 +02:00
Dominik Picheta
d0b8724aa2 Fixes crashes when asyncdispatch.adjustTimeout returns a negative value. (#11231) 2019-05-15 18:15:10 +02:00
Arne Döring
2339542832 Tuple error message (#11141); fixes #3211 2019-05-15 17:59:06 +02:00
Boris Shomodjvarac
de6b2e88d2 added getSocket proc (#11233) 2019-05-15 17:47:25 +02:00
Araq
7fb256bded fixes #8053 2019-05-15 12:25:31 +02:00
Arne Döring
5e68d8f9e9 less copy tree (#11249) 2019-05-15 12:11:03 +02:00
Ștefan Talpalaru
dfc7685420 fixes #11250 (#11251) 2019-05-15 08:42:30 +02:00
Oscar Nihlgård
bc0f2f0dd2 Add test case for #3766 (#11252) 2019-05-15 08:22:45 +02:00
Dominik Picheta
6b2ed28d55 Workaround "move not found" exception in JS when using tables. (#11256) 2019-05-15 08:21:25 +02:00
Andreas Rumpf
95f8ed0382 fixes #6732 (#11255) 2019-05-15 08:18:20 +02:00
Andreas Rumpf
9ecb24e443 fixes #88 (#11243) 2019-05-15 08:17:29 +02:00
Ștefan Talpalaru
fa3d19b477 cas(): use an "__atomic" builtin instead of the legacy "__sync" one (#11246)
"New code should always use the ‘__atomic’ builtins rather than the ‘__sync’ builtins." - https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
2019-05-14 21:47:14 +02:00
Hitesh Jasani
0b41f26bd6 Expose api to disable autoinitializing OpenSSL. (#11247) 2019-05-14 17:08:52 +02:00
Andreas Rumpf
651ae68567 fixes #11202 2019-05-14 12:02:26 +02:00
Andreas Rumpf
2fba65b29f fixes #7937 (#11244) 2019-05-14 07:44:39 +02:00
Aditya Siram
a6d4421241 Fixes #9365 : let with exportC pragma in template. (#11235)
* Fixes #9365 : let with exportC pragma in template.

* Fix according to comments.
2019-05-14 01:34:32 +02:00
Arne Döring
55cf971adf fixes #11194 (#11242) 2019-05-14 01:28:44 +02:00
Jasper Jenkins
6fc74cec55 Iterator fixes (#11234) 2019-05-13 20:50:21 +02:00
Andreas Rumpf
fb1c3a95a5 fixes #11124 2019-05-13 17:34:15 +02:00
Andreas Rumpf
69658ad396 fixes #11131 2019-05-13 17:25:57 +02:00
Araq
f84293ac8f fixes #11237 2019-05-13 09:40:43 +02:00
Araq
869007b005 ccgexprs.nim: fewer newlines 2019-05-13 09:38:56 +02:00
Jasper Jenkins
07eca7decd Fixes #4140 (#11238)
* correct error

* cleaner

* fix line info
2019-05-13 07:47:30 +01:00
Clyybber
0c869eaa47 Fix destructor injections for global variables (#11230)
* attach global destructors at end of mainModule
* Add testcase
* Minor cleanup
* Inject topLevelVar temporaries' destructors early
* Fix megatest
2019-05-13 08:28:33 +02:00
Araq
a3e27ffa2c fixes #11215 2019-05-12 15:07:35 +02:00
Benny Elgazar
a83d609960 exposing procs (#11218) 2019-05-11 10:32:34 +02:00
Arne Döring
b92fd30282 rename tyExpr/tyStmt to tyUntyped/tyTyped (#11227) 2019-05-11 10:11:08 +02:00
Araq
f03391d477 fixes #6855 2019-05-10 19:50:23 +02:00
Araq
95b65504e6 sequtils: minor typo 2019-05-10 19:50:23 +02:00
Ico Doornekamp
a170719d1a repr on seq now outputs @[...] (#11224) 2019-05-10 16:33:42 +02:00
Araq
9aa6aa6514 make epochTime available in DLLs; refs #6855 2019-05-10 15:20:39 +02:00
Arne Döring
3ef727adfe Testament print failed command (#11219) 2019-05-10 14:04:08 +02:00
Araq
22881a3543 closes #9825 2019-05-10 11:43:58 +02:00
Oscar Nihlgård
de5c0d3aa9 Make range checks in semConv (#7164)
* Remove NaN/Inf/NegInf magic
* Make range checks in semConv
* fix the failing line
* fix `firstOrd` and `lastOrd`
* fix `localError`
* remove debug comment
* Cleanup, fix failing test
* make tests green
2019-05-10 11:10:11 +02:00
Araq
3a479ff53f fixes #11153 2019-05-10 09:44:20 +02:00
Miran
e54546bcff fixes #7569, all credit to @vincentvidal (#11213) 2019-05-10 08:48:12 +02:00
Clyybber
a4f531c243 Add testcase for #9684 (#11221) 2019-05-10 08:03:48 +02:00
Clyybber
6be9b98e35 Fix #9844 (#11216)
* Fixes #9844
2019-05-09 22:58:41 +02:00
cooldome
f4c9eb1774 fixes #11204 (#11207) 2019-05-09 16:45:56 +02:00
Andreas Rumpf
532edc3e9a Merge pull request #11208 from JasperJenkins/10139
Fix typdesc arg iterators
2019-05-09 11:53:29 +02:00
Jjp137
541751305c manual: fix typo in inImplicitlyConvertible [ci skip] (#11211) 2019-05-09 06:47:43 +02:00
Jasper Jenkins
55a3b51e40 fix complex typdesc iterators 2019-05-08 14:29:42 -07:00
Andreas Rumpf
aa76857462 Merge pull request #11181 from nim-lang/pending-future-tracking
Implements pending future tracking in async.
2019-05-08 20:37:31 +02:00
Andreas Rumpf
641e8f596c Merge pull request #11201 from nim-lang/araq-fixes-11200
fixes 11200
2019-05-08 20:36:25 +02:00
Andreas Rumpf
3b27b80069 Merge pull request #11069 from jrfondren/devel
(docs) fix unidecode.unidecode example input string
2019-05-08 17:56:48 +02:00
Andreas Rumpf
99ae911391 Merge pull request #11132 from jrfondren/expand-amb-identifier-output
provide more useful ambiguous-identifier error output
2019-05-08 17:54:53 +02:00
Andreas Rumpf
cd79c6f532 Merge pull request #11159 from JasperJenkins/const-named-tuple-unpack
Const named tuple unpacking
2019-05-08 17:50:41 +02:00
Andreas Rumpf
65b6250e59 Merge pull request #11199 from mratsim/allow-float-ranges-again
Reallow float ranges in random module
2019-05-08 17:49:49 +02:00
Andreas Rumpf
61380d0a07 Small cleanup (#11185)
* Remove mStaticTy and mTypeTy

* Replace countup(x, y-1) with x ..< y

* Replace countup(x, y) with x .. y
2019-05-08 17:18:46 +02:00
Araq
f6c9fe789f fixes #11200 2019-05-08 16:31:59 +02:00
Araq
ddad57e7a9 typo 2019-05-08 15:05:21 +02:00
Matt Haggard
8180d443b9 Allow for locale-based parsing/formatting of dates (#11170)
* Allow for locale-based parsing/formatting of dates

* Updates based on review feedback of PR 11170

DateTimeLocale arrays are now indexed by Month and WeekDay enums.
More sane date used for testing.
Documentation newline.
Case change of DefaultLocale (and make it public)

* Add changelog entry for DateTimeLocale addition to times module

* Use pattern symbols for DateTimeLocale attribute names
2019-05-08 13:48:04 +02:00
Mamy André-Ratsimbazafy
5363b8cc59 Reallow float ranges in random module 2019-05-08 13:48:03 +02:00
Araq
072566d5f4 fixes #11196 2019-05-08 13:09:49 +02:00
Araq
ac670a49c0 no 'defers' in my backend 2019-05-08 12:47:09 +02:00
Jacek Sieka
3d9269195f testament: apply skip to hard-coded categories (#11168)
* testament: apply skip to hard-coded categories

* allow disabling megatest
2019-05-08 12:35:13 +02:00
Taylor Hoff
1e89e5bf9c Pass command line arguments from build_all.sh to build.sh (#11195) 2019-05-08 10:23:17 +02:00
Arne Döring
34405db80f forbid casting to bare unchecked array (#11186)
* fixes #11180, forbid casting to unchecked array.
* allow UncheckedArray as param
2019-05-08 09:36:27 +02:00
Miran
a5fb0acf5f CountTable: check for usages after sorting (#11189) 2019-05-08 09:31:57 +02:00
Dominik Picheta
d24585c49e Merge pull request #11190 from zestyr/etimeout
Update outdated ETimeout exception name
2019-05-07 22:38:59 +01:00
Jasper Jenkins
425baeaec6 cleanup (#11192) 2019-05-07 20:33:09 +02:00
Clyybber
cc28eef38e Replace countup(x, y) with x .. y 2019-05-07 12:37:28 +02:00
Clyybber
f18b3af9d4 Replace countup(x, y-1) with x ..< y 2019-05-07 12:32:05 +02:00
Clyybber
9ffab44c35 Remove mStaticTy and mTypeTy 2019-05-07 11:23:03 +02:00
Arne Döring
6f7f043c9b Fix type recursion check (#11144)
* fixes #3456
* add test #3456
2019-05-07 08:29:17 +02:00
Jasper Jenkins
a6ba3116b2 Fixes for ptr array deref codegen (#11191)
* fixes for ptr array derefence codegen
* fix comments, make diff nicer
2019-05-07 08:14:38 +02:00
Zestyr
a06038be3f Update outdated ETimeout exception name 2019-05-07 01:28:33 +02:00
Araq
7804b5c558 nicer 'CC' output messages 2019-05-06 23:58:15 +02:00
Araq
2475d92c36 fixes #10192 2019-05-06 21:42:49 +02:00
Araq
a85d387928 fixes #10978 2019-05-06 21:42:49 +02:00
Araq
4032726e87 manual: add a section about aliasing restrictions for parameter passing; Spark inspired 2019-05-06 21:42:49 +02:00
Araq
8b9d59d973 koch.nim: nothing to do here 2019-05-06 21:42:49 +02:00
Oscar Nihlgård
4c6fc173b7 low/high for float ranges (#11177) 2019-05-06 21:19:40 +02:00
Dominik Picheta
abe634aefe Implements pending future tracking in async. 2019-05-06 17:18:30 +01:00
jcosborn
b1091f85d4 fixes #9578 (#11176)
* fixes #9578

* fixed and expanded test
2019-05-06 09:34:03 +02:00
Jasper Jenkins
1f207df7ae handle in semConst 2019-05-05 11:45:53 -07:00
Araq
0ecaaa85e9 fixes #9403 2019-05-05 16:08:16 +02:00
Jasper Jenkins
d4167c3f8c make work again 2019-05-05 03:46:02 -07:00
nc-x
e42c304e4a Fix loop tuple unpacking in templates (#11174)
* Fix loop tuple unpacking in templates

* Add test
2019-05-05 12:22:41 +02:00
Araq
094d71cb6f fixes #11175 2019-05-05 12:20:43 +02:00
Araq
a60305fbf3 fixes macros.quote documentation; doubling of the escape operator never worked! 2019-05-05 12:20:43 +02:00
Jasper Jenkins
ec099fc13f handle separately in backends 2019-05-05 01:15:31 -07:00
Clyybber
4fd79f5b47 Fix #11058 (#11172) 2019-05-05 08:26:22 +02:00
Araq
9348636cba docs: minor subjective improvement 2019-05-05 00:10:26 +02:00
Araq
6ed1f2b939 docs: minor subjective improvement 2019-05-05 00:04:06 +02:00
Federico Ceratto
70f5d7fc42 Run nimscript without "nim e" (#11121)
Add a link to nimscript.rst
Add a suggestion on disabling hints.
2019-05-04 23:54:05 +02:00
Federico Ceratto
90a7460d91 Document bit fields usage (#11011) 2019-05-04 23:31:05 +02:00
Jasper Jenkins
6e4ea40475 empty container param error msg (#11158) 2019-05-04 23:28:09 +02:00
Miran
ce152ed91f iterators: several small fixes (#11162)
* fix pairs, mpairs, mitems for cstring for JS backend
* add mutation check for pairs and mpairs for strings and seqs
* change the assertion message - modifying (changing elements) is not
  a problem, changing the length is
2019-05-04 23:02:50 +02:00
Miran
d2e1936cf2 tables: check for mutation when iterating (#11160) 2019-05-04 22:58:42 +02:00
Aditya Siram
cc2be5e4c6 Fixes #11045. Assigning a proc to const and invoking. (#11076) 2019-05-04 22:57:15 +02:00
genotrance
45759b5e90 Fix 105, few fixes for 101 (#11148) 2019-05-04 22:38:52 +02:00
nc-x
20e3a39d6c Fix nim doc ignoring doc comments with implicit returns and implicit conversions (#11173) 2019-05-04 22:35:00 +02:00
cooldome
d3db189eb4 Destructor lifting fixes #11149 (#11163)
* fixes #11149

* add test
2019-05-04 22:34:37 +02:00
Arne Döring
9c3e23e075 Fix ..< iterator (#11103)
* add iterator overloads

* add test
2019-05-03 23:43:41 +02:00
jrfondren
8cadeb9605 Merge branch 'devel' into expand-amb-identifier-output 2019-05-03 13:03:45 -05:00
narimiran
515ab81477 add whitespace on the right-hand side of --
This is an em-dash, not some `--use` flag.
2019-05-03 11:33:29 +02:00
Araq
9ad96b58e6 decent borrow check for --newruntime 2019-05-02 11:46:38 +02:00
Araq
1ff2b021a5 fixes #11114 2019-05-02 09:39:57 +02:00
Arne Döring
43749c4cb8 Append all output on failed test. (#11156) 2019-05-02 08:13:10 +02:00
Andreas Rumpf
e1515b53d1 introduce temporary <//> for 'owned' to get this compile with 0.19 (#11145)
* introduce temporary <//> for 'owned' to get this compile with 0.19
* make newTable[string, owned Node]() compile (but it crashes)
* make sink/owned parameters consistent
* make actiontable test compile again
* VM: support sytem.move; makes tests green
2019-05-02 08:07:09 +02:00
Jasper Jenkins
0add3a6dc0 enable t9177. 2019-05-01 22:37:38 -07:00
Jasper Jenkins
8a6b416c28 const named tuple unpacking 2019-05-01 22:18:45 -07:00
genotrance
c94ab46923 Fix ospaths import error (#11150) 2019-05-01 08:54:02 +02:00
Jasper Jenkins
60e3d7930d discard type is an error, fixes #7470 (#11146) 2019-05-01 08:53:20 +02:00
Andrii Riabushenko
7cfc7cfb26 fixes #11118 2019-04-30 21:46:45 +01:00
Jasper Jenkins
3d0190f470 Fix unexpected result of rand on a range, fixes #11015 (#11035) 2019-04-30 09:28:28 +02:00
Arne Döring
9dbf56ba2b Update bug_report.md (#11123) 2019-04-30 09:27:38 +02:00
Julian Fondren
6dfde0e931 fix test expecting ambiguous-identifier error
the test is only against the first line, but testament doens't
support multi-line error messages yet.
2019-04-29 23:15:10 -05:00
Araq
bb8e2eea38 move analyser: fixes another critical bug 2019-04-29 21:06:38 +02:00
Julian Fondren
8274c0c6b3 balance space around emdash -- 2019-04-29 10:39:26 -05:00
jrfondren
0e1bc3f5ca fixes #11133, error on runtime use of compile-time procs in JS target (#11134) 2019-04-29 15:31:44 +02:00
Araq
6e3a4ebf6a added unown test case 2019-04-29 13:36:00 +02:00
Araq
0a84b8fb4d added system.unown to make 'owned' sane to use in practice; later on we might change the type inference rules to make it more convenient 2019-04-29 13:36:00 +02:00
jiro
ddc86d1b4b streams: Update documentation, refs #10330 (#11059) 2019-04-29 11:32:02 +02:00
Miran
737fff5902 Initialized collections (#11094)
* tables: initialized by default
* sets: initialized by default
* DRY: extract shared functionality
* add a changelog entry
* fix errors
* don't test include files
* make it work for sharedtables
* fix discovered bugs
* add exhaustive tests
2019-04-29 08:13:52 +02:00
Julian Fondren
93edefbf5b add indent to ambiguous-identifier output 2019-04-28 09:34:08 -05:00
Andreas Rumpf
55aa2129b5 make twidgets example green (#11135) 2019-04-28 13:28:18 +02:00
Arne Döring
a432aedb54 Generic tuple recursion fix (#11115)
* fixes #1145
* unify error messages
2019-04-28 10:11:41 +02:00
Julian Fondren
d8e0d6801b re-include ambiguous identifier in ambiguous identifier output 2019-04-28 02:00:06 -05:00
Julian Fondren
d85de3cd57 re-include module in ambiguous identifier output 2019-04-28 01:51:56 -05:00
Julian Fondren
86b7de224a provide more useful ambiguous-identifier error output 2019-04-28 01:40:42 -05:00
cooldome
da3b649539 bug fix in sym body hash (#11127) 2019-04-27 14:31:05 +01:00
Mamy Ratsimbazafy
98002149a8 Fix #11111 nkIdentsDef left in vmgen (#11126)
fixes #11111
2019-04-27 14:29:39 +01:00
cooldome
3647c03cad reimplement_pr_10974 (#11130) 2019-04-27 12:41:08 +01:00
Lolo Iccl
69755542f4 add progmas to params of macros.newProc (#11025)
Merging
2019-04-27 12:22:02 +01:00
Andreas Rumpf
46ce797231 newruntime: progress... 2019-04-27 09:36:34 +02:00
Araq
8e27bddb97 newruntime: make 'discard new RootObj' work 2019-04-26 20:33:58 +02:00
Araq
b350a9fc52 preparations to make the twidgets test work 2019-04-26 15:44:06 +02:00
Araq
1f7615ad9d make seq.add more effective for --newruntime 2019-04-25 13:54:25 +02:00
Araq
a36d8bbf6c introduce a special typing rule that makes seq[owned ref T] easier to use; remains to be investigated... 2019-04-25 13:54:04 +02:00
Andreas Rumpf
eb9043c0e9 fixes #11095 (#11104)
* fixes #11095
2019-04-25 07:59:34 +02:00
Alvydas Vitkauskas
a644f443bc Fix: remove pragma inline from parseBin|Oct|Hex (#11105) 2019-04-24 19:46:13 +02:00
Alvydas Vitkauskas
ae2923e5de Make parseutils.parseBin|Oct|Hex generic (#11067)
* make parsutils.parseBin generic and improve runnableExamples
* reimplement parseBin/Oct/Hex and improve runnableExamples
* update changelog.md file with parseBin/Oct/Hex and fix a typo
2019-04-24 17:26:01 +02:00
Miran
25e3e6db8e docgen: generate docs for modules imported in system.nim, fixes #10972 (#11101) 2019-04-24 14:12:16 +02:00
Oscar Nihlgård
1ddb496b6d Add missing deprecated pragma (#11100) [ci skip] 2019-04-24 13:39:28 +02:00
Jacek Sieka
3c689c1f2e tester: add test skipping capability (#11080) 2019-04-23 22:09:41 +02:00
Andreas Rumpf
02920c2cd9 fixes #11082 2019-04-23 21:51:38 +02:00
Andreas Rumpf
7ce24d91a3 newruntime: fix for -d:useMalloc 2019-04-23 21:26:43 +02:00
Araq
437f464810 fixes #1192 2019-04-23 14:44:05 +02:00
Aditya Siram
809a4a77a5 Ignore nimble test packages some generated files. (#11087) 2019-04-23 14:39:14 +02:00
Jasper Jenkins
e64dde734b Fixes #11078 (#11079)
* Fixes #11078
* Move to existing runnableExamples, update the expected html.
* Remove second comment token.
2019-04-23 14:20:27 +02:00
Jacek Sieka
9d5e8e55f9 deprecate programResult, avoid exposing in standalone mode (#11075) 2019-04-23 12:10:33 +02:00
Federico Ceratto
2cdff617fd Update docs around docSeeSrcUrl #6071 (#11074)
Flag docSeeSrcUrl as deprecated.
Add quick start paragraph.
Add links from the language manual.
2019-04-23 11:36:16 +02:00
Araq
8d206b20d4 fixes #11089 2019-04-23 10:44:00 +02:00
Araq
3161e48760 strformat: minor style changes 2019-04-23 10:44:00 +02:00
Jjp137
e597db83b7 tables: fix link (#11090) [ci skip] 2019-04-23 09:37:21 +02:00
Zed
3b4952da94 Fix header inconsistencies in documentation (#11071) 2019-04-23 08:40:20 +02:00
Araq
4f93669754 fixes #11065 2019-04-22 10:11:37 +02:00
Araq
0194f43467 system.nim: copyMem and friends do not raise any exception 2019-04-22 10:00:54 +02:00
Araq
665fcb12dd fixes #11073 2019-04-22 08:05:16 +02:00
Andreas Rumpf
fabc2a7086 revert discardable transformation (#10905)
* Revert "Properly wrap discarded statements (#10322)"

This reverts commit 15584879b9.

* add test for implicit discard after defer
* enable t10241 again
* make C++ tests green again
2019-04-21 09:57:53 +02:00
Zed
88079a0dee Documentation import fixes (#11070)
* Move asyncdispatch imports below introduction

* Move nre imports below documentation
2019-04-21 09:45:05 +02:00
Julian Fondren
42fffc3250 fix unidecode.unidecode example input string 2019-04-20 21:10:52 -05:00
Andreas Rumpf
375b444ecd make -d:nimQuirky work with devel 2019-04-20 22:16:22 +02:00
Araq
5edc5fc650 manual_experimental: cleanup the type/typedesc confusions, typedesc is here to stay for good 2019-04-20 17:55:25 +02:00
Araq
135f867870 manual: cleanup the type/typedesc confusions, typedesc is here to stay for good 2019-04-20 17:51:42 +02:00
Andreas Rumpf
33a370866c hotfix: nimParseBiggestFloat needs to be patched for the newer string implementations; refs #11062 2019-04-20 15:33:26 +02:00
Andreas Rumpf
0121dda9ba remove the restriction that module names need to be unique per Nimble… (#11064)
* remove the restriction that module names need to be unique per Nimble package

* make tests green again

* use the 'response' linker file also on Unix in order to fix megatest
2019-04-20 15:19:02 +02:00
Andreas Rumpf
44ec66bd48 fixes #11053 2019-04-19 18:02:43 +02:00
Andreas Rumpf
bc7d1de7fd added a note about what to not do 2019-04-19 18:02:43 +02:00
Andreas Rumpf
a394d31746 move analyser is smarter; refs #11053 2019-04-19 18:02:43 +02:00
Arne Döring
abb05ab645 fewer ropes (#11037) 2019-04-19 09:05:31 +02:00
Arne Döring
a55817f9ac Fix varargs int32 (#11054)
* fixes #10999
* adds a test for #10999
2019-04-18 20:53:57 +02:00
Arne Döring
ed6160ad6d callsite lineinfe for stackTrace template (#10785) 2019-04-18 14:02:10 +02:00
Araq
750f50b6c0 destructors: internal compiler refactoring 2019-04-18 00:53:02 +02:00
Araq
fb3681b425 make the CIs happy 2019-04-17 21:35:50 +02:00
Araq
7640a230fc fixes #11050 2019-04-17 17:26:59 +02:00
Araq
850e90ac30 DFA: We are not allowed to take ownership of parameters 2019-04-17 17:18:47 +02:00
Araq
5bdab044f5 fixes #11048 2019-04-17 13:22:22 +02:00
Christopher Dunn
14fc7437c3 Improve tables docs for del/take (#11030)
* Continuation of b40a637f
* https://forum.nim-lang.org/t/4789
2019-04-17 11:57:32 +02:00
cooldome
7d8af25d58 revert parser stmtListExpr (#11007)
* Revert "Support for stmtListExpr in parser after major keywords. Scaled down version. (#10852)"

This reverts commit 862897dc0f.

* redo fix for #4035

* render stmtlistExpr using semicolon

* Revert "render stmtlistExpr using semicolon"

This reverts commit cafb78b8d5.

* revert test
2019-04-17 11:55:41 +02:00
Miran
43832f8e57 remove shadow warning, fixes #10732 (#11039) 2019-04-17 11:54:51 +02:00
Araq
d8a8c8806f fixes #11014 2019-04-17 00:15:40 +02:00
Araq
ce024a73bf make move-analysis smarter; see tuse_ownedref_after_move test case 2019-04-16 10:35:43 +02:00
Araq
a520eb7766 injectdestructors.nim: code cleanups 2019-04-16 10:35:43 +02:00
Araq
0e157de3a0 astalgo: use the code style that the other lines use; make debug() less verbose 2019-04-16 10:35:43 +02:00
Araq
045e026d0e dfa.nim: track object/tuple field accesses more precisely; sink(o.x); sink(o.y) needs to compile; activate the tuple unpacking transf.nim bugfix 2019-04-16 10:35:43 +02:00
Andy Davidoff
01f09567c4 faster CountTable sort(), optional SortOrder (#11010)
* use existing sort for CountTable, and
add SortOrder options to CountTable, OrderedTable sort(s)

* add some tests, runnables, etc.

* fix runnable imports
2019-04-16 09:42:54 +02:00
cooldome
374a85bb9c Review of vcc command line arguments (#11003)
* fixes #11000

* trigger commit

* Trigger build
2019-04-16 08:47:31 +02:00
narimiran
41ee3538df disable testing of nimly package 2019-04-15 18:53:25 +02:00
Clyybber
2f56dd6b2b Extend the fix for #11018 to strings (#11031)
* Extend the fix for #11018 to strings

* Fix testcase
2019-04-15 17:06:31 +02:00
Jasper Jenkins
a68c5662f2 Add len check for newIfStmt to avoid segfault (#11032) 2019-04-15 17:02:25 +02:00
Andy Davidoff
e2848ccd2b minor capitalization typo in manual (#11028) [ci skip] 2019-04-15 08:44:45 +02:00
Arne Döring
107905919e $ command in gdb now works (#10956) 2019-04-15 08:25:21 +02:00
Araq
a517a9985b fixes another regression; the behaviour of 'array' formatting was changed 2019-04-15 08:20:28 +02:00
Araq
59ccaa43c7 fixes #11012 2019-04-15 08:20:28 +02:00
Clyybber
499fa3f3dc Fixes #11018 (#11019) 2019-04-14 23:34:19 +02:00
Andreas Rumpf
0e6eb7d483 make strscans module work with --newruntime 2019-04-14 23:13:49 +02:00
Andy Davidoff
485d5448fa render urls correctly (#11022) 2019-04-14 08:20:23 +02:00
cooldome
fdc3f54f97 fix reraise (#11017) 2019-04-13 10:50:30 +02:00
Araq
e33266ded1 make koch.nim compile with --newruntime. Again. 2019-04-12 19:59:04 +02:00
Araq
0e57b4cf64 we do not support -d:useWinAnsi switch anymore 2019-04-12 15:17:47 +02:00
Araq
8201db81b2 added system.disarm (experimental) 2019-04-12 13:28:13 +02:00
Araq
3ceb258ebf fixes #11005 2019-04-12 13:28:13 +02:00
Araq
572735bbfa fixes #11004 2019-04-12 13:28:12 +02:00
cooldome
041d15392a Compiler plugin for implementing incremental computation in user space (#10819)
This plugin provides essential building block for implementing incremental computations in your programs. The idea behind incremental computations is that if you do the same calculation multiple times but with slightly different inputs you don't have to recompute everything from scratch. Also you don't want to adopt special algorithms either, you would like to write your code in standard from scratch manner and get incrementality for free when it is possible.

The plugin computes the digest of the proc bodies, recursively hashing all called procs as well . Such digest with the digest of the argument values gives a good "name" for the result. Terminology loosely follows paper "Incremental Computation with Names" link below. It works well if you have no side effects in your computations. If you have global state in your computations then you will need problem specific workarounds to represent global state in set of "names" . SideEffect tracking in Nim also useful in this topic.

Classical examples:

Dashboard with ticking data. New data arrives non stop and you would like to update the dashboard recomputing only changed outputs.
Excel spreadsheet where user changes one cell and you would like to recompute all cells that are affected by the change, but do not want to recompute every cell in the spreadsheet.
2019-04-11 23:09:11 +02:00
cooldome
de02fd0b89 fixes #10765 (#10993) [backport] 2019-04-11 13:51:51 +02:00
Araq
a2ad069769 preparations for --newruntime owned refs/callbacks 2019-04-11 12:42:51 +02:00
Araq
1c0b1e9d05 sem'check understands 'owned procs' 2019-04-11 12:35:49 +02:00
Araq
8fb04b320a sigmatch: ensure 'owned proc' works with system.isNil 2019-04-11 12:35:49 +02:00
Arne Döring
1da98b1636 Less ropes (#10979)
* convert ropecg to a macro
* fewer intermediate ropes
2019-04-11 09:48:10 +02:00
Miran
9f94199d0c random: works for slices and enums, fixes #7698 (#10998) 2019-04-11 08:38:18 +02:00
Araq
2846156e13 newruntime: raising an exception works but currently leaks memory because currentException global is not an 'owned' ref 2019-04-10 20:34:00 +02:00
Araq
cb4e04d88e enable more tests 2019-04-10 20:34:00 +02:00
c-blake
1394978347 Make secureHash accept any openArray[char], not only string. (#10988)
* Make `secureHash` accept any `openArray[char]`, not only `string`.

* Put in a changelog entry as per Araq request.
2019-04-10 17:48:22 +02:00
Miran
1494d88fa2 rst: parse brackets individually, fixes #10475 (#10997) 2019-04-10 15:55:57 +02:00
Miran
2608bc369e json: add '\v' support, fixes #10541 (#10987) 2019-04-10 15:54:49 +02:00
Araq
bc50795d9c enable most tnewruntime_strutils tests 2019-04-10 15:49:04 +02:00
Araq
26fc7d465a strutils.nim: fixes the indentation of formatEng 2019-04-10 15:44:34 +02:00
Araq
a34ce2714a newruntime: fixes another bug 2019-04-10 13:53:47 +02:00
Araq
28b4db4470 be consistent, strings have destructors for --gc:destructors 2019-04-10 11:04:38 +02:00
Araq
0518794291 make parseopt compile with --newruntime 2019-04-10 10:10:08 +02:00
Araq
6617b8deee make tests green again 2019-04-10 08:41:38 +02:00
Araq
4974f999c3 manual: make currency example compile and ensure it remains working 2019-04-09 22:16:52 +02:00
Araq
72408842d9 koch.nim compiles with --newruntime 2019-04-09 21:25:36 +02:00
Miran
a4883b8426 make nimble packages testing more robust (#10984)
* better tests for the existing packages
* enable testing for packages not in packages.json
* add new packages
2019-04-09 19:38:49 +02:00
Araq
2430521c84 newruntime: fixes memory leak 2019-04-09 12:20:10 +02:00
Araq
32ad3bb236 make 'raise' statement work with --newruntime 2019-04-09 11:39:10 +02:00
Araq
d59e9c37fa added lowerings.evalOnce 2019-04-09 11:38:54 +02:00
Araq
da6ff14184 don't emit an implicit try finally when in system.nim in order to prevent endless recursions in the try handler 2019-04-09 11:22:23 +02:00
Araq
0a01f5b655 strs.nim: fixed a silly typo 2019-04-09 11:21:35 +02:00
Araq
f44e1e2214 make tests green again 2019-04-09 09:11:44 +02:00
Arne Döring
2c645eded5 add strformat limitations section (#10982)
* add strformat limitations section
* Update lib/pure/strformat.nim
2019-04-09 08:14:59 +02:00
Andreas Rumpf
58df5b0a8f allocators.nim: use zero initialization 2019-04-08 23:07:21 +02:00
Araq
430814fdb3 make it compile with older nim versions 2019-04-08 17:17:54 +02:00
Araq
6efa7ecf18 respect -d:useMalloc everywhere; turn ansi_c and memory into proper Nim modules 2019-04-08 17:09:27 +02:00
Araq
9565b844dd compute sinks/assignments properly for for-loop iteration variables 2019-04-08 13:53:15 +02:00
Araq
001835bdec use old for loop unpack syntax for bootstrapping 2019-04-08 07:48:51 +02:00
Andreas Rumpf
b2898cd254 an owned ref parameter behaves as a 'sink' parameter 2019-04-07 23:11:37 +02:00
Andreas Rumpf
f08e90f0d6 more efficient enumToStr implementation that works without the old typeinfo structures 2019-04-07 21:14:54 +02:00
Araq
f6ad071a46 make strformat work as NimScript again 2019-04-06 20:56:48 +02:00
Araq
9f5d9d1993 makes koch.nim sem'check with --newruntime 2019-04-06 19:13:10 +02:00
Araq
f1ee36692a fixes compiler regression 2019-04-06 19:12:44 +02:00
Araq
6e6a9a721f destructors: we are cooking now 2019-04-06 17:32:53 +02:00
Araq
fab75fbaf1 added nimAsgnStrV2 compilerproc 2019-04-06 17:32:53 +02:00
Araq
1a202b9754 render lent types properly 2019-04-06 17:32:53 +02:00
Andreas Rumpf
bc681a328f fixes unowned->owned conversion rule 2019-04-06 09:53:59 +02:00
Alexander Ivanov
f101f09256 Fix astdef typ deref (#10245) 2019-04-05 16:43:36 +02:00
Arne Döring
3a5a0f6d46 Strformat symbol binding (#10927) 2019-04-05 15:27:04 +02:00
Araq
f2f9386101 make sets.nim useful for selective 'from import's 2019-04-05 14:57:59 +02:00
cooldome
e749fc08e7 fixes #10943 (#10947) 2019-04-05 14:50:57 +02:00
Andreas Rumpf
efeee326f8 destructors: progress 2019-04-05 12:38:30 +02:00
Andreas Rumpf
3e3a8bd4cd newruntime: codegen fix 2019-04-05 12:38:30 +02:00
Miran
f309e4ff54 relax warning about inconsistent spacing (#10968)
Now the warning is raised only in the cases when there is an
inconsistency in the style (spacing vs no spacing):
* if a> b      --> warning
* if a >   b   --> no warning
2019-04-05 12:37:33 +02:00
cooldome
795de374fb fixes destructor tuple regression #10940 (#10941)
* fixes #10940

* bug fixes

* fix spacing
2019-04-04 20:46:02 +01:00
Araq
d5f2a5c204 add back what was required 2019-04-04 16:35:15 +02:00
Araq
228d53006a refactoring: move threadlocalstorage into its own file 2019-04-04 16:35:15 +02:00
Araq
c9c6741cde newruntime: fixes codegen for closures 2019-04-04 16:35:15 +02:00
tofu
94a21134e9 fixes #9811 (#10961)
* fixed wrong default indent value (nimpretty)

* fixed help message of nimpretty
2019-04-04 15:09:01 +02:00
tofu
a990afcedc fixes #10200 (#10950)
* fixes #10200

* add rule for other comparison operators

* add rule for '!='

* add test

* fixed to pass the test
2019-04-04 14:58:54 +02:00
cooldome
8546393ddb Merge pull request #10954 from cooldome/atomicInc_regression
fixes regression #10953
2019-04-04 11:42:08 +01:00
Arne Döring
65ee80e50c Pure ref object; fixes #10721 (#10955) 2019-04-04 09:06:12 +02:00
Arne Döring
e5cdd7f773 add alias for --debugger:native (#10957) 2019-04-04 08:59:26 +02:00
MrZoraman
c6327e229a Fix dead sequtils link (#10960) [ci skip] 2019-04-04 07:03:15 +02:00
Andrii Riabushenko
ad1c6fe8b9 fixes #10953 2019-04-03 15:06:26 +01:00
cooldome
dc2986789b fixes #10942. Lent T bug (#10946)
* fixes #10942

* add test

* bug build
2019-04-03 15:55:53 +02:00
cooldome
734da9544d fixes #10948 (#10949) 2019-04-03 10:42:41 +02:00
Andreas Rumpf
eaca62f331 make tests green again 2019-04-02 14:55:45 +02:00
Miran
d337e4a932 md5: add missing .gcsafe. to the forward declarations (#10944) 2019-04-02 14:44:19 +02:00
Araq
f2691fdc7e try to make travis green 2019-04-02 12:24:58 +02:00
Araq
9029257a99 attempt to make the CIs green again 2019-04-02 11:01:38 +02:00
Araq
0b96b135f8 simple program works with --newruntime 2019-04-02 10:43:11 +02:00
Miran
b707790519 do not display stacktrace twice, fixes #10922 (#10939) 2019-04-02 09:10:03 +02:00
Araq
f5a7a3bee9 make megatest work again 2019-04-02 08:23:13 +02:00
Araq
b77a2037f8 newruntime: progress 2019-04-02 00:46:38 +02:00
Araq
3b14f0ed10 see what appveyor thinks about this 2019-04-01 17:50:03 +02:00
Araq
0f0cc9e6eb see what appveyor thinks about this 2019-04-01 17:45:23 +02:00
Araq
204ecfc817 os.nim: proper indentation 2019-04-01 17:45:08 +02:00
Araq
c3067e36bb newruntime: progress 2019-04-01 16:51:18 +02:00
Araq
fda1352ccf json.nim: tiny refactoring 2019-04-01 16:24:04 +02:00
Araq
cce8d3da27 fixes #10934 2019-03-31 19:59:17 +02:00
Miran
aeb30a72c0 update unicode.nim (#10921)
* update unicode.nim

* create a script to create the needed unicode data
* make unicode.nim compatible with Unicode v12.0.0
* slightly improve unicode.nim documentation (fixes #4795)

* more documentation
2019-03-31 08:36:04 +02:00
Andreas Rumpf
aa072b9525 fixes #10930 2019-03-30 23:45:40 +01:00
Araq
caf0552573 make Boehm GC work on Windows 2019-03-30 00:56:21 +01:00
Arne Döring
00f419bcd6 remove check for better error message (#10926) 2019-03-29 20:21:28 +01:00
Andreas Rumpf
f8e720fda9 fixes json.nim regression 2019-03-29 08:01:59 +01:00
Miran
dafd995402 change the order of appveyor tests (#10920)
Testing packages sometimes randomly fails because of some
reason not connected to Nim (e.g. github is down).
Currently, that would prevent "regular" appveyor tests
from running.

Changing the order will allow "regular tests" to run
regardless of the outside problems with packages.
2019-03-28 17:18:42 +01:00
Arne Döring
e904b3f952 code cleanup (#10874) 2019-03-28 12:32:02 +01:00
Andreas Rumpf
fcd3b0c4d8 manual: prefer 'typeof(x)' over 'type(x)' 2019-03-27 15:08:32 +01:00
Andreas Rumpf
3cb645ab50 move more stuff into manual_experimental 2019-03-27 15:08:32 +01:00
Andreas Rumpf
4d0f05a98a manual.rst: move experimental features to manual_experimental 2019-03-27 15:08:32 +01:00
Miran
d74179dde3 use atomicInc/atomicDec (#10906) 2019-03-27 11:17:44 +01:00
genotrance
0378bfa402 Fix #10907 - remove unused typedef string (#10908) 2019-03-26 16:20:26 -05:00
narimiran
d9913593c1 proper fix 2019-03-26 20:26:23 +01:00
narimiran
3c4f1acf0c fix nim-chronicles test: there is a new dependency 2019-03-26 18:35:17 +01:00
Araq
3cf846e02c fixes #10904 2019-03-26 16:12:47 +01:00
narimiran
73a77e9bef disable testing of nim-chronicles until is fixed 2019-03-26 16:03:40 +01:00
Arne Döring
04f901b63b add NimFrameFilter to nim-gdb.py (#10873) 2019-03-26 13:12:39 +01:00
Andreas Rumpf
bc29094af9 fixes 'nimble install nimble' problems 2019-03-26 09:51:31 +01:00
Andreas Rumpf
802ecbc49e macros: typo 2019-03-26 09:51:31 +01:00
Andreas Rumpf
8e1c6e2e2d fixes #10896 (#10903) 2019-03-25 19:26:38 +01:00
Andreas Rumpf
663b1f2c96 newruntime: bugfixes 2019-03-25 16:45:51 +01:00
Jjp137
b0e236674c logging: better documentation (#10895) 2019-03-24 18:53:04 +01:00
Andreas Rumpf
1332f649b2 stats.nim: bugfix: use min in '+' [backport] 2019-03-23 15:09:28 +01:00
Andreas Rumpf
0cc6e12425 fixes #8202 (#10888)
* fixes #8202

* make tests green
2019-03-23 14:49:21 +01:00
Viktor Kirilov
f8146dfd84 improvements on the hot code reloading support (#10892)
* calling the "_actual" versions of functions when defined within the same module - slowdown for the snappy compression is now down from x6 to x4-x5 when HCR is ON
* dynamically linking to the runtime for VS when HCR is on - binaries are smaller
* compilerProcs are also called using the _actual direct version within the module they are defined (system)!
* updated comments & goals
* handling VS-compatible compilers on Windows in a cleaner way
* now the .dll/.so files end up in the nimcache even when --nimcache isn't explicitly stated
2019-03-23 14:48:47 +01:00
Andreas Rumpf
0b2a3f6f7f fixes #10886 [backport] (#10897) 2019-03-23 14:44:53 +01:00
Andreas Rumpf
7c08303faf system.nim: documentation improvements 2019-03-23 10:55:26 +01:00
Miran
714c4f0d67 add short overview of the system module (#10883) 2019-03-23 08:34:59 +01:00
Andreas Rumpf
bf592c4e94 more destructor based changes (#10885)
* mark user defined destructors with sfOverriden to simplify the logic
* refactoring in preparation to merge liftings and generic instantiations for destructors
* ast: introduce nkHiddenTryStmt for destructor generation in order to be able to optimize better the code later on
* renamed 'patterns' switch to 'trmacros' as it was totally misleading before
* destructors: introduce tfCheckedForDestructor flag in preparation of strict =destroy checking
* test for invalid/too late destructor introductions
* liftdestructors: make code robust for nimsuggest
* --newruntime works for hello world again
* newruntime: code generation for closures
2019-03-23 00:12:05 +01:00
Mamy Ratsimbazafy
25649616ea Add OpenMP overload with stepping (#10891) 2019-03-22 23:38:43 +01:00
Andreas Rumpf
04ad200b40 fixes #10884 (#10887) 2019-03-22 11:55:15 +01:00
Andreas Rumpf
83c105c3a3 Merge branch 'devel' of github.com:nim-lang/Nim into devel 2019-03-21 09:34:02 +01:00
Andreas Rumpf
49c786331a fixes -d:nimTypeNames leak detection regression 2019-03-21 09:33:53 +01:00
Arne Döring
48d5e4f95c add condition for szUnknown (#10869) 2019-03-21 06:55:21 +01:00
Arne Döring
3794338aba Lineinfo fix (#10871) 2019-03-21 06:54:42 +01:00
Arne Döring
514674cb38 use abort instead of quit (#10872) 2019-03-21 06:52:30 +01:00
cooldome
28a926cb67 fixes #10861 (#10877) 2019-03-21 06:48:54 +01:00
Andrii Riabushenko
67e91558cf REVERT "optPar"
This reverts commit 5f1a59216b.
2019-03-21 00:45:21 +00:00
Andrii Riabushenko
5f1a59216b optPar 2019-03-21 00:17:52 +00:00
cooldome
7ba877914a increase VM limit (#10870) 2019-03-20 14:01:07 +01:00
Miran
54151ce398 docgen: add links for var, let and const (refs #10487) (#10868)
* docgen: add links for var, let and const (refs #10487)

* change the expected html
2019-03-20 11:23:38 +01:00
Miran
1eefbf6da8 improve docs for os.joinPath, fixes #10836 (#10866) 2019-03-20 08:38:24 +01:00
Araq
eeae88d81e live with the hacks, PCRE's design is crap 2019-03-19 15:49:24 +01:00
Miran
bfc7522401 docgen: generate pragma after generic, fixes #10792 (#10865) 2019-03-19 12:55:28 +01:00
Andreas Rumpf
cd9caf09d1 pcre.nim: added pcre_free and removed hacks in nre and re.nim 2019-03-19 12:48:54 +01:00
Andreas Rumpf
d3df1b8eda mark user defined destructors with sfOverriden to simplify the logic 2019-03-19 12:48:54 +01:00
Arne Döring
389b140029 add tastspec (and ast_pattern_matching) (#10863) 2019-03-19 11:45:29 +01:00
Anthon van der Neut
5c1c5902e2 fixes #10857 invisible span had width (#10860) 2019-03-19 10:38:48 +01:00
Arne Döring
188870648a sizeof alignof offsetof macros api (#10855) 2019-03-19 08:23:00 +01:00
genotrance
16fcbee1bc Fix nightlies :test: snippet issue (#10862) 2019-03-19 08:17:35 +01:00
Arne Döring
97c3b113a5 Size ptr tuple (#10846)
* fixes #10117
* Add support for recursive tuples
* detect in generics
2019-03-18 11:37:09 +01:00
Anthon van der Neut
5661a8303c correct argument name, (#10813)
* correct argument name,

updated using poUsePath, based on feedback from c-blake

* Update osproc.nim

* explicit args parameter
2019-03-18 11:13:52 +01:00
cooldome
862897dc0f Support for stmtListExpr in parser after major keywords. Scaled down version. (#10852)
* Support for stmtListExpr in parser after major keywords
* fixes #4035
2019-03-18 11:09:49 +01:00
cooldome
c19cd14fc9 fixes #10838 (#10841)
* fixes #10838
* reject func in types instead
* trigger tests
2019-03-18 11:04:01 +01:00
Miran
afeca3d9fe multi-methods need to be explicitly enabled (#10856)
* multi-methods need to be explicitly enabled

* update changelog, manual and tutorial
2019-03-18 08:21:37 +01:00
Dominik Picheta
9e28d52c2f Merge pull request #10850 from FedericoCeratto/egress-ipaddr
Detect local "egress" IP address
2019-03-17 19:29:51 +00:00
Federico Ceratto
5825dcb0b5 Detect local "primary" IP address 2019-03-17 16:58:27 +00:00
Andreas Rumpf
328901757a make DLLs tests green again 2019-03-15 17:51:52 +01:00
Andreas Rumpf
ed878014be newruntime: progress 2019-03-15 17:51:52 +01:00
Andreas Rumpf
8e5c1436ad fixes #10845 2019-03-15 17:51:52 +01:00
Andreas Rumpf
16355de5eb rename for code clarity 2019-03-15 17:51:52 +01:00
Andreas Rumpf
831626be85 newruntime: make dynamic destructors compatible with C++ 2019-03-15 17:51:52 +01:00
cooldome
5dea7c5ad7 revert discard in destroyer (#10840)
* revert discard in destroyer

* disable test
2019-03-15 13:49:32 +01:00
Andreas Rumpf
e263702688 --newruntime: progress 2019-03-14 19:53:27 +01:00
narimiran
f1a945b05f bring back typetraits.$ for backward compatibility
Some packages are still using ``from typetraits import `$` ``
which is now available from system (no need to import it).
2019-03-14 17:09:33 +01:00
narimiran
7372a4c4aa Revert "put extracted modules behind the switch, to enable doc generation"
This reverts commit 71bff7d2df.
2019-03-14 13:22:46 +01:00
narimiran
71bff7d2df put extracted modules behind the switch, to enable doc generation 2019-03-14 11:14:04 +01:00
Andreas Rumpf
4181baf400 multi-methods: remove hack, make tmethod_various compile under strict C++ [backport] 2019-03-14 09:03:21 +01:00
Andreas Rumpf
2ab6b2c657 --newruntime: work in progress 2019-03-14 07:59:44 +01:00
Andreas Rumpf
79b1eafa59 gc: removed dead code 2019-03-14 07:59:44 +01:00
Andreas Rumpf
62ab338900 added lowerings.genLen helper proc 2019-03-14 07:59:44 +01:00
Andreas Rumpf
1f61498238 added types.isFinal helper proc 2019-03-14 07:59:44 +01:00
Andreas Rumpf
ee7a9a272d destroyer.nim: added a remark about code generation 2019-03-14 07:59:44 +01:00
Andreas Rumpf
436ec57f83 seqs.nim: added a remark about C++ optimizers 2019-03-14 07:59:44 +01:00
Andreas Rumpf
07f58ddfa9 rename: semasgn -> liftdestructors 2019-03-14 07:59:44 +01:00
narimiran
939c151224 create docs for the extracted modules 2019-03-13 17:43:54 +01:00
Miran
84d3f3d448 move system.dollars in a separate file (#10829) 2019-03-13 15:59:09 +01:00
Bogdan
b270917de1 Make HWND a pointer instead of a cint and fix MSVC compiler warning (#10789)
In Windows, a HWND is a HANDLE which is a PVOID so a pointer in Nim
2019-03-13 15:54:36 +01:00
Tomohiro
cd3a58d7b0 bitops: add reverseBits and test (#10835) 2019-03-13 15:53:40 +01:00
Miran
091da5c979 testament: catch failing nimble tests (#10832)
* testament: catch failing nimble tests and clean up a bit
* fix name collision
2019-03-13 11:52:15 +01:00
cooldome
d8c3df2683 fixes #10805 (#10806) 2019-03-13 10:23:06 +01:00
sealmove
ab872be476 Added nimscript support to repl (#10834)
* added nimscript support to repl
* added bool parameter to runRepl en/disabling nimscript support
2019-03-13 10:21:24 +01:00
cooldome
8ceba8a7f3 fixes #10807 (#10814)
* fixes  #10807
* use nkAddr instead of nkHiddenAddr
2019-03-12 13:45:05 +01:00
cooldome
ea3e18bc6c fixes dce regression #10703 (#10820)
* fixes #10703

* emit frame defines once
2019-03-12 08:24:17 +01:00
Dominik Picheta
3e04afda9f Merge pull request #10823 from narimiran/json-tuples
simplify json.% for tuples and objects
2019-03-11 21:38:42 +00:00
Arne Döring
35aab357e2 Less warnings in macros (#10799) 2019-03-11 19:21:39 +01:00
narimiran
863848ad56 simplify json.% for tuples and objects 2019-03-11 16:51:06 +01:00
Miran
06f23572d0 system: some documentation improvements (#10809) 2019-03-11 11:04:08 +01:00
narimiran
44d47134f9 Revert "Follow the documentation's recommendation (#10808)"
This reverts commit 1a13b3a14e.
2019-03-10 20:09:35 +01:00
sealmove
92cd07be8b Fixed order of output in repl and added a proc for opening a custom repl (#10802) 2019-03-10 20:02:47 +01:00
zah
b9f8528db6 Don't include the nimhcr dev docs in the system module documentation (#10759) 2019-03-08 15:23:36 +01:00
Miran
bba3a20e7c documentation style tweaks (#10790)
* exports are the least important field in the docs:
  they are put in the last place (at the bottom)
* indent text after proc/type declaration for an easier navigation
  (noticeable difference between declarations and examples)
* quickfix invalid style in `asynchttpserver`
2019-03-08 13:55:26 +01:00
Alexander Ivanov
3294ce3831 Render a colon for command if last arg list (#10803) 2019-03-08 13:31:24 +01:00
Anthon van der Neut
1a13b3a14e Follow the documentation's recommendation (#10808)
The doc states "Make sure to pass options explicitly.", but the example didn't. 
Since constructing a string for the shell with appropriate quotes is non-trivial, the first example should be how to use `execProcess`  including `args`
2019-03-08 13:20:36 +01:00
Andreas Rumpf
5c201791b3 make tests green again 2019-03-07 17:11:22 +01:00
Andreas Rumpf
0a93cf6fb9 fixes the regression 2019-03-07 12:55:30 +01:00
Andreas Rumpf
5b1a2eecd5 owned refs must be moved 2019-03-07 12:50:33 +01:00
Andreas Rumpf
f8bf24623c explicit default values for a leaner codegen, .cursor variables for optimization 2019-03-07 12:50:33 +01:00
Miran
2b5e48d807 move assertions and iterators out of system.nim (#10597)
* move assertions and iterators out of system.nim
* limit nimsuggest tests to the first 3 suggestions
2019-03-07 00:49:39 +01:00
narimiran
26f48437ca better nimpy test
As discussed with @yglukhov.
2019-03-06 17:48:01 +01:00
Andreas Rumpf
3c0f01faa0 fixes #10791 2019-03-06 14:22:12 +01:00
Andreas Rumpf
32c9ca605e fixes #10795 2019-03-06 10:15:27 +01:00
Andreas Rumpf
e3e4cd9fd5 make tests green again 2019-03-06 09:26:48 +01:00
Andreas Rumpf
cfd5210405 dfa.nim: continues are bad 2019-03-06 09:00:06 +01:00
Arne Döring
2c01f0ad8d tsizeof test is now correct (#10788) 2019-03-06 08:12:16 +01:00
Dominik Picheta
63c847dc50 Merge pull request #10787 from silent-observer/patch-1
Remove var
2019-03-05 23:13:05 +00:00
Andreas Rumpf
551d6d00df make tests green again 2019-03-05 20:05:47 +01:00
Andreas Rumpf
1c64934f46 implement system.default for the JS target 2019-03-05 19:58:54 +01:00
Andreas Rumpf
4be36d77f6 introduce tfHasOwned for fast must-move checkings; removed tfAcyclic as the GC has ignored this hint for quite some time now 2019-03-05 19:58:54 +01:00
Arne Döring
20a21aa184 colors for debugging (not for windows) (#10786) 2019-03-05 19:58:14 +01:00
Andreas Rumpf
c86b1fbcac fixes a critical GC safety inference bug (#10615)
* fixes a critical GC safety inference bug
* make nimsuggest compile again
* make Nimble compile again
2019-03-05 19:54:44 +01:00
silent-observer
7e52c798db Remove var
Shouldn't testing bit require only immutable access? I think this is a typo
2019-03-05 14:19:41 +05:00
Andreas Rumpf
aed8766e84 stdlib: use system.default if it exists 2019-03-05 10:03:24 +01:00
Andreas Rumpf
142a2d3551 added system.default in order to prevent the abstraction inversion that 'template default(T): untyped = (var x: T; x)' causes 2019-03-05 09:54:59 +01:00
Andreas Rumpf
2dc8a32324 make megatest green again 2019-03-05 08:17:30 +01:00
Andreas Rumpf
22445867d4 no underscores 2019-03-05 07:45:28 +01:00
Andreas Rumpf
e0437dfec4 better error message for 'owned' 2019-03-05 06:25:33 +01:00
Andreas Rumpf
9a9c002abe make exception handling use owned refs 2019-03-05 05:54:42 +01:00
Andreas Rumpf
9c6b628df6 DFA: fixes wrong 'def' instruction emission 2019-03-05 05:54:08 +01:00
Andreas Rumpf
71fd4acaeb make test green 2019-03-05 05:53:28 +01:00
Andreas Rumpf
f907354121 make tests green again 2019-03-04 22:44:23 +01:00
Andreas Rumpf
3e922d0fec destructors/dfa: more documentation 2019-03-04 22:41:50 +01:00
Andreas Rumpf
a59f5e5a9d attempt to make the CIs happy by using the older syntax 2019-03-04 16:48:02 +01:00
Andreas Rumpf
55bc29c761 nimsuggest: make use project file name if none given for 'sug' command; allows for more convenient debugging 2019-03-04 15:41:07 +01:00
Andreas Rumpf
75f8e136e1 ccgexprs.nim: less confusing code layout 2019-03-04 15:41:07 +01:00
Andreas Rumpf
4700018d7e cgen.nim: code cleanups 2019-03-04 15:41:07 +01:00
Andreas Rumpf
a6d49c3a81 special typing rules for owned pointers 2019-03-04 15:41:07 +01:00
Andreas Rumpf
0fd5417aff code cleanup: there is no MoveError and sinks are always available 2019-03-04 15:41:07 +01:00
Tomohiro
df3d08b58b Fixes #10387 (#10743) 2019-03-04 12:15:07 +01:00
sealmove
bf1f4b914b Added optional proc parameter to llStreamOpenStdIn (#10769) 2019-03-04 10:52:34 +01:00
Jacek Sieka
7072e3ddca doc: move specific checks to advanced options, for a less intimidatin… (#10779)
* doc: move specific checks to advanced options, for a less intimidating help

* remove useless bool
2019-03-04 10:49:55 +01:00
Arne Döring
1d9b88f25d sizealign of union type (#10780)
* sizealign of union type

* add error message for packed union
2019-03-04 09:19:38 +01:00
Arne Döring
ebe0473511 More depth debug proc (#10782)
* improved output on debugType
* cycle detection in debug print
* debug info finally really helpful
* finally usable debug info
* quote enum values
2019-03-04 09:17:47 +01:00
alaviss
8e12691213 compiler/extccomp: use getNimcacheDir for writing build instruction (#10772)
`conf.nimcacheDir` might be empty during build, which results in the
json build instructions being generated in the current directory. This
commit fixes the problem by using getNimcacheDir, which generates a
valid nimcacheDir should it be empty.

Fixes #10768
2019-03-04 09:09:14 +01:00
Andreas Rumpf
65ad496fed typo 2019-03-04 09:04:54 +01:00
Andreas Rumpf
1d1be03d81 make 'doc io.nim' work 2019-03-04 09:04:14 +01:00
Andreas Rumpf
f9231eb569 make 'nim doc times.nim' work on old versions of OSX again 2019-03-04 08:50:28 +01:00
Dominik Picheta
2647653589 Merge pull request #10776 from arnetheduck/wasm32-platform
add wasm32 platform
2019-03-03 22:59:57 +00:00
Jacek Sieka
7edc8bfe14 add wasm32 platform 2019-03-03 09:03:28 -06:00
narimiran
792dfac521 hashes: fix inconsistent tests, fixes #10771 2019-03-03 10:53:37 +01:00
ee7
d6882691ad times.nim: Fix docs for duration conversion procs [ci skip] (#10770) 2019-03-02 18:25:14 +01:00
Anthon van der Neut
5ac7e32c7c Matching actual proc name (#10766) [ci skip] 2019-03-02 15:50:21 +01:00
Dominik Picheta
5d67208e34 Merge pull request #10764 from alaviss/htmlparser-doc
htmlparser: update example
2019-03-01 20:46:36 +00:00
Leorize
78d7ecae90 htmlparser: update example
This update htmlparser example to compile with the current stdlib.
2019-03-02 01:51:38 +07:00
Araq
e1d17ece5b alloc et al don't have any effect; fixes #9746 2019-03-01 14:50:51 +01:00
Miran
ca7980f301 improved documentation for several modules (#10752)
More detailed documentation for:
* md5
* hashes

Mostly cosmetic improvements for:
* threadpool
* typetraits
* channels
* threads
2019-03-01 12:57:55 +01:00
zah
e9d3c5de19 Fix corner-case uses of newLit (#10760) 2019-03-01 11:09:13 +01:00
Federico Ceratto
7d7cd69070 Improved posix module, added new posix_utils module (#10723) 2019-02-28 23:03:49 +01:00
Arne Döring
1102b8ac6e StringStream and parseJson, parseCfg, parseSql et al for the vm (#10746) 2019-02-28 22:57:57 +01:00
Andreas Rumpf
728ff1004a gc:destructors: progress 2019-02-28 22:39:24 +01:00
Andreas Rumpf
9563be37d3 destructor based seqs: bugfix 2019-02-28 22:39:24 +01:00
narimiran
ec66fd07cb quickfix: make tsizeof3 also work on 32-bit 2019-02-28 19:20:22 +01:00
Simon Krauter
0b56b3595a Make doku of os.moveFile() more precise. (#10758) [ci skip] 2019-02-28 18:58:07 +01:00
alaviss
38aec488b7 compiler/commands: keep extension for output file (#10755)
Fixes #10747
2019-02-28 14:47:15 +01:00
alaviss
1b542e7320 compiler/[main,docgen]: don't put generated doc in subfolder (#10754)
* compiler/[main,docgen]: don't put generated doc in subfolder

Fixes regression caused by ca4b971bc8.

foo.nim will now generates foo.html instead of foo/foo.html

* compiler/[main,docgen]: map -o to -outdir for project

This reinstantiate the old behavior of -o for project-wide docgen
2019-02-28 14:46:35 +01:00
narimiran
588610b395 add tests, closes #3012, closes #7244 2019-02-27 12:39:35 +01:00
zah
ca4b971bc8 Initial version of the hot-code reloading support for native targets (#10729)
* squashed work by Zahary

* squashing a ton of useful history... otherwise rebasing on top of upstream Nim after commit 82c009a2cb would be impossible.

* Code review changes; Working test suite (without code reloading enabled)

* - documentation
- implemented the HCR test - almost works...
- fix the issue on Unix where for executable targets the source file for the main module of a project in nimcache was being overwritten with the binary itself (and thus the actual source code was lost)
- fixing embedded paths to shared objects on unix (the "lib" prefix was being prepended to the entire path instead of just the filename)
- other fixes
- removing unnecessary includes since that file is already included in chcks.nim which is in turn included in system.nim (and previously was getting imported in chcks.nim but then system.nim improts something... and that breaks HCR (perhaps it could be fixed but it would be nice not to import anything in system))

* fix for clang & C++ - explicitly casting a function pointer to void*
more stable mangling of parameter names when HCR is on
the length of the static arrays in the DatInit functions is now part of the name of the variables, so when they get resized they get also recreated
more stable mangling for inline functions - no longer depends on the module which first used them
work on the new complicated HCR test - turned surprisingly complex - WIP
test now successfully passes even when re-running `koch test` (previously when the nimcache wasn't cold that lead to errors)
better documentation
calling setStackBottomWith for PreMain
passes over the HcrInit/DatInit/Init calls of all modules are now in the proper order (first all of one type, then all of the next). Also typeinfo globals are registered (created) in a single pass before the DatInit pass (because of the way generic instantiations are handled)
Fix the test suite execution on macOs
fix for being able to query the program arguments when using HCR on posix!
other fixes

* Bugfix: Fix a compilation error in C++ mode when a function pointer
is converted to a raw pointer

* basic documentation for the new hot code reloading semantics

* Add change log entry

* Don't re-execute the top-level statements while reloading JS code

* fix a number of tests broken in a recent bugfix

* Review changes

* Added {.executeOnReload.} pragma that indicates top-level statements
  that should be executed on each reload. To make this work, I've modified
  the way the `if (hcr_init_) {...}` guards are produced in the init code.
  This still needs more work as the new guards seem to be inserted within
  the previously generated guards.

  This change also removes the need for `lastRegistedGlobal` in nimhcr.

* Implemented the `signatureHash` magic and the `hasModuleChanged` API
  depending on it (the actual logic is not imlemented yet).

* Add the "hcr" prefix to all HCR-related symbols in the system module.
  Added a new `hotcodereloading` module exporting the high-level API to
  the user.

  Besides being more hygienic, this was also required in order to make
  it possible to use macros in the high-level API. Without the split,
  `system` would have to import `macros`, which was going to produce
  the well-known init problems.

* Attempted to solve the "GC markers problem".

  Crashes were expected with the previous code, because the GC markers
  were compiled as normal procs are registered in the GC. When their
  module is unloaded, dangling pointers will remain in the GC tables.
  To solve this issue, I don't register any GC markers when HCR is on,
  but I add them to the HCR globals metadata and I use a single marker
  registed in nimhcr during the initialization of the system module that
  will be responsible for marking all globals.

* fix a compilation error

* - implemented the hasModuleChanged functionality
- tuples can be returned and broken into different vars in global scope
- added comments for the closnig scopes of the if statements in the init proc
- the new executeOnReload pragma works now!
- other fixes

* finally! fixing this hack in a proper way - declaring the destructor out of line (out of the class body) - we no longer need to forward-declare popCurrentExceptionEx

* Force full module parsing

This is a temporary hack that breaks some tests. I'll investigate
later how these can be fixed.

* tuples are now properly handled when global!

* these comments mess up the codegen in debug mode when $n is not actually a new line (or something like that) - these labels are intended only for GOTO labels anyway...

* "solved" the issue with the .pdb locks on windows when a binary is being debugged and hot code reloading is used at the same time

* fixes after rebasing...

* small fixes for the test

* better handling of globals! no more compiler crashes for locals with the global pragma, also simplified code around loops in global scope which have local vars (actually globals)

* we can now use the global pragma even for ... globals!

* the right output

* lets try those boehm GC tests

* after the test is ran it will be at its starting state - no git modifications

* clarification in the docs

* removed unnecessary line directives for forward declarations of functions - they were causing trouble with hot code reloading when no semantic change propagates to the main module but a line directive got changed and thus the main module had to be recompiled since the .c code had changed

* fixed bug! was inserting duplicate keys into the table and later was removing only 1 copy of all the duplicates (after a few reloads)

* no longer breaking into DatInit code when not supposed to

* fixes after rebasing

* yet more fixes after rebasing

* Update jssys.nim

* Rework the HCR path-handling logic

After reviewing the code more carefully, I've noticed that the old logic
will be broken when the user overrides the '--out:f' compiler option.

Besides fixing this issues, I took the opportunity to implement the
missing '--outdir:d' option.

Other changes:

* ./koch test won't overwrite any HCR and RTL builds located in nim/lib
* HCR and RTL are compiled with --threads:on by default

* Clean up the globals registration logic

* Handle non-flattened top-level stmtlists in JS as well

* The HCR is not supported with the Boehm GC yet

Also fixes some typos and the expected output of the HCR integration test

* The GC marker procs are now properly used as trampolines

* Fix the HCR integration test in release builds

* Fix ./koch tools

* this forward declaration doesn't seem to be necessary, and in fact breaks HCR because a 2nd function pointer is emitted for this externed/rtl func

* the forward declaration I removed in the last commit was actually necessary

* Attempt to make all tests green

* Fix tgenscript

* BAT file for running the HCR integration test on Windows [skip ci]

* Fix the docgen tests

* A final fix for Travis (hopefully)
2019-02-26 15:48:55 +01:00
Arne Döring
ba38c05eb6 add gdb commands: koch, nim, nimble (#10741)
* add gdb commands: koch, nim, nimble
* make commands path independent
2019-02-26 15:47:34 +01:00
Arne Döring
287206f993 minor fix for debug on symbols (#10742) 2019-02-26 15:45:01 +01:00
Yuriy Glukhov
d53ab9e5c8 Prevent options from calling custom ref == operators (#10745) 2019-02-26 15:43:34 +01:00
Andreas Rumpf
84f0a33bf0 make typeToString sane for sequence again 2019-02-25 19:01:01 +01:00
Miran
fb863a147a use initHashSet and toHashSet, fixes #10730 (#10736) 2019-02-25 16:53:05 +01:00
WhiteDuke
1397ad7c54 [random] add support for sets (#10532)
* Support for sets

* Rename 'rand' to 'sample'

* Update random.nim
2019-02-25 16:45:44 +01:00
Andreas Rumpf
bf4e688ca3 make nimsuggest aware of tyOwned 2019-02-25 16:37:09 +01:00
narimiran
2074ad1416 strutils: document parseEnum [ci skip] 2019-02-25 11:35:37 +01:00
deech
68a82f100e Fixes #10727. (#10728) 2019-02-25 11:21:14 +01:00
Federico Ceratto
28a83a8388 Handle IPv6 in bindAddr #7633
Add test
2019-02-23 13:06:26 +00:00
LemonBoy
f39aa1b40b discard destroys its argument in-place (#9478) 2019-02-23 14:03:32 +01:00
Neelesh Chandola
9884129058 Tuple unpacking now works for for vars (#10152)
* Tuple unpacking now works for `for` vars
* Give error if length of tuple vars != length of tuple
* Fix error message showing wrong tuple length
* unpacking now works now for mutable items
* Update changelog
2019-02-23 14:01:34 +01:00
LemonBoy
e89aaaeaab Open a new scope for static: expr blocks (#10649)
Bring this in line with how plain blocks are analysed and avoids codegen
errors if one references variables defined in such a block.
2019-02-23 12:05:07 +01:00
Andreas Rumpf
f86835ce77 manual: document implicit type conversions involving 'range'; refs #10495 2019-02-23 11:49:29 +01:00
LemonBoy
71df1b060b Tighten the conversion from tyRange to scalar types (#10495)
* Tighten the conversion from tyRange to scalar types.

Introduce the `isIntConv` rule for unsigned types.
Do not allow mixed-signedness conversions between ranges and scalar types.

* More json adjustments
2019-02-23 11:52:52 +01:00
Andreas Rumpf
c5dbb0379f disable compile-time FFI support 2019-02-23 11:34:39 +01:00
Andreas Rumpf
7ec187a8e1 make the VM aware of tyOwned 2019-02-23 11:31:31 +01:00
Timothee Cour
adbabf145c FFI at CT (#10150)
* enable FFI at CT
* rename useFFI=>nimHasLibFFI; improve formatting rawExecute traceCode
* disable libffi on windows (works for win32, not yet win64)
2019-02-23 11:31:01 +01:00
Arne Döring
30ab7e6bdd fixes #10678 (#10681) 2019-02-23 10:58:40 +01:00
Miran
e7878c0d08 add tests for recently closed issues (#10722) 2019-02-23 10:41:35 +01:00
Andreas Rumpf
ea409fb15a first steps in implementing 'owned' pointers; undocumented, do not use 2019-02-23 08:44:08 +01:00
Andreas Rumpf
721bf7188b code cleanup: there is no tyOptRef 2019-02-22 19:42:11 +01:00
Andreas Rumpf
15c208cd29 it's spelt callsite 2019-02-22 18:28:49 +01:00
narimiran
4fb73e6d8f fix nimble package tests 2019-02-22 14:09:08 +01:00
Miran
cedf784751 better docs: options (#10720) 2019-02-22 12:28:00 +01:00
Andreas Rumpf
a4543c1aac gc:destructors: make strutils compile (but still crashes) 2019-02-22 12:06:30 +01:00
Andreas Rumpf
417d27c544 gc:destructors: progress 2019-02-21 12:19:06 +01:00
Andreas Rumpf
f2f0b5d695 system.nim: spacing 2019-02-21 12:03:47 +01:00
Andreas Rumpf
418cbbb450 macros.nim: spacing 2019-02-21 12:03:34 +01:00
Andreas Rumpf
43d570c178 gc:destructors: make system/repr compile 2019-02-21 07:57:29 +01:00
Araq
6c10d331db gc:destructors: slightly more stuff compiles 2019-02-20 14:29:18 +01:00
narimiran
873539b50d lib.rst: add link to asyncstreams, fixes #6383 [ci skip] 2019-02-20 14:16:38 +01:00
Araq
ffd0f81247 times.nim: avoid some stdlib dependencies 2019-02-20 12:30:51 +01:00
Araq
2990a5ea54 koch.nim: indentation uses 2 spaces 2019-02-20 12:28:43 +01:00
Araq
7b31a81d45 system.nim: avoid 'cannot prove init' warnings for the '..' constructors 2019-02-20 12:28:22 +01:00
Miran
6a5c74722e add xmltree.clear, fixes #3797 (#10711)
* add `xmltree.clear`, fixes #3797
* use `setLen`
2019-02-20 08:41:34 +01:00
Andreas Rumpf
c025786b75 gc:destructors: sink parameters need to be destroyed properly 2019-02-20 02:04:58 +01:00
Andreas Rumpf
7e404c670d gc:destructors: add first test program 2019-02-19 23:32:41 +01:00
Araq
68ce92d4eb fixes a critical strutils bug [backport] 2019-02-19 19:37:25 +01:00
Oscar Nihlgård
1a771a8248 Replace the duration conversion procs with new improved ones (#10710) 2019-02-19 19:12:44 +01:00
Miran
50d1a46537 better docs: osproc (#10708)
* better docs: osproc
* fix a typo in the docs, deprecate "demon"
2019-02-19 17:25:03 +01:00
Araq
e4a76c6ebf fixes #6832 2019-02-19 17:17:12 +01:00
Araq
f31d1fa98b fixes #10195 2019-02-19 16:25:57 +01:00
Miran
51f516e030 better docs: strtabs (#10704) 2019-02-19 12:49:47 +01:00
Miran
8cf97908cc document proper imports, fixes #8164 (#10698) 2019-02-19 12:49:09 +01:00
Arne Döring
6b9a139f7f error message for accidental use of macro (#10490)
* error message for accidental use of macro
2019-02-19 12:21:42 +01:00
Araq
257965e105 fixes 10697 [backport] 2019-02-19 11:56:14 +01:00
Araq
315d438677 asyncnet.nim: Minor code cleanup 2019-02-19 11:56:14 +01:00
Miran
2fae94cdc5 add more nimble packages to the test (#10707) 2019-02-19 11:43:34 +01:00
narimiran
83f5839e2c manual: fix broken sentence 2019-02-19 09:07:25 +01:00
Andreas Rumpf
7b68da9bf1 manual: typo 2019-02-18 15:24:55 +01:00
Andreas Rumpf
c8cb567938 Merge branch 'devel' of github.com:nim-lang/Nim into devel 2019-02-18 15:23:43 +01:00
Andreas Rumpf
2deb1e354f fixes #10702 (#10705)
* --define:nimQuirky exception handling for Nim; in preparation of a blog post
* make it work with latest system.nim
* make code more readable
* fixes #10702
2019-02-18 15:23:05 +01:00
Andreas Rumpf
739dc8094e make set specification more clear; refs #10524 2019-02-18 15:18:42 +01:00
Timothee Cour
1d66222901 fixes #10659 koch boot fails on windows (#10660) 2019-02-18 12:18:52 +01:00
LemonBoy
cf32d61fa5 Prevent crash on pragma templates w/ generics (#10685)
* Prevent crash on pragma templates w/ generics

* Remove incorrect call to pragma reconversion

`semOverloadedCall` may return a node with more elements than the
original nkCall node had (implicit and/or explicit generics).
2019-02-18 12:17:00 +01:00
Andreas Rumpf
b5eed8ab3f make code more readable 2019-02-18 10:30:30 +01:00
Andreas Rumpf
c8e33cbb75 fixed merge conflict 2019-02-18 09:56:01 +01:00
LemonBoy
8b39551fca Small CI improvements (#10699)
* [appveyor] Cache all the downloaded binaries

* [travis] Enable fast_finish
2019-02-18 08:07:10 +01:00
Federico Ceratto
d8ff25f032 Provide access to getsockname()/getpeername()
Port of #3323 with added tests
2019-02-17 17:04:57 +00:00
narimiran
a0fb77dfd5 add links to every document, fixes #5515 2019-02-16 18:26:28 +00:00
Federico Ceratto
51c43218c9 Comment on isSorted complexity. (#10686) [ci skip] 2019-02-16 15:56:26 +01:00
liuxiaodong
2610b16f6e some dom proc correction and complement (#10684) 2019-02-15 17:43:22 +01:00
LemonBoy
bb9fe2046e Merge pull request #10680 from narimiran/fix-10561
allow string insert in nimscript, fixes #10561
2019-02-15 16:20:26 +01:00
narimiran
1eaa18fe84 allow string insert in nimscript, fixes #10561 2019-02-15 11:09:32 +01:00
Juan Carlos
b3ffbac93c Return result when found instead of keep iterating for no reason the whole mimedb on mimetypes module (#10675) 2019-02-15 08:42:13 +01:00
Miran
6d8ce609d7 add more nimble packages for testing (#10671) 2019-02-15 08:41:43 +01:00
Arne Döring
80992c7a12 introduce object before tuple in the tutorials (#10664) 2019-02-14 22:17:05 +01:00
Araq
b081eb4d6d fixes #10651 2019-02-14 15:55:38 +01:00
Araq
70f0aab188 osproc: fix minor typo 2019-02-14 15:55:37 +01:00
Arne Döring
d2b3046c70 deprecated leftovers from era of no unsigned integer types (#10605) 2019-02-14 10:58:09 +01:00
Timothee Cour
9913cef872 fix typo in codeReordering error msg (#10667)
* fix typo in codeReordering

* reorder=>codeReordering
2019-02-14 09:52:15 +01:00
alaviss
9e754c3b06 compiler/types: correctly generates signature for non-proc types (#10658)
This makes signatures generated for nimsuggest correctly distinguish
template/macro/converter from proc.
2019-02-13 23:30:14 +01:00
Arne Döring
1ae61767f8 disable talloc2 on 32 bits (#10656) 2019-02-13 23:30:14 +01:00
Arne Döring
28394153ab 32 bit fixes (#10608) 2019-02-13 23:30:14 +01:00
Timothee Cour
304b1dd34b randomize: added doAssert(seed!=0) to avoid invalid (non-random) behavior (#10635) 2019-02-13 23:30:14 +01:00
Timothee Cour
e3ba2e24cf fix travis: add set -e in script (#10631) 2019-02-13 23:30:14 +01:00
Arne Döring
f4b2793bdf reduce debug output (#10638) 2019-02-13 23:30:14 +01:00
LemonBoy
76df77f912 Fix codegen problem with strict C++ compilers (#10639)
Since tyCString is convertible to a tyPointer we must be extra careful
to emit a cast to (void*) in order to appease clang++.

Reported by masnagam on the Nim forum.
2019-02-13 23:30:14 +01:00
alaviss
d64e218abd nimsuggest: only log when logging is enabled (#10646)
fixes #6199
2019-02-13 23:30:14 +01:00
Arne Döring
dfa3099929 deprecated list comprehension (#10636) 2019-02-13 23:30:14 +01:00
Juan Carlos
f5e55162ba Lowercase ext before querying the mimedb on mimetypes module, change isMainModule to runnableExamples (#10644) 2019-02-13 23:30:14 +01:00
Timothee Cour
cf87687c40 travis:upgrade to xenial (trusty end of life is april 2019) (#10643) 2019-02-13 23:30:14 +01:00
narimiran
e26a0c4f1a better docs: times 2019-02-13 23:30:14 +01:00
Andreas Rumpf
36f6f035ff attempt to make nightlies work again 2019-02-13 23:30:14 +01:00
Juan Carlos
d3a74ea515 Update mimetypes (#10621)
* Update mimetypes const mimes, Fix for Nim mimetypes to recognize Nim and Nimble
2019-02-13 23:30:14 +01:00
narimiran
572739a4f3 macros: add links in the docs [ci skip] 2019-02-13 23:30:14 +01:00
Jjp137
7bb94abc31 better docs: random (#10546) 2019-02-13 23:30:14 +01:00
LemonBoy
0ebef1764d Propagate tfGcSafe flag to generic instantiations (#10620)
Fixes a nasty endless loop in the generic instantiation phase.
2019-02-13 23:30:14 +01:00
Timothee Cour
942495611b revive #10228 (fix #9880) (#10610)
* Make index out of bounds more useful by including the 'bounds'.
* fixes #9880 index out of bounds (remaining cases); revives #10228
* change err msg to: `index 3 not in 0 .. 1`
2019-02-13 23:30:14 +01:00
Federico Ceratto
8f05b34125 Add note on channel usage with spawn (#10627) [ci skip] 2019-02-13 23:30:14 +01:00
Andreas Rumpf
02b5fc940d fixes #10547 2019-02-13 23:30:14 +01:00
Emery Hemingway
d1e3f58afc Use standard XML escaping 2019-02-13 23:30:14 +01:00
Dean Thompson
f785286743 Expanded the typeinfo module's doc comment to warn that rtti will evolve and suggest alternative approaches. (#10596) 2019-02-13 23:30:14 +01:00
Juan Carlos
dcbab1031a Fixes #10357 (#10618) 2019-02-13 23:30:14 +01:00
Brent Pedersen
fe26328a19 sets: avoid calling countBits32 for 0 (#10619)
this speeds up the system.sets time from ~0.2 to ~0.06
in release mode. This is still slower than intsets and
tables (which both are ~0.01).

This assumes that most sets will be sparse.

fixes #10617
2019-02-13 23:30:14 +01:00
Oscar Nihlgård
779c51c29b Implement json.% for tables and options 2019-02-13 23:30:14 +01:00
LemonBoy
d83520ec8f Do not walk into type sub-nodes for cast/conv expr (#10616) 2019-02-13 23:30:14 +01:00
LemonBoy
eb30c78694 Misc macro things (#10612)
* Misc cleanup in macro code

Generate error messages using `error` instead of `assert`.

Fixes #10574

* Fix crash with hasCustomPragma on quoted fields

Use the `$` operator instead of reaching for the `strVal` field directly
2019-02-13 23:30:14 +01:00
Kobi
dd422bfb0f fix replacef typo in example 2019-02-13 23:30:14 +01:00
Andreas Rumpf
f55d094cf2 fixes #6955 2019-02-13 23:30:14 +01:00
Andreas Rumpf
49a5213713 fixes #10606 2019-02-13 23:30:14 +01:00
Andreas Rumpf
354e3f2a40 disable flaky coroutines test 2019-02-13 23:30:14 +01:00
Andreas Rumpf
614b731caf new AppVeyor configuration that should test the compiler against sele… (#10549) 2019-02-13 23:30:14 +01:00
Arne Döring
43a0dd42bc Print missing case labels (#10600) 2019-02-13 23:30:14 +01:00
LemonBoy
048a7a6539 Fix compilation w/ Atomic[T] types (#10607) 2019-02-13 23:30:14 +01:00
cooldome
d70dd6f3cb Move cpp exception handler from system to excpt next to the signal handler (#9435) 2019-02-13 23:30:14 +01:00
b3liever
695206a00c Add summation algorithms (#9284) 2019-02-13 23:30:14 +01:00
Andreas Rumpf
04cdf99448 koch and testament improvement; make testing command easier to get right 2019-02-13 23:30:14 +01:00
alaviss
3520253a09 compiler/types: correctly generates signature for non-proc types (#10658)
This makes signatures generated for nimsuggest correctly distinguish
template/macro/converter from proc.
2019-02-13 08:07:58 +01:00
Arne Döring
b6c22eae6a disable talloc2 on 32 bits (#10656) 2019-02-13 08:04:06 +01:00
Arne Döring
6870345cd2 32 bit fixes (#10608) 2019-02-12 22:00:31 +01:00
Timothee Cour
bdc150adff randomize: added doAssert(seed!=0) to avoid invalid (non-random) behavior (#10635) 2019-02-12 09:33:20 +01:00
Timothee Cour
cc507668cb fix travis: add set -e in script (#10631) 2019-02-12 08:30:53 +01:00
Arne Döring
0e5d4f1036 reduce debug output (#10638) 2019-02-12 08:27:38 +01:00
LemonBoy
1d1360496f Fix codegen problem with strict C++ compilers (#10639)
Since tyCString is convertible to a tyPointer we must be extra careful
to emit a cast to (void*) in order to appease clang++.

Reported by masnagam on the Nim forum.
2019-02-12 08:23:24 +01:00
alaviss
cf5812aa9f nimsuggest: only log when logging is enabled (#10646)
fixes #6199
2019-02-12 08:17:39 +01:00
Arne Döring
c59fa80367 deprecated list comprehension (#10636) 2019-02-12 08:10:40 +01:00
Juan Carlos
33ddc21057 Lowercase ext before querying the mimedb on mimetypes module, change isMainModule to runnableExamples (#10644) 2019-02-12 01:22:04 -05:00
Timothee Cour
85f2ab1c43 travis:upgrade to xenial (trusty end of life is april 2019) (#10643) 2019-02-12 01:18:55 -05:00
narimiran
242b6eb16c better docs: times 2019-02-11 15:36:35 +01:00
Andreas Rumpf
9f98678008 attempt to make nightlies work again 2019-02-11 15:28:23 +01:00
Juan Carlos
6cd3fff093 Update mimetypes (#10621)
* Update mimetypes const mimes, Fix for Nim mimetypes to recognize Nim and Nimble
2019-02-11 11:44:49 +01:00
narimiran
d3e35c3200 macros: add links in the docs [ci skip] 2019-02-11 09:11:04 +01:00
Jjp137
305f6052ee better docs: random (#10546) 2019-02-11 08:50:31 +01:00
LemonBoy
5fd9bf9cd5 Propagate tfGcSafe flag to generic instantiations (#10620)
Fixes a nasty endless loop in the generic instantiation phase.
2019-02-10 22:07:50 +01:00
Timothee Cour
4910608394 revive #10228 (fix #9880) (#10610)
* Make index out of bounds more useful by including the 'bounds'.
* fixes #9880 index out of bounds (remaining cases); revives #10228
* change err msg to: `index 3 not in 0 .. 1`
2019-02-10 22:07:11 +01:00
Federico Ceratto
352b52a0c9 Add note on channel usage with spawn (#10627) [ci skip] 2019-02-10 20:52:13 +01:00
LemonBoy
c5dc46926c Merge pull request #10622 from ehmry/xml
Use standard XML escaping
2019-02-10 19:33:59 +01:00
Andreas Rumpf
f0e6becc23 fixes #10547 2019-02-10 17:03:32 +01:00
Emery Hemingway
a9b2e83daa Use standard XML escaping 2019-02-10 16:10:23 +01:00
Dean Thompson
d46a590f74 Expanded the typeinfo module's doc comment to warn that rtti will evolve and suggest alternative approaches. (#10596) 2019-02-10 08:56:28 +01:00
Juan Carlos
b73ee96641 Fixes #10357 (#10618) 2019-02-10 08:53:38 +01:00
Brent Pedersen
0c9a3d4804 sets: avoid calling countBits32 for 0 (#10619)
this speeds up the system.sets time from ~0.2 to ~0.06
in release mode. This is still slower than intsets and
tables (which both are ~0.01).

This assumes that most sets will be sparse.

fixes #10617
2019-02-10 08:49:54 +01:00
Oscar Nihlgård
f1ae0ed6ea Implement json.% for tables and options 2019-02-10 00:29:24 +00:00
LemonBoy
0c4d1fd10b Do not walk into type sub-nodes for cast/conv expr (#10616) 2019-02-09 19:55:26 +01:00
LemonBoy
1e88bf1def Misc macro things (#10612)
* Misc cleanup in macro code

Generate error messages using `error` instead of `assert`.

Fixes #10574

* Fix crash with hasCustomPragma on quoted fields

Use the `$` operator instead of reaching for the `strVal` field directly
2019-02-09 18:22:07 +01:00
LemonBoy
467519f80d Merge pull request #10614 from kobi2187/patch-1
fix replacef typo in example
2019-02-09 16:53:57 +01:00
Kobi
dcf725d228 fix replacef typo in example 2019-02-09 15:12:59 +02:00
Andreas Rumpf
c6fdf93c7f fixes #6955 2019-02-09 11:18:21 +01:00
Andreas Rumpf
3c909ae8ff fixes #10606 2019-02-09 08:18:33 +01:00
Andreas Rumpf
c4ad297544 disable flaky coroutines test 2019-02-09 07:41:19 +01:00
Andreas Rumpf
dee9a94278 new AppVeyor configuration that should test the compiler against sele… (#10549) 2019-02-09 07:40:00 +01:00
Arne Döring
594c2576e6 Print missing case labels (#10600) 2019-02-09 07:36:30 +01:00
LemonBoy
bcbe130ea7 Fix compilation w/ Atomic[T] types (#10607) 2019-02-09 07:30:48 +01:00
cooldome
55fe7c114e Move cpp exception handler from system to excpt next to the signal handler (#9435) 2019-02-08 21:42:45 +01:00
b3liever
e0e8fdf737 Add summation algorithms (#9284) 2019-02-08 21:38:27 +01:00
Andreas Rumpf
c751c914fc koch and testament improvement; make testing command easier to get right 2019-02-08 20:01:20 +01:00
Andreas Rumpf
ec68d89e42 make it work with latest system.nim 2019-02-08 17:41:34 +01:00
Andreas Rumpf
0841c64a32 Merge branch 'devel' into araq-quirky-exceptions 2019-02-08 17:18:17 +01:00
Andreas Rumpf
444f2231c9 make tests green again 2019-02-08 16:54:12 +01:00
Andreas Rumpf
6fc90ab1c2 macros.nim: minor comment change 2019-02-08 16:09:22 +01:00
LemonBoy
aa6e40abe6 Fix wrong result in tuple assignment (#9340)
Fixes #9177
2019-02-08 12:24:03 +01:00
Araq
8bc7c50c86 DOM module: re-add more missing stuff 2019-02-08 12:18:42 +01:00
Araq
4ed7507cb2 error messages can have spaces, don't be dyslexic 2019-02-08 12:18:42 +01:00
LemonBoy
710cfcecd3 Rework exception handling in the VM (#10544)
* Rework exception handling in the VM

Make the safepoint handling more precise and less forgiving.
The new code is clearer and more commented.
Perform cleanup on `return`.
The no-exception-thrown case in a try block should be slightly faster
since we don't parse the whole set of exceptions every time.
More tests.

* Fix silly error that broke a few tests

* Testament doesn't like files having the same name

* Remove test case that failed compilation to js
2019-02-08 11:57:47 +01:00
LemonBoy
631a8ab57f Fix edge case in type hashing (#10601) [backport]
Empty types introduced by a template produced the same hash of the
"clean" type sharing the same name.
2019-02-08 09:56:32 +01:00
Araq
4572568045 fixes #10602 2019-02-08 09:52:29 +01:00
Matt Haggard
fd62d24c4c Add non-interactive installer flag (-y) to finish.nim (#10603) [backport] 2019-02-08 09:39:58 +01:00
LemonBoy
6b88ce3384 Stop useless suggestion of unsafeAddr (#10598)
Fixes #10594
2019-02-08 08:59:38 +01:00
Araq
c7c495f08a testament: use bin/nim.exe as the default 2019-02-07 20:35:23 +01:00
alaviss
2fdf816332 compiler/[msgs, suggest]: improve highlighter accuracy (#10496)
Previously the compiler would generate suggestions based on the symbol
identifier length, but that might not reflect the actual representation
of it within the actual source code.

This commit implements a simple source scanner for the suggest module to
address the problem outlined above.

Fixes nim-lang/nimsuggest#24
2019-02-07 17:08:15 +01:00
LemonBoy
29fbf111a8 Fix codegen when debugger is enabled (#10595)
Decrement the frame length before closing the parent scope.

Fixes #10589
2019-02-07 17:07:35 +01:00
LemonBoy
f23b0a7dc8 Fix handling of reraise in effect tracking (#10582)
This is the MVP in order not to get a completely useless error message
from the compiler.

Fixes #10579
2019-02-07 17:07:03 +01:00
Araq
c95616f6ee fixes #10586 2019-02-07 16:13:03 +01:00
narimiran
27364ece14 mention correct usage of export in the manual, fixes #6227 [ci skip] 2019-02-07 16:10:48 +01:00
Araq
84d10f7d8a fixes #10585 2019-02-07 15:04:05 +01:00
Araq
3dc270eee5 DOM module: add more missing stuff 2019-02-07 15:04:05 +01:00
Timothee Cour
b8f4ff8b9f followup on #10573: prevent common user config to interfere with testament (excessiveStackTrace) (#10590) 2019-02-07 12:29:31 +01:00
Araq
d5da450100 helpers2 now has a real name 2019-02-07 12:12:20 +01:00
Timothee Cour
6f412fc6cb fix #10591 regression (#10592) 2019-02-06 22:31:36 -06:00
Andreas Rumpf
37f9ace517 further system.nim cleanups 2019-02-06 22:35:51 +01:00
Andreas Rumpf
2851f316f6 ignore nkCommentStmt in lambda lifting 2019-02-06 22:00:16 +01:00
Andreas Rumpf
4338f86acb fixes some bug 2019-02-06 22:00:16 +01:00
LemonBoy
294b2e03b2 Reject assignments with nkEmpty RHS (#9000)
Fixes #8997
2019-02-06 21:26:55 +01:00
Andreas Rumpf
0036014727 system refactorings (#10559)
* move IO subsystem into its own module; refs #10385
* make standalone test compile again
* make C++ examples compile again
* make more tests green
* make sysAssert and gcAssert work again
2019-02-06 21:00:00 +01:00
Andreas Rumpf
65f3e390e8 fixes #10584 [backport] 2019-02-06 20:58:28 +01:00
Oscar Nihlgård
bfb2ad5078 New implementation of times.between (#10523)
* Refactor ttimes

* New implementation of times.between

* Deprecate times.toTimeInterval
2019-02-06 20:13:29 +01:00
Araq
e457ccc7e1 make travis green 2019-02-06 17:42:38 +01:00
Araq
035134de42 make streams.close more forgiving in order to break less code out there 2019-02-06 15:51:21 +01:00
Araq
b5991f52b9 DOM.nim: fix regression, missing procs 2019-02-06 15:37:32 +01:00
Araq
e33544ad13 koch winrelease: also bundle c2nim for Windows [backport] 2019-02-06 14:39:32 +01:00
LemonBoy
864c3e874c Merge pull request #10577 from zielmicha/fix-10568
Fixes #10568: Fix null pointer dereference in address computation for incrSeqV3.
2019-02-06 14:23:24 +01:00
LemonBoy
6c8dee4180 Avoid evaluating macros twice in type sections (#10550)
Fixes #10548
2019-02-06 11:35:44 +01:00
LemonBoy
26255c72fd Fix getCustomPragmaVal on var fields 2019-02-06 11:34:55 +01:00
Michał Zieliński
580f62220c Fixes #10568: Fix null pointer dereference in address computation.
According to https://hownot2code.com/2016/08/18/null-pointer-dereferencing-causes-undefined-behavior/ this was an undefined behaviour.
2019-02-06 10:13:44 +01:00
Andreas Rumpf
c174d09245 [doc] lots of fixes in doc/{contributing,docstyle}.rst (#10571)
* [doc] lots of fixes in doc/contributing.rst and doc/docstyle.rst

* fixup
2019-02-06 09:49:05 +01:00
Timothee Cour
cf8366a569 prevent common user config to interfere with testament (#10573) 2019-02-06 09:41:05 +01:00
LemonBoy
4c3f841212 Do not raise ProveInit/WanrUninit for .noinit. var (#10566) 2019-02-06 09:14:09 +01:00
Timothee Cour
f7a0a42b05 fixup 2019-02-05 17:45:30 -08:00
Timothee Cour
86f4dae748 [doc] lots of fixes in doc/contributing.rst and doc/docstyle.rst 2019-02-05 17:19:29 -08:00
Araq
2e880c726b fixes a lexer regression for 'nimble check' 2019-02-05 15:40:03 +01:00
Vindaar
7424ea4315 fix typo in stats module (#10562) [ci skip] 2019-02-05 15:37:55 +01:00
narimiran
21b256dbc9 fix documentation CSS
- make documentation usable on small (narrow) screens
- slightly smaller font size in tables
- fix search input width
2019-02-05 14:01:47 +01:00
Timothee Cour
2b30998159 document that multiple yield in inline iterator cause code bloat (#10553)
* document that multiple `yield` in inline iterator cause code duplication
* doc: rule `Start types with a capital T` was deprecated
2019-02-05 13:05:26 +01:00
Arne Döring
824f39b32e Vm bitops fixes (#10520) 2019-02-05 09:31:37 +01:00
LemonBoy
bcb5995ddf Fix regression w/ keep-alive connections to AsyncHttpServer
We should keep listening if the connection is marked as keep-alive.

Fixes #10536
2019-02-04 22:16:55 +00:00
LemonBoy
59574b89a6 Clean up some code using a tuple unpack expression 2019-02-04 22:16:55 +00:00
LemonBoy
d7ca7fd03e Small change in how tuples are handled in async macro
A small change that brings no functional change beside a flatter tree.
2019-02-04 22:16:55 +00:00
Andreas Rumpf
56d2b08c5a times.nim: make it compile on older OSX versions 2019-02-04 21:06:43 +01:00
Andreas Rumpf
57b49cc509 allocators: add a name field for easier debugging 2019-02-04 21:06:23 +01:00
Araq
6e1d2df74e testament: test nimble packages is beginning to work 2019-02-04 15:59:18 +01:00
Araq
9fa116b6e1 compiler: don't use 2 spaces in an error message 2019-02-04 15:59:18 +01:00
Araq
23c11987b4 make the lexer more forgiving so that nim-regex compiles again 2019-02-04 15:59:18 +01:00
narimiran
10219584ee tut3.rst formatting fix 2019-02-04 14:31:52 +01:00
Miran
8cb80238c4 update documentation CSS (#10543)
* update documentation CSS
* update the expected htmls
2019-02-04 12:27:02 +01:00
LemonBoy
1adc749ed6 Merge pull request #10539 from GULPF/strtabs-nexttry
Change strtabs.nextTry to match the assumption in strtabs.del
2019-02-03 11:49:41 +01:00
Oscar Nihlgård
315abd7163 Change strtabs.nextTry to match the assumption in strtabs.del 2019-02-03 09:37:11 +01:00
Oscar Nihlgård
0091f2ad3b Implement {.booldefine.} (#10533) 2019-02-03 09:06:00 +01:00
genotrance
07553034de Enable Travis folding in winrelease (#10528) 2019-02-02 13:26:32 +01:00
Miran
ad4e3fd28c devel docs should point to devel src (#10529)
Currently, devel docs (https://nim-lang.github.io/Nim/lib.html)
source links point to master branch,
leading to outdated source code and showing the wrong line.
2019-02-02 13:23:10 +01:00
Andreas Rumpf
17d0ce9c1c DOM API: make compatible with Karax's requirements (#10517)
* DOM API: make compatible with Karax's requirements
* make tools\dochack.nim compile again
2019-02-02 00:21:13 +01:00
Araq
f4c76bc8e5 testament: revive ability to test specific important Nimble packages 2019-02-02 00:19:02 +01:00
Timothee Cour
2b35a51651 brew almost never requires sudo (#10525) 2019-02-01 14:56:31 -08:00
Oscar Nihlgård
1ac28f6f5e Deprecate the times.countX procs (#10522) 2019-02-01 20:05:05 +01:00
narimiran
237a36075a another quickfix for os.nim documentation 2019-02-01 19:44:19 +01:00
narimiran
9bd0c2d59a quick-fix for os.nim documentation 2019-02-01 19:37:24 +01:00
Arne Döring
b80dbdb77d Fix vm signed xor (#10519)
* fix #10482

* undo changes

* fix for bitwise not

* remove dead opcode
2019-02-01 12:12:10 +01:00
cooldome
1d5437e9d2 vm fix for bitwise signed ints (#10507)
* fixes #10482

* add missing file

* bug fix
2019-01-31 19:48:39 +01:00
Andreas Rumpf
fc99ddc648 Merge pull request #10513 from LemonBoy/uri-encq
Add `encodeQuery` and `?` to Uri module
2019-01-31 18:19:37 +01:00
Andreas Rumpf
c268bfd5a2 new doc terminology for "compile-time" and "runtime" (#10497)
* First pass at compile-time/runtime terminology changes.

* Solid edit pass on changes and successful rst2html; still need to review HTML output.

* Finished this terminology update.

* Incorporated Araq's initial feedback.
2019-01-31 16:19:19 +01:00
Araq
0ecec8362a distros.nim: brew usually requires 'sudo' 2019-01-31 15:12:36 +01:00
LemonBoy
ec26bc472d Add encodeQuery and ? to Uri module 2019-01-31 13:47:51 +01:00
Timothee Cour
ec6e5681da fix #8063 by adding a testcase for: Deprecation warnings for enum values print twice (#10508) 2019-01-31 11:44:11 +01:00
Miran
fa058773db fixes #10042 (allow spaces in import) (#10504)
This allows spaces in imports, by using the following syntax:
* `import "directory with spaces" / subdir / file`, or
* `import "directory with spaces/subdir/file"`
2019-01-31 08:20:00 +01:00
LemonBoy
81e5a35d56 Show correct address for ipv6 sockets, fixes #7634 (#10505) 2019-01-31 07:34:26 +01:00
Timothee Cour
abcd9fd2e8 fixup #10466 to use runnableExamples (#10510) 2019-01-31 07:19:16 +01:00
deansher
e16310525c Incorporated Araq's initial feedback. 2019-01-30 16:22:08 -05:00
alaviss
acac107fe7 times: use clock_gettime() for epochTime() (#10499)
* times: use clock_gettime() for epochTime()

Fixes #10494

* times: remove gettimeofday()

As FreeBSD and OSX support CLOCK_REALTIME, there's no reason to keep
this code around.
2019-01-30 19:52:21 +01:00
Miran
3d6f2b77b8 fix #9725 (#10503) 2019-01-30 19:50:20 +01:00
Miran
47037ebee3 fixes #9471 (#10502) 2019-01-30 19:49:09 +01:00
Araq
2ce9845fe4 fixes silly typo causing tons of async regressions 2019-01-30 19:48:21 +01:00
Araq
0a628f36f0 destructors: do not produce strong backrefs in closure environments so that refcounting works 2019-01-30 18:17:49 +01:00
Miran
0c2c2dca2a better docs: os (#10492)
* better docs: os
* remove broken test on osx
2019-01-30 17:35:09 +01:00
Miran
9ac0cbdd51 fixes #2796 (#10500) [backport] 2019-01-30 17:31:06 +01:00
Mandeep Singh
7118e1ca01 Example for json.pretty (#10466) 2019-01-30 16:35:45 +01:00
LemonBoy
fa7b757823 Remove unused variable 2019-01-30 10:01:59 +01:00
LemonBoy
49710b9d14 The file directive is relative to the file it is in 2019-01-30 10:01:59 +01:00
LemonBoy
9031c8fb0f Make sure the test snippet directory exists 2019-01-30 10:01:59 +01:00
Timothee Cour
e98bd3aceb fix #10488 GC memory leak regression (#10498)
* fix #10488 GC memory leak regression

* re-enable gch.stack.bottom.repr but only inside when defined(logGC)
2019-01-30 09:26:33 +01:00
deansher
7295468516 Finished this terminology update. 2019-01-29 19:43:01 -05:00
c-blake
b2a5195e92 Add a standard Rusage type definition and wait4, getrusage declarations (#10484) 2019-01-29 21:25:08 +01:00
Andreas Rumpf
dee8e6e98a gc: destructors is beginning to work (#10483)
* kochdocs.nim: code cleanup
* docgen: nicer indentation
* parser.nim: code cleanup
* fixes #10458
* make tests green again
* make =destroy mixins
* gc:destructors: produced C code is almost working
* --gc:destructors simple program compiles (but leaks memory)
* gc:destructors make examples compile in C++ mode
* destructors: string implementation bugfixes
* strs.nim: minor code cleanup
* destructors: builtin seqs are beginning to work
* remove debugging helpers
2019-01-29 15:12:16 +01:00
Emery Hemingway
15422a3e5a Genode fixes (#10491)
Readline pasthru, add linker to config, do not pass -lm to linker.
2019-01-29 15:08:43 +01:00
Araq
07a0a61875 fixes #9149 [backport] 2019-01-29 14:31:43 +01:00
deansher
03a628dddc Solid edit pass on changes and successful rst2html; still need to review HTML output. 2019-01-29 05:35:04 -05:00
deansher
6bae78f365 First pass at compile-time/runtime terminology changes. 2019-01-29 05:35:04 -05:00
deansher
c2e6fc0dfb Merge remote-tracking branch 'upstream/devel' into devel 2019-01-29 05:34:09 -05:00
LemonBoy
a58f5b6023 Merge pull request #10480 from narimiran/docstyle-fix
fix documentation css
2019-01-28 17:47:39 +01:00
Federico Ceratto
aa0a9dd78c Improve Travis CI folding (#10473) 2019-01-28 17:33:35 +01:00
Federico Ceratto
cf323104fc Print error summary in Travis CI (#10474) 2019-01-28 17:32:30 +01:00
Oscar Nihlgård
ac8f6c57a1 Improve exception tracking in the streams module (#10453) 2019-01-28 17:18:07 +01:00
narimiran
ee8bc96a89 change the expected output of nim doc 2019-01-28 16:59:07 +01:00
deansher
d60f8ab991 Merge remote-tracking branch 'upstream/devel' into devel 2019-01-28 08:12:24 -05:00
narimiran
96a8caa9ef fix documentation css 2019-01-28 10:58:24 +01:00
Oscar Nihlgård
9402c82e80 Cleanup heapqueue module (#10476) 2019-01-28 09:58:37 +01:00
Neelesh Chandola
2b0ed9995d Fixes https://github.com/nim-lang/Nim/issues/8484 (#10470) [backport] 2019-01-28 09:52:48 +01:00
LemonBoy
db2a4d230d Add logic to deserialize tyRange fields from json (#10469) 2019-01-28 09:51:54 +01:00
slangmgh
dfa5faea0f Fixes #10352 (#10416) 2019-01-28 09:34:03 +01:00
alaviss
74a7b09412 suggest: quote operators and keywords on suggestion (#10460) 2019-01-28 09:29:49 +01:00
cooldome
690f21043d isLastRead regression fix (#10463)
* fixes #10462

* add a test
2019-01-28 08:32:14 +01:00
Timothee Cour
5fa8a61a23 add git diff hints to help with reviews (#10435) 2019-01-28 07:10:20 +01:00
Thomas T. Jarløv
91b39f2219 uri: Update documentation typo (#10471) 2019-01-27 21:59:58 +01:00
Neelesh Chandola
4f0c3274ee Fix example in manual for line pragma (#10468) 2019-01-27 17:29:33 +01:00
Federico Ceratto
7533f3bcbd Add link to nims.html (#10472) [ci skip] 2019-01-27 17:27:54 +01:00
alaviss
0b02241fc5 semcall: correct lineinfo for accquoted symbols (#10461) 2019-01-27 14:58:10 +01:00
c-blake
322f395f31 Make MemSlice stringification both simpler and faster. (#10464) 2019-01-27 13:52:46 +01:00
LemonBoy
3ce6b2acb9 Fix exception tracking in try blocks (#10455)
Exceptions raised inside a nkFinally/nkExcept block are not caught by
the block itself.

Fixes #3886
2019-01-27 10:32:44 +01:00
Mandeep Singh
a0623a2356 Updated httpClient.nim: added import httpClient statements in examples
Added import httpClient statements in examples, as it was not obvious for a new started from python regarding what to import
2019-01-26 14:45:26 +00:00
Matt Haggard
3c106541fa Increase verbosity of logGC (#10449)
* Increase verbosity of logGC

* Remove & c.repr to avoid re-entering the GC
2019-01-26 12:26:36 +01:00
Federico Ceratto
68dd9be0f5 Handle empty lines in parsecsv; fixes #8365 (#9343) 2019-01-26 10:27:08 +01:00
Timothee Cour
4d230db5ab closes #8610 ; adds test case (#10454) 2019-01-25 19:28:03 +01:00
Miran
268197add8 properly deprecate parseopt2 (#10452) 2019-01-25 13:13:55 +01:00
Federico Ceratto
87fce94d65 Add "cmd" description, minor improvements (#10436) 2019-01-25 11:29:46 +01:00
Araq
70c7348d3e gc:regions: undo the regression introducing changes 2019-01-25 09:49:16 +01:00
narimiran
83caa58c7a docs: fix trailing comma in links 2019-01-25 09:43:47 +01:00
Christian Lyder Jacobsen
8313e5f24e Use hexadecimal in json escaping (#10437) [backport] 2019-01-25 09:29:32 +01:00
cooldome
1c2abb8d88 fixes double object field symbol lookups (no test case available) (#10450) 2019-01-25 09:25:11 +01:00
Araq
43613ff49d docgen: style tweak 2019-01-25 09:22:31 +01:00
Araq
3de255541a docgen: do not produce trailing commas for links 2019-01-25 09:21:51 +01:00
Araq
13d667ee53 docgen: produce links for proc names 2019-01-25 09:21:51 +01:00
Araq
46d5fb9ed7 docgen: nicer indentation 2019-01-25 09:21:51 +01:00
Miran
44923a1b1f fix #10287 (#10448)
The only thing separating these two files
(which wrongly appear on index.html as modules)
and the rest of the (correctly placed)
documents was the style of the title :D
2019-01-25 08:34:02 +01:00
narimiran
baf72691cb include missing modules in lib.rst 2019-01-24 20:09:16 +00:00
jiro
bc31eb301a better docs: parsecsv (#10391) 2019-01-24 17:14:23 +01:00
Miran
251b014bf4 fix #9556 (#10445)
The old logic wasn't very useful because
`relPath` is almost always shorter than `absPath`,
e.g. `../../../../../` is shorter than `C:\Program Files`.

This way allows the usage of a relative path for
at most two levels deep, e.g. `../../relPath`,
otherwise the absolute path is used.
2019-01-24 14:40:16 +01:00
Miran
e75049d7b6 fixes #10433 (#10444) 2019-01-24 12:22:59 +01:00
alaviss
d72921ecf6 compiler/sem: correct macros lineinfo (#10438)
The compiler believes these are where a macro call starts (marked with
`^`):

    m "string"
    ^ ^

This commit addresses that.
2019-01-24 12:22:19 +01:00
Arne Döring
6555d89c2c free some registers after usage, allows more complex macros (#10443) 2019-01-24 11:33:44 +01:00
Federico Ceratto
15ee5d65d1 Add koch run example (#10434) 2019-01-24 11:24:58 +01:00
Thomas T. Jarløv
f9a0eaf89d better docs: algorithm (#10372) 2019-01-24 10:28:07 +01:00
narimiran
ce5e8b93e2 better docs: xmltree 2019-01-24 00:35:37 +01:00
narimiran
f0be575ed1 move tests from tospaths to tos, fixes #9671
Also, change some of `echo`s to `doAssert`.
2019-01-23 22:04:00 +01:00
Araq
28cb81ea87 make DLLs tests compile again; remove dependency on nimbase.h slightly 2019-01-23 22:03:15 +01:00
Araq
c4d2cb9ea6 excpt.nim: code cleanup, don't produce nimFrame in -d:release mode 2019-01-23 22:03:15 +01:00
Araq
40d1c7d43a OutOfMemError is never raised so there is no need to check for it (produce less code) 2019-01-23 22:03:15 +01:00
Araq
400b4e4e0e improve the generated code size for --gc:regions 2019-01-23 22:03:15 +01:00
alaviss
35d96d8749 compiler/sem*: better lineinfo for templates (#10428)
* compiler/sem*: better lineinfo for templates

Lineinfo for templates is inconsistant across the compiler, for example:

    doAssert true
    ^        ^

    a[int](10)
    ^^    ^

The `^` marks where the compiler thinks the template starts.

For qualified call, we got the same situation with `proc`s before #10427:

    system.once
          ^

Generics lineinfo within template declaration is also incorrect, for
example, this is where the compiler believes the `T` in `[T]` is:

    template a[T](b: T)
                  ^

This PR addresses all of these problems.

* nimsuggest: add tests for template highlighting
2019-01-23 16:35:34 +01:00
Tomohiro
bad5ad6dc7 Fix issue #10358 (#10383)
* Fix bug: vccexe finds oldest VCC

* echo path to vcvarsall.bat as hint when failed to execute cl.exe
2019-01-23 15:02:26 +01:00
narimiran
c60bb94647 update gitignore [ci skip] 2019-01-23 13:30:32 +01:00
Vindaar
d9ee377517 fix #10339 by returning type attached to nkEmpty (#10370)
* fix #10339 by checking for nkObjConstr

* revert check for nkObjConstr, return type from nkEmpty node

The correct type needed in `semObjConstr` to fix #10339 is indeed
available, but attached to an `nkEmpty` node. These were previously
discarded in `semTypeNode`, which is used to extract the type for the
object.

* simplify return of PType from  `nkEmpty`

* also fixes #9866, add test case
2019-01-23 11:17:32 +01:00
Ico Doornekamp
efa4b9adaa Fixes #10263; [backport] 2019-01-23 11:13:44 +01:00
Federico Ceratto
c3229dc1c3 Add packaging guide #5182 (#10384) 2019-01-23 11:12:46 +01:00
LemonBoy
9c0e5c4c07 Harmonize the var/let and const handling (#10410)
Fixes #10333
2019-01-23 11:10:51 +01:00
Ico Doornekamp
7fcf51248b Added --docInternal option to allow 'nim doc' to include non-exported symbols 2019-01-23 11:09:26 +01:00
Andreas Rumpf
2655f242a8 use the lastRead analysis; it's correct by construction, not a mess of special cases and seems to be just as fast as the old algorithm 2019-01-23 11:08:51 +01:00
Andreas Rumpf
112f7e650a destroyer.nim: code cleanup 2019-01-23 11:08:51 +01:00
Andreas Rumpf
1b0372c6e9 make tests green again 2019-01-23 11:08:51 +01:00
Andreas Rumpf
11022fea1b control flow graphs: introduce 'join' points for easy analyses based on abstract interpretation 2019-01-23 11:08:51 +01:00
alaviss
2fb8b1d132 nimsuggest/tester: disable highlight tests for epc (#10426)
The EPC backend of nimsuggest currently doesn't support nimsuggest
highlighter, see nim-lang/nim-mode#140
2019-01-23 09:43:11 +01:00
alaviss
e962be8981 compiler/sem*: improve lineinfo for qualified and generic procs (#10427)
Previously the compiler will believe these are where `newSeq` symbol
starts:

    newSeq[int]()
          ^
    system.newSeq[int]()
                 ^

This commit moves them back to:

    newSeq[int]()
    ^
    system.newSeq[int]()
           ^
2019-01-23 09:24:21 +01:00
narimiran
f1a841c605 remove tdont_be_stupid, fixes #10386 2019-01-23 09:19:42 +01:00
Ico Doornekamp
0d480bfe22 Added basic bit manipulation procs to bitops (#10338) 2019-01-23 09:16:14 +01:00
Vindaar
36e34d9aed close #3899 by adding test case (#10424) 2019-01-23 08:44:19 +01:00
LemonBoy
eee9729f53 Fix semantic analysis with noReturn proc in tail pos (#10422)
Fixes #10417
2019-01-23 07:30:49 +01:00
Ray Imber
94f6a6b294 Fix for issue #10342. better message for generic subclass instantiation (#10354)
* Fix for issue #10342. better message for generic subclass instantiation errors.
2019-01-22 17:05:26 -08:00
pgkos
a0c07ef863 Fix wrong integer types in odbcsql and db_odbc (#10419)
* Fix wrong parameter type in SQLErr
* Fix wrong types of integers passed to SQLGetData
2019-01-22 22:39:53 +01:00
LemonBoy
53eda40d40 Restore compatibility with old vcc versions [backport] (#10415)
Local variables are declared before anything else.

Fixes #10352
2019-01-22 22:38:52 +01:00
Miran
0ebfcd4c0f Remove deprecated modules (asyncio, sockets, ftpclient) (#10401) 2019-01-22 16:06:44 +01:00
Federico Ceratto
54fecdb8df Enable log folding in Travis CI (#10414)
Prevent log truncation in browsers
2019-01-22 15:50:50 +01:00
Jjp137
a6a014a859 better docs: parseopt (#10398) 2019-01-22 14:52:43 +01:00
Araq
458c827077 make --define:noSignalHandler compile again 2019-01-22 11:45:45 +01:00
Araq
ced62f3307 compiler interface: don't overdocument the on|off switches 2019-01-22 11:45:45 +01:00
LemonBoy
6825430831 Restrict ptr/ref to ptr/ref implicit conversion (#10411)
* Restrict ptr/ref to ptr/ref implicit conversion

Fixes #10409

* Make the ptr conversions explicit in db_odbc
2019-01-22 11:17:20 +01:00
Miran
39e1cd2bf6 Better docs for sets and intsets (#10362)
* better docs: sets

* better docs: intsets
2019-01-22 10:18:12 +01:00
LemonBoy
792dbed57e Restore the docstring during the .async. transform (#10404) [backport]
Fixes #9816
2019-01-22 09:41:11 +01:00
Neelesh Chandola
226c15499f Fix compileTime pragma applying to whole var/let section (#10389) 2019-01-22 07:55:11 +01:00
LemonBoy
44c04b3571 Object downconversion in VM should not copy (#10378)
Hopefully the type-check phase already rejected all the invalid
conversions by the time we execute the VM bytecode.

Problem reported by chrisheller on the Nim Forum
2019-01-22 07:36:40 +01:00
LemonBoy
3ea099bc7f Finalizer proc must be global (#10388)
Fixes #10376
2019-01-22 07:35:52 +01:00
LemonBoy
7a3f382517 Fix corner case of checked div/mod on x86 (#10406)
Fixes #10377
2019-01-22 07:33:27 +01:00
Miran
a0e8d4a93f Gdb reload (#10408)
* gdb pretty printer survive reload

* precise printer injection
2019-01-22 06:25:11 +01:00
genotrance
4b1e227531 Fix gorge caching (#10407) 2019-01-22 06:24:45 +01:00
Dean Thompson
a6de0274ee Merge pull request #1 from nim-lang/devel
Getting the latest from nim-lang
2019-01-21 16:40:04 -05:00
LemonBoy
ee89ba6bdb Fix subtype conversion w/ varargs arguments (#10402)
The type matching is done on the `T` of the `varargs[T]` so the
conversion must be performed to `T` and not to the whole type.

This problem is only noticeable with the cpp backend since C doesn't
give a damn shit about your fucking (wrong) types.

Fixes #9845
2019-01-21 19:12:17 +01:00
Arne Döring
b4d329d69f precise printer injection 2019-01-21 17:38:17 +01:00
LemonBoy
ae5d8fbd9d Proper check for tyStatic[T] -> U conversions (#10382)
Drop the outer tyStatic shell then perform the check.

Fixes #7609
2019-01-21 17:27:36 +01:00
Oscar Nihlgård
a4cdd25b19 Support system.reset in vm (#10400) 2019-01-21 17:00:33 +01:00
alaviss
413755fd45 Correct lineinfo for accent quoted symbols in proc definition (#10399)
* compiler/parser: preserve lineinfo for accent quoted symbols

Previously the lineinfo for symbol $$$ in this example is:

    proc `$$$`
             ^

After this commit:

    proc `$$$`
          ^

* compiler/semstmts: correct lineinfo for accent quoted idents

Previously nimsuggest would highlight this as:

    proc `$$$`
         ^~~

After this commit:

    proc `$$$`
          ^~~

* nimsuggest/tests: add a test for accent quoted proc

Disabled by default
2019-01-21 16:57:48 +01:00
Miran
4bea8dd674 better docs for lists and deques (#10390)
* better docs: lists

* better docs: deques
2019-01-21 15:22:53 +01:00
Oscar Nihlgård
9a003bae06 Fix error lexer error messages for to large numbers (#10394) 2019-01-21 15:14:38 +01:00
Arne Döring
ea0c1811c5 gdb pretty printer survive reload 2019-01-21 14:22:16 +01:00
Neelesh Chandola
5491f40d54 fix vccexe not using correct path for detecting vcvarsall (#10364) 2019-01-21 10:05:23 +01:00
Timothee Cour
32a90f7406 fix json bug []= misplaced (#10397) 2019-01-21 08:24:06 +01:00
Kobi
28b3c8d74d prevent index out of bounds error in oserr.nim 2019-01-19 10:56:36 -08:00
Federico Ceratto
095eaacf21 Fix spelling errors (#10379) 2019-01-19 16:01:27 +01:00
Thomas T. Jarløv
bfeade9791 better docs: uri (#10373) 2019-01-19 15:31:14 +01:00
Thomas T. Jarløv
4a04470450 better docs: sha1 (#10374) 2019-01-19 15:24:39 +01:00
Thomas T. Jarløv
15aea78405 better docs: base64 (#10371) 2019-01-19 15:21:07 +01:00
Andreas Rumpf
2371b4be96 ported havlak and gcbench benchmarks to work with --gc:regions 2019-01-19 12:48:39 +01:00
Andreas Rumpf
9985706fb8 GC tests: make them take less time to save CI cycles 2019-01-19 12:48:39 +01:00
Andreas Rumpf
f7c0360aba allocators: introduce --define:nimMinHeapPages for tuning mmap calls (omg they are slow on OSX...) 2019-01-19 12:48:39 +01:00
Oscar Nihlgård
86a91c1a4a Fix parseutils.parseBiggestInt regression (#10348) 2019-01-18 19:15:29 +01:00
Neelesh Chandola
3cc39c2eb9 Show filename in exception raised by expandFilename on windows (#10365) 2019-01-18 18:46:35 +01:00
Arne Döring
8399e0f78a deprecate += and friends for bool and enum (#10336)
* fixes #10257
* add version to deprecation
2019-01-18 14:36:38 +01:00
Thomas T. Jarløv
6fb618da4b better docs: parseutils 2019-01-18 14:17:25 +01:00
Ico Doornekamp
f11f36e7d5 Fixed getCustomPragmaVal to allow multiple fields in custom annotations (#10289) 2019-01-18 09:04:12 +01:00
Timothee Cour
27e2ed4375 fix #9629 every binary cmd line option allows on/off/empty=on (#10353)
* fix #9629 every binary cmd line option allows on/off/empty=on

* workaround refs #10359
2019-01-18 09:03:26 +01:00
Tomohiro
4b4e4fc029 Fix unhandled exception that raised when nim was executed with --cc:vcc option (#10356) 2019-01-18 09:00:32 +01:00
cooldome
1e63f1edb3 destructors: first step towards fixing #9617 (#10341) 2019-01-18 08:51:22 +01:00
Miran
214f48eae9 Remove long deprecated stuff (#10332) 2019-01-18 07:18:32 +01:00
Miran
cceb28b5eb remove queues (#10347)
This module was deprecated and superseded by deques 2 years ago.
2019-01-17 20:37:39 +01:00
Timothee Cour
42bac52426 [CI] now enables NIM_COMPILE_TO_CPP=true to run without allow_failures (#10315)
* better fix for `nim cpp` bootstrap error: error: no member named raise_id
* [CI] now enables runs NIM_COMPILE_TO_CPP=true without allow_failures
* workaround refs #10343
2019-01-17 08:00:44 +01:00
LemonBoy
15584879b9 Properly wrap discarded statements (#10322)
Failing to do so lead the codegen to emit invalid code sometimes,
especially when C++ references were involved.

Fixes #10241
2019-01-17 07:55:29 +01:00
narimiran
52a54f5f04 documentation: remove author field [ci skip] 2019-01-17 07:15:40 +01:00
Araq
2039dad273 koch.nim: Make bootstrapping in C++ mode robust 2019-01-16 21:19:51 +01:00
Araq
8947779dd0 disable one more test for C++ 2019-01-16 21:19:51 +01:00
Oscar Nihlgård
5df411bd6e Revert export of times.CTime; add std/time_t instead. (#10319)
* Revert export of times.CTime
* Add std/time_t
2019-01-16 21:08:32 +01:00
alaviss
fc30cf02bc nimsuggest: add an option to bind to a free port (#10328) 2019-01-16 21:06:32 +01:00
Araq
1cb5e20620 parseutils.nim: help the codegen produce better code 2019-01-16 17:59:24 +01:00
narimiran
2e8bf88614 sequtils doc: another quickfix [ci skip] 2019-01-16 12:32:00 +01:00
narimiran
3abe6e9e14 quickfix for sequtils docs [ci skip] 2019-01-16 11:58:51 +01:00
Miran
b48364694d Merge pull request #10318 (Better docs for four modules) 2019-01-16 11:48:37 +01:00
Timothee Cour
b8454327c5 json: support tuple (#10010) 2019-01-16 10:16:14 +01:00
narimiran
387f481e86 better docs: math 2019-01-16 09:46:01 +01:00
narimiran
b40a637fac better docs: tables 2019-01-16 09:45:57 +01:00
narimiran
be6456f0f4 better docs: strutils 2019-01-16 09:45:51 +01:00
narimiran
b097081f10 better docs: sequtils 2019-01-16 09:45:27 +01:00
tweenietomatoes
384e517f09 Most important date change ever (#10323) 2019-01-16 09:36:18 +01:00
Timothee Cour
e0afacb9f2 properly fix #10030 by skipping all external configs (#10324) 2019-01-16 08:14:55 +01:00
Timothee Cour
fbd6743ea1 fix sdl_test test that failed in CI cpp mode (#10314)
* fix sdl_test test that failed in CI cpp mode

* preserve old code for NimInAction in `nim c` mode
2019-01-15 15:17:52 -08:00
Oscar Nihlgård
1d7e3a84fd Improve exception usage in parseutils (#10284) 2019-01-15 23:48:19 +01:00
Araq
ece5887ab0 another attempt to fix https://github.com/nim-lang/nightlies/issues/17 2019-01-15 23:08:09 +01:00
nepeckman
7920dc2898 Added support for --genDeps on JS backend (#10320) 2019-01-15 22:58:44 +01:00
Araq
ef769e20b3 attempt to fix https://github.com/nim-lang/nightlies/issues/17 2019-01-15 22:57:50 +01:00
Araq
27e366eaec fixes #8294 [backport] 2019-01-15 22:47:21 +01:00
Timothee Cour
795e5e11ef parseopt2.cmdLineRest is now correct too (#10304) 2019-01-15 21:51:02 +01:00
Timothee Cour
beed27b75d improve vmgen.codeListing formatting (#10306)
* improve vmgen.codeListing formatting
* address comments
2019-01-15 19:02:01 +01:00
Reimer Behrends
06e3d3ab4d Disable interior pointer checking by default for the Boehm GC. (#10316)
The Boehm GC only needs interior pointer checking if pointers in global
variables or on the heap point to the interior of an object rather than
the beginning. If this does not happen, then checking for interior
pointers causes additional overhead, in particular because any objects
whose sizes are an exact multiple of two words gain another two words of
padding, wasting memory.

If checking of interior pointers is still desired, this can be achieved
by setting the environment variable GC_ALL_INTERIOR_POINTERS.

Pointers on the stack will always be treated as potential interior
pointers, as compiler optimizations may advance the only live reference
to a point past the beginning of an object.
2019-01-15 19:00:02 +01:00
Timothee Cour
4355f23ee5 fix #10305 nim cpp is now nan-correct at CT (#10310)
* fix #10305 nim cpp is now nan-correct at CT
* add example where simply `nim cpp -d:release` would exhibit nan bug
2019-01-15 14:50:28 +01:00
Timothee Cour
9a92bc15b3 [CI] runCI runs kochExec "boot" regardless of nim mode (#10312) 2019-01-15 14:46:29 +01:00
Timothee Cour
c05e9c7c73 fix twrong_refcounts in nim cpp mode (#10313) 2019-01-15 14:46:01 +01:00
Andreas Rumpf
05c52ff34f fixes #10203 (#10290)
* fixes #10203
* make typredef test green again
* fixes the regressions differently
2019-01-15 10:15:27 +01:00
Andreas Rumpf
06a8b48811 disable one more test for C++ 2019-01-15 10:02:09 +01:00
Andreas Rumpf
fbf9b1f88a fixed indentation 2019-01-15 10:02:09 +01:00
Timothee Cour
1d941b8735 refs #10249 #10266; each command logged only if --verboseCommands:true (#10303) 2019-01-15 09:53:58 +01:00
Neelesh Chandola
8922063bd8 typed/untyped return type is invalid for everything except templates and macros (#10275) 2019-01-15 08:08:12 +01:00
Jjp137
c8ba9ffdba lib.rst: fix a typo (#10308) [ci skip] 2019-01-15 07:05:05 +01:00
Timothee Cour
9e68b2ce5d fix test 2019-01-14 17:00:54 -08:00
Timothee Cour
0a8762eb7b fix #9842 #9951: nim -r and parseopt.cmdLineRest are now correct 2019-01-14 17:00:54 -08:00
Timothee Cour
e17321aa24 improve formatting in assertEquals 2019-01-14 17:00:54 -08:00
genotrance
dd1f23f6fc Expose CTime (#10301) 2019-01-14 22:16:11 +01:00
Andreas Rumpf
1899d8d107 make tests green again 2019-01-14 20:11:33 +01:00
Arne Döring
b78af990b8 Fixes #10065 (#10260)
CountTable now returns 0 instead of 'key not found' for get requests.
2019-01-14 17:16:17 +01:00
Araq
d69a7842fa fixes #7878 2019-01-14 12:36:34 +01:00
Araq
825e08b046 fixes #7524 2019-01-14 12:15:40 +01:00
Timothee Cour
65593e76f4 fixes leftover from #9647 : use nimf as standardized extension for source code filters (#10294) 2019-01-14 11:58:16 +01:00
genotrance
c707267212 Add stdin read support to nimscrit #3983 (#10292) 2019-01-14 09:26:10 +01:00
narimiran
29e0a792ff [backport] fix documentation leak to os.nim[ci skip] 2019-01-14 09:24:12 +01:00
Arne Döring
2b37bf5d5b added proc rand for typedesc (#10259) 2019-01-14 09:20:31 +01:00
Araq
d983d998b2 fixes #9218 2019-01-13 18:53:27 +01:00
Araq
3c2d82eaae make megatest green 2019-01-13 17:19:36 +01:00
Araq
80c69ffd31 nimgrep: use standard regular expression syntax, not reExtended 2019-01-13 16:23:08 +01:00
Araq
bd5dd2b95b nimgrep: fixes #989 2019-01-13 16:22:19 +01:00
Araq
2ccc9db59d closes #3744 2019-01-13 16:05:42 +01:00
Araq
aa7ad88978 fixes #10075 [backport] 2019-01-13 15:52:50 +01:00
Araq
ab99bdfc40 fixes #10136 2019-01-13 14:56:50 +01:00
Araq
451377f737 fixes #10271 [backport] 2019-01-13 14:24:38 +01:00
Araq
7f0559b93f fixes #7241 2019-01-13 14:09:14 +01:00
Araq
0c10fc67eb fixes #10104 2019-01-13 14:09:13 +01:00
Dominik Picheta
d740a5b79a Implements BackwardsIndex [] for deque. (#10105) 2019-01-13 14:06:16 +01:00
Araq
796432ff94 make tests more robust; tests should be deterministic, no randomize() calls in tests 2019-01-13 13:54:44 +01:00
Araq
40115cd645 improve error messages quality for '.push: raises []' 2019-01-13 13:30:01 +01:00
Araq
5cd18b0f24 make system.task compatible with NimScript; refs #10254 2019-01-13 09:04:57 +01:00
Strømberg
2823da5e52 setCommand nop update documentation (#10254)
When I used Warning: Using `setCommand 'nop'` is not necessary.
2019-01-13 09:04:40 +01:00
Timothee Cour
9af85fb69f fixes #10273 execShellCmd now returns nonzero when child killed with signal + other fixes (#10274)
* s/exitStatus(...)/exitStatusLikeShell(...)/
* fix #10273 execShellCmd now returns nonzero when child exits with signal
* test case for #10249 and explanation for the bug
* fix test failure
* add tests/nim.cfg
2019-01-13 09:00:39 +01:00
rec
f5cc2e2de5 Fixes 10202 (#10283)
* Add a test case for #10202
* Fix asgn for object tyVars; fixes #10202
* Check the variant kind before accessing the sym field
2019-01-12 19:49:31 +01:00
Timothee Cour
98ef545bed fix #10281 (#10282) 2019-01-12 08:18:04 +01:00
Ico Doornekamp
7e7603ed2b Documented error source argument of macros.error() (#10279) 2019-01-12 08:17:20 +01:00
Araq
647066e378 make the stdlib work with the changed docgen 2019-01-11 22:17:43 +01:00
Araq
56b804a283 RST parser: fixes #8158 2019-01-11 22:17:43 +01:00
Araq
ee7f2d97cc docgen: support markdown headings too 2019-01-11 22:17:43 +01:00
Araq
5ef5dc86c5 docgen: support markdown link syntax; enable markdown extensions 2019-01-11 22:17:43 +01:00
Araq
c3d80647ae docgen: render 'interpreted text' the same as inline literals for markdown compat 2019-01-11 22:17:43 +01:00
Neelesh Chandola
b0979c8b1c Cleanup comesFromPush logic (#10278) 2019-01-11 19:16:03 +01:00
Timothee Cour
09ef25810a refs #10249 ; more debug info to diagnose failures (#10266) 2019-01-11 17:03:19 +01:00
Andreas Rumpf
5397c5d31d fixes #10216 (#10270) 2019-01-11 16:34:22 +01:00
Andreas Rumpf
d1b7aa28e7 fixes #10240 (#10269)
* kochdocs.nim: code cleanup

* fixes #10420
2019-01-11 15:55:16 +01:00
Jörg Wollenschläger
ceabbeadd7 Fixes new atomics for C + vcc (#10267) 2019-01-11 12:07:46 +01:00
narimiran
0a2f711b9e revert moving oids and smtp to graveyard 2019-01-11 08:51:19 +01:00
Timothee Cour
540d102d87 fix #10261 unittest now returns 1 on error instead of buggy behavior (#10264) 2019-01-11 07:59:20 +01:00
Jörg Wollenschläger
ab425d793a [RFC] Better atomics (#8620)
* Initial version of C++11 style atomics
* Make Atomic[T] always concrete
2019-01-10 19:18:00 +01:00
Ico Doornekamp
a5fe676f37 Added 'Limitations' section to nimscript manual listing the restrictions of the VM (#10209) 2019-01-10 17:57:21 +01:00
Timothee Cour
0bb76dde54 fixes #10030 bootstrap is insulated from user config (#10244) 2019-01-10 17:49:57 +01:00
Vindaar
8e600b78ca add unsetControlCHook to remove a Ctrl-C hook after it was set (#7267)
* add unsetControlCHook to remove a Ctrl-C hook after it was set

Adds the inverse proc to setControlCHook in order to lift a Ctrl-C
hook after it has been set.

* remove check for noSignalHandler in system/excpt.nim
2019-01-10 13:44:44 +01:00
Neelesh Chandola
d998cb58dd void object fields are now ignored by codegen and fields/fieldPairs iterator (#10144)
* Codegen now ignores object fields of type void
* Fix `$` bug for objects/tuples where it does not add a comma
* fields/fieldPairs iterators now ignore void types
* Use `isEmptyType` instead of checking for `tyVoid` directly
2019-01-10 12:49:35 +01:00
Miran
6389271d1c Merge pull request #10248 from narimiran/graveyard
Move four modules to graveyard
2019-01-10 11:17:06 +01:00
Oscar Nihlgård
b3435d22dc Times cosmetic changes (#10237)
* Add more Date wrappers to jscore

* Times cosmetic changes
- Improved docs
- Code wrapped at 80 chars
- Formatting fixes using nimpretty
- Remove some old deprecated procs
2019-01-10 10:56:12 +01:00
Timothee Cour
d2b95cb476 fixes #10039 : CI now runs buildTools (eg, nimfind wasn't being compiled before); refactoring (#10242) 2019-01-10 09:35:37 +01:00
narimiran
f7d2f9c5f0 update changelog 2019-01-10 09:31:18 +01:00
Oscar Nihlgård
3ed5f83704 Fix exception tracking for system.open (#10253) 2019-01-10 09:28:09 +01:00
Arne Döring
f55c8d4d54 fixes #10251 (#10255) 2019-01-10 09:27:01 +01:00
cooldome
44b4e289d6 destructors: lift type bound operations for case and distinct objects (#10238) 2019-01-10 09:25:35 +01:00
narimiran
be958d60c9 remove oids 2019-01-10 09:17:12 +01:00
narimiran
1a3763fe13 remove smtp 2019-01-10 09:17:12 +01:00
narimiran
8d9b093440 remove scgi 2019-01-10 09:17:12 +01:00
narimiran
da57c0ab99 remove subexes 2019-01-10 09:17:12 +01:00
Oscar Nihlgård
87232a38e4 ValueError now inherits from CatchableError (#10246) 2019-01-10 08:49:57 +01:00
Notkea
11050d1104 make Stream.{read,peek} procs public (#9806)
Those are useful in generic code, and `proc write*[T](s: Stream, x: T)` was already public.
2019-01-09 08:06:40 -06:00
Ico Doornekamp
0229dfd199 epoll selector starts with reasonable fd set size (1024) and increases in powers of two when needed. This prevents the selector to allocate large amounts of memory at startup on systems with a high RLIMIT_NOFILE setting (#10194) 2019-01-09 10:46:22 +01:00
Timothee Cour
23c1ee982e add alignTable, parseTableCells to align/format a tab(etc) delimited table (#10182)
* add compiler/unittest_light.nim for easy diffing: assertEquals and mismatch
* fixup
* add alignTable, parseTableCells
2019-01-09 09:46:44 +01:00
narimiran
258952832f remove float128 from the manual, fixes #10213 [ci skip] 2019-01-09 07:01:32 +01:00
genotrance
ae508f81d8 Merge pull request #10239 from timotheecour/pr_fix_comment_9766
fix leftover comment from #9766
2019-01-08 23:30:47 -06:00
genotrance
def477acb7 Merge pull request #10236 from treeform/passSSLPath
Fix libssl order. Newest one is 1.1
2019-01-08 23:24:45 -06:00
Timothee Cour
6ce3949c8a add isNamedTuple; make $(1, 2) be (1, 2) instead of (Field0: 1, Field1: 2) which leaked implementation detail (#10070)
* add `isNamedTuple`; make $(1, 2) be (1, 2) instead of leaking implementation detail (Field0: 1, Field1: 2)
  fixes this: #8670 (comment) /cc @alehander42 @Vindaar @mratsim

* Note: isNamedTuple is useful in other places, eg #10010 (comment)

* move isNamedTuple to helpers.nim to avoid exposing new symbol to system.nim

* remove workaround in tests/vm/tissues.nim failing test now that #10218 was makes it work
2019-01-08 18:37:25 -08:00
Timothee Cour
fc7fcca9df fix leftover comment from #9766 2019-01-08 17:07:46 -08:00
Timothee Cour
bf3a308e86 [error messages, stacktraces] fix #8794 #9270 #9767 #9768 (#9766)
* fixes #8794 : `Error: undeclared field: 'foo'` should show type (+ where type is defined) (hard to guess in generic code)

* fixes #9270: `--listFullPaths` not honored by `declared in foo.nim` messages

* fixes #9767: VM stacktrace doesn't honor --excessiveStackTrace:on

* fixes #9768: VM stacktrace misses column info, can lead to ambiguous or harder to read stacktraces

* refactors some col+1 code to col + ColOffset (self documents code)

* make getProcHeader show declared info location also for types and all routine kinds (including macros,templates) instead of just (rather arbitrarily) for iterator,proc,func,method

* --listFullPaths now is honored in more places

* fix typo system/except.nim => lib/system/excpt.nim

* remove substr(foo, 0) hack in compiler/vm.nim which seems old and not applicable anymore
2019-01-08 15:58:47 -08:00
Neelesh Chandola
fb26b95f81 {.deprecated: msg.} now works for vars and lets (#10234) 2019-01-08 19:44:47 +01:00
Andre von Houck
21078798ea Fix libssl order. Newest one is 1.1 2019-01-08 10:30:22 -08:00
narimiran
d0366c5194 update issue templates [ci skip] 2019-01-08 15:30:15 +01:00
Timothee Cour
c60916a2af [CI] fixes #10041 move bulk of travis and appveyor logic to koch.nim (#10183) 2019-01-08 13:08:19 +01:00
alaviss
6737634d88 os.execShellCmd: fixes #10231 (#10232)
Darwin has long deprecated the wait union, but their macros still assume
it unless you define _POSIX_C_SOURCE. This trips up C++ compilers.

This commit duplicates the behavior of WEXITSTATUS when _POSIX_C_SOURCE
is defined.
2019-01-08 12:41:15 +01:00
Timothee Cour
821920aa39 [nimpretty] fix #10211; fix #10199 (#10212)
* [nimpretty] fix #10211; fix #10199
* address comments
* un-document --backup and set its default to false
2019-01-08 10:38:34 +01:00
Clyybber
427435a814 Don't use deprecated pragma syntax (#10187)
* Don't use deprecated pragma syntax

* Remove pure pragma, since it's a noop now
2019-01-08 10:13:39 +01:00
treeform
3ed833198b Better LibSSL search order. (#10230) 2019-01-08 09:50:25 +01:00
alaviss
20402579a2 system/strmantle: avoid leaking docs to system.nim [ci skip] (#10233)
thanks @timotheecour for spotting this
2019-01-08 08:42:10 +01:00
Arne Döring
abad758a7e Fix for sizeof bitsize combination (#10227)
* fix #10082

* added test
2019-01-07 18:09:57 +01:00
Neelesh Chandola
387831d657 Show error when trying to export individual enum field (#10109) 2019-01-07 16:02:47 +01:00
jcosborn
044cef152f add custom pragma support for var and let symbols (#9582)
* add custom pragma support for var and let symbols
* updated changelog for custom pragmas on var and let symbols
* add oldast switch for backwards compatibility
2019-01-07 12:36:06 +01:00
alaviss
139fa396e8 os.execShellCmd: use WEXITSTATUS to retrieve exit code (#10222)
According to POSIX, system() shall returns the termination status in the
format specified by waitpid(), which means WEXITSTATUS should be used to
retrieve the exit code portably.

This fixes execShellCmd on Haiku.
2019-01-07 12:27:07 +01:00
zah
87f8ec5b92 Fix #10073 (#10218) 2019-01-07 12:10:54 +01:00
Miran
5345c5b130 remove deprecated modules (#10215)
* removed from `compiler`:
    * lists (deprecated 2 years ago)

* removed from `lib` (all deprecated 3 years ago):
    * ssl
    * matchers
    * httpserver

* removed from `lib/deprecated`:
    * unsigned
    * actors (and three accompanying tests)
    * parseurl

* moved to `lib/deprecated`:
    * securehash (the reason for not directly removing - it was deprecated (only) one year ago)
2019-01-07 10:37:49 +01:00
Ico Doornekamp
be9d1280ae Added examples to strtabs module (#10160) 2019-01-07 00:52:19 +01:00
Neelesh Chandola
e77dd683eb Fix defer not not-working at top level (#10191) 2019-01-07 00:51:17 +01:00
Alexander Ivanov
15773c455a Add changelog for the isNil JavaScript change (#10184)
Forgot to add an item,  breaking change
2019-01-07 00:50:21 +01:00
Leonardo Cecchi
b7be67349b Fix ODBC SQL Error string decoding (#10207) [backport]
ODBC Errors were presented to the users as a sequence of characters.
I.e.:

    >test_oracle.exe

    Error: ['H', 'Y', '0', '0', '0', '\x00', '\x00', ...]

    test_oracle.nim(15)      test_oracle
    test_oracle.nim(8)       test_oracle
    db_odbc.nim(534)         open
    db_odbc.nim(168)         dbError
    Error: unhandled exception: ODBC Error [DbError]

This patch fix the string decoding, creating a real string:

    >test_oracle.exe

    Error: HY000 [Oracle][ODBC][Ora]ORA-12541: TNS:no listener

    test_oracle.nim(15)      test_oracle
    test_oracle.nim(8)       test_oracle
    db_odbc.nim(534)         open
    db_odbc.nim(168)         dbError
    Error: unhandled exception: ODBC Error [DbError]
2019-01-07 00:48:55 +01:00
c-blake
ea3e32c224 Remove totally unneeded import of hashes. (#10221) 2019-01-07 00:42:49 +01:00
Federico Ceratto
2fa35126b0 Fix getAddrInfo, add IPPROTO_ICMPV6 Closes #10198 2019-01-06 20:23:44 +00:00
Tristano Ajmone
f3bd3691e7 Minor Fixes to Manual Wording (#10214) 2019-01-06 10:45:24 +01:00
Timothee Cour
4a720394bb testament megatest: we can now tell which test failed; helps debugging and prevents certain bugs, plus other fixes (#10089)
* [testament] --verboseMegatest flag to make megatest compilation verbose
* replace "tests" by testsDir
* megatest's nimcache is now in same dir as other tests to avoid clobbering (eg when running tests from multiple Nim repos)
2019-01-05 16:07:09 +01:00
Timothee Cour
ffea3fbfae * move up runnableExamples definition so can be used more in system.nim (#10196)
* document that toInt, toBiggestInt round towards 0 and add runnableExamples
* minor doc fixes
2019-01-05 16:01:10 +01:00
Hugo Locurcio
e5ca57d85c Fix the tuple returned by os.splitFile() in documentation (#10197) 2019-01-05 01:00:38 +01:00
alaviss
be0a4d1342 fix system.nim documentations (#10168)
* system: fix nimGC_getStackBottom doc
* system/helpers: avoid leaking docs to system
2019-01-04 15:13:07 +01:00
Neelesh Chandola
e9a192c36f expandFilename on windows is now consistent with other platforms (#10154) 2019-01-04 15:11:48 +01:00
rec
ba7d33b4e4 Guard against null exception (#10162) 2019-01-04 15:05:03 +01:00
Tristano Ajmone
4eee92a7a3 Fix Typo in Compiler Guide (#10189)
Change 'ableit' to 'albeit'.
2019-01-04 14:37:07 +01:00
Timothee Cour
319b46230c fix bug in doAssertRaises when exception==Exception (#10172)
* fix bug in doAssertRaises when exception==Exception
* add testcase for doAssertRaises
2019-01-04 13:54:02 +01:00
Araq
5101b6befd fixes #10188 2019-01-04 13:39:54 +01:00
Miran
69149a0e92 [backport] improve unicode docs, fixes #2353 (#10174)
* as instructed in #2353, provides a short description why
there are no specialized procs for seq[Rune]
* adds several examples to better explain what some functions do
* small fixes (double backticks, add missing dots, etc.)
* use `rune` instead of "unicode characer"
2019-01-04 13:20:12 +01:00
Neelesh Chandola
db7ff50fe5 Undocument --genmapping (#10175) 2019-01-04 10:43:29 +01:00
Araq
086229459a runnableExamples: compile and test them as a single file; fixes #9300 2019-01-04 09:52:22 +01:00
Miran
77166ba795 [backport] correctly document toInt, fixes #2764 [ci skip] (#10176) 2019-01-04 09:25:58 +01:00
Araq
e6cbf9e790 koch.nim: speed up tests for the 'testinstall' target for the nightly builds (these tests are also covered by the other CIs) 2019-01-03 23:45:42 +01:00
Andreas Rumpf
cb9110c43d --define:nimQuirky exception handling for Nim; in preparation of a blog post 2019-01-03 18:56:05 +01:00
Neelesh Chandola
7c5ae00887 exportc is now not allowed for type aliases (#9979) 2019-01-02 20:01:06 +01:00
Oscar Nihlgård
9fb8c3d965 Add {.noReturn.} to system.raiseAssert (#10161) 2019-01-02 17:39:53 +01:00
Timothee Cour
a1e268e3dc [cleanup] remove dead code compiler.options.mergeConfigs (#10165) 2019-01-02 10:26:40 +01:00
Ico Doornekamp
31b8bc7866 Add link to tutorial part III to docs.rst (#10157) [ci skip] 2019-01-01 19:49:29 +01:00
Neelesh Chandola
6ed9676af5 Show field not initialized warning only when notnil used (#10155) 2019-01-01 18:49:44 +01:00
Neelesh Chandola
9faad7591e Deprecate gc v2 (#10151)
* Deprecate gc v2

* warnDeprecated now has custom messages
2019-01-01 13:50:48 +01:00
jiro
e7fa8f3443 Add Example code to Documentation comment of wordWrap proc. (#10146) 2019-01-01 09:56:59 +01:00
cooldome
7c90e22ddd fixes #10148 (#10149)
* fixes #10148
* fix a typo
2018-12-31 22:57:09 +01:00
Timothee Cour
ab72d68ec8 fix off by 1 error in col shown by toFileLineCol (#10138)
* fix off by 1 error in `col` shown by toFileLineCol
* fix test failures
2018-12-31 15:42:01 +01:00
c-blake
7ac1fc81fd Resolve things raised in https://github.com/nim-lang/Nim/issues/10081 ? (#10084)
* Resolve things raised in https://github.com/nim-lang/Nim/issues/10081 ?
CDF is a standard ident in all things related to random numbers/sampling,
and full words "cumulativeDistributionFunction" would be silly long, in
this case, IMO.  We use lowercase `cdf` to make it not look like a type,
remove all looping from `sample` letting callers do it.  Besides just
side-stepping any `sampleSize` name choice, callers may want to filter
out samples anyway which this makes slightly simpler.

Also add two variants of `cumsum`, value return and in-place update
distinguished by the var-ness of the first argument.  Add tests for
`int` and `float` for both `cumsum` and the new `sample`.  (The sample
tests exercise the value return mode of `cumsum`.)

Functionality pre-this-PR `sample(a, w)` is now the almost as simple
`for i in 0..<n: sample(a, w.cumsum)`, but this new code factoring is
almost surely better.  The statistical tests pass, as before.

* Address Araq comment in https://github.com/nim-lang/Nim/pull/10084
We can always add in some `var` version later if desired to save
memory, but this change now at least firms up the `sample` interface.

* Rename `cumsum` -> `cumsummed` to honor NEP1 style.  Re-instate `cumsum` as
the in-place transformation.  Test both in `tests/stdlib/tmath.nim` and use
`cumsummed` in the example code for sample since that's a simpler example.

* Fix requests from https://github.com/nim-lang/Nim/pull/10084 :
  example in lib/pure/math.nim and comment whitespace in lib/pure/random.nim
2018-12-31 14:52:51 +01:00
deech
e87910197a Check there are no side effects before optimizing away compile time expressions. (#9934) 2018-12-31 14:41:24 +01:00
Neelesh Chandola
bcbe317d17 Before showing deprecated warning, check whether enum field was marked deprecated or the whole enum type (#10135) 2018-12-30 18:34:41 +01:00
Andreas Rumpf
2ee2022c29 help Nim optimize intsets.initIntSet 2018-12-30 11:45:16 +01:00
cooldome
82c009a2cb Dead code elimination for entire modules and their init procs if empty (#10032)
* fixes #9798
* Change order of write modules
* Move datInit calls ahead of initStackBottom
2018-12-30 11:28:12 +01:00
Neelesh Chandola
cbbdcb2669 Show deprecation warning for fields of a deprecated enum (#10112)
* Show deprecation warning for fields of a deprecated enum

* Add test
2018-12-30 09:45:39 +01:00
Neelesh Chandola
c5ad4c10cb Deprecated pragma is now supported on enum fields (#10113)
* {.deprecated.} pragma is now supported for enum fields
* Add tests
* Simplify code
2018-12-30 09:43:59 +01:00
Timothee Cour
a6633b9658 fix typetraits.$ regression https://github.com/c-blake/cligen/issues/84 (#10131)
* fix typetraits.`$` regression https://github.com/c-blake/cligen/issues/84
* add test
2018-12-30 09:40:21 +01:00
Alexander Ivanov
aadbdd6b06 Support undefined in isNil (#9960) 2018-12-30 02:48:37 +01:00
Andreas Rumpf
062d7e3a39 fixes #10082 2018-12-30 02:45:43 +01:00
Timothee Cour
dd33f41877 refs #10121 (#10124) 2018-12-30 02:06:15 +01:00
Timothee Cour
7f81195e5a document --profiler:on (#10115) 2018-12-30 01:31:30 +01:00
Neelesh Chandola
527b774772 {.push raises: [].} is now ignored for vars/lets/consts (#10026) 2018-12-30 01:28:56 +01:00
Timothee Cour
e98d54b050 nim dump: add nimcache entry (#10122) 2018-12-30 01:27:37 +01:00
Timothee Cour
9c65ea0d16 nim c now allows: when defined(c) (#10130) 2018-12-30 01:21:33 +01:00
Timothee Cour
0831292863 revives: Move typetraits.$ to system. Fixes #5827 (#10071)
* Move typetraits.`$` to system. Fixes #5827.
* revive PR; adjust code to make sure everything works and add tests
* fix tests/concepts/tstackconcept.nim
* address comments
2018-12-30 01:09:47 +01:00
Timothee Cour
eba8ffcf70 checkErr now shows actual system error msg instead of unknown error (#9987) 2018-12-27 22:46:53 +01:00
ee7
cc4720fac1 Const tuple unpacking: add tests (#10100) 2018-12-27 22:40:40 +01:00
Timothee Cour
1b7c8482fe fixes #10101 (#10103) 2018-12-27 22:40:09 +01:00
Neelesh Chandola
05b8085a87 Pragma syntax is now consistent (#9993)
* Give deprecation warning when type pragmas do not follow the type name
* pragma before generic parameter list in type definition is now deprecated
* Update changelog
* Fix bug where deprecated warning was being shown even though no generic param list was present
* Fix bug
* Use errGenerated
* Best attempt at writing the grammar
2018-12-27 22:38:24 +01:00
Timothee Cour
8948894713 [ci skip] update docs for build_all.sh (#10086) 2018-12-27 22:28:08 +01:00
alaviss
ca0ef62c9e config/nim.cfg: disable tlsEmulation on Haiku (#10092) [backport]
As of hrev52662, TLS support in Haiku is usable again. This has since
been backported to R1/Beta1, so we can flip the switch upstream.
2018-12-27 22:27:23 +01:00
Dominik Picheta
e3cee541bd Fixes long-standing asynchttpserver regression. (#10102) 2018-12-27 22:26:48 +01:00
Dominik Picheta
513a287c61 Revert sub-second randomize(). Fixes randomize for JS backend. (#10000)
Fixes #9999.
2018-12-27 11:55:21 +01:00
Neelesh Chandola
65a52ecebb Fix const tuple unpacking not working for variables > 2 (#10099) 2018-12-27 00:50:33 +01:00
alaviss
58d293d6a9 fixes nim-lang/nimsuggest#76 (#10093)
* nimsuggest: prevent out-of-bound access

* fixes nim-lang/nimsuggest#76

* undo tester changes
2018-12-25 21:08:16 +01:00
Timothee Cour
5f2b66751a fix #10049 (#10083) 2018-12-23 23:00:37 +01:00
c-blake
e1d5356ae9 Add ability to sample elements from openArray according to a weight array (#10072)
* Add the ability to sample elements from an openArray according to a parallel
array of weights/unnormalized probabilities (any sort of histogram, basically).
Also add a non-thread safe version for convenience.

* Address Araq comments on https://github.com/nim-lang/Nim/pull/10072

* import at top of file and space after '#'.

* Put in a check for non-zero total weight.

* Clarify constraint on `w`.

* Rename `rand(openArray[T])` to `sample(openArray[T])` to `sample`, deprecating
old name and name new (openArray[T], openArray[U]) variants `sample`.

* Rename caller-provided state version of rand(openArray[T]) and also clean
up doc comments.

* Add test for new non-uniform array sampler.  3 sd bound makes it 99% likely
that it will still pass in the future if the random number generator changes.
We cannot both have a tight bound to check distribution *and* loose check to
ensure resilience to RNG changes.  (We cannot *guarantee* resilience, anyway.
There's always a small chance any test hits a legitimate random fluctuation.)
2018-12-23 12:23:20 +00:00
Araq
d407af565f fixes #10024 2018-12-22 23:13:05 +01:00
Araq
bdb67201b2 fixes #10033 [backport] 2018-12-22 18:39:20 +01:00
Oscar Nihlgård
2539363851 Don't use parseutils.parseInt in the times module (#10028) 2018-12-22 10:41:54 +01:00
Andreas Rumpf
ca672ec62e appveyor: make the build green again 2018-12-22 09:47:22 +01:00
Alexis Hope
bec493925f IntSet documentation notes (#10051) 2018-12-21 22:55:58 +01:00
Taylor Hoff
8869aa74db Stop false positives in distros.detectOs (#10062)
* Stop false positives in distros.nim

* Fix bad string comparison on line 176 of distros.nim
2018-12-21 22:52:57 +01:00
Timothee Cour
8aa5d126fe clarify doc for <= on tuple uses lexicographic order (#10069) 2018-12-21 22:52:28 +01:00
Yuriy Glukhov
39a8ab469a Fixed insert for nil seq in js (#10068) 2018-12-21 22:45:20 +01:00
Araq
237085db5d C++ tests: make DLL test green 2018-12-21 22:03:41 +01:00
Araq
4a6d699bc5 C++: make async tests green on Windows 2018-12-21 22:03:41 +01:00
hlaaf
da80992577 Add system.$(HSlice) and fix #7898 (#8670)
* Add system.$(HSlice) and fix #7898

* Surround system.$(HSlice) with spaces
2018-12-21 18:10:07 +01:00
Araq
0c97d3a41c fixes #10066 2018-12-21 14:28:52 +01:00
alaviss
b6257f3f21 os.walkDir: correctly evaluate paths when relative = true (#10057) [backport] 2018-12-21 14:12:48 +01:00
Timothee Cour
52e36a19a9 fix #9933 (#10067) 2018-12-21 12:29:45 +01:00
Araq
23448a96cc fixes #10058 [backport] 2018-12-21 11:50:24 +01:00
Timothee Cour
f9d58b9305 lots of testament bug fixes and improvements: (#10044) 2018-12-20 11:49:32 +01:00
Andreas Rumpf
2fd522cf58 use anon structs and unions for a much better debug experience (#10055) 2018-12-20 11:44:26 +01:00
Taylor Hoff
68ec42cec7 Add call to hostnamectl in detectOsImpl (#10048) 2018-12-20 08:45:43 +01:00
rec
ca18dc2505 Make copies for params which are captured in closures. Fixes #7048 (#10050)
* Copy params which are captured in closures. Fixes #7048
* Forgot to emit a newline; minor adjustments to the test
2018-12-20 08:24:57 +01:00
Andreas Rumpf
cd65e5328d GC: avoid pathological behaviour; fixes #10040 [backport] (#10052) 2018-12-20 08:20:32 +01:00
Timothee Cour
6cbe1d48d7 [json] document fact that key ordering is preserved (#10020) 2018-12-20 01:13:25 +01:00
Timothee Cour
fc7df3283c fix test failure 2018-12-19 16:11:23 -08:00
Timothee Cour
8fbe3b3b7d add to changelog 2018-12-19 16:11:23 -08:00
Timothee Cour
656770402c fix #8255 numerous issues with splitFile 2018-12-19 16:11:23 -08:00
Araq
c129107b32 make nimrtl.dll compile for the C++ target 2018-12-19 18:06:28 +01:00
Araq
f7d0e5c1d1 strutils: minor code cleanup 2018-12-19 18:06:13 +01:00
Neelesh Chandola
730b1b2b87 proc does not take untyped/typed as argument (#9981)
* proc does not take untyped/typed as argument

* Add TODO
2018-12-19 16:18:57 +01:00
Timothee Cour
37cb5e8f53 Update osproc.nim (#10043) 2018-12-19 11:25:50 +01:00
Andreas Rumpf
3300c8a500 much simpler implementation of constant tuple declarations 2018-12-19 11:11:33 +01:00
Neelesh Chandola
8e90ed0618 Const tuple unpacking (#9964)
* tuple unpacking is now supported for consts

* Move nkConstTuple to the end of TNodeKind

* Add nnkConstTuple in macros.nim

* Fix Formatting
2018-12-19 10:52:41 +01:00
Andreas Rumpf
3f917c8d91 Merge pull request #9959 from nc-x/better-error-message
Better error messages in enums which don't have ordinal types
2018-12-19 10:03:55 +01:00
Andreas Rumpf
72500420d3 Fixes #3060 and adds error checking for invalid else branches in object variants (#9957)
* Fix semRecordCase

* Fix ftpclient.nim

* Check for ordinal type

* Check tyRange for exhaustiveness
2018-12-19 10:03:22 +01:00
Neelesh Chandola
48437d0a84 Give better error message when profiler and memProfiler used at same time (#9948)
* Give better error message when profiler and memProfiler used at same time

* Move to profiler.nim
2018-12-19 10:02:20 +01:00
Neelesh Chandola
642ce799ec Add support for clang-cl (#9977) 2018-12-19 09:35:25 +01:00
Timothee Cour
2d404a5a24 undo last commit (meant to send a PR instead) 2018-12-18 22:42:19 -08:00
Timothee Cour
7b9ba71b47 Update osproc.nim 2018-12-18 22:39:08 -08:00
Yuriy Glukhov
264627a657 Add nimsuggest to installDirs (#10035) 2018-12-18 22:31:01 +01:00
Neelesh Chandola
2acefee044 Nimsuggest now shows gotodef for y in from x import y (#10023) 2018-12-18 19:51:14 +01:00
alaviss
8f4befe368 Testament fixes (#10034)
* testament/htmlgen: add support for disabled and joined tests

* testament/tester: respect --targets
2018-12-18 19:49:43 +01:00
Timothee Cour
25d3539da7 [os] fix #10017 regression, fix #10025 regression (#10018)
* [os] fix #10017 regression
* [os] fix #10025 regression
2018-12-18 12:43:25 +01:00
Andreas Rumpf
d7d17d5ab0 see what breaks with a global config.nims (#10016)
* see what breaks with a global config.nims

* make tests green with a global config.nims file
2018-12-18 09:29:15 +01:00
Timothee Cour
dd5812546f [pathutils] add AnyPath; add $; lift arbitrary API restrictions (#10021) 2018-12-18 09:28:26 +01:00
Timothee Cour
e1098fa01a document NIM_EXTERNC for emit (#10022) 2018-12-18 09:20:09 +01:00
Timothee Cour
c4e3c4ca2d add getCurrentCompilerExe to vmops (eg allows to get nim compiler at CT); add tests for vmops (#9925) 2018-12-18 09:07:12 +01:00
Araq
09b9a54418 make tests green with a global config.nims file 2018-12-17 23:03:54 +01:00
Andreas Rumpf
bb1160b73c Merge pull request #10029 from LambdaInsight/more-logging-doc
Adding more documentation to logging.nim
2018-12-17 20:56:14 +01:00
Istvan
915a9ec082 Adding more documentation to logging.nim
Just minor addition to the documentation with the use of operators
2018-12-17 19:29:08 +01:00
Araq
86c3ac6a61 see what breaks with a global config.nims 2018-12-16 20:53:50 +01:00
Andreas Rumpf
0409f2348e Merge pull request #10012 from nc-x/header-path
Add project directory to include path
2018-12-16 20:51:41 +01:00
Araq
9526009e0e fixes #9120 2018-12-16 20:34:07 +01:00
Araq
d91d1865b8 fixes #9420 2018-12-16 20:11:04 +01:00
Araq
d66eb04ce9 fixes #8991, fixes #4446 2018-12-16 19:22:49 +01:00
Araq
7ec77684e9 fixes #9153 2018-12-16 19:17:09 +01:00
Araq
bae662fa8a restore the old .nims processing behaviour; fixes #9989; fixes #9995 2018-12-16 18:44:29 +01:00
Araq
6e5c2af203 fixes #9991 2018-12-16 18:01:59 +01:00
Neelesh Chandola
e70c6af188 escape the include path 2018-12-16 14:42:57 +05:30
Andreas Rumpf
20d9dd1ac6 Merge pull request #10003 from nc-x/fix-enum-internal-error
Fix internal error when casting to invalid enum value
2018-12-16 09:15:56 +01:00
Andreas Rumpf
4222b551ed Merge pull request #10006 from recloser/issue10005
Fixes #10005
2018-12-16 09:15:29 +01:00
Andreas Rumpf
442e12ebb1 testament: individual tests with more than a subdir in their path (#9971)
e.g.: PATH="./bin:$PATH" ./koch tests r stdlib/nre/captures.nim
2018-12-16 09:12:16 +01:00
Neelesh Chandola
303ef57b15 Fix clang not producing debug info in cpp mode (#9976)
* Fix clang on windows to produce debug info

* Fix clang not producing debug info in cpp mode
2018-12-16 09:08:31 +01:00
Neelesh Chandola
c99407b07a Add project directory to include path 2018-12-16 11:39:29 +05:30
recloser
19f5835d5c Fixes #10005 2018-12-15 22:57:18 +01:00
Neelesh Chandola
c673607d36 Fix internal error when casting to invalid enum value 2018-12-15 22:19:39 +05:30
Andreas Rumpf
b53327c92a fixes #9994 2018-12-15 14:30:21 +01:00
alaviss
50193b95ea fix experimental/diff documentation rendering (#9983)
also remove references to non-existant parameters
2018-12-15 14:10:44 +01:00
Andreas Rumpf
a87be40339 fixes #9985 2018-12-15 14:09:06 +01:00
Andreas Rumpf
39ae55e6e4 fixes #9995 2018-12-15 14:01:18 +01:00
Andreas Rumpf
e3a668a33b --gc:destructors: baby steps 2018-12-15 13:54:41 +01:00
Andreas Rumpf
446f911a17 better error message for 'proc' that is not intended to be used as a typeclass 2018-12-15 09:09:46 +01:00
Andreas Rumpf
f76bd06643 fixes #9982 2018-12-14 20:03:12 +01:00
Andreas Rumpf
5ba22c9315 document the change for fix #9978 2018-12-14 17:15:03 +01:00
Andreas Rumpf
675b6f0773 fixes #9978 2018-12-14 17:15:03 +01:00
Araq
32c6b35d97 fixes yet another NimScript regression 2018-12-14 12:00:57 +01:00
c-blake
a54e3f4602 Allow an escape hatch for platform specific flags/default override (#9968)
* Allow an escape hatch for platform specific flags (of which there are many,
for example MAP_POPULATE itself is a Linux-only thing, not other Unix).

Continue with same defaults as before in this commit, but that really
should be changed to *not* include MAP_POPULATE.  While pre-faulting
all the pages can be useful sometimes *if* you know you're going to
access all the data, it is highly unlikely to be what users expect the
default to be.  For some things all that up front work is 1000s of
times slower than being lazy/on-demand/only ever faulting parts of the
file.  Even the MAP_POPULATE fan who originally in 2014 committed to
this file defaulted it to off (but turned it always-on as a "temporary"
work around for some long since gone/mutated compiler issue).

Anyway, at least something like this `mapFlags` gives users the ability
to override the poor default choice or activate any other idiosyncratic
platform-specific features.

* Use simple, efficient default flags, but also accept whatever the open/mapMem
caller specifies.  Save flags in MemFile so they can be used in `resize`.

This field should not need exporting like the others -- callers can always
save whatever values they pass -- but we include a cautionary comment in
case anyone ever asks for a `*` there, as well as for documentation.

Also make documentation for ``mapFlags`` in open more likely to inspire care.
2018-12-14 11:44:11 +01:00
Araq
3ba8f158fb added parseopt.remainingArgs; refs #9951 2018-12-14 11:41:19 +01:00
Araq
f551b72fba fixes #9965 2018-12-14 09:56:59 +01:00
Araq
359a4b5fac timers.nim: avoid parser warning 2018-12-14 09:56:43 +01:00
Araq
ce9815bcf5 os.nim: use the new pathnorm.normalizePath implementation 2018-12-14 08:57:55 +01:00
Neelesh Chandola
f233b2fe8b Merge remote-tracking branch 'upstream/devel' into better-error-message 2018-12-14 09:34:46 +05:30
Ștefan Talpalaru
a96928968e testament: individual tests with more than a subdir in their path
e.g.: PATH="./bin:$PATH" ./koch tests r stdlib/nre/captures.nim
2018-12-13 22:06:03 +01:00
Araq
5b39c7aca9 fixes joinPath regressions 2018-12-13 16:19:00 +01:00
Araq
5d34dec97d fixes testament regression due to changed '/' operator 2018-12-13 16:19:00 +01:00
Neelesh Chandola
6bdf7fdbce enum types can now be assigned values from enum with holes (#9958)
* Fixes https://github.com/nim-lang/Nim/issues/9952

* Remove workaround from vccexe
2018-12-13 12:14:25 +01:00
Araq
9cc4a57768 os.nim: big refactoring, use the new pathnorm that was extracted by compiler/pathutils.nim; added os.relativePath 2018-12-13 12:05:50 +01:00
Alexander Ivanov
467f53512f Show lineinfo of for in yield (#9779) 2018-12-13 10:38:32 +01:00
Neelesh Chandola
31cff752e0 Better error messages in enums which don't have ordinal types 2018-12-13 15:07:36 +05:30
Neelesh Chandola
e6c510bbbd Check tyRange for exhaustiveness 2018-12-13 14:40:22 +05:30
Neelesh Chandola
fa4644006a Check for ordinal type 2018-12-13 14:12:22 +05:30
Neelesh Chandola
b2411db541 Merge remote-tracking branch 'upstream/devel' into record-case 2018-12-13 13:59:46 +05:30
Neelesh Chandola
a3c4791e9c Give error when case has an else branch even though all cases are already covered (#9930)
* Give error when case has an else branch even though all cases are already covered.
* Don't check for invalid else for type tyFloat..tyFloat128, tyString, tyError
* Remove unnecessary else in unittest.nim
* Fix sockets.nim
2018-12-13 09:08:10 +01:00
Neelesh Chandola
bb85869237 Undefine some symbols and globalOptions when processing nimscript (#9945) [backport]
* Undefine some symbols when processing nimscript
* Undefine taintMode when processing nimscript
* Reload .cfg configuration
2018-12-13 09:05:24 +01:00
Andreas Rumpf
8dfe7c0963 Merge pull request #9950 from nc-x/fix-nimsuggest-build
Fix nimsuggest build with clang on windows
2018-12-13 09:02:55 +01:00
Andreas Rumpf
52c7653556 Merge pull request #9956 from nc-x/fix-vccexe
Fix vccexe compilation
2018-12-13 09:02:24 +01:00
Neelesh Chandola
abcf4d8b5d Fix ftpclient.nim 2018-12-13 12:45:47 +05:30
Neelesh Chandola
9ebe52cdeb Fix vccexe compilation 2018-12-13 12:40:52 +05:30
Neelesh Chandola
1f1d7b1088 Fix semRecordCase 2018-12-13 12:11:56 +05:30
Dominik Picheta
76c214a2e9 Merge pull request #9915 from zevv/asyncnet-unix
Added basic AF_UNIX support to asyncnet.
2018-12-12 23:06:08 +00:00
Neelesh Chandola
b245b80e72 Fix nimsuggest build with clang on windows 2018-12-13 02:16:29 +05:30
Andreas Rumpf
e4ae7a8929 Merge pull request #8748 from LemonBoy/when-in-objects
Pervasive replacement of nkRecWhen in generic types
2018-12-12 18:19:52 +01:00
Araq
cc97453808 Merge branch 'couven92-devel' into devel 2018-12-12 18:17:29 +01:00
Araq
0ab1229c69 resolve merge conflicts 2018-12-12 18:16:53 +01:00
Araq
ac8274c60f fix merge conflict 2018-12-12 17:51:33 +01:00
Araq
eb8383cb28 move diff.nim to experimental 2018-12-12 17:48:30 +01:00
Andreas Rumpf
9f453592a4 Merge pull request #9552 from recloser/strmisc-doc
Add runnableExamples for strmisc procs and a better doc for expandTabs
2018-12-12 16:32:09 +01:00
Andreas Rumpf
9d81586879 Merge pull request #9879 from data-man/sorted_deduplicate
Add the parameter isSorted for the sequtils.deduplicate
2018-12-12 16:30:00 +01:00
Andreas Rumpf
a1bf9fd2b6 Merge branch 'devel' into sorted_deduplicate 2018-12-12 16:29:46 +01:00
Araq
070bcf4cea added diff.nim to the stdlib 2018-12-12 16:27:37 +01:00
Araq
afa2ca6a0b Merge branch 'krux02-std-diff' into devel 2018-12-12 16:17:56 +01:00
Araq
f080a15da1 diff.nim: massive code cleanups 2018-12-12 16:17:35 +01:00
Araq
9ce21bb8de Merge branch 'std-diff' of https://github.com/krux02/Nim into krux02-std-diff 2018-12-12 15:43:03 +01:00
Araq
f828e5da49 clean up the implementation of the new memfiles.resize 2018-12-12 12:10:17 +01:00
Araq
77a884f178 export every field of MemFile for more low level trickery; refs #9922 2018-12-12 12:03:57 +01:00
Araq
cc8ba356f9 advopt.txt: minor layouting change 2018-12-12 12:00:42 +01:00
Andreas Rumpf
cddc4be209 Merge pull request #9922 from c-blake/devel
Let handles be seen outside of `memfiles` module so that "updating"
2018-12-12 12:00:12 +01:00
Andreas Rumpf
d9ae9201c4 Merge pull request #9937 from cooldome/pragmablock_custom_pragma
Language feature: implement custom pragmas in pragma blocks
2018-12-12 10:15:25 +01:00
Andreas Rumpf
3a70d18b84 Merge pull request #9755 from flaviut/nre-missing-match
Fix for #9243, nre returns "" instead of nil for missing matches
2018-12-12 06:35:15 +01:00
Andrii Riabushenko
1d16676dd6 add test 2018-12-11 23:53:59 +00:00
Andrii Riabushenko
9becb41e04 Add changelog item 2018-12-11 23:37:48 +00:00
Andrii Riabushenko
df0f0f2858 custom pragmas in pragma blocks 2018-12-11 23:35:46 +00:00
Flaviu Tamas
c0a47f7e22 Rework nil/option for nre in light of ""==nil
Fixes #9243
2018-12-11 22:15:57 +00:00
Flaviu Tamas
22b3e9df27 Revert 7f49364fd0 for nre 2018-12-11 22:15:02 +00:00
Andreas Rumpf
c682671fea minor cleanups 2018-12-11 23:07:36 +01:00
Andreas Rumpf
5dc83d0c8f cleanup of excpt.nim 2018-12-11 23:04:49 +01:00
Andreas Rumpf
239846a528 Merge pull request #9805 from pacien/181126-list-append
add SinglyLinkedList.append procs
2018-12-11 22:18:40 +01:00
Andreas Rumpf
c58f430e2e Merge pull request #9916 from timotheecour/pr_ref_9906_errorMax
refs #9906; --errorMax:10 allows stopping after 10 errors (more robust than nim check)
2018-12-11 22:14:08 +01:00
Andreas Rumpf
e3d91a5b74 Merge pull request #9923 from stefantalpalaru/calldepth
replace misleading "stack overflow" message when reaching Nim's call depth limit
2018-12-11 22:07:44 +01:00
Andreas Rumpf
3695819018 cleanup main.nim's code style 2018-12-11 22:06:15 +01:00
Andreas Rumpf
5ffa9a8be6 destructors: defensive programming against wrong generated destructor for string/seq 2018-12-11 22:02:18 +01:00
Andreas Rumpf
d20a273215 Merge pull request #9917 from timotheecour/pr_dump_msg
enhance `dump --dump.format:json` : report `out`, `hints`, `warnings`, document it ; closes #9513
2018-12-11 22:01:28 +01:00
Andreas Rumpf
bb1ce398af Merge pull request #9881 from timotheecour/pr_ref_9880
refs #9880 show index and bound in lots of `index out of bounds` errors
2018-12-11 21:49:08 +01:00
Araq
f18fcf65b3 make tests green again 2018-12-11 21:23:26 +01:00
Araq
01892eee4b don't skip tests that really were not joined 2018-12-11 21:23:25 +01:00
Araq
8aa4b6b552 remove outputGotten.txt file on success 2018-12-11 21:23:25 +01:00
Araq
f3d2c18a12 attempt to make travis green 2018-12-11 21:23:25 +01:00
Araq
dc604ca762 don't run megatest in parallel for better error messages 2018-12-11 21:23:25 +01:00
Araq
34815a4697 megatest: make it green on Linux 2018-12-11 21:23:25 +01:00
Araq
916955dc95 make more tests green 2018-12-11 21:23:25 +01:00
Araq
4d616b5dc4 make tests green; better output for when megatest execution fails 2018-12-11 21:23:24 +01:00
Araq
0d99ff6113 testament megatest: furher refactorings making more tests green 2018-12-11 21:23:24 +01:00
Andreas Rumpf
ac785b0623 testament: joinable is now an explicit concept of a test spec 2018-12-11 21:23:24 +01:00
Araq
46820b94a6 the linking step doesn't mind Windows' 8K command line limit anymore 2018-12-11 21:23:24 +01:00
Araq
77272ceb3c fixes extccomp regressions 2018-12-11 21:23:24 +01:00
Araq
044c7d0921 fixes extccomp regressions 2018-12-11 21:23:23 +01:00
Araq
1946d1a61d fixes extccomp regressions 2018-12-11 21:23:23 +01:00
Araq
3b783f7e13 Testament: refactoring; makes the test joiner green 2018-12-11 21:23:23 +01:00
Araq
8896770f8f workaround against silly Windows command line length limitations for the upcoming megatest.nim 2018-12-11 21:23:23 +01:00
Arne Döring
a5ecbf823f lots of small changes 2018-12-11 21:23:22 +01:00
Arne Döring
c0c35839cc megatest integrated in default test all 2018-12-11 21:23:22 +01:00
Arne Döring
3859878db8 megatest checks output and nimout 2018-12-11 21:23:22 +01:00
Arne Döring
2a4c09ff88 megatest can be executed 2018-12-11 21:23:21 +01:00
Arne Döring
fb1f5c62b5 tshouldfail is stricter 2018-12-11 21:23:21 +01:00
Arne Döring
1105d03644 require errormsg to be specified before file. 2018-12-11 21:23:21 +01:00
Arne Döring
ca394ebd95 allow to disable backend logging 2018-12-11 21:23:20 +01:00
Arne Döring
199018ef2e test can fail because of invalid spec 2018-12-11 21:23:20 +01:00
Arne Döring
a22bf14bb6 fix htmlgen, that I broke 2018-12-11 21:23:19 +01:00
Arne Döring
dec863a85a kill testnospec 2018-12-11 21:23:19 +01:00
Arne Döring
465e742182 fix js category 2018-12-11 21:23:19 +01:00
Arne Döring
e9ea8fb6b0 remove echo 2018-12-11 21:23:19 +01:00
Arne Döring
da78c3d04d one error less 2018-12-11 21:23:18 +01:00
Arne Döring
b26378a468 WIP, most tests are now skipped 2018-12-11 21:23:18 +01:00
Arne Döring
7f6feb6034 minor changes 2018-12-11 21:23:18 +01:00
Arne Döring
7b40c864bc kick unused benchmarks 2018-12-11 21:23:18 +01:00
Arne Döring
75e4a0098a remove caas 2018-12-11 21:23:18 +01:00
Arne Döring
ef44c12a34 kick taint mode 2018-12-11 21:23:18 +01:00
Arne Döring
fa6a9a21e0 WIP 2018-12-11 21:23:18 +01:00
Charles Blake
b92594572e For now just implement resize per https://github.com/nim-lang/Nim/pull/9922
discussion (with special mremap usage on Linux, but ordinary munmap, mmap on
other POSIX).  Someone needs to do the when windows branch.
2018-12-11 14:57:28 -05:00
Charles Blake
369ac2dd2d Address dom96/Araq opinions in https://github.com/nim-lang/Nim/pull/9922
Updating accessors are also provided since the idea of this change is to
allow "updating" operations external to the module which are by their very
nature closely tied to module internals (as well as to OS interface details).
2018-12-11 10:27:27 -05:00
Andreas Rumpf
a8b53c97ee Merge pull request #9929 from nc-x/fix-js-regression
tyProc does not require copying in JS codegen
2018-12-11 14:29:58 +01:00
Andreas Rumpf
6924b33141 Merge pull request #9924 from cooldome/destructor_hotfix
destructor hot fix
2018-12-11 12:47:23 +01:00
Araq
366b6be4fb compiler refactoring: TSymSeq is gone for good 2018-12-11 12:37:05 +01:00
Neelesh Chandola
685a5544c4 tyProc does not require copying in JS codegen 2018-12-11 16:58:36 +05:30
Andreas Rumpf
3177aee75f Merge pull request #9910 from nc-x/fix-semicolon
Fixes #9907
2018-12-11 12:26:23 +01:00
Araq
4ec40796e6 fixes #9868 2018-12-11 10:28:56 +01:00
Andreas Rumpf
03c4231951 Merge pull request #9909 from nc-x/fix-regression
Fix enum regression
2018-12-11 08:36:15 +01:00
Neelesh Chandola
5aba5875da Address Comments 2018-12-11 10:44:43 +05:30
Neelesh Chandola
47c38cb98e Better fix 2018-12-11 10:34:10 +05:30
Andrii Riabushenko
a9978db42f destructor_hotfix 2018-12-10 23:23:46 +00:00
Ștefan Talpalaru
497e8c41e8 replace misleading "stack overflow" message on call depth limit
The new error message looks like this:
"Error: call depth limit reached in a debug build (2000 function calls).
You can change it with -d:nimCallDepthLimit=<int> or switch to a release
build with -d:release."
2018-12-10 19:35:37 +01:00
Charles Blake
740c5b13ea Let handles be seen outside of memfiles module so that "updating"
operations (like eg., resizing a file and re-mapping) do not need
to worry about race conditions of re-opened paths, renamed parent
directories and that sort of thing.  Operating directly on already
open handles is both safer and more efficient than relying upon the
stability of filesystem paths.
2018-12-10 11:40:08 -05:00
Andreas Rumpf
cd81f368d1 Merge pull request #9826 from cooldome/destructor_move_them_all
destructors: sink`em all
2018-12-10 15:46:19 +01:00
Andreas Rumpf
4f8ae98446 Merge pull request #9914 from nc-x/fix-koch
Fixes #9913
2018-12-10 13:18:44 +01:00
Andrii Riabushenko
d22fa09000 minor correction 2018-12-10 09:20:43 +00:00
Timothee Cour
9d10278a9c --errorMax:0 means: unlimited 2018-12-09 23:39:57 -08:00
Timothee Cour
fc7b3a7c2a enhance dump --dump.format:json 2018-12-09 21:45:15 -08:00
Timothee Cour
daaf50ae03 refs #9906; --errorMax:10 allows stopping after 10 errors 2018-12-09 19:11:08 -08:00
Timothee Cour
f3ecc15a94 refs #9880 show index and bound in lots of index out of bounds errors 2018-12-09 16:50:45 -08:00
Ico Doornekamp
71e9fff364 Added basic AF_UNIX support to asyncnet.
Unfortunately this required some code duplication because the
doConnect() from asynccommon.nim only works with addrInfo which does not
make sense for AF_UNIX.

makeUnixAddr() was moved to nativesocket.nim and exported
2018-12-09 20:53:05 +01:00
Andrii Riabushenko
8b7f416c37 reduce changes 2018-12-09 18:40:46 +00:00
Andrii Riabushenko
8a690fd530 Remove not used code 2018-12-09 18:38:21 +00:00
Andrii Riabushenko
97b9e8a435 remove not used code 2018-12-09 18:37:33 +00:00
Andrii Riabushenko
dc935f2b41 use control flow graph for sink params 2018-12-09 18:32:43 +00:00
Andreas Rumpf
606b43ba11 Merge pull request #9911 from nc-x/fixes-#9627
`include` now accepts collective arguments
2018-12-09 13:47:45 +01:00
Andreas Rumpf
981dcc6b9a Merge pull request #9890 from nim-lang/remove-asynccommon
Merge async common into asyncdispatch.
2018-12-09 13:00:10 +01:00
Andreas Rumpf
9cafa5ac58 Merge pull request #9902 from arnetheduck/daily-clean
daily cruft removal
2018-12-09 12:59:28 +01:00
Andreas Rumpf
c16963083d Merge pull request #9912 from nim-lang/araq-fixes-nested-gensym
fixes nested gensym'ed parameters; fixes #9476
2018-12-09 12:58:33 +01:00
Neelesh Chandola
04a4ff5671 Fixes #9913 2018-12-09 15:54:53 +05:30
Neelesh Chandola
96647618c2 Fix compilation of test on linux and mac 2018-12-09 15:44:18 +05:30
Andreas Rumpf
8035f408f1 Merge pull request #9898 from cooldome/enum_notused
Enum fields get hintXDeclaredButNotUsed hint even marked with used pragma
2018-12-09 09:51:35 +01:00
Neelesh Chandola
e44641b6cb Float values are invalid in enum 2018-12-09 14:20:01 +05:30
Neelesh Chandola
81427b535d Add final newlines 2018-12-09 13:57:17 +05:30
Neelesh Chandola
f77ddccb6c add tests 2018-12-09 13:56:11 +05:30
Neelesh Chandola
9aa783624d include now accepts collective arguments 2018-12-09 12:33:58 +05:30
Neelesh Chandola
d977fc6f32 Fix test case expected output 2018-12-09 11:20:52 +05:30
Neelesh Chandola
abdfbd07a5 Fixes #9907 2018-12-09 10:35:30 +05:30
Neelesh Chandola
93503c18aa Add test 2018-12-09 10:33:20 +05:30
Neelesh Chandola
b0f860d90f Fix enum regression 2018-12-09 10:28:34 +05:30
Andrii Riabushenko
e03fb08c24 change approach 2018-12-09 00:05:57 +00:00
Andrii Riabushenko
a50cfbf814 fix 2018-12-08 23:05:45 +00:00
Andrii Riabushenko
ae24b87219 Double sink checks 2018-12-08 23:04:38 +00:00
Araq
7a66616d74 fixes #9889, fixes #9886 2018-12-08 23:48:20 +01:00
Timothee Cour
f838b1e6c1 fix #9872: setLen now works properly at CT [backport] 2018-12-08 14:33:42 -08:00
Jacek Sieka
a65141fc0b daily cruft removal 2018-12-08 13:36:38 -06:00
Andrii Riabushenko
e5b9d89bcf style improvements 2018-12-08 19:20:34 +00:00
Andrii Riabushenko
0fdd7629b4 remove dropbits in favour of destructive moves 2018-12-08 19:18:00 +00:00
Andreas Rumpf
32a08d4450 Merge pull request #9895 from GULPF/unpack-defect
Make options.UnpackError inherit from system.Defect
2018-12-08 17:42:16 +01:00
Araq
e874705971 fixes nested gensym'ed parameters; fixes #9476 2018-12-08 13:30:06 +01:00
Andrii Riabushenko
5f9234e5cb add comment, fixes #9896 2018-12-08 11:39:11 +00:00
Andrii Riabushenko
94a63eef9a Fix hintXDeclaredButNotUsed for enum fields marked as used 2018-12-08 11:35:18 +00:00
Oscar Nihlgård
0a749f1a37 Make options.UnpackError inherit from system.Defect 2018-12-08 10:04:53 +01:00
Dominik Picheta
775bfb3e8d Merge async common into asyncdispatch. 2018-12-07 22:47:10 +00:00
Andrii Riabushenko
43c70a6b12 improve test 2018-12-07 22:25:32 +00:00
Andrii Riabushenko
d9815574c0 more undo 2018-12-07 22:14:46 +00:00
Andrii Riabushenko
948c625f95 undo more stuff 2018-12-07 22:11:34 +00:00
Andrii Riabushenko
961b7a9f66 undo more changes 2018-12-07 22:00:55 +00:00
Andrii Riabushenko
4799589fb3 undo some changes 2018-12-07 21:59:43 +00:00
Arne Döring
43ea41bdf4 added lib/std/diff.nim 2018-12-07 16:21:50 +01:00
data-man
a38f353597 Add the parameter isSorted for the sequtils.deduplicate 2018-12-07 02:17:40 +05:00
Andreas Rumpf
160a034643 Merge pull request #9803 from GULPF/walkdirrec-relative
Add `relative` parameter to walkDirRec
2018-12-06 09:29:35 +01:00
Andreas Rumpf
d6dbc50793 Merge pull request #9873 from arnetheduck/uints-are-consts [bac,ö
allow uints to appear in deep constant expressions
2018-12-06 09:26:14 +01:00
Araq
7a0191ac7e fixes #9441 2018-12-06 08:06:54 +01:00
Jacek Sieka
db51eb3e32 allow uints to appear in deep constant expressions 2018-12-05 20:33:49 -06:00
Andrii Riabushenko
135191d9d6 collapse to tables into one 2018-12-05 22:17:19 +00:00
Dominik Picheta
467274a19a Merge pull request #9869 from nim-lang/timotheecour-patch-3
Update parseutils.nim
2018-12-05 21:54:54 +00:00
Andrii Riabushenko
268461f06e add comment 2018-12-05 21:45:01 +00:00
Andrii Riabushenko
972707440a remove debug 2018-12-05 21:37:27 +00:00
Andrii Riabushenko
f46573c1ed remove debug statements 2018-12-05 21:36:42 +00:00
Andrii Riabushenko
69347f6c95 implement everything 2018-12-05 21:33:15 +00:00
Andrii Riabushenko
938d3ffad7 add test 2018-12-05 19:29:14 +00:00
Timothee Cour
14223c4b7f Update parseutils.nim 2018-12-05 11:27:22 -08:00
Araq
bc8cea2672 fixes #9614 [backport] 2018-12-05 19:49:37 +01:00
Araq
1711a60f7b fixes #9868 2018-12-05 16:16:58 +01:00
Araq
9eaf99f7e6 lambdalifting: be consistent in its handling for 'func' 2018-12-05 11:25:47 +01:00
Araq
af815c3c18 fixes #9864 [backport] 2018-12-05 10:58:18 +01:00
Araq
24106ade8f hotfix: discriminants can be of size 8 bytes [backport] 2018-12-05 09:43:59 +01:00
Andreas Rumpf
d215296497 Merge pull request #9846 from timotheecour/pr_getpid
add os.getCurrentProcessId()
2018-12-05 08:12:17 +01:00
Andreas Rumpf
88dcad7c01 Merge pull request #9862 from zevv/posix-cmsg
Added CMSG_SPACE and CMSG_LEN macros to posix.nim
2018-12-05 08:11:27 +01:00
Araq
d50336837d IC: much faster caching 2018-12-04 22:41:06 +01:00
Araq
633832d0de times.nim: Minor formatting change in the example code 2018-12-04 22:41:06 +01:00
Ico Doornekamp
c37fdbf843 Added CMSG_SPACE and CMSG_LEN macros to posix.nim 2018-12-04 21:17:22 +01:00
Andreas Rumpf
5abb6caed8 Don't use deprecated fmod in VM (#9837)
* Don't use deprecated fmod in VM

* Update changelog
2018-12-04 16:50:54 +01:00
Timothee Cour
d502ddea9e fix #9832 (fixup) (#9859) 2018-12-04 16:48:08 +01:00
data-man
d80e585438 Update changelog 2018-12-04 17:42:50 +05:00
rec
e3e5ae287f Fix fat pointers, object copying, magic double evals on JS (#9411) [backport]
* Add a test for issue #9389

* Fixes #9389.

* Make object contructors copy objects properly by checking whether the expressions passed to them don't need to be copied.
* Make mArrToSeq implementation actually check if a copy needs to be made.

* Avoid unnecessary copy in mChr impl

* Assume set constructor elements need no copy

* Add a test for issue #9410

* Add a test

* fix passing fat pointers (#9410)

* Enhance tests

* More tests and fixes

* Add more (failing) tests [ci skip]

* Added equality operator for fat pointers, more tests and fixes

* Fix printing uninitialized strings

* Fix mInc, mDec double eval, add more tests

* Tests

* Refactored, fixed multiple evals, revamped the tests, added missing ops

* Fix ups

* Fix #9643 and #9644

* add pointer normalization
2018-12-04 12:04:27 +01:00
Timothee Cour
e4850b7f1c address comments 2018-12-04 02:51:27 -08:00
Jacek Sieka
07744b6e47 More dead code (#9835)
* remove more assignment flags
* needsComplexAssignment > containsGarbageCollectedRef
* remove OnStackShadowDup
2018-12-04 11:22:59 +01:00
Timothee Cour
05769020d3 fixes #9832 (#9841) [backport] 2018-12-04 11:13:49 +01:00
Timothee Cour
c0a91970f2 fixup 2018-12-04 00:45:58 -08:00
Timothee Cour
0768d3ae38 fixup 2018-12-03 15:40:03 -08:00
Timothee Cour
53147cc546 fixup 2018-12-03 14:25:04 -08:00
Timothee Cour
af7d758cfc address comments 2018-12-03 14:03:06 -08:00
Timothee Cour
0caab530fb fixup 2018-12-03 12:51:28 -08:00
Timothee Cour
e7ab4817e2 fixup 2018-12-03 12:46:32 -08:00
Timothee Cour
b93fbcf09a add osproc.processID() 2018-12-03 12:04:46 -08:00
Araq
f86b827d9e IC: more things work 2018-12-03 18:57:44 +01:00
data-man
b0a977fe41 Don't use deprecated fmod in VM 2018-12-01 23:23:51 +05:00
Andreas Rumpf
c74226f4c1 enables .raises: [] via a .push (#9834) [backport] 2018-12-01 16:12:46 +01:00
PMunch
3f546b70ed Moved some code around in nimsuggest to avoid crash when run as library (#9818)
* Moved some code around in nimsuggest to avoid crash when run as library

* Moved the common executecallback setting to a procedure

* Fixed slight issue
2018-12-01 09:38:18 +01:00
Araq
abbafe606e IC: further progress 2018-12-01 00:36:14 +01:00
Andrii Riabushenko
ca473d0f94 add array constructors 2018-11-30 09:47:55 +00:00
Andrii Riabushenko
6459d4ec72 reduce changes 2018-11-30 09:37:26 +00:00
Andrii Riabushenko
e90f70af42 Improve approach 2018-11-30 09:36:04 +00:00
Timothee Cour
9a2736d999 fix #8289 (#9828) 2018-11-30 09:09:32 +01:00
Arne Döring
2f13d27720 improve line info retreival (#9822)
* improve line info
* fix error message
2018-11-30 08:12:11 +01:00
Andrii Riabushenko
c0b91bc024 revert debug statements 2018-11-29 23:43:19 +00:00
Andrii Riabushenko
4c327d9ae2 merge devel 2018-11-29 23:41:38 +00:00
Andrii Riabushenko
9bba790534 fix spacing 2018-11-29 23:36:06 +00:00
Andrii Riabushenko
4b31d7bb83 move moves 2018-11-29 23:33:48 +00:00
Andreas Rumpf
350396e1ca gc:destructors: more progress 2018-11-29 20:10:52 +01:00
Andreas Rumpf
7d82df20be gc:destructors further progress 2018-11-29 01:13:32 +01:00
Timothee Cour
ab38c075f8 add: proc deepCopy*[T](y: T): T (#9740) 2018-11-28 08:46:22 +01:00
Dominik Picheta
8ff18c0fb9 Merge pull request #9813 from yyyc514/fix_outdated_invoke_example
fix outdated example to invoke Nim from C
2018-11-27 22:44:31 +00:00
Josh Goebel
dace2a0999 fix outdated example to invoke Nim from C
- resolves #8139
2018-11-27 15:44:03 -05:00
cooldome
5b98afb8a8 Destructors: more moves for tuples (#9808) 2018-11-27 18:59:21 +01:00
pacien
4e483bb01a add SinglyLinkedList.append procs 2018-11-27 10:34:34 +01:00
Arne Döring
cc0364e72f Tester tests (#9787)
* remove --lib:lib
* added some tests for testatment
* tests are addad WIP: add colors switch to tester
* meta tester is integrated
2018-11-27 10:00:32 +01:00
Andreas Rumpf
8990764709 some progress on --gc:destructors 2018-11-27 00:36:29 +01:00
Andreas Rumpf
413580bc04 new minor language feature: .noSideEffect blocks like .gcsafe blocks 2018-11-27 00:36:29 +01:00
Andreas Rumpf
93cf0ef52e don't crash where there is an unknown statement pragma [backport] 2018-11-27 00:36:29 +01:00
Oscar Nihlgård
e5aae93bfe Add relative parameter to walkDirRec 2018-11-26 22:08:45 +01:00
pgkos
518c72e57a fixes #9800 (#9804) [backport]
* fixes #9800
* add tests for #9800
2018-11-26 18:59:24 +01:00
Emery Hemingway
ed8b4befbf times: use clock_gettime for cpuTime with POSIX (#9793)
The POSIX 'clock()' procedure returns process CPU time in an
implementation specific unit, which for historical reasons can be as
large as ~7ms in the case of FreeBSD. Use 'clock_gettime' for higher
accuracy.
2018-11-26 17:00:17 +01:00
alaviss
ac56d3b0ed fixes #7365 2018-11-26 13:02:37 +01:00
Andreas Rumpf
eb919c35b2 fixes #9675 2018-11-26 10:41:26 +01:00
Andreas Rumpf
6206ba8f30 document the breaking change for osproc 2018-11-26 10:40:16 +01:00
Tomohiro
3a3ff76526 Add workingDir parameter to execProcess and test (#9549)
* Add workingDir parameter to execProcess
* Fix tests/stdlib/tosproc.nim compile error
* Suppress output from tosproc.nim
2018-11-26 10:28:44 +01:00
Constantine Molchanov
3f3aee4078 Added cgi.readData. Add test for cgi module. (#9645)
Added cgi.readData. Add test for cgi module.
2018-11-26 10:27:13 +01:00
cooldome
c50a04adc5 More converter fixes (#9737)
* fixes #9735
* fixes #9736
* fixes #3503
2018-11-26 09:51:13 +01:00
Jacek Sieka
87568830ab Remove dead code (#9777)
* gc/gc2: remove unused ref counting stuff
* also removes some false threading support - hasSharedHeap is always
false in gc/gc2
* gc: remove some threading cruft
* remove asgnRefNoCycle
* compiler: remove TLoc.dup (unused)
2018-11-26 09:47:39 +01:00
cooldome
ea5fc9f204 fixes #9794: sizeof tuple is incorrect if contains imported object (#9795)
* fixes #9794

* Fix linux test
2018-11-26 09:46:19 +01:00
cooldome
2ac7f52388 Fixes multiple bugs with sink arguments (#9802)
* fixes #9781

* fix spacing
2018-11-26 09:45:45 +01:00
Yuriy Glukhov
410fd1deae Fixes 9716 [backport] (#9790)
* reuse temporary variable
* fixes #9716 [backport]
* Declare local vars in safer place
2018-11-24 10:50:48 +01:00
Dominik Picheta
47d0582ebf Merge pull request #9548 from tonygparsehub/put-delete
fix #8777 add missing http methods in httpClient
2018-11-23 22:45:28 +00:00
Arne Döring
56c4a4ae1f fix #9759 (#9789) 2018-11-23 16:19:35 +01:00
PMunch
a20169af91 Made nimsuggest importable as a library and add Nim-path override option (#9784)
* Made nimsuggest importable as a library and add Nim-path override option

* Remove leftover debug output
2018-11-23 15:45:48 +01:00
Alexander Ivanov
88d707cb88 Support only some types as JsAssoc types (#8627) 2018-11-23 15:05:15 +01:00
Araq
562d185cb7 cleanup tests; don't use non-working 'msg' spec field 2018-11-23 13:16:45 +01:00
Araq
2d0aa9b72b testament: remove debugging echo 2018-11-23 11:59:59 +01:00
Araq
e07188b79e threw away a silly test 2018-11-23 11:58:33 +01:00
Araq
0c0f9ba974 Windows: disabled tests 2018-11-23 11:58:32 +01:00
Arne Döring
1f7dcb874d print more to see the test in the log that was never finished. 2018-11-23 11:58:32 +01:00
Arne Döring
a29ec40032 join simple test 2018-11-23 11:58:32 +01:00
Arne Döring
ce7121530d remove problem test 2018-11-23 11:58:31 +01:00
Arne Döring
be553e691b more eyewash 2018-11-23 11:58:31 +01:00
Arne Döring
523ca76c4d eyewash 2018-11-23 11:58:31 +01:00
Arne Döring
6946116272 fix for nimInAction 2018-11-23 11:58:30 +01:00
Arne Döring
161e14829a disable tio.nim, it just causes problems 2018-11-23 11:58:30 +01:00
Arne Döring
bfcf82c7e5 maybe this time? 2018-11-23 11:58:29 +01:00
Arne Döring
d60615583f hopefully this time the tests will compile on the server 2018-11-23 11:58:29 +01:00
Arne Döring
27a9e369de fix coro test 2018-11-23 11:58:29 +01:00
Arne Döring
f200976058 fix for dll tests 2018-11-23 11:58:29 +01:00
Arne Döring
534601637a more tests fixed 2018-11-23 11:58:29 +01:00
Arne Döring
9c2365d5c2 activated more tests, allow input in test spec 2018-11-23 11:58:28 +01:00
Arne Döring
e012eb1001 updated tests to be executed 2018-11-23 11:58:28 +01:00
Arne Döring
8ea72bdcea delete old cruft 2018-11-23 11:58:28 +01:00
Arne Döring
031bfdec6f make run the default action of a test in tester 2018-11-23 11:58:28 +01:00
Araq
610283b9b0 fixes #9764 2018-11-23 09:54:57 +01:00
Araq
61d08ebcd8 IC: further progress 2018-11-22 23:17:47 +01:00
cooldome
962b2e4b39 Destructors: move into nkTupleConstr and move on tuple unpacking (#9776) 2018-11-22 18:33:19 +01:00
Ștefan Talpalaru
f8fa94cb20 fix segfault when calling shallow() on an empty string (#9782) [backport]
shallow() casts its string argument to a seq and then tries to access
its fields. Guess what happens when that string is nil, which seems to
be the representation of an empty string (both the default value and an
explicitly assigned "").

Segfault encountered when running "ntags -R ." on a large project. The relevant line:
a1c62c38e5/ntags.nim (lines-125)
2018-11-22 14:47:27 +01:00
alaviss
c7eba64dee don't raise exception in the default handler (#9783)
fixes #9657
2018-11-22 14:46:07 +01:00
Timothee Cour
02351d02e7 universal toSeq: works with UFCS; works with inline & closure iterators, and with iterables (#8711)
* universal toSeq: works with UFCS; works with inline, closure, and proc
iterators, and also non-iterators

* support all iterables with toSeq

* workaround for #9130
2018-11-22 11:47:14 +01:00
cooldome
086676782a Add isInstanceOf for generic procs to the macros module (#9730) 2018-11-21 21:30:03 +01:00
Araq
1cc8b7814d tut3: improved the wording 2018-11-21 20:45:31 +01:00
Arne Döring
30480605c1 added a new macro tutorial (#9588) 2018-11-21 15:46:58 +01:00
ishowta
6ff596d4f8 Empty check in shallow [backport] (#9676) 2018-11-21 11:56:38 +01:00
Araq
b78699917e document the --incremental build switch; make CIs green again 2018-11-21 11:39:38 +01:00
Araq
6ad5e01160 pathutils: remove dead code 2018-11-21 11:39:38 +01:00
Jacek Sieka
2b2fc5c7e9 compiler: remove unused assignment flags (#9760) 2018-11-21 11:04:45 +01:00
Andreas Rumpf
574cdfc156 IC: produce a good error message for when the compiler was built without the incremental recompilation feature 2018-11-20 23:55:06 +01:00
Araq
8285e24805 IR: also serialize the new transformedBody field 2018-11-20 23:48:15 +01:00
Timothee Cour
fe2eb25650 nimsuggest: fixes #96 2018-11-20 22:57:27 +01:00
Oscar Nihlgård
b4a42386d9 Times module cosmetic changes (#9770) 2018-11-20 22:56:25 +01:00
Araq
eeb7cc6780 IC: further progress 2018-11-20 19:30:00 +01:00
Arne Döring
39ad3a0da6 fix #9726 (#9765) 2018-11-20 13:12:47 +01:00
Yuriy Glukhov
d146516008 Fixed wording (#9761) 2018-11-20 12:50:08 +01:00
Araq
e8bec61413 incremental compilation: bugfixes 2018-11-19 18:51:47 +01:00
Araq
6acffcd28f incremental compilation: simple recompilation works 2018-11-19 17:16:52 +01:00
Arne Döring
1e08fff2d5 bitsize respected in size calculation. (#9756) 2018-11-19 13:48:40 +01:00
Araq
2418d0cac5 fixes #9743 2018-11-19 11:28:06 +01:00
Randy Smith
6c7abe6e5b Fixes #9671 (#9750) 2018-11-19 09:22:21 +01:00
cooldome
9b9f5dee0b Fixes discard bug in cpp codegen (#9747) [backport]
Fixes discard bug in cpp codegen
2018-11-19 08:44:49 +01:00
Flaviu Tamas
ebcf9406be Improve nre documentation (fixes #9470) 2018-11-18 20:12:24 -05:00
Yuriy Glukhov
5a2290f788 Fixed yield in nkObjConstr. Fixes #9694 [backport] (#9744)
* Fixed yield in nkObjConstr. Fixes #9694
* Separate expr lowering from state splitting, introduce a clear lowering internal error
2018-11-18 23:09:33 +01:00
Arne Döring
5dfcc4e91c make tsizeof run on C++ backend (#9734) 2018-11-18 14:36:20 +01:00
narimiran
696dc1609f fix manual entry for .this pragma [ci skip] 2018-11-18 12:53:21 +01:00
Andreas Rumpf
e2f32deba3 make niminst compile again 2018-11-16 22:41:01 +01:00
Araq
6279b0587a make tests green again 2018-11-16 19:54:49 +01:00
Araq
3f6168b337 removes deprecated T/P types 2018-11-16 13:27:56 +01:00
Timothee Cour
4233046e3f make hex digit error msg more helpful (#9727) 2018-11-16 13:09:19 +01:00
Araq
4929f74023 fixes #9728 2018-11-16 11:30:34 +01:00
pgkos
4efbde84ee Make getEnv case insensitive on Windows (#9722) 2018-11-16 08:45:50 +01:00
Araq
4bd9f32f33 --gc:destructors: hello world example compiles and runs 2018-11-16 00:13:49 +01:00
Timothee Cour
2eb14bdd41 add nimCompile to simplify koch; add nimfind to koch tools (#9723) 2018-11-15 20:32:31 +01:00
Araq
3fe8b4f69d fixes #9692 2018-11-15 16:18:28 +01:00
Araq
dd3e1cbc9b make testament compile again with -d:nimCoroutines 2018-11-15 15:15:20 +01:00
Araq
9a05fd9dcf disable some tests for the C++ target; refs #7870 2018-11-15 15:10:50 +01:00
cooldome
c5c4da4f3c Converter bug fixes (#9700)
* Fixes #9698
* Fixes #9699
2018-11-15 13:14:48 +01:00
cooldome
8c1083d3b7 Of operator in vm fixes [backport] (#9717)
* fixes #9701
*  fixes #9702
* optimize of statement to bool
2018-11-15 13:03:42 +01:00
Andreas Rumpf
2104863910 nimfind: improvements 2018-11-15 12:17:12 +01:00
Andreas Rumpf
632ec94b5d gc_common: fixes a typo 2018-11-15 11:36:35 +01:00
Andreas Rumpf
9eb9a57ffd nimfind: improvements 2018-11-15 11:36:35 +01:00
Timothee Cour
6e003eeecb refs #9637 ; cleanup installation of nimsuggest (#9703) 2018-11-15 10:02:34 +01:00
Solitude
ae36dfb747 Add .46 as supported libssl version (#9704) 2018-11-15 09:04:30 +01:00
Andreas Rumpf
6e8ed8c6fa added first version of a nimfind tool for the poor souls that don't have a good nimsuggest integretation 2018-11-14 16:04:54 +01:00
Mamy Ratsimbazafy
b65c0c336c Inline generic min and max - https://github.com/nim-lang/Nim/issues/9514 (#9688) 2018-11-14 12:37:46 +01:00
Timothee Cour
b5448bf25c fix #9647 tmpl=>nimf (#9658) 2018-11-14 08:27:48 +01:00
Dominik Picheta
d89c815c41 Disable tasyncssl on Windows to fix CI
Workarounds #9689
2018-11-13 21:14:57 +00:00
Dominik Picheta
679a52f53c Merge pull request #9687 from narimiran/fix-7192
export `asyncdispatch.callSoon` (fixes #7192)
2018-11-13 21:12:19 +00:00
narimiran
c2b16b46ec export asyncdispatch.callSoon (fixes #7192) 2018-11-12 15:40:33 +01:00
Dominik Picheta
d2f7ecb80e Merge pull request #9682 from cyberlis/reprocsplitfix
Fix split proc in re module ignored maxsplit argument.
2018-11-11 16:39:49 +00:00
Araq
030fe373e4 fixes the travis build for NIM_COMPILE_TO_CPP 2018-11-11 17:02:00 +01:00
Denis Lisovik
8b4a910c91 fix split proc ignored maxsplit argument. Proc split didn't pass maxsplit argument to split iterator 2018-11-11 18:40:43 +03:00
Andreas Rumpf
d1fe195dcc nimpretty: explicit --indent option; fixes #9502; refs #9510 [backport] 2018-11-11 10:39:20 +01:00
Andreas Rumpf
532647171e nimpretty: fixes #9673 [backport] 2018-11-11 10:39:20 +01:00
narimiran
c0b5479e6b coro: minor documentation fix [backport] [ci skip] 2018-11-11 10:16:32 +01:00
Lolo Iccl
37d88e5168 Add proc [](n: NimNode, s: HSlice[T, U]): seq[NimNode] to macros (#7735)
fixes #7670.
2018-11-10 14:10:50 +01:00
ratiotile
95d79ac760 add vs2017 support when run from developer command prompt. (#9672) 2018-11-10 07:49:00 +01:00
Miran
964b5dac7c complete future only once in or (fixes #8982) (#9632)
* complete future only once in `or`

Analogous to `and`.
Credits to @k0zmo for proposing the solution.

* add test
2018-11-09 22:45:17 +00:00
Andreas Rumpf
8d850f7a69 deprecated ospaths (#9665) 2018-11-09 16:36:49 +01:00
Arne Döring
8507e506ce change dir when koch starts (#9663) 2018-11-09 14:18:09 +01:00
Arne Döring
573d02760e newLit works on enum (#9662)
* newLit works on enum

* remove debugging echo
2018-11-09 12:15:00 +01:00
Andreas Rumpf
130c218ff9 parseopt: remove confusing dead code 2018-11-09 09:03:28 +01:00
Andreas Rumpf
c0fc2f5726 fixes #9619 2018-11-09 09:03:28 +01:00
Arne Döring
fdd09ad090 add illegal discard test 2018-11-08 22:28:29 +01:00
Arne Döring
b306e0bfe2 feedback injected 2018-11-08 22:28:29 +01:00
Arne Döring
ff950725fa changelog entry. 2018-11-08 22:28:29 +01:00
Arne Döring
77a0f3768b adopt tests 2018-11-08 22:28:29 +01:00
Arne Döring
16353c2ac8 fix #8011 2018-11-08 22:28:29 +01:00
Arne Döring
a147166710 fix #8335 2018-11-08 22:28:29 +01:00
Arne Döring
cba86a9893 fix #9319 2018-11-08 22:28:29 +01:00
Araq
9eed62f71c add the new modules to the documentation generator 2018-11-08 20:52:22 +01:00
Araq
84ca9d2903 add new stdlib modules to the changelog 2018-11-08 20:52:22 +01:00
Araq
56f76c5b08 better implementation for wrapWords 2018-11-08 20:52:22 +01:00
Arne Döring
4f787ac4f4 fill region 2018-11-08 20:52:22 +01:00
Arne Döring
13defcc9f6 add doc string 2018-11-08 20:52:22 +01:00
Arne Döring
1d7c36bd8c wordwrap stuff 2018-11-08 20:52:22 +01:00
Arne Döring
795d7e3217 WIP 2018-11-08 20:52:22 +01:00
Arne Döring
6a57ec6d2e NaN fixes for clang backend (#9652) 2018-11-08 20:17:37 +01:00
Andreas Rumpf
3cf3c2d722 er... 'a not b' is an infix call 2018-11-08 09:39:27 +01:00
Andreas Rumpf
5845716df8 fixes parsing regressions; binary 'not' for 'not nil' must stay 2018-11-08 09:15:15 +01:00
Andreas Rumpf
05683e3aab fixes #9633 2018-11-08 09:15:15 +01:00
Dominik Picheta
d0a02fe66b Merge pull request #9642 from narimiran/callback-order
keep the order of the callbacks
2018-11-07 23:46:29 +00:00
Andreas Rumpf
8a357c270b parser change: 'not' is always a unary operator; fixes #9574 2018-11-07 21:17:52 +01:00
Jacek Sieka
b1ad5fd7da Simplify cgen forward proc (#9635)
* cgen: remove module resetting (unused)

* cgen: keep single list of forwarded modules

fewer counters to keep track of

* cgen: fix module lookup
2018-11-07 21:08:10 +01:00
Andreas Rumpf
4e94f49065 parser/grammar sync; fixes #9608 [backport] 2018-11-07 20:07:43 +01:00
Andreas Rumpf
1c73db08b8 nim check fix; fixes #9609 [backport] 2018-11-07 20:07:43 +01:00
Timothee Cour
08de33a2e3 remove ---path:"../compiler" from nimsuggest/nimsuggest.nim.cfg 2018-11-07 19:52:11 +01:00
Timothee Cour
f9bf095853 remove redundant -p:compiler in koch.nim given modules use import compiler/foo 2018-11-07 19:52:11 +01:00
Andreas Rumpf
cb4d810659 make Nim take roughly 100MB less RAM for bootstrapping via a new compiler switch -d:leanCompiler; useful for the Raberry PI 2018-11-07 18:36:52 +01:00
narimiran
15c66a06f9 keep the order of the callbacks 2018-11-07 15:22:02 +01:00
Konstantin Molchanov
d5e113c3a6 Add readData proc that accepts a string. 2018-11-07 11:26:51 +01:00
Arne Döring
c2c05f5e72 fix #9639 (#9640) 2018-11-07 10:58:48 +01:00
jcosborn
fc740c54ec fixes #9600 (#9601) 2018-11-07 08:40:00 +01:00
pgkos
b9cdad7497 times - remove unneeded negative sign when parsing formats z and zz (#9631)
* fix wrong utcoffset sign for formats z and zz

* add tests for the timezone offset formats
2018-11-06 22:29:23 +01:00
Andreas Rumpf
73c306258b Nimscript: fixes #9246 [backport] 2018-11-06 21:55:13 +01:00
Andreas Rumpf
24902394f7 VM: don't inject destructor calls, refs #7041 2018-11-06 19:36:39 +01:00
Miran
66a76d3165 Merge tests into a larger file (part 8 of ∞) (#9583)
* merge tuple tests

* merge trmacros tests

* merge template tests
2018-11-06 18:33:58 +01:00
Araq
c735b75f6f compiler cleanup: flag tfOldSchoolExprStmt is gone 2018-11-06 13:55:03 +01:00
Araq
1fa22d4cfe removed the undocumented #? strongSpaces parsing mode 2018-11-06 13:55:03 +01:00
Araq
25cb2e0c70 document system.UncheckedArray 2018-11-06 13:55:03 +01:00
Araq
1c7fbad378 make tests green again 2018-11-06 13:55:03 +01:00
Araq
e71410d74e language cleanup: the .unchecked pragma is dead 2018-11-06 13:55:03 +01:00
Arne Döring
cc5b8c6ad2 Generic Complex type (#9590)
* remove `**`
* const `im` can now be used with Complex64
* converters from float|int to Complex are replaced by procs
* converters between various Complex types must stay to allow usage
of `im` with Complex64
* limit types for `+`, `-`, `/`, and `*` between Complex and float
* add `pow` for Complex and a number
* complex type changes
* unpublish approximation function
2018-11-05 20:27:46 +01:00
skilchen
da178e4090 make mod on floats available in the VM (#9591)
* make `mod` on floats available in the VM
* add testcase
* removed no longer needed imports
2018-11-05 09:36:28 +01:00
Timothee Cour
e4e19f8288 stripLineEnd aka chomp (#9623) 2018-11-05 08:01:31 +01:00
Federico Ceratto
62693457df Add 'dedent' to documentation index (#9615) 2018-11-04 08:36:13 +01:00
Araq
2eff0ca2b8 added test case for #9594 2018-11-03 22:50:46 +01:00
Andreas Rumpf
ae27f8ac58 fixes #9611 2018-11-03 19:11:10 +01:00
Andreas Rumpf
c739b9192f produce more helpful error messages when overloading resolution fails 2018-11-03 15:56:13 +01:00
Andreas Rumpf
b4f16fab49 Nim devel is version 0.19.9 2018-11-03 12:45:55 +01:00
Andreas Rumpf
a2e6a873af fixes #9610 2018-11-03 11:04:30 +01:00
Neelesh Chandola
7a15d2d04b Fixes #9556 (#9604) [backport] 2018-11-02 18:55:53 +01:00
Neelesh Chandola
2bc016b172 Add test for #6836 (#9602) 2018-11-02 13:17:57 +01:00
Araq
234bed1b38 destructors; fixes #9594 2018-11-02 11:29:31 +01:00
Araq
bc26c08862 unicode.nim: minor alignment change 2018-11-02 11:29:30 +01:00
Miran
3806e5640a delete unused issue_template.md
The templates in .github/ISSUE_TEMPLATE are used.
2018-11-02 09:30:33 +01:00
Timothee Cour
d294cec805 Revert "nimsuggest somehow transforms \n into \\x0A, not \x0A"
This reverts commit f96e2764c4.
2018-11-01 14:29:18 -07:00
Timothee Cour
f96e2764c4 nimsuggest somehow transforms \n into \\x0A, not \x0A
/cc @Araq
2018-11-01 14:22:09 -07:00
Alexandros Naskos
eb3c9e1d1c Added "typeof" and "restrict" to special words. (#9226)
* Added "typeof" and "restrict" to special words.
* Added C and C++ reserved keyword as object field identifier test
2018-11-01 17:24:02 +01:00
Neelesh Chandola
dbfc5c5a44 Fixes https://github.com/nim-lang/Nim/issues/6836 (#9595) 2018-11-01 17:23:30 +01:00
PMunch
e9ed4dccb6 Quote do now works with result in block (#7343)
* Fix result not being able to use in quote do

This fixes the annoying issue of not be able to use result inside a
quote do block. It works by a simple trick. The quote do mechanic is
based on dynamically creating a template and immediately calling it with
the arguments found within the quote do block. Since this is called in
the scope of the macro the result variable is shadowed. This trick works
by changing all occurences of result (which shouldn't cause any issues
as result isn't used for anything else for the same reason) to another
name and then passing in an IdentNode with result as a named parameter
with that name.

Note that currently this just replaces it with a fixed named variable
"res" which should be changed to a non-colliding, dynamically created
name.

* Fix hard coded parameter "res" to anonymous symbol

This fixes the hard coded parameter "res" to be an anonymous symbol
instead so it won't collide with other parts of the argument list.

* Add test case for result in quote do block

A simple test case based on GitHub issue #7323 on how you can't put
result in a quote do block. This test verifies that it actually works
correctly now.

* Add test for explicit capturing of result

* Rebased against devel
2018-10-31 22:14:29 +01:00
Arne Döring
d56312624e Merge pull request #9586 from b3liever/fix-hypot-js
Fix #9585 hypot in js
2018-10-31 21:53:40 +01:00
Arne Döring
0059f16dfb Merge pull request #9511 from krux02/krux02-devel
Krux02 devel
2018-10-31 17:12:36 +01:00
Arne Döring
80843373ba changelog entry 2018-10-31 14:29:40 +01:00
B3liever
8a1d52fa48 Fix #9585 hypot in js 2018-10-31 14:09:39 +02:00
Arne Döring
84db658eb4 fix typo 2018-10-31 10:44:44 +01:00
Miran
313bbf5b9b Change documentation details (closes #5525) (#9542) 2018-10-31 07:40:05 +01:00
Tony G
4bb472effd fix #8777 add missing http methods in httpClient 2018-10-30 21:01:09 -04:00
Araq
48f73aaa1c docgen: fixes #9432 [backport] 2018-10-31 00:19:24 +01:00
Araq
8f28be0dd8 docgen: make tests green again [backport] 2018-10-30 23:30:02 +01:00
Araq
c9e8b899ed docgen: fixes #9235 [backport] 2018-10-30 23:29:47 +01:00
Araq
b138e89772 contributing guide: document the new [backport] convention 2018-10-30 22:45:38 +01:00
Araq
1dd1d66f16 system.nim: workaround for the fixed documentation generator 2018-10-30 21:58:59 +01:00
Araq
eb03684c57 docgen: fixes #9169 [backport] 2018-10-30 21:58:59 +01:00
Araq
895ac5bec4 nre: don't use the deprecated import syntax 2018-10-30 21:58:59 +01:00
Arne Döring
9c6620eba1 Merge pull request #9570 from b3liever/macrosfixname
Fix name set and get procs in macros (fixes #9569)
2018-10-30 17:15:37 +01:00
Arne Döring
e653121633 fixes #9557 2018-10-30 17:13:02 +01:00
Araq
7ae6b7e9a2 make more tests green for C++; refs #7870 2018-10-30 16:52:33 +01:00
Araq
b3d80dac9c make tmissingbracket compile for C++; refs #7870 2018-10-30 16:52:33 +01:00
Arne Döring
1ec5c6fdf5 Sizeof alignof fixes (#9568)
fixes #9545
2018-10-30 16:41:06 +01:00
Arne Döring
cf3d206b9e undo try break 2018-10-30 16:35:54 +01:00
Araq
432a4d1787 fixes #5549 2018-10-30 15:30:33 +01:00
Araq
e844e536bf Nim style checker: document the switch; fixes #9564 2018-10-30 15:03:28 +01:00
Araq
5c25b93898 change system.nim to adhere to the style guide 2018-10-30 15:03:28 +01:00
Araq
05964b95e4 change system.nim to adhere to the style guide 2018-10-30 15:03:28 +01:00
B3liever
fb75e3bb49 Fix names set and get procs in macros 2018-10-30 15:42:48 +02:00
Arne Döring
bab9e0020a fixes #5549 2018-10-30 13:50:06 +01:00
Arne Döring
f84bf45f17 set code owner 2018-10-30 13:50:06 +01:00
Arne Döring
07f76c3ef9 fix compiler crash 2018-10-30 13:50:06 +01:00
Flaviu Tamas
45040a8716 Merge pull request #9539 from flaviut/ft-remove-nre-floats
Eliminate floating point arithmatic in nre
2018-10-30 07:29:51 -04:00
Araq
331d1a6ca1 fixes regressions 2018-10-30 11:28:45 +01:00
Araq
f6def4286c fixes #8603 2018-10-30 11:28:45 +01:00
Ahmed T. Youssef
df68c2da49 write logs to stderr instead of stdout; fixes #9547 (#9554) 2018-10-30 07:36:31 +01:00
rec
9899c4525c Add parsing empty attribs to htmlparser (#9559) 2018-10-30 06:58:39 +01:00
jcosborn
69c0a9c6fb getTypeImpl now returns pragmas for object types (#9538) 2018-10-30 06:41:12 +01:00
Neelesh Chandola
e377c55c10 Cleanup installer.ini (#9558) 2018-10-30 06:31:17 +01:00
Ian
5ddeead29c #9348 Merge some small test files (#9561)
* Consolidated types issue tests
* Consolidated vm issue tests
2018-10-30 06:30:39 +01:00
Miran
1b17c9f693 More descriptive names of test files (#9531)
* change generic `tissues` name to more specific
* change `tvarious` to more specific names
2018-10-29 17:07:27 +01:00
Dominik Picheta
8d9866a6d4 Maps out keyword to an nnkIdent. Fixes #6011. (#9536) 2018-10-29 16:33:56 +01:00
Araq
e44df5dca6 fixes #7667; underlying issue is that dot calls in generics have no concept of 'friend' symbols, will be addressed later 2018-10-29 13:46:55 +01:00
Arne Döring
5ebd111f7f Merge pull request #9541 from narimiran/fix-6986
Closes #6986
2018-10-29 12:01:22 +01:00
rec
9fd0a71e4d Make htmlparser parse unquoted attrib values (#9537)
Fixes #6154
2018-10-29 11:10:00 +01:00
Araq
680f5eeb15 fixes #9540 2018-10-29 10:06:36 +01:00
Araq
9d31dfdf1a fixes tnre regression 2018-10-29 10:06:36 +01:00
recloser
e14f5025a2 Add runnable examples for strmisc procs and a better doc for expandTabs 2018-10-29 04:59:05 +01:00
narimiran
80b78b50d0 more examples for mod and div, plus corrections [ci skip] 2018-10-28 22:37:58 +00:00
Clyybber
2aa7eeda39 actually do ceiling division, not a similar operation
Co-Authored-By: flaviut <tamasflaviu@gmail.com>
2018-10-28 14:34:05 -04:00
Neelesh Chandola
95cc1abdc7 Fixes #9525 (#9526) 2018-10-28 14:27:17 +01:00
cooldome
dfb8730f51 Implements #9434. Minimal Stacktrace for Exceptions in release mode (#9480)
* Fixes #9434
2018-10-28 13:40:42 +01:00
Dominik Picheta
f670c55daa Moves fsmonitor into graveyard. Fixes #6718. (#9529) 2018-10-28 13:37:51 +01:00
Utwo
a68a4bfaf2 Remove install.txt and readme.txt (#9521)
* Remove install.txt and readme.txt

* Refactor tests that use readme.txt

* Tests open own source code
2018-10-28 13:36:52 +01:00
xzfc
95a60dc780 Fix strscans.scanp (#9518)
* strscans: fix typo

* strscans: fix #9240

* strscans: add tests
2018-10-28 13:35:30 +01:00
zah
ee54d6977b Parse the usage of the SQL in operator properly (#9527)
Also adds a `treeRepr` renderer for the SQL nodes.
2018-10-28 13:34:57 +01:00
Araq
f9eec2aa1e fixes #9532 2018-10-28 13:23:27 +01:00
Araq
c804b606f9 make tests\benchmarks programs compile again 2018-10-28 13:17:08 +01:00
Araq
fe855d8ba4 make tstatic_t_bug compile with the C++ backend 2018-10-28 13:17:08 +01:00
Arne Döring
2fa13040b9 Merge pull request #9496 from cooldome/vm_float_casts
VM: add int <-> float casts of the same size
2018-10-28 11:56:30 +01:00
narimiran
f4149ae535 Closes #6986 2018-10-28 11:30:41 +01:00
Flaviu Tamas
9ca1c2c930 Eliminate floating point arithmatic in nre
Integer division is already hard enough on your CPU, using floating
point here is WAY slower and can just as effectivly be done using
integers. This is important because matchImpl tends to be in the center
of very hot loops (like split()).
2018-10-28 00:53:09 -04:00
Andrii Riabushenko
2f781781d0 update changelog 2018-10-27 23:15:24 +01:00
David Krause
f2cd8ed99a fixes #7842 if no uri.scheme specified raise ValueError with hint (#7846)
* fixes #7842 if no uri.scheme specified on request rais ValueError with hint

Signed-off-by: enthus1ast <david@code0.xyz>

* Update httpclient.nim
2018-10-27 21:54:45 +01:00
citycide
4362ba7293 docs: clarify asyncCheck vs waitFor 2018-10-27 18:04:25 +01:00
Kaushal Modi
f8cef575b3 Improve dumpLisp macro (#9515)
* Improve dumpLisp macro

- Remove commas from the lisp representation of the AST.
- Make the dumpLisp output "pretty" and indented.
- Improve docs of `dumpTree` and `dumpLisp` macros.

With:

    dumpLisp:
      echo "Hello, World!"

Output before this commit:

    StmtList(Command(Ident("echo"), StrLit("Hello, World!")))

Output after this commit:

    (StmtList
     (Command
      (Ident "echo")
      (StrLit "Hello, World!")))

* Re-use the traverse proc inside treeRepr for lispRepr too

- Add module-local `treeTraverse` proc.
- Also fix treeRepr/dumpTree not printing nnkCommentStmt node contents.

* More doc string updates

* Allow unindented lispRepr output for tests

* Update a test affected by the lispRepr change

* Fix dumpTree

* Add note about lispRepr and dumpLisp to changelog [ci skip]
2018-10-27 14:10:05 +01:00
Andreas Rumpf
dd252ce640 nimpretty tester: strengthen the comparison, do not use strip 2018-10-26 01:54:09 +02:00
Andreas Rumpf
03005fde99 nimpretty: fixes #9506 2018-10-26 01:53:10 +02:00
Andreas Rumpf
0c3e6735ac fixes #9358 2018-10-26 01:25:06 +02:00
Mamy Ratsimbazafy
5b97762787 Openmp parallel iterator improvements (#9493)
* More flexibility in OpenMP pragma
* Use static to constrain to compile-time annotation string
* Update changelog with OpenMP change
2018-10-25 18:09:35 +02:00
Araq
c844a9169c fixes #9498, typeof is for everybody 2018-10-25 13:04:51 +02:00
Araq
8fbdac544b correct tnoop test case 2018-10-25 13:04:17 +02:00
Araq
87d60b2a4b nimpretty: fixes #9500 2018-10-25 11:48:06 +02:00
Araq
0afca3dd6b nimpretty: fixes #9504 2018-10-25 11:18:03 +02:00
Araq
eb2e494a52 fixes #9507 2018-10-25 11:08:46 +02:00
Andreas Rumpf
5fd2827ab6 nimpretty: fixes #9499 2018-10-25 07:52:27 +02:00
Andreas Rumpf
223e92b83a stdlib: documenation updates, the exception names have been changed 2018-10-25 07:42:45 +02:00
Andrii Riabushenko
4c53d45674 Merge branch 'devel' into vm_float_casts 2018-10-24 22:16:25 +01:00
Andreas Rumpf
f5a2c6e19d make tests green again 2018-10-24 22:29:01 +02:00
Andreas Rumpf
9331f06c0b parsutils: minor doc improvements 2018-10-24 21:52:33 +02:00
Andrii Riabushenko
a54e0703a9 Add test 2018-10-24 20:29:51 +01:00
Araq
963292f725 added system.typeof operation; fixes #9093 2018-10-24 17:09:51 +02:00
Araq
e7e75224a2 nimpretty: closes #9484 2018-10-24 15:22:28 +02:00
Araq
06a6433db7 nimpretty: test for idempotence; fixes #9483 2018-10-24 15:19:29 +02:00
genotrance
8500076651 Make Windows cross-compilation simpler (#9485) 2018-10-24 13:12:08 +02:00
Arne Döring
eb6225ad8c fixes #9276 (#9317) 2018-10-24 13:10:44 +02:00
Andrii Riabushenko
bd68d3d8f4 improve style 2018-10-24 11:26:32 +01:00
Andrii Riabushenko
a7c9533a73 Add int float casts to vm 2018-10-24 11:24:23 +01:00
LemonBoy
16d82c82e3 Remove a hack in the destroyer impl (#9479)
Generate nkHiddenAddr nodes w/ proper type attached.
2018-10-24 09:11:46 +02:00
Araq
3ee53a7c8e nimpretty: fixes #8078 2018-10-24 00:59:57 +02:00
Araq
e3a0415650 nimpretty: fixes #9398 2018-10-24 00:53:41 +02:00
Araq
72370c8dfa closes #9400 2018-10-23 17:52:18 +02:00
Araq
695074214b nimpretty: minor bug fix 2018-10-23 17:52:18 +02:00
Araq
00f84d3d22 tar.xz building: also ship with the moved testament tool 2018-10-23 17:52:18 +02:00
loongw
4841fc5356 \#include "windows.h" instead of "Windows.h" (#9475)
This fixes #9474
2018-10-23 15:50:11 +02:00
Oscar Nihlgård
16c3d4332f Fix infinite loop with nim check (#9448) 2018-10-22 17:24:14 +02:00
LemonBoy
b613092de8 Don't crash if GC_{un,}ref is called on nil (#9445)
Fixes #9442
2018-10-22 17:09:15 +02:00
cooldome
9c88df220a Compile pragma. Recompile on external file compilation failure (#9455) 2018-10-22 12:49:57 +02:00
Arne Döring
0dd3038a39 Merge pull request #9460 from recloser/fix-printing-uninitialized-strings
Fix printing and comparing uninitialized strings on JS
2018-10-22 08:26:53 +02:00
recloser
2b03bed2db Fix printing and comparing uninitialized strings 2018-10-21 21:18:10 +02:00
Arne Döring
ce05a850a5 Merge pull request #9457 from Vindaar/fixes-9456
Fixes #9456
2018-10-20 21:57:17 +02:00
Vindaar
557fa85e02 add test case 2018-10-20 20:36:32 +02:00
Vindaar
e190f485ae fixes #9456 by only calling c_fclose if non nil 2018-10-20 20:35:04 +02:00
Dominik Picheta
863d3ef4ed Merge pull request #9446 from GULPF/times-32
Fix times 32-bit issue
2018-10-19 23:24:47 +01:00
Oscar Nihlgård
81f5427ed4 Fix times 32-bit issue 2018-10-19 22:33:40 +02:00
LemonBoy
5afcd09cb3 Pervasive replacement of nkRecWhen in generic types
Long story short, even if the type contains no reference at all to its
generic parameters we still have to walk its AST and evaluate any
nkRecWhen nodes that semRecordNodeAux skipped due to the type being a
generic one.

We also must be careful to modify the type `n` node in place since it
may be referenced by the caller as seen in the tillegaltyperecursion
test.

Moreover we also can't have the nkSym drift away from their original
values in order not to break the JS nkObjConstr codegen.
2018-10-19 22:17:38 +02:00
LemonBoy
16a70c84aa Fixes 6544 (#9427)
* Fix call to converters with var/lent args

Fixes #6544

* Fix printing of lent types

* lent is only valid for result types
2018-10-19 21:04:32 +02:00
Timothee Cour
d0dd5ea887 [doc] add tips to doc/contributing.rst: git, code review, CI (#9429) 2018-10-19 21:03:25 +02:00
cooldome
b1ff37c08f Transf minor code optimization (#9433) 2018-10-19 20:17:30 +02:00
Miran
fc625091e0 Update issue templates
Create `bug report` and `feature request` templates.
2018-10-19 16:52:14 +02:00
Araq
cd9bc941e1 incremental compilation: fixes basic caching logic of 'module' table 2018-10-19 16:27:20 +02:00
Arne Döring
d26beedfb1 Create issue_template.md 2018-10-19 15:07:14 +02:00
cooldome
953f2ef261 Minor bug fix (#9430) 2018-10-19 11:45:59 +02:00
Miran
9fb212cfdf merge stdlib tests (#9439) 2018-10-19 11:43:35 +02:00
jcosborn
3b1ade0350 added test for #4674 (#9438) 2018-10-19 11:18:13 +02:00
Timothee Cour
162e7ee5b5 fixes #9376: old changelogs should be kept instead of erased (#9428) 2018-10-19 09:33:42 +02:00
cooldome
eaca5be9d6 Change the order of compilation passes, transformation is made lazy at code gen (#8489)
* Ast no transformation
* Add getImplNoTransform to the macros module
* progress on delaying transf
* Fix methods tranformation
* Fix lazy lambdalifting
* fix create thread wrapper
* transform for lambda lifting
* improve getImplTransformed
* Fix destructor tests
* try to fix nimprof for linux
2018-10-18 20:21:25 +02:00
Timothee Cour
15dbd973de [doc] start of best practices section in contributing.rst (#9415) 2018-10-18 20:20:26 +02:00
Arne Döring
9f18a4f448 Merge pull request #8366 from krux02/nimnode-or
or on NimNode
2018-10-18 17:49:47 +02:00
Araq
604dfebee0 disallow 'continue' that is not used within a loop; fixes #6367 2018-10-18 17:42:57 +02:00
Araq
c64391e30b closes #6220 2018-10-18 17:28:00 +02:00
Araq
68c6d709d3 fixes #5519 2018-10-18 17:06:04 +02:00
Araq
4644484fb7 closes #5321 2018-10-18 17:00:23 +02:00
Araq
ec4985a573 fixes #7972 2018-10-18 17:00:23 +02:00
Arne Döring
f9bc4d014a changelog entry 2018-10-18 16:07:15 +02:00
Arne Döring
016e0b1aac fix typo 2018-10-18 15:42:14 +02:00
Arne Döring
358b5225df fixed comment 2018-10-18 15:39:22 +02:00
Arne Döring
48697dc5bb added test case for or operator 2018-10-18 15:39:22 +02:00
Arne Döring
abe8ac1962 or on NimNode 2018-10-18 15:39:22 +02:00
Vindaar
82a1576263 fix #9394 by replacing fmt with strutils.% (#9417)
* fix #9394 by replacing `fmt` with normal string append

Until issue #7632 is fixed, use string append.

* use `strutils.%` instead of normal string add
2018-10-18 14:47:47 +02:00
LemonBoy
1fe949b9d5 Make the swap procs safe for unaligned input ptrs (#9210)
* Make the swap procs safe for unaligned input ptrs

The copy to a temporary local variable is often elided by a sufficiently
smart compiler when it can prove the input pointer is aligned.

Refs #9206

* Explain why copyMem is used
2018-10-18 14:30:31 +02:00
Araq
e66b51eb16 make testament compile again with --taintMode:on 2018-10-18 14:25:54 +02:00
Miran
675c629fee replace deprecated safeAdd with add (#9416) 2018-10-18 12:29:32 +02:00
Timothee Cour
7d8e281239 [nimscript] document currentSourcePath in thisDir (#9402) 2018-10-18 12:18:40 +02:00
Araq
be77710c8c testament: use NIM_COMPILE_TO_CPP environment variable 2018-10-18 12:12:15 +02:00
Araq
381498b0db tests: disable flaky tests for now; closes #9421 2018-10-18 12:12:15 +02:00
Araq
03a05ca456 intern.rst: minor formating improvements 2018-10-18 12:12:15 +02:00
LemonBoy
6ef198e07b Relax the restrictions on the index types (#9412) 2018-10-18 11:08:05 +02:00
Bo Lingen
458aab0b10 docs(lib): update Nimble notes since package list is not inline anymore (#9397) 2018-10-18 11:07:10 +02:00
Araq
d2ca808106 koch: bootstrap with C++ for NIM_COMPILE_TO_CPP env var 2018-10-18 10:58:28 +02:00
Araq
505571f31c travis: use explicit build matrix; prepare for extensive C++ testing 2018-10-18 10:06:50 +02:00
Miran
95504caa31 make some tests faster (#9413)
* remove duplicated slow test

* smaller `convex hull`

* smaller sleep

* faster `trtree`

* smaller sleep in `tfuturestream`
2018-10-17 19:46:42 +02:00
Araq
81e33b9d87 make thavlak and tmarkerproc_regression tests take fewer iterations in order to speedup the CIs 2018-10-17 13:20:45 +02:00
Araq
bd9d5787f0 nimpretty: fixes #9384 2018-10-17 13:07:29 +02:00
technicallyagd
88adf77569 Elaborate on source code filter usage in the documentation. (#9407)
* Elaborate on source code filter usage.
Also gives it an abbreviation, SCF.

* Fix the code block formatting

* Trim off the unintended usage with import.
2018-10-17 12:51:51 +02:00
Yuriy Glukhov
dc72cf7564 No setjump in GC for emscripten/wasm (#9386) 2018-10-17 00:46:13 +02:00
PMunch
db95fad6fa Fixes #9364 and add moduleDescription to jsondoc (#9396)
This fixes `jsondoc0` so that it has comments in the output as described
by the documentation. It also fixes `jsondoc`/`jsondoc2` as it stored
it's output in a file with an html extension. Along with this it also
adds a new field `moduleDescription` to `jsondoc`/`jsondoc2` which
contains the module description.
2018-10-17 00:34:47 +02:00
Miran
e8cf289bee improve error message, closes #2361 (#9387)
* improve error message

* use single % operation
2018-10-17 00:18:51 +02:00
Federico Ceratto
afc453beff Update example (#9395) 2018-10-17 00:17:37 +02:00
Kaushal Modi
3e9f506923 Update config.nims search path in docs (#9388)
Related: https://github.com/nim-lang/Nim/pull/8682

Also mention the "nim help" command to list all available tasks.
2018-10-17 00:17:10 +02:00
Oscar Nihlgård
163e9de3c2 Unicode escape in string literals (#9390) 2018-10-17 00:14:22 +02:00
Andreas Rumpf
0d48bafcf0 fixes a regression about indexing into UncheckedArray 2018-10-16 20:09:12 +02:00
Andreas Rumpf
b340f677eb fixes #9244 2018-10-16 20:09:12 +02:00
eqperes
afd9d8dd8d Some documentation added to strutils (#9379)
* wip documentation strutils

* some runnableExamples in strutils

* assert -> doAssert

* corrected doc for abbrev; some more runnable examples

* runnableExamples for join

* fix c&p error

* corrections
2018-10-16 17:30:38 +02:00
Andreas Rumpf
480d228603 nimpretty: added an new simple test 2018-10-16 17:25:12 +02:00
Andreas Rumpf
778e4d1775 nimpretty: fixes #9144 2018-10-16 17:21:41 +02:00
Andreas Rumpf
f3c0703b7d nimpretty: add #!nimpretty on/off directives 2018-10-16 16:55:04 +02:00
Andreas Rumpf
ed38079b9b nimpretty: fixes #8626 2018-10-16 16:55:04 +02:00
LemonBoy
72cd3b7914 Fix repr() for UncheckedArray (#9385) 2018-10-16 14:27:42 +02:00
Andreas Rumpf
89ba0f8592 nimpretty: render r-strings properly, fixes #9236 2018-10-16 13:33:14 +02:00
Miran
749dbce4c6 Merge tests into a larger file (part 5 of ∞) (#9368)
* merge magics

* merge metatype tests

* merge method tests

* merge objects tests

* change `import future` to `import sugar`

Nim in Action tests are left with `import future`, to ensure compatibility.

* merge overload tests

* merge proc tests

* merge procvar tests

* merge range tests

* merge seq tests

* merge sets tests

* remove wrong assert from `tsets3`

* fix `jsTests`

* better fix
2018-10-16 10:50:10 +02:00
skilchen
f04c93b5dd math.round is not needed in strutils (#9383) 2018-10-16 09:19:53 +02:00
Araq
0c04da6f26 Merge branch 'devel' of github.com:nim-lang/Nim into devel 2018-10-15 12:20:52 +02:00
Araq
bf01d7136e Merge branch 'Fixes-7845' of https://github.com/cooldome/Nim into cooldome-Fixes-7845 2018-10-15 11:50:12 +02:00
Araq
8252c65cf2 system.nim deprecate 'getRefcount'; refs #2839, refs #3713 2018-10-15 10:54:20 +02:00
Araq
37986d0ba8 ospaths docs: add 'basename' to theindex 2018-10-15 10:51:47 +02:00
Araq
f8e805a614 fixes #2760 2018-10-15 10:43:56 +02:00
Araq
fe091997aa system.nim: fixes typo 2018-10-15 02:38:04 +02:00
Timothee Cour
3bef851143 fix #8225 os.isHidden was buggy on posix (#8315)
* fix #8225 isHidden was broken on posix

* scope rest of tos.nim under blocks to avoid variable scope bugs
2018-10-15 00:22:34 +02:00
Andreas Rumpf
b39302b0d2 DFA: implement exception handling properly 2018-10-14 17:36:55 +02:00
Miran
a30ba8cc37 merge macros tests (#9367) 2018-10-14 17:08:42 +02:00
Andreas Rumpf
8955470644 fixes #9306 properly, fixes #9306 2018-10-14 11:19:51 +02:00
Federico Ceratto
b62328cb76 Add strip() example (#8002) 2018-10-14 11:05:28 +02:00
Andreas Rumpf
8960efa340 unicode: added strip, align, alignLeft, repeat procs; refs #6301 2018-10-14 11:00:22 +02:00
Andreas Rumpf
77a8c6ffd8 unicode: add split procs; refs #6301 2018-10-14 10:47:54 +02:00
Andreas Rumpf
152c7d99c3 struils: don't use the deprecated accumulateResult 2018-10-14 10:28:50 +02:00
Andreas Rumpf
7656925140 added new editdistance stdlib module, deprecated strutils.editDistance, refs #6301 2018-10-14 10:26:45 +02:00
Andreas Rumpf
7f81519f41 strutils/unicode: deprecate isLower and friends operating on complete strings; fixes #7963 properly 2018-10-14 09:48:54 +02:00
LemonBoy
4808ef72db [WIP] Early evaluation of mIs (#8723)
* Early evaluation of mIs

The `evalIs` implementation was just a broken copy of `isOpImpl` so
let's just avoid it alltogether: `mIs` nodes are either resolved during
the semantic phase or bust.

* Remove dead code and tidy it up
2018-10-14 08:53:41 +02:00
Miran
9f8b93641e Merge tests into a larger file (part 3 of ∞: generics) (#9347)
* merge generics issues tests
* merge tgeneric
* merge test with local imports
* merge tcan tests
* merge matcher tests
* more issue tests merged
* one more tcan test
* merge various small tests into one file
* add a test for #3717
2018-10-14 08:50:39 +02:00
Vindaar
afd5abdfc2 add issue #5707 as test case (#9361) 2018-10-14 08:44:57 +02:00
Josh Goebel
38454c6951 Fix type in docs (#9362) 2018-10-14 08:44:36 +02:00
Timothee Cour
eb946f37a7 fixes #8671; show helpful msg (lookup symbol, eg iterator) on 'attempting to call undeclared routine' error (#8786) 2018-10-14 01:16:04 +02:00
Araq
8232bd04f9 sizeof(UncheckedArray) should be invalid; fixed the formating of sizealignoffsetimpl.nim to make it bearable 2018-10-14 00:58:43 +02:00
Timothee Cour
745f1642d6 implement sizeof and alignof operator (manually squashed #5664) (#9356) 2018-10-14 00:52:28 +02:00
Timothee Cour
3e2d8c1c53 correctly render AST in doAssert/assert condition: fixes #8518; refs #9301 (#9332)
* fixes #8518; refs #9301; correctly render AST in doAssert condition
2018-10-14 00:17:10 +02:00
LemonBoy
166720bdf9 Make sure the annotation for || is avail. at CT (#9354)
Closes #9353
2018-10-14 00:00:21 +02:00
Miran
d570dea480 put several issues in tests (#9352)
* put several issues in tests

* remove wrong test
2018-10-13 20:17:59 +02:00
Federico Ceratto
e435dbd35e Update makefile and buildsh templates for riscv64 (#9351) 2018-10-13 17:18:06 +02:00
Timothee Cour
e4c76f8a2a add strutils.stripLineEnd (#9346) 2018-10-13 14:59:56 +02:00
Miran
3c9fcc4c30 Merge tests into a larger file (part 2 of ∞) (#9335)
* merge controlflow tests

* merge distinct tests

* merge enum tests

* merge fields tests

* merge implicit tests

* merge iter issues tests
2018-10-13 14:58:31 +02:00
Timothee Cour
ef820769a4 deprecate accumulateResult => sequtils.toSeq (#8666) 2018-10-13 09:23:33 +02:00
Tomohiro
eb4272ba1c manual: Fix links to Parallel & Spawn (#9342) 2018-10-13 08:55:34 +02:00
Vindaar
9cdd9be5a5 fixes #8916 by fixing typeinfo and marshal. (#9341)
* fixes #8916 by removing `tyString`, `tySeq`, mod. marshal, typeinfo

Need to check in `typeinfo` for nil of the underlying pointer.
In marshal don't have to check for nil of seq anymore.

* remove reference to string, sequence in `isNil` doc string
2018-10-13 08:47:58 +02:00
Oscar Nihlgård
c495e97ec4 Build codeowners.rst (#9337) 2018-10-13 08:44:39 +02:00
Timothee Cour
d5fe8e1e0c doc: tests/testament/specs.nim => testament/specs.nim (#9338) 2018-10-13 08:41:47 +02:00
Andreas Rumpf
1475697fbf make tests green again 2018-10-13 08:39:56 +02:00
Andreas Rumpf
33cdae8c32 dfa.nim: clarify exception handling 2018-10-13 08:28:56 +02:00
Andreas Rumpf
fcca59e415 destructors: optimize more assignments into moves; also fixes #9294 2018-10-12 20:36:42 +02:00
Andreas Rumpf
2fecf4f36a compiler: cleanup dfa.nim 2018-10-12 19:56:51 +02:00
Andreas Rumpf
dcc3ac74f4 don't crash when rendering wrong nkInfix nodes 2018-10-12 19:22:39 +02:00
c-blake
1b3725e395 Add toOpenArray[T](ptr UncheckedArray[T]) for clarity. (#9316)
* Add `toOpenArray[T](ptr UncheckedArray[T])` for clarity.  `ptr array[0,T]`
for some unchecked type already works but A) `UncheckedArray` seems to be
the intended future way for this kind of access, and B) essentially all use
cases will have a `ptr` for that kind of array source and this call signature
lets callers drop the trailing `[]` corresponding to that `ptr` deref.
This PR relates to issue https://github.com/nim-lang/Nim/issues/9001 .

* Add a test for toOpenArray() for UncheckedArray[T]s.
2018-10-12 17:40:07 +02:00
eqperes
14925ee8b6 Proposed solution for issue #8919 (#9280)
* Proposed solution for issue #8919

* count sub/subs must be non-empty
2018-10-12 17:28:21 +02:00
Jacek Sieka
97738a4f28 Testament pre parallel (#9137)
* testament: move to root dir (it's not a test)

* osproc: fix process index passed to afterRunEvent for parallel runs

it was passing the index of the process, not index of all commands

* testament: complete file move
2018-10-12 17:27:47 +02:00
Miran
c492a7fd83 complete removal of web folder, fixes #9304 (#9310)
* complete removal of web folder, fixes #9304

* remove `buildJS`
2018-10-12 17:27:04 +02:00
Miran
7f18d7cbc1 Merge tests into a larger file (part 1 of ∞) (#9318)
* merge actiontable tests

* merge arithm tests

* merge array tests

* merge assign tests

* merge bind tests

* merge casestmt tests

* merge closure tests

* merge cnt seq tests

* merge collections tests

* merge concept issues tests

* merge concept tests

* fix failing tests

* smaller outputs

Use `doAssert` where possible.

* fix wrong output

* split `tcomputedgoto`

* revert merging concepts

* fix failing test
2018-10-12 17:02:46 +02:00
Tomohiro
d2b04a8bc7 manual: Remove stmt or expr template related text from manual (#9321) 2018-10-12 09:00:27 +02:00
LemonBoy
71636059e9 Avoid memory allocation during dynlib loading (#9320)
By using `write` instead of `rawWrite` we'd end up asking the compiler
to generate the GC dynlib _while_ we were already generating another
dynlib!

Fixes #9123
2018-10-12 08:56:14 +02:00
LemonBoy
fab4d38411 string to string conversion keeps the dest type (#9323)
Fixes #9322
2018-10-12 08:50:28 +02:00
cooldome
9b002e0d4f Align to the actual experience (#9324)
* Align to the actual experience

* add exception handling
2018-10-12 08:49:33 +02:00
Konstantin Molchanov
fde4a086c5 8684 add shortcut sort procs (#9174)
* Stdlib: Algorithm: Add shortcut versions of sort, sorted, and isSorted procs.
* Add tests for sort, sorted, and isSorted procs from algorithm module.
* Merge sort tests into tsortcall.nim, remove tsort.nim.
* Stdlib: Algorithm: Add shortcut versions of sort, sorted, and isSorted procs.
* Add tests for sort, sorted, and isSorted procs from algorithm module.
* Merge sort tests into tsortcall.nim, remove tsort.nim.
2018-10-11 22:51:23 +02:00
Ștefan Talpalaru
10f5f67767 gogc: GCC-8.2.0 compatibility and other improvements (#9211)
- Go's write barriers are now plugged-in in all the relevant points
- "gcGo" is correctly classified by usesWriteBarrier()
- some gogc structures and functions now use golib wrappers to keep GCC
  version-specific conditions out of the compiler/stdlib code
- we no longer allow mixing the C malloc with Go's
- fix a problem with string copying
2018-10-11 22:15:17 +02:00
Araq
d48e964950 fixes #9281 2018-10-11 19:52:48 +02:00
Araq
8ab6fa1be2 fixes #9306 2018-10-11 16:15:35 +02:00
Andrea Ferretti
160f8599c6 Clarify that term rewriting macros are applied recursively (#9305)
Fixes https://github.com/nim-lang/Nim/issues/9288 fixes https://github.com/nim-lang/Nim/issues/8376 and fixes https://github.com/nim-lang/Nim/issues/2901
2018-10-11 15:59:14 +02:00
Araq
26a9ba71c8 codeowners: try to make github's RST parser happy 2018-10-11 13:52:44 +02:00
Araq
78f9c9a2cd update contributing.rst and added codeowners.rst 2018-10-11 13:45:37 +02:00
eqperes
00c4aba828 compile date and compile time tz written in doc (#9283) 2018-10-11 12:15:15 +02:00
Solitude
027a11d7c8 Add procs to retrieve project name, directory and full path to nimscript (#9274) 2018-10-11 09:56:12 +02:00
cooldome
7a5b614edc fixes #9297 (#9298)
* fixes #9297

* improve spacing
2018-10-11 09:54:50 +02:00
Timothee Cour
a58c982a49 test case for #9180 and re-enables the disabled tcompilerapi test (#9181)
* add findNimStdLibCompileTime and un-disable tcompilerapi test; add test case for #9180

* address comments
2018-10-11 09:44:35 +02:00
xzfc
8fc7cecfa2 compiler: show name of instantiating context in error traces (#6763) (#9207) 2018-10-11 09:34:56 +02:00
Timothee Cour
da4215af6a make contributing.rst more up to date; reference it in readme.md to make it more discoverable (#9302) 2018-10-11 08:55:15 +02:00
Timothee Cour
6d910dedf0 rm web/website.ini (#9290) 2018-10-11 08:41:44 +02:00
Oscar Nihlgård
eade49d7a7 Fix OrderedSet.excl (#9287) 2018-10-11 08:40:09 +02:00
Timothee Cour
0aac5c9725 fix #9295 (#9299) 2018-10-11 08:36:36 +02:00
LemonBoy
7775b7efd1 Fix wrong heuristic in codegen (#9293)
A bare return may trigger the insertion of a genericReset.

Fixes #9286
2018-10-11 08:36:05 +02:00
xzfc
8ed3dac1dc Fix tests on NixOS (#9209) (#9285)
* Replace `/bin/sleep` with just `sleep`, i.e. use environment variable
  `$PATH` to locate binary.
* Replace `/usr/share/zoneinfo` with `$TZDIR` when it is defined,
  fallback to hardcoded path otherwise. This is the same behavior that
  Glibc2 normally have, see man 3 tzset.
2018-10-10 22:47:08 +02:00
LemonBoy
0ead36dae6 Unchecked arrays now have their own type (#9267) 2018-10-10 21:03:18 +02:00
Andreas Rumpf
0803b532f4 fixes #9263 2018-10-10 21:00:54 +02:00
eqperes
6620b5dc8d Documentation improved for math module (#9266) 2018-10-10 14:25:39 +02:00
manterolat
16a941a642 Fixes #9154 (#9193) 2018-10-10 13:17:28 +02:00
Miran
462bff48b2 Iter test: closes #3819 (#9272) 2018-10-10 10:21:38 +02:00
Timothee Cour
77f836b403 fix #9264 regression (#9265) 2018-10-09 23:48:27 +02:00
LemonBoy
32d5b80938 Fix macro expansion in expandMacros (#8998)
* Fix macro expansion in expandMacros

Running a semanticized node trough the semantic pass was a bad idea.

Fixes #7723

* Simpler smaller implementation
2018-10-09 23:24:54 +02:00
Miran
98a8868cb4 better docs for tables module (#9221)
* better docs for `tables` module

* lower case for the first sentence in docs
2018-10-09 22:39:51 +02:00
Timothee Cour
63c00d7be9 fix tests/generics/t8694.nim: runnableExamples were not run because of #9216 (#9262) 2018-10-09 21:51:51 +02:00
Miran
47828efe32 better docs for algorithm module (#9192)
* better docs for `algorithm` module

* address the comments

* small first letter in the first sentence
* last argument is reverted to be `int`
* `rotateLeft` keeps `discardable` pragma, as discussed on IRC

* another small correction
2018-10-09 21:36:51 +02:00
Miran
27e4825c62 [cleanup] remove xmldom and xmldomparser (#9234) 2018-10-09 20:58:56 +02:00
Kaushal Modi
c6dfbfc2cf Do not encode the anchors in docs (id attr in a tags) (#9261)
Update the tests too.

Fixes https://github.com/nim-lang/Nim/issues/9232.
2018-10-09 20:48:00 +02:00
hlaaf
c68ea019f9 Separate high/low/len docs for each overload (#8816) 2018-10-09 20:15:55 +02:00
Steve Kellock
173e8c4913 fixes unexpected transforming of runnableExamples (#9158) 2018-10-09 20:14:54 +02:00
LemonBoy
33458894da Fix overload resolution for pragmas evaluation (#8902)
Fixes #6448
Fixes #4384
2018-10-09 19:58:23 +02:00
LemonBoy
ee14ace5d3 Field checks for everybody (#8957)
* Field checks for JS backend

* Clean nkCall nodes with no arguments

Generating a nkEmpty in place of no arguments makes no sense form the
AST point of view and also trips up the VM codegen.

* Field checks for VM backend

* Test case for #6612

This patchset fixes #6612

* Add test case for LHS double evaluation

* Prevent LHS double-eval for JS backend

* Prevent double evaluation in VM backend
2018-10-09 19:54:12 +02:00
LemonBoy
a3fb0a769c Try/Catch support for native JS exceptions (#8955)
* Try/Catch support for native JS exceptions

* Better tests
2018-10-09 19:51:29 +02:00
LemonBoy
f98a3056c6 Fix transformation of yield in inline context (#9135)
When the loop variables are part of the envP block it is not safe to use
a nkFastAsgn.

Fixes #2656
2018-10-09 19:43:31 +02:00
Dominik Picheta
21ecf64d24 Fixes #8994. FutureStream read procedure data loss no longer occurs. (#9183)
* Fixes #8994. FutureStream read procedure data loss no longer occurs.

* Optimises the fix for #8994.
2018-10-09 19:39:12 +02:00
Arne Döring
5076fda2e2 fix for #9082 (#9089) 2018-10-09 19:37:53 +02:00
Yasuhiro Horimoto
fe19670c52 Fixes #8841 (#9101)
Modify comments for readChar and peekChar to the same as the comment for them in the source code.
2018-10-09 19:30:02 +02:00
Timothee Cour
a98b1a7764 fix #8341: add lastPathPart (#9116) 2018-10-09 19:27:31 +02:00
LemonBoy
b97a7dbf3d Make the registered passes local to the ModuleGraph (#9259)
Closes #9068
2018-10-09 19:24:02 +02:00
technicallyagd
85187d4ba3 Fixes some minor typos in nimsuggest.rst (#9223)
* Fix Minor typo in nimsuggest.rst

* Fixes two more typo in nimsuggest.rst
2018-10-09 17:45:00 +02:00
alaviss
2a31f42d35 asyncmacro: add nnkSym support for getName() (#9204)
Fixes #9201
2018-10-09 15:53:13 +02:00
LemonBoy
8a1055adce Fix range type construction in the VM (#9205)
The `range[X,Y]` representation is wrong, we use `range[X .. Y]`
instead.

Fixes #9194
2018-10-09 15:51:49 +02:00
alaviss
dad290accb os: use unlink() to remove file (#9220)
removeFile() behavior should now be consistant between Windows and POSIX

Fixes #9200
2018-10-09 15:37:36 +02:00
Kaushal Modi
c0266e1afa Fix typo in an algorithm runnableExamples (#9260)
Fixes the 'koch docs' build failure.

Ref:
b90b45b01b
2018-10-09 15:36:36 +02:00
cooldome
036c52f0b6 fixes #9222 (#9224) 2018-10-09 15:19:21 +02:00
Timothee Cour
73e6b229aa [os] clarify docs for existsDir (#9212)
* Update os.nim

* Update os.nim
2018-10-09 15:04:29 +02:00
LemonBoy
d36f98fa8b nim doc can run code blocks (#9228) 2018-10-09 14:58:40 +02:00
xzfc
505ae14f4b Codegen fix for procs taking type(nil) (#9231) 2018-10-09 14:51:34 +02:00
LemonBoy
b8d2f79ef0 Prevent the construction of recursive tyStatic types (#9256)
Fixes #9255
2018-10-09 14:26:34 +02:00
Dheepak Krishnamurthy
70018aa683 Add checks for except: body blocks (#9191) 2018-10-09 14:09:22 +02:00
jcosborn
dd65986795 fixes #4435 (#9185) 2018-10-09 13:34:03 +02:00
pqflx3
b90b45b01b Add algorithm.[sort,sorted,isSorted] overloads using 'system.cmp'. (#8778)
* Add algorithm.[sort,sorted,isSorted] overloads using 'system.cmp'. Fixes 8684.

* Change signatures to 'func'. Improve overload sort doc comments
2018-10-09 13:25:25 +02:00
Juan Carlos
bc557e4c6a HTMLGen Update, Add runnableExamples, Add HTML Tags center, details, dialog, marquee, picture, slot, summary (#9252) 2018-10-09 13:13:13 +02:00
LemonBoy
18023c023d Replace the sha1 implementation w/ a working one (#9242)
As #9239 points out the old implementation had some serious flaws.
The new implementation is a port of the MIT-licensed one used by
Chromium OS and has been tested against the FIPS-provided vectors and by
generating huge files like the ones mentioned in the issue above.

While I tried my best to take into account the existence of BE machines
the code has only been tested on a LE one.
2018-10-09 11:50:10 +02:00
cooldome
541c2a3fec one more attempt 2018-06-28 09:21:09 +01:00
cooldome
c20d1ac1c0 Fix failing test 2018-06-26 23:50:06 +01:00
cooldome
34170db963 Merge branch 'devel' into Fixes-7845 2018-06-26 23:33:34 +01:00
cooldome
0b709fb916 FIx test tembarrassing_generic_failure 2018-06-12 21:41:35 +01:00
cooldome
a274d77b55 Fixes 2018-06-12 00:28:09 +01:00
cooldome
7302a8ce7a Fixes 7845 2018-06-10 22:49:09 +01:00
Fredrik Høisæther Rasch
caeb6110e6 VCCEXE: lower case const identifier 2017-04-04 19:26:59 +02:00
Fredrik Høisæther Rasch
618a15ed48 Moved vccdiscover to vccexe 2017-04-04 19:26:07 +02:00
Fredrik Høisæther Rasch
3d21e2ab66 Added documentation and explanatory comments to vccexe 2017-03-26 17:14:02 +02:00
Fredrik Høisæther Rasch
24f07d9b71 Exchanged debug compilation with verbose command-line argument 2017-03-21 12:18:32 +01:00
Fredrik Høisæther Rasch
513b0fed4d vcvarsallpath explaination no longer needed with vccdiscover
This reverts commit 7c4911d
2017-03-21 12:18:32 +01:00
Fredrik Høisæther Rasch
c7a0087c82 vccdiscover: Added additional documentation
Added explaination that vccdiscover output is machine-parsable
2017-03-21 12:18:32 +01:00
Fredrik Høisæther Rasch
05faad30a4 vccexe tool can use vccdiscover utility
Used when vcvarsall path is not specified, or if only a vccversion is specified
2017-03-21 12:18:32 +01:00
Fredrik Høisæther Rasch
aa14ee1856 Created vccdiscover utility for vcc auto-discovery 2017-03-21 12:18:31 +01:00
Fredrik Høisæther Rasch
747e5a6b64 vccenv module for vcc auto-discovery
Only works for VCC Installations with Visual Studio 2015 and below
2017-03-21 12:18:31 +01:00
Fredrik Høisæther Rasch
289f72ad67 Fixed vccexe, now regards the command argument 2017-03-21 12:18:31 +01:00
Fredrik Høisæther Rasch
5341d36397 Reduced verbosity of vcvarsall
Only lines that are not part of the loaded developer environment are echoed
2017-03-21 12:18:29 +01:00
Fredrik Høisæther Rasch
86206b2533 Added explanatory comments about vccexe and its path argument in nim.cfg 2017-03-21 12:18:29 +01:00
Fredrik Høisæther Rasch
503a816b36 Corrected erroneous vccexe tool path in koch 2017-03-21 12:18:22 +01:00
Fredrik Høisæther Rasch
45f61ad046 Moved vccexe to a more logical place (vccexe) 2017-03-21 12:17:09 +01:00
Fredrik Høisæther Rasch
9446ae5576 Moved vccenv over to vcvarsall
Updated vccexe with new command-line arguments
2017-03-21 12:17:09 +01:00
Fredrik Høisæther Rasch
93e03144fc Added Visual Studio build artifacts to gitignore
The Microsoft Linker creates an incremental linker database (extension: ilk)

Debugging symbols are stored in pdb files.
2017-03-21 12:17:09 +01:00
Fredrik Høisæther Rasch
7267d35c3f Removed arch option in compiler definition
Previous Artifiact, changed to better reflect the settings in the default nim.cfg
2017-03-21 12:17:09 +01:00
Fredrik Høisæther Rasch
4002bdf873 Added missing VCC C++ options to nim.cfg 2017-03-21 12:17:09 +01:00
2566 changed files with 155781 additions and 170590 deletions

37
.builds/freebsd.yml Normal file
View File

@@ -0,0 +1,37 @@
# see https://man.sr.ht/builds.sr.ht/compatibility.md#freebsd
image: freebsd/latest
# packages:
# - databases/sqlite3
# - devel/boehm-gc-threaded
# - devel/pcre
# - devel/sdl20
# - devel/sfml
# - www/node
# - devel/gmake
# - devel/git
sources:
- https://github.com/nim-lang/Nim
environment:
CC: /usr/bin/clang
tasks:
- setup: |
# workaround https://github.com/timotheecour/Nim/issues/76
sudo pkg update -q -f
sudo pkg install -y -q databases/sqlite3 devel/boehm-gc-threaded devel/pcre \
devel/sdl20 devel/sfml www/node devel/gmake devel/git
cd Nim
git clone --depth 1 -q https://github.com/nim-lang/csources.git
gmake -C csources -j $(sysctl -n hw.ncpu)
bin/nim c --skipUserCfg --skipParentCfg koch
echo 'export PATH=$HOME/Nim/bin:$PATH' >> $HOME/.buildenv
- test: |
cd Nim
if ! ./koch runCI; then
nim c -r tools/ci_testresults.nim
exit 1
fi
triggers:
- action: email
condition: failure
to: Andreas Rumpf <rumpf_a@web.de>

12
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: 'araq' # Replace with a single Patreon username
open_collective: 'nim' # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: 'https://nim-lang.org/donate.html' # Replace with a single custom sponsorship URL

40
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,40 @@
---
name: Bug report
about: Have you found an unexpected behavior? Use this template.
title: Think about the title, twice
labels: ''
assignees: ''
---
Function `echo` outputs the wrong string.
### Example
```nim
echo "Hello World!"
```
### Current Output
```
Hola mundo!
```
### Expected Output
```
Hello World!
```
### Possible Solution
* In file xyz there is a call that might be the cause of it.
### Additional Information
* It was working in version a.b.c
* Issue #abc is related, but different because of ...
* This issue is blocking my project xyz
```
$ nim -v
Nim Compiler Version 0.1.2
```

View File

@@ -0,0 +1,35 @@
---
name: Feature request
about: Do you want to suggest a new feature? Use this template.
title: ''
labels: ''
assignees: ''
---
<!---
Notice there is now a separate repository for the detailed RFCs and proposals:
https://github.com/nim-lang/RFCs
If you have a simple feature request, you can post it here using this template,
but bear in mind that adding new features to the language is currently a low priority.
-->
### Summary
<!--- Short summary of your proposed feature -->
### Description
<!--- Describe your solution, what problem does it fix? -->
### Alternatives
<!--- Are there any alternatives you've considered? -->
### Additional Information
<!--- For Example:
* A link to a project where the issue is relevant.
* A link to a related issue or discussion.
-->

122
.github/workflows/ci.yml.disabled vendored Normal file
View File

@@ -0,0 +1,122 @@
name: Continous Integration
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
os: [ubuntu-18.04, macos-10.15, windows-2019]
cpu: [amd64, i386]
cpp: ['false', 'true']
pkg: ['false', 'true']
exclude:
- os: ubuntu-18.04
cpp: 'true'
- os: ubuntu-18.04
pkg: 'true'
- os: macos-10.15
cpu: i386
- os: macos-10.15
pkg: 'true'
- os: windows-2019
cpu: i386
- os: windows-2019
cpp: 'true'
name: '${{ matrix.os }} (${{ matrix.cpu }}, cpp: ${{ matrix.cpp }}, pkg: ${{ matrix.pkg }})'
runs-on: ${{ matrix.os }}
env:
NIM_COMPILE_TO_CPP: ${{ matrix.cpp }}
NIM_TEST_PACKAGES: ${{ matrix.pkg }}
steps:
- name: 'Checkout'
uses: actions/checkout@v2
- name: 'Checkout csources'
uses: actions/checkout@v2
with:
repository: nim-lang/csources
path: csources
- name: 'Install node.js 8.x'
uses: actions/setup-node@v1
with:
node-version: '8.x'
- name: 'Install dependencies (Linux amd64)'
if: runner.os == 'Linux' && matrix.cpu == 'amd64'
run: |
sudo apt-fast update -qq
DEBIAN_FRONTEND='noninteractive' \
sudo apt-fast install --no-install-recommends -yq \
libcurl4-openssl-dev libgc-dev libsdl1.2-dev libsfml-dev \
valgrind libc6-dbg
- name: 'Install dependencies (Linux i386)'
if: runner.os == 'Linux' && matrix.cpu == 'i386'
run: |
sudo dpkg --add-architecture i386
sudo apt-fast update -qq
DEBIAN_FRONTEND='noninteractive' \
sudo apt-fast install --no-install-recommends --allow-downgrades -yq \
g++-multilib gcc-multilib libcurl4-openssl-dev:i386 libgc-dev:i386 \
libsdl1.2-dev:i386 libsfml-dev:i386 libglib2.0-dev:i386 \
libffi-dev:i386
cat << EOF > bin/gcc
#!/bin/bash
exec $(which gcc) -m32 "\$@"
EOF
cat << EOF > bin/g++
#!/bin/bash
exec $(which g++) -m32 "\$@"
EOF
chmod 755 bin/gcc
chmod 755 bin/g++
- name: 'Install dependencies (macOS)'
if: runner.os == 'macOS'
run: brew install boehmgc make sfml
- name: 'Install dependencies (Windows)'
if: runner.os == 'Windows'
shell: bash
run: |
mkdir dist
curl -L https://nim-lang.org/download/mingw64.7z -o dist/mingw64.7z
curl -L https://nim-lang.org/download/dlls.zip -o dist/dlls.zip
7z x dist/mingw64.7z -odist
7z x dist/dlls.zip -obin
echo "::add-path::${{ github.workspace }}/dist/mingw64/bin"
- name: 'Add build binaries to PATH'
shell: bash
run: echo "::add-path::${{ github.workspace }}/bin"
- name: 'Build csources'
shell: bash
run: |
ncpu=
case '${{ runner.os }}' in
'Linux')
ncpu=$(nproc)
;;
'macOS')
ncpu=$(sysctl -n hw.ncpu)
;;
'Windows')
ncpu=$NUMBER_OF_PROCESSORS
;;
esac
[[ -z "$ncpu" || $ncpu -le 0 ]] && ncpu=1
make -C csources -j $ncpu CC=gcc ucpu='${{ matrix.cpu }}'
- name: 'Build koch'
shell: bash
run: nim c koch
- name: 'Run CI'
shell: bash
run: ./koch runCI
- name: 'Show failed tests'
if: failure()
shell: bash
run: nim c -r tools/ci_testresults.nim

133
.github/workflows/ci_docs.yml vendored Normal file
View File

@@ -0,0 +1,133 @@
name: Nim Docs CI
on:
push:
# Run only on changes on these files
paths:
- 'lib/**.nim'
- 'doc/**.rst'
- 'doc/nimdoc.css'
- '.github/workflows/ci_docs.yml'
pull_request:
# Run only on changes on these files
paths:
- 'lib/**.nim'
- 'doc/**.rst'
- '.github/workflows/ci_docs.yml'
jobs:
build:
strategy:
fail-fast: false
matrix:
target: [linux, windows, osx]
include:
- target: linux
os: ubuntu-18.04
- target: windows
os: windows-2019
- target: osx
os: macos-10.15
name: ${{ matrix.target }}
runs-on: ${{ matrix.os }}
steps:
- name: 'Checkout'
uses: actions/checkout@v2
- name: 'Install build dependencies (macOS)'
if: runner.os == 'macOS'
run: brew install make
- name: 'Install build dependencies (Windows)'
if: runner.os == 'Windows'
shell: bash
run: |
mkdir dist
curl -L https://nim-lang.org/download/mingw64.7z -o dist/mingw64.7z
curl -L https://nim-lang.org/download/dlls.zip -o dist/dlls.zip
7z x dist/mingw64.7z -odist
7z x dist/dlls.zip -obin
echo "::add-path::${{ github.workspace }}/dist/mingw64/bin"
- name: 'Add build binaries to PATH'
shell: bash
run: echo "::add-path::${{ github.workspace }}/bin"
- name: 'Get current csources version'
id: csources-version
shell: bash
run: |
sha=$(git ls-remote https://github.com/nim-lang/csources master | cut -f 1)
echo "::set-output name=sha::$sha"
- name: 'Get prebuilt csources from cache'
id: csources-cache
uses: actions/cache@v1
with:
path: bin
key: '${{ matrix.os }}-${{ steps.csources-version.outputs.sha }}'
- name: 'Checkout csources'
if: steps.csources-cache.outputs.cache-hit != 'true'
uses: actions/checkout@v2
with:
repository: nim-lang/csources
path: csources
- name: 'Build 1-stage compiler from csources'
shell: bash
run: |
ext=
[[ '${{ runner.os }}' == 'Windows' ]] && ext=.exe
if [[ ! -x bin/nim-csources$ext ]]; then
ncpu=
case '${{ runner.os }}' in
'Linux')
ncpu=$(nproc)
;;
'macOS')
ncpu=$(sysctl -n hw.ncpu)
;;
'Windows')
ncpu=$NUMBER_OF_PROCESSORS
;;
esac
[[ -z "$ncpu" || $ncpu -le 0 ]] && ncpu=1
make -C csources -j $ncpu CC=gcc
cp bin/nim{,-csources}$ext
else
echo 'Cache hit, using prebuilt csources'
cp bin/nim{-csources,}$ext
fi
- name: 'Build koch'
shell: bash
run: nim c koch
- name: 'Build the real compiler'
shell: bash
run: ./koch boot -d:release
- name: 'Build documentation'
shell: bash
run: ./koch doc --git.commit:devel
- name: 'Prepare documentation for deployment'
if: |
github.event_name == 'push' && github.ref == 'refs/heads/devel' &&
matrix.target == 'linux'
shell: bash
run: cp -f doc/html/{overview,index}.html
- name: 'Publish documentation to Github Pages'
if: |
github.event_name == 'push' && github.ref == 'refs/heads/devel' &&
matrix.target == 'linux'
uses: crazy-max/ghaction-github-pages@v1
with:
build_dir: doc/html
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

91
.github/workflows/ci_ssl.yml vendored Normal file
View File

@@ -0,0 +1,91 @@
name: Nim SSL CI
on:
pull_request:
# Run only on changes on related files
paths:
- 'lib/pure/httpclient.nim'
- 'lib/pure/net.nim'
- 'lib/pure/ssl_certs.nim'
- 'lib/wrappers/openssl.nim'
- 'tests/stdlib/thttpclient_ssl*'
- 'tests/untestable/thttpclient_ssl*'
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-18.04, macos-10.15, windows-2019]
cpu: [amd64]
name: '${{ matrix.os }} (${{ matrix.cpu }})'
runs-on: ${{ matrix.os }}
steps:
- name: 'Checkout'
uses: actions/checkout@v2
- name: 'Checkout csources'
uses: actions/checkout@v2
with:
repository: nim-lang/csources
path: csources
- name: 'Install dependencies (Linux amd64)'
if: runner.os == 'Linux' && matrix.cpu == 'amd64'
run: |
sudo apt-fast update -qq
DEBIAN_FRONTEND='noninteractive' \
sudo apt-fast install --no-install-recommends -y libssl1.1
- name: 'Install dependencies (macOS)'
if: runner.os == 'macOS'
run: brew install make
- name: 'Install dependencies (Windows)'
if: runner.os == 'Windows'
shell: bash
run: |
mkdir dist
curl -L https://nim-lang.org/download/mingw64.7z -o dist/mingw64.7z
curl -L https://nim-lang.org/download/dlls.zip -o dist/dlls.zip
7z x dist/mingw64.7z -odist
7z x dist/dlls.zip -obin
echo "::add-path::${{ github.workspace }}/dist/mingw64/bin"
- name: 'Add build binaries to PATH'
shell: bash
run: echo "::add-path::${{ github.workspace }}/bin"
- name: 'Build 1-stage compiler from csources'
shell: bash
run: |
ncpu=
case '${{ runner.os }}' in
'Linux')
ncpu=$(nproc)
;;
'macOS')
ncpu=$(sysctl -n hw.ncpu)
;;
'Windows')
ncpu=$NUMBER_OF_PROCESSORS
;;
esac
[[ -z "$ncpu" || $ncpu -le 0 ]] && ncpu=1
make -C csources -j $ncpu CC=gcc ucpu='${{ matrix.cpu }}'
- name: 'Build koch'
shell: bash
run: nim c koch
- name: 'Build the real compiler'
shell: bash
run: ./koch boot
- name: 'Run SSL nimDisableCertificateValidation integration tests'
shell: bash
run: nim c -d:nimDisableCertificateValidation -d:ssl -r -p:. tests/untestable/thttpclient_ssl_disabled.nim
- name: 'Run SSL certificate check integration tests'
# Not supported on Windows due to old openssl version
if: runner.os != 'Windows'
shell: bash
run: nim c -d:ssl -p:. --threads:on -r tests/untestable/thttpclient_ssl.nim

34
.gitignore vendored
View File

@@ -11,7 +11,9 @@ dnimcache/
!/icons/*.o
*.obj
*.ilk
*.exp
*.pdb
*.lib
*.dll
*.exe
*.so
@@ -19,6 +21,7 @@ dnimcache/
*.zip
*.iss
*.log
*.pdb
mapping.txt
tags
@@ -30,7 +33,7 @@ doc/*.html
doc/*.pdf
doc/*.idx
/web/upload
build/*
/build/*
bin/*
# iOS specific wildcards.
@@ -40,6 +43,7 @@ bin/*
*.perspectivev3
*.swp
.DS_Store
.tags
project.xcworkspace/
xcuserdata/
@@ -48,14 +52,20 @@ xcuserdata/
/compiler/nim.dot
/reject.json
/run.json
/tools/dochack/dochack.js
*.json
/pkgstemp/**/*
# for `nim doc foo.nim`
/*.html
lib/**/*.html
#/testresults.html #covered by /*.html
/testresults.json
testament.db
/tests/**/*.json
/tests/**/*.js
/csources
dist/
/dist/
# Private directories and files (IDEs)
.*/
@@ -66,3 +76,23 @@ testresults/
test.txt
/test.ini
tweeter.db
tweeter_test.db
megatest.nim
/outputExpected.txt
/outputGotten.txt
/lib/pure/*.js
!/.builds/
!/.github
# ignore debug dirs generated by dsymutil on OSX
*.dSYM
nimdoc.out.css
# for `nim c -r nimdoc/tester` etc; this can be in multiple places
htmldocs

View File

@@ -53,9 +53,8 @@ test-windows:
<<: *win_set_path_def
script:
- call ci\deps.bat
- nim c --taintMode:on tests\testament\tester
- tests\testament\tester.exe --pedantic all
- nim c testament\tester
- testament\tester.exe --pedantic all
tags:
- windows
- fast

View File

@@ -1,60 +1,46 @@
sudo: false
language: c
os:
- linux
- osx
dist: trusty
#matrix:
# allow_failures:
# - os: osx
dist: xenial
matrix:
include:
- os: linux
env:
- NIM_COMPILE_TO_CPP=false
- CPU=amd64
addons:
apt:
# update the list above if more deps are introduced
packages:
- libcurl4-openssl-dev
- libsdl1.2-dev
- libgc-dev
- libsfml-dev
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install boehmgc; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install sfml; fi
- libc6-dbg
- valgrind
before_script:
- set -e
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then unset -f cd; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then shell_session_update() { :; }; fi
- git clone --depth 1 https://github.com/nim-lang/csources.git
- cd csources
- sh build.sh
- cd ..
- export PATH=$(pwd)/bin${PATH:+:$PATH}
- export PATH="$PWD/bin${PATH:+:$PATH}"
- make -C csources -j 2 LD=$CC ucpu=$CPU
script:
- echo "travis_fold:start:nim_c_koch"
- nim c koch
- echo "travis_fold:end:nim_c_koch"
- echo "travis_fold:start:koch_boot"
- ./koch boot
- ./koch boot -d:release
- ./koch nimble
- nim e tests/test_nimscript.nims
#- nimble install zip -y
#- nimble install opengl
#- nimble install sdl1
#- nimble install jester@#head -y
#- nimble install niminst
- nim c --taintMode:on -d:nimCoroutines tests/testament/tester
- tests/testament/tester --pedantic all -d:nimCoroutines
- nim c -o:bin/nimpretty nimpretty/nimpretty.nim
- nim c -r nimpretty/tester.nim
- ./koch docs
- ./koch csource
- ./koch nimsuggest
- nim c -r nimsuggest/tester
- nim c -r nimdoc/tester
- echo "travis_fold:end:koch_boot"
- echo "travis_fold:start:koch_doc"
- ./koch doc
- echo "travis_fold:end:koch_doc"
before_deploy:
# Make https://nim-lang.github.io/Nim work the same as https://nim-lang.github.io/Nim/overview.html
- cp -f ./doc/html/overview.html ./doc/html/index.html
deploy: # https://nim-lang.github.io/Nim
provider: pages
# local-dir *has* to be a relative path from the repo root.

View File

@@ -1,65 +1,37 @@
version: '{build}'
cache:
- x86_64-4.9.2-release-win32-seh-rt_v4-rev4.7z
- sqlite-dll-win64-x64-3160200.zip
# - i686-4.9.2-release-win32-dwarf-rt_v4-rev4.7z
matrix:
fast_finish: true
environment:
DLLS_URL: https://nim-lang.org/download/dlls.zip
DLLS_ARCHIVE: dlls.zip
MINGW_DIR: mingw64
MINGW_URL: https://nim-lang.org/download/mingw64.7z
MINGW_ARCHIVE: mingw64.7z
matrix:
- MINGW_DIR: mingw64
MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/x86_64-4.9.2-release-win32-seh-rt_v4-rev4.7z/download
MINGW_ARCHIVE: x86_64-4.9.2-release-win32-seh-rt_v4-rev4.7z
SQLITE_URL: http://www.sqlite.org/2017/sqlite-dll-win64-x64-3160200.zip
SQLITE_ARCHIVE: sqlite-dll-win64-x64-3160200.zip
platform: x64
# - MINGW_DIR: mingw32
# MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/dwarf/i686-4.9.2-release-win32-dwarf-rt_v4-rev4.7z/download
# MINGW_ARCHIVE: i686-4.9.2-release-win32-dwarf-rt_v4-rev4.7z
# SQLITE_URL: http://www.sqlite.org/2017/sqlite-dll-win32-x86-3160200.zip
# SQLITE_ARCHIVE: sqlite-dll-win32-x86-3160200.zip
# platform: x86
- NIM_TEST_PACKAGES: false
- NIM_TEST_PACKAGES: true
cache:
- '%MINGW_ARCHIVE%'
- '%DLLS_ARCHIVE%'
install:
- ps: Install-Product node 8 # node 8 or later is required to test js async stuff
- MKDIR %CD%\DIST
- MKDIR %CD%\DIST\PCRE
- nuget install pcre -Verbosity quiet -Version 8.33.0.1 -OutputDirectory %CD%\DIST\PCRE
- IF not exist "%SQLITE_ARCHIVE%" appveyor DownloadFile "%SQLITE_URL%" -FileName "%SQLITE_ARCHIVE%"
- 7z x -y "%SQLITE_ARCHIVE%" -o"%CD%\DIST"> nul
- IF not exist "%DLLS_ARCHIVE%" appveyor DownloadFile "%DLLS_URL%" -FileName "%DLLS_ARCHIVE%"
- 7z x -y "%DLLS_ARCHIVE%" -o"%CD%\BIN"> nul
- IF not exist "%MINGW_ARCHIVE%" appveyor DownloadFile "%MINGW_URL%" -FileName "%MINGW_ARCHIVE%"
- 7z x -y "%MINGW_ARCHIVE%" -o"%CD%\DIST"> nul
- SET PATH=%CD%\DIST\%MINGW_DIR%\BIN;%CD%\BIN;%PATH%
- IF "%PLATFORM%" == "x64" ( copy C:\OpenSSL-Win64\libeay32.dll %CD%\BIN\libeay64.dll & copy C:\OpenSSL-Win64\libeay32.dll %CD%\BIN\libeay32.dll & copy C:\OpenSSL-Win64\libssl32.dll %CD%\BIN\libssl64.dll & copy C:\OpenSSL-Win64\libssl32.dll %CD%\BIN\libssl32.dll )
ELSE ( copy C:\OpenSSL-Win32\libeay32.dll %CD%\BIN\libeay32.dll & copy C:\OpenSSL-Win32\libssl32.dll %CD%\BIN\libssl32.dll )
- IF "%PLATFORM%" == "x64" ( copy %CD%\DIST\sqlite3.dll %CD%\BIN\sqlite3_64.dll ) ELSE ( copy %CD%\DIST\sqlite3.dll %CD%\BIN\sqlite3_32.dll )
- IF "%PLATFORM%" == "x64" ( copy %CD%\DIST\PCRE\pcre.redist.8.33.0.1\build\native\bin\v100\x64\Release\dynamic\utf8\pcre8.dll %CD%\bin\pcre64.dll ) ELSE ( copy %CD%\DIST\PCRE\pcre.redist.8.33.0.1\build\native\bin\v100\Win32\Release\dynamic\utf8\pcre8.dll %CD%\bin\pcre32.dll )
- git clone --depth 1 https://github.com/nim-lang/csources
- cd csources
- IF "%PLATFORM%" == "x64" ( build64.bat ) else ( build.bat )
- build64.bat
- cd ..
build_script:
- openssl version
- openssl version -d
- bin\nim c koch
- koch boot -d:release
- koch nimble
- nim e tests/test_nimscript.nims
- nim c -o:bin/nimpretty.exe nimpretty/nimpretty.nim
- nim c -r nimpretty/tester.nim
# - nimble install zip -y
# - nimble install opengl -y
# - nimble install sdl1 -y
# - nimble install jester@#head -y
- nim c --taintMode:on -d:nimCoroutines --os:genode -d:posix --compileOnly tests/testament/tester
- nim c --taintMode:on -d:nimCoroutines tests/testament/tester
test_script:
- tests\testament\tester --pedantic all -d:nimCoroutines
- nim c -r nimdoc\tester
# - koch csource
# - koch zip
- koch runCI
deploy: off

164
azure-pipelines.yml Normal file
View File

@@ -0,0 +1,164 @@
trigger:
branches:
include:
- '*'
pr:
branches:
include:
- '*'
jobs:
- job: packages
timeoutInMinutes: 90 # default `60` led to lots of cancelled jobs; use 0 for unlimited (may be undesirable)
strategy:
matrix:
Linux_amd64:
vmImage: 'ubuntu-16.04'
CPU: amd64
Linux_i386:
vmImage: 'ubuntu-16.04'
CPU: i386
OSX_amd64:
vmImage: 'macOS-10.15'
CPU: amd64
OSX_amd64_cpp:
vmImage: 'macOS-10.15'
CPU: amd64
NIM_COMPILE_TO_CPP: true
Windows_amd64:
vmImage: 'windows-2019'
CPU: amd64
Windows_amd64_pkg:
vmImage: 'windows-2019'
CPU: amd64
NIM_TEST_PACKAGES: true
pool:
vmImage: $(vmImage)
workspace:
clean: all
steps:
- bash: git config --global core.autocrlf false
displayName: 'Disable auto conversion to CRLF by git (Windows-only)'
condition: eq(variables['Agent.OS'], 'Windows_NT')
- checkout: self
- bash: git clone --depth 1 https://github.com/nim-lang/csources.git
displayName: 'Checkout csources'
- task: NodeTool@0
inputs:
versionSpec: '8.x'
displayName: 'Install node.js 8.x'
- bash: |
sudo apt-fast update -qq
DEBIAN_FRONTEND='noninteractive' \
sudo apt-fast install --no-install-recommends -yq \
libcurl4-openssl-dev libgc-dev libsdl1.2-dev libsfml-dev valgrind libc6-dbg
displayName: 'Install dependencies (amd64 Linux)'
condition: and(eq(variables['Agent.OS'], 'Linux'), eq(variables['CPU'], 'amd64'))
- bash: |
sudo dpkg --add-architecture i386
# Downgrade llvm, libgcc and libstdc++:
# - llvm has to be downgraded to have 32bit version installed for sfml.
# - libgcc and libstdc++ have to be downgraded as an optimization to
# prevent the use of the toolchain ppa, which has a terrible download
# speed.
cat << EOF | sudo tee /etc/apt/preferences.d/pin-to-rel
Package: libllvm6.0 libgcc1 libstdc++6
Pin: origin "azure.archive.ubuntu.com"
Pin-Priority: 1001
Package: *
Pin: release o=LP-PPA-ubuntu-toolchain-r-test
Pin-Priority: 100
EOF
sudo apt-fast update -qq
# `:i386` (e.g. in `libffi-dev:i386`) is needed otherwise you may get:
# `could not load: libffi.so` during dynamic loading.
DEBIAN_FRONTEND='noninteractive' \
sudo apt-fast install --no-install-recommends --allow-downgrades -yq \
g++-multilib gcc-multilib libcurl4-openssl-dev:i386 libgc-dev:i386 \
libsdl1.2-dev:i386 libsfml-dev:i386 libglib2.0-dev:i386 libffi-dev:i386
cat << EOF > bin/gcc
#!/bin/bash
exec $(which gcc) -m32 "\$@"
EOF
cat << EOF > bin/g++
#!/bin/bash
exec $(which g++) -m32 "\$@"
EOF
chmod 755 bin/gcc
chmod 755 bin/g++
displayName: 'Install dependencies (i386 Linux)'
condition: and(eq(variables['Agent.OS'], 'Linux'), eq(variables['CPU'], 'i386'))
- bash: brew install boehmgc make sfml
displayName: 'Install dependencies (OSX)'
condition: eq(variables['Agent.OS'], 'Darwin')
- bash: |
mkdir dist
curl -L https://nim-lang.org/download/mingw64.7z -o dist/mingw64.7z
curl -L https://nim-lang.org/download/dlls.zip -o dist/dlls.zip
7z x dist/mingw64.7z -odist
7z x dist/dlls.zip -obin
echo '##vso[task.prependpath]$(System.DefaultWorkingDirectory)/dist/mingw64/bin'
displayName: 'Install dependencies (Windows)'
condition: eq(variables['Agent.OS'], 'Windows_NT')
- bash: echo '##vso[task.prependpath]$(System.DefaultWorkingDirectory)/bin'
displayName: 'Add build binaries to PATH'
- bash: |
echo 'PATH:' "$PATH"
echo '##[section]gcc version'
gcc -v
echo '##[section]nodejs version'
node -v
echo '##[section]make version'
make -v
displayName: 'System information'
- bash: |
ncpu=
case '$(Agent.OS)' in
'Linux')
ncpu=$(nproc)
;;
'Darwin')
ncpu=$(sysctl -n hw.ncpu)
;;
'Windows_NT')
ncpu=$NUMBER_OF_PROCESSORS
;;
esac
[[ -z "$ncpu" || $ncpu -le 0 ]] && ncpu=1
make -C csources -j $ncpu CC=gcc ucpu=$(CPU)
displayName: 'Build csources'
- bash: nim c koch
displayName: 'Build koch'
# set result to omit the "bash exited with error code '1'" message
- bash: |
./koch runCI || echo '##vso[task.complete result=Failed]'
displayName: 'Run CI'
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

17
bin/nim-gdb Normal file → Executable file
View File

@@ -3,8 +3,19 @@
# Exit if anything fails
set -e
which nim > /dev/null || (echo "nim not in PATH"; exit 1)
which gdb > /dev/null || (echo "gdb not in PATH"; exit 1)
if [[ "$(uname -s)" == "Darwin" ]]; then
which greadlink > /dev/null || (echo "readlink not in PATH. Please install coreutils from homebrew."; exit 1)
READLINK=greadlink
else
which readlink > /dev/null || (echo "readlink not in PATH."; exit 1)
READLINK=readlink
fi
# Find out where the pretty printer Python module is
NIM_SYSROOT=$(dirname $(dirname $(readlink -e $(which nim))))
NIM_SYSROOT=$(dirname $(dirname $($READLINK -e $(which nim))))
GDB_PYTHON_MODULE_PATH="$NIM_SYSROOT/tools/nim-gdb.py"
# Run GDB with the additional arguments that load the pretty printers
@@ -13,6 +24,4 @@ GDB_PYTHON_MODULE_PATH="$NIM_SYSROOT/tools/nim-gdb.py"
NIM_GDB="${NIM_GDB:-gdb}"
# exec replaces the new process of bash with gdb. It is always good to
# have fewer processes.
exec ${NIM_GDB} \
-eval-command "source $GDB_PYTHON_MODULE_PATH" \
"$@"
exec "${NIM_GDB}" -eval-command="source $GDB_PYTHON_MODULE_PATH" "$@"

1
bin/nim-gdb.bash Symbolic link
View File

@@ -0,0 +1 @@
nim-gdb

14
bin/nim-gdb.bat Normal file
View File

@@ -0,0 +1,14 @@
@echo off
for %%i in (nim.exe) do (set NIM_BIN=%%~dp$PATH:i)
for %%i in ("%NIM_BIN%\..\") do (set NIM_ROOT=%%~fi)
set @GDB_PYTHON_MODULE_PATH=%NIM_ROOT%\tools\nim-gdb.py
set @NIM_GDB=gdb.exe
@echo source %@GDB_PYTHON_MODULE_PATH%> wingdbcommand.txt
%@NIM_GDB% --command="wingdbcommand.txt" %*
del wingdbcommand.txt /f /q
EXIT /B %ERRORLEVEL%
@echo on

17
build_all.bat Normal file
View File

@@ -0,0 +1,17 @@
@echo off
rem build development version of the compiler; can be rerun safely
if not exist csources (
git clone --depth 1 https://github.com/nim-lang/csources.git
)
if not exist bin\nim.exe (
cd csources
if PROCESSOR_ARCHITECTURE == AMD64 (
SET ARCH=64
)
CALL build.bat
cd ..
)
bin\nim.exe c --skipUserCfg --skipParentCfg koch
koch.exe boot -d:release --skipUserCfg --skipParentCfg
koch.exe tools --skipUserCfg --skipParentCfg

View File

@@ -1,31 +1,52 @@
#! /bin/sh
# build development version of the compiler; can be rerun safely
# build development version of the compiler; can be rerun safely.
# arguments can be passed, eg `--os freebsd`
set -u # error on undefined variables
set -e # exit on first error
echo_run(){
printf "\n$*\n"
echo "$*"
"$@"
}
[ -d csources ] || echo_run git clone --depth 1 https://github.com/nim-lang/csources.git
[ -d csources ] || echo_run git clone -q --depth 1 https://github.com/nim-lang/csources.git
nim_csources=bin/nim_csources
build_nim_csources_via_script(){
echo_run cd csources
echo_run sh build.sh "$@"
}
build_nim_csources(){
## avoid changing dir in case of failure
# avoid changing dir in case of failure
(
echo_run cd csources
echo_run sh build.sh
if [ $# -ne 0 ]; then
# some args were passed (eg: `--cpu i386`), need to call build.sh
build_nim_csources_via_script "$@"
else
# no args, use multiple Make jobs (5X faster on 16 cores: 10s instead of 50s)
makeX=make
unamestr=$(uname)
if [ "$unamestr" = 'FreeBSD' ]; then
makeX=gmake
fi
nCPU=$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || 1)
which $makeX && echo_run $makeX -C csources -j $((nCPU + 2)) -l $nCPU || build_nim_csources_via_script
fi
)
# keep $nim_csources in case needed to investigate bootstrap issues
# without having to rebuild from csources
echo_run cp bin/nim $nim_csources
}
[ -f $nim_csources ] || echo_run build_nim_csources
[ -f $nim_csources ] || echo_run build_nim_csources $@
# Note: if fails, may need to `cd csources && git pull`
echo_run bin/nim c --skipUserCfg --skipParentCfg koch
echo_run ./koch boot -d:release --skipUserCfg --skipParentCfg
echo_run ./koch tools --skipUserCfg --skipParentCfg # Compile Nimble and other tools.
echo_run bin/nim c koch
echo_run ./koch boot -d:release
echo_run ./koch tools # Compile Nimble and other tools.

View File

@@ -1,253 +1,15 @@
## v0.19.X - XX/XX/2018
### Changes affecting backwards compatibility
- The stdlib module ``future`` has been renamed to ``sugar``.
- ``macros.callsite`` is now deprecated. Since the introduction of ``varargs``
parameters this became unnecessary.
- Anonymous tuples with a single element can now be written as ``(1,)`` with a
trailing comma. The underlying AST is ``nnkTupleConstr(newLit 1)`` for this
example. ``nnkTupleConstr`` is a new node kind your macros need to be able
to deal with!
- Indexing into a ``cstring`` for the JS target is now mapped
to ``charCodeAt``.
- Assignments that would "slice" an object into its supertype are now prevented
at runtime. Use ``ref object`` with inheritance rather than ``object`` with
inheritance to prevent this issue.
- The ``not nil`` type annotation now has to be enabled explicitly
via ``{.experimental: "notnil"}`` as we are still not pleased with how this
feature works with Nim's containers.
- The parser now warns about inconsistent spacing around binary operators as
these can easily be confused with unary operators. This warning will likely
become an error in the future.
- The ``'c`` and ``'C'`` suffix for octal literals is now deprecated to
bring the language in line with the standard library (e.g. ``parseOct``).
- The dot style for import paths (e.g ``import path.to.module`` instead of
``import path/to/module``) has been deprecated.
#### Breaking changes in the standard library
- ``re.split`` for empty regular expressions now yields every character in
the string which is what other programming languages chose to do.
- The returned tuple of ``system.instantiationInfo`` now has a third field
containing the column of the instantiation.
- ``cookies.setCookie`` no longer assumes UTC for the expiration date.
- ``strutils.formatEng`` does not distinguish between ``nil`` and ``""``
strings anymore for its ``unit`` parameter. Instead the space is controlled
by a new parameter ``useUnitSpace``.
- The ``times.parse`` and ``times.format`` procs have been rewritten.
The proc signatures are the same so it should generally not break anything.
However, the new implementation is a bit stricter, which is a breaking change.
For example ``parse("2017-01-01 foo", "yyyy-MM-dd")`` will now raise an error.
- ``proc `-`*(a, b: Time): int64`` in the ``times`` module has changed return type
to ``times.Duration`` in order to support higher time resolutions.
The proc is no longer deprecated.
- The ``times.Timezone`` is now an immutable ref-type that must be initialized
with an explicit constructor (``newTimezone``).
- ``posix.Timeval.tv_sec`` has changed type to ``posix.Time``.
- ``math.`mod` `` for floats now behaves the same as ``mod`` for integers
(previously it used floor division like Python). Use ``math.floorMod`` for the old behavior.
- For string inputs, ``unicode.isUpper`` and ``unicode.isLower`` now require a
second mandatory parameter ``skipNonAlpha``.
- For string inputs, ``strutils.isUpperAscii`` and ``strutils.isLowerAscii`` now
require a second mandatory parameter ``skipNonAlpha``.
- ``osLastError`` is now marked with ``sideEffect``
- The procs ``parseHexInt`` and ``parseOctInt`` now fail on empty strings
and strings containing only valid prefixes, e.g. "0x" for hex integers.
- ``terminal.setCursorPos`` and ``terminal.setCursorXPos`` now work correctly
with 0-based coordinates on POSIX (previously, you needed to use
1-based coordinates on POSIX for correct behaviour; the Windows behaviour
was always correct).
- ``lineInfoObj`` now returns absolute path instead of project path.
It's used by ``lineInfo``, ``check``, ``expect``, ``require``, etc.
- ``net.sendTo`` no longer returns an int and now raises an ``OSError``.
- `threadpool`'s `await` and derivatives have been renamed to `blockUntil`
to avoid confusions with `await` from the `async` macro.
# v1.4.0 - yyyy-mm-dd
#### Breaking changes in the compiler
- The undocumented ``#? braces`` parsing mode was removed.
- The undocumented PHP backend was removed.
- The default location of ``nimcache`` for the native code targets was
changed. Read [the compiler user guide](https://nim-lang.org/docs/nimc.html#generated-c-code-directory)
for more information.
### Library additions
- ``re.split`` now also supports the ``maxsplit`` parameter for consistency
with ``strutils.split``.
- Added ``system.toOpenArray`` in order to support zero-copy slicing
operations. This is currently not yet available for the JavaScript target.
- Added ``getCurrentDir``, ``findExe``, ``cpDir`` and ``mvDir`` procs to
``nimscript``.
- The ``times`` module now supports up to nanosecond time resolution when available.
- Added the type ``times.Duration`` for representing fixed durations of time.
- Added the proc ``times.convert`` for converting between different time units,
e.g days to seconds.
- Added the proc ``algorithm.binarySearch[T, K]`` with the ```cmp``` parameter.
- Added the proc ``algorithm.upperBound``.
- Added inverse hyperbolic functions, ``math.arcsinh``, ``math.arccosh`` and ``math.arctanh`` procs.
- Added cotangent, secant and cosecant procs ``math.cot``, ``math.sec`` and ``math.csc``; and their hyperbolic, inverse and inverse hyperbolic functions, ``math.coth``, ``math.sech``, ``math.csch``, ``math.arccot``, ``math.arcsec``, ``math.arccsc``, ``math.arccoth``, ``math.arcsech`` and ``math.arccsch`` procs.
- Added the procs ``math.floorMod`` and ``math.floorDiv`` for floor based integer division.
- Added the procs ``rationals.`div```, ``rationals.`mod```, ``rationals.floorDiv`` and ``rationals.floorMod`` for rationals.
- Added the proc ``math.prod`` for product of elements in openArray.
- Added the proc ``parseBinInt`` to parse a binary integer from a string, which returns the value.
- ``parseOct`` and ``parseBin`` in parseutils now also support the ``maxLen`` argument similar to ``parseHexInt``.
- Added the proc ``flush`` for memory mapped files.
- Added the ``MemMapFileStream``.
- Added a simple interpreting event parser template ``eventParser`` to the ``pegs`` module.
- Added ``macros.copyLineInfo`` to copy lineInfo from other node.
- Added ``system.ashr`` an arithmetic right shift for integers.
### Library changes
- ``macros.astGenRepr``, ``macros.lispRepr`` and ``macros.treeRepr``
now escapes the content of string literals consistently.
- ``macros.NimSym`` and ``macros.NimIdent`` is now deprecated in favor
of the more general ``NimNode``.
- ``macros.getImpl`` now includes the pragmas of types, instead of omitting them.
- ``macros.hasCustomPragma`` and ``macros.getCustomPragmaVal`` now
also support ``ref`` and ``ptr`` types, pragmas on types and variant
fields.
- ``system.SomeReal`` is now called ``SomeFloat`` for consistency and
correctness.
- ``algorithm.smartBinarySearch`` and ``algorithm.binarySearch`` is
now joined in ``binarySearch``. ``smartbinarySearch`` is now
deprecated.
- The `terminal` module now exports additional procs for generating ANSI color
codes as strings.
- Added the parameter ``val`` for the ``CritBitTree[int].inc`` proc.
- An exception raised from a ``test`` block of ``unittest`` now shows its type in
error message.
- The ``compiler/nimeval`` API was rewritten to simplify the "compiler as an
API". Using the Nim compiler and its VM as a scripting engine has never been
easier. See ``tests/compilerapi/tcompilerapi.nim`` for an example of how to
use the Nim VM in a native Nim application.
- Added the parameter ``val`` for the ``CritBitTree[T].incl`` proc.
- The proc ``tgamma`` was renamed to ``gamma``. ``tgamma`` is deprecated.
- The ``pegs`` module now exports getters for the fields of its ``Peg`` and ``NonTerminal``
object types. ``Peg``s with child nodes now have the standard ``items`` and ``pairs``
iterators.
- The ``accept`` socket procedure defined in the ``net`` module can now accept
a nil socket.
### Language additions
- Dot calls combined with explicit generic instantiations can now be written
as ``x.y[:z]`` which is transformed into ``y[z](x)`` by the parser.
- ``func`` is now an alias for ``proc {.noSideEffect.}``.
- In order to make ``for`` loops and iterators more flexible to use Nim now
supports so called "for-loop macros". See
the [manual](manual.html#macros-for-loop-macros) for more details.
This feature enables a Python-like generic ``enumerate`` implementation.
- Case statements can now be rewritten via macros. See the [manual](manual.html#macros-case-statement-macros) for more information.
This feature enables custom pattern matchers.
## Standard library additions and changes
- the `typedesc` special type has been renamed to just `type`.
- `static` and `type` are now also modifiers similar to `ref` and `ptr`.
They denote the special types `static[T]` and `type[T]`.
- Forcing compile-time evaluation with `static` now supports specifying
the desired target type (as a concrete type or as a type class)
- The `type` operator now supports checking that the supplied expression
matches an expected type constraint.
### Language changes
- The `importcpp` pragma now allows importing the listed fields of generic
C++ types. Support for numeric parameters have also been added through
the use of `static[T]` types.
(#6415)
- Native C++ exceptions can now be imported with `importcpp` pragma.
Imported exceptions can be raised and caught just like Nim exceptions.
More details in language manual.
- ``nil`` for strings/seqs is finally gone. Instead the default value for
these is ``"" / @[]``. Use ``--nilseqs:on`` for a transition period.
- Accessing the binary zero terminator in Nim's native strings
is now invalid. Internally a Nim string still has the trailing zero for
zero-copy interoperability with ``cstring``. Compile your code with the
new switch ``--laxStrings:on`` if you need a transition period.
- The command syntax now supports keyword arguments after the first comma.
- Thread-local variables can now be declared inside procs. This implies all
the effects of the ``global`` pragma.
- Nim now supports the ``except`` clause in the export statement.
- Range float types, example ``range[0.0 .. Inf]``. More details in language manual.
- The ``{.this.}`` pragma has been deprecated. It never worked within generics and
we found the resulting code harder to read than the more explicit ``obj.field``
syntax.
- "Memory regions" for pointer types have been deprecated, they were hardly used
anywhere. Note that this has **nothing** to do with the ``--gc:regions`` switch
of managing memory.
- The exception hierarchy was slightly reworked, ``SystemError`` was renamed to
``CatchableError`` and is the new base class for any exception that is guaranteed to
be catchable. This change should have minimal impact on most existing Nim code.
## Language changes
### Tool changes
## Compiler changes
- ``jsondoc2`` has been renamed ``jsondoc``, similar to how ``doc2`` was renamed
``doc``. The old ``jsondoc`` can still be invoked with ``jsondoc0``.
### Compiler changes
## Tool changes
- The VM's instruction count limit was raised to 3 million instructions in
order to support more complex computations at compile-time.
- Support for hot code reloading has been implemented for the JavaScript
target. To use it, compile your code with `--hotCodeReloading:on` and use a
helper library such as LiveReload or BrowserSync.
- A new compiler option `--cppCompileToNamespace` puts the generated C++ code
into the namespace "Nim" in order to avoid naming conflicts with existing
C++ code. This is done for all Nim code - internal and exported.
- Added ``macros.getProjectPath`` and ``ospaths.putEnv`` procs to Nim's virtual
machine.
- The ``deadCodeElim`` option is now always turned on and the switch has no
effect anymore, but is recognized for backwards compatibility.
- ``experimental`` is now a pragma / command line switch that can enable specific
language extensions, it is not an all-or-nothing switch anymore.
- Nintendo Switch was added as a new platform target. See [the compiler user guide](https://nim-lang.org/docs/nimc.html)
for more info.
- macros.bindSym now capable to accepts not only literal string or string constant expression.
bindSym enhancement make it also can accepts computed string or ident node inside macros /
compile time functions / static blocks. Only in templates / regular code it retains it's old behavior.
This new feature can be accessed via {.experimental: "dynamicBindSym".} pragma/switch.
- On Posix systems the global system wide configuration is now put under ``/etc/nim/nim.cfg``,
it used to be ``/etc/nim.cfg``. Usually it does not exist, however.
- On Posix systems the user configuration is now looked under ``$XDG_CONFIG_HOME/nim/nim.cfg``
(if ``XDG_CONFIG_HOME`` is not defined, then under ``~/.config/nim/nim.cfg``). It used to be
``$XDG_CONFIG_DIR/nim.cfg`` (and ``~/.config/nim.cfg``).
Similarly, on Windows, the user configuration is now looked under ``%APPDATA%/nim/nim.cfg``.
This used to be ``%APPDATA%/nim.cfg``.
### Bugfixes

View File

@@ -0,0 +1,663 @@
## v0.18.0 - 01/03/2018
### Changes affecting backwards compatibility
#### Breaking changes in the standard library
- The ``[]`` proc for strings now raises an ``IndexError`` exception when
the specified slice is out of bounds. See issue
[#6223](https://github.com/nim-lang/Nim/issues/6223) for more details.
You can use ``substr(str, start, finish)`` to get the old behaviour back,
see [this commit](https://github.com/nim-lang/nimbot/commit/98cc031a27ea89947daa7f0bb536bcf86462941f) for an example.
- ``strutils.split`` and ``strutils.rsplit`` with an empty string and a
separator now returns that empty string.
See issue [#4377](https://github.com/nim-lang/Nim/issues/4377).
- Arrays of char cannot be converted to ``cstring`` anymore, pointers to
arrays of char can! This means ``$`` for arrays can finally exist
in ``system.nim`` and do the right thing. This means ``$myArrayOfChar`` changed
its behaviour! Compile with ``-d:nimNoArrayToString`` to see where to fix your
code.
- `reExtended` is no longer default for the `re` constructor in the `re`
module.
- The behavior of ``$`` has been changed for all standard library collections. The
collection-to-string implementations now perform proper quoting and escaping of
strings and chars.
- `newAsyncSocket` taking an `AsyncFD` now runs `setBlocking(false)` on the
fd.
- ``mod`` and bitwise ``and`` do not produce ``range`` subtypes anymore. This
turned out to be more harmful than helpful and the language is simpler
without this special typing rule.
- ``formatFloat``/``formatBiggestFloat`` now support formatting floats with zero
precision digits. The previous ``precision = 0`` behavior (default formatting)
is now available via ``precision = -1``.
- Moved from stdlib into Nimble packages:
- [``basic2d``](https://github.com/nim-lang/basic2d)
_deprecated: use ``glm``, ``arraymancer``, ``neo``, or another package instead_
- [``basic3d``](https://github.com/nim-lang/basic3d)
_deprecated: use ``glm``, ``arraymancer``, ``neo``, or another package instead_
- [``gentabs``](https://github.com/lcrees/gentabs)
- [``libuv``](https://github.com/lcrees/libuv)
- [``numeric``](https://github.com/lcrees/polynumeric)
- [``poly``](https://github.com/lcrees/polynumeric)
- [``pdcurses``](https://github.com/lcrees/pdcurses)
- [``romans``](https://github.com/lcrees/romans)
- [``libsvm``](https://github.com/nim-lang/libsvm_legacy)
- [``joyent_http_parser``](https://github.com/nim-lang/joyent_http_parser)
- 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`.
Counting occurrences in a sequence used to be:
```nim
let mySeq = @[1, 2, 1, 3, 1, 4]
var myCounter = initCountTable[int]()
for item in mySeq:
myCounter.inc item
```
Now, you can simply do:
```nim
let
mySeq = @[1, 2, 1, 3, 1, 4]
myCounter = mySeq.toCountTable()
```
- If you use ``--dynlibOverride:ssl`` with OpenSSL 1.0.x, you now have to
define ``openssl10`` symbol (``-d:openssl10``). By default OpenSSL 1.1.x is
assumed.
- ``newNativeSocket`` is now named ``createNativeSocket``.
- ``newAsyncNativeSocket`` is now named ``createAsyncNativeSocket``
and it no longer raises an OS error but returns an ``osInvalidSocket`` when
creation fails.
- The ``securehash`` module is now deprecated. Instead import ``std / sha1``.
- The ``readPasswordFromStdin`` proc has been moved from the ``rdstdin``
to the ``terminal`` module, thus it does not depend on linenoise anymore.
#### Breaking changes in the compiler
- ``\n`` is now only the single line feed character like in most
other programming languages. The new platform specific newline escape sequence is
written as ``\p``. This change only affects the Windows platform.
- The overloading rules changed slightly so that constrained generics are
preferred over unconstrained generics. (Bug #6526)
- We changed how array accesses "from backwards" like ``a[^1]`` or ``a[0..^1]`` are
implemented. These are now implemented purely in ``system.nim`` without compiler
support. There is a new "heterogeneous" slice type ``system.HSlice`` that takes 2
generic parameters which can be ``BackwardsIndex`` indices. ``BackwardsIndex`` is
produced by ``system.^``.
This means if you overload ``[]`` or ``[]=`` you need to ensure they also work
with ``system.BackwardsIndex`` (if applicable for the accessors).
- The parsing rules of ``if`` expressions were changed so that multiple
statements are allowed in the branches. We found few code examples that
now fail because of this change, but here is one:
```nim
t[ti] = if exp_negative: '-' else: '+'; inc(ti)
```
This now needs to be written as:
```nim
t[ti] = (if exp_negative: '-' else: '+'); inc(ti)
```
- The experimental overloading of the dot ``.`` operators now take
an ``untyped``` parameter as the field name, it used to be
a ``static[string]``. You can use ``when defined(nimNewDot)`` to make
your code work with both old and new Nim versions.
See [special-operators](https://nim-lang.org/docs/manual.html#special-operators)
for more information.
- ``yield`` (or ``await`` which is mapped to ``yield``) never worked reliably
in an array, seq or object constructor and is now prevented at compile-time.
### Library additions
- **Added ``sequtils.mapLiterals`` for easier construction of array and tuple literals.**
- Added ``system.runnableExamples`` to make examples in Nim's documentation easier
to write and test. The examples are tested as the last step of
``nim doc``.
- Implemented ``getIoHandler`` proc in the ``asyncdispatch`` module that allows
you to retrieve the underlying IO Completion Port or ``Selector[AsyncData]``
object in the specified dispatcher.
- For string formatting / interpolation a new module
called [strformat](https://nim-lang.org/docs/strformat.html) has been added
to the stdlib.
- The `ReadyKey` type in the selectors module now contains an ``errorCode``
field to help distinguish between ``Event.Error`` events.
- Implemented an `accept` proc that works on a `SocketHandle` in
``nativesockets``.
- Added ``algorithm.rotateLeft``.
- Added ``typetraits.$`` as an alias for ``typetraits.name``.
- Added ``system.getStackTraceEntries`` that allows you to access the stack
trace in a structured manner without string parsing.
- Added ``parseutils.parseSaturatedNatural``.
- Added ``macros.unpackVarargs``.
- Added support for asynchronous programming for the JavaScript backend using
the `asyncjs` module.
- Added true color support for some terminals. Example:
```nim
import colors, terminal
const Nim = "Efficient and expressive programming."
var
fg = colYellow
bg = colBlue
int = 1.0
enableTrueColors()
for i in 1..15:
styledEcho bgColor, bg, fgColor, fg, Nim, resetStyle
int -= 0.01
fg = intensity(fg, int)
setForegroundColor colRed
setBackgroundColor colGreen
styledEcho "Red on Green.", resetStyle
```
### Library changes
- ``echo`` now works with strings that contain ``\0`` (the binary zero is not
shown) and ``nil`` strings are equal to empty strings.
- JSON: Deprecated `getBVal`, `getFNum`, and `getNum` in favour of
`getBool`, `getFloat`, `getBiggestInt`. A new `getInt` procedure was also
added.
- ``rationals.toRational`` now uses an algorithm based on continued fractions.
This means its results are more precise and it can't run into an infinite loop
anymore.
- ``os.getEnv`` now takes an optional ``default`` parameter that tells ``getEnv``
what to return if the environment variable does not exist.
- The ``random`` procs in ``random.nim`` have all been deprecated. Instead use
the new ``rand`` procs. The module now exports the state of the random
number generator as type ``Rand`` so multiple threads can easily use their
own random number generators that do not require locking. For more information
about this rename see issue [#6934](https://github.com/nim-lang/Nim/issues/6934)
- ``writeStackTrace`` is now proclaimed to have no IO effect (even though it does)
so that it is more useful for debugging purposes.
- ``db_mysql`` module: ``DbConn`` is now a ``distinct`` type that doesn't expose the
details of the underlying ``PMySQL`` type.
- ``parseopt2`` is now deprecated, use ``parseopt`` instead.
### Language additions
- It is now possible to forward declare object types so that mutually
recursive types can be created across module boundaries. See
[package level objects](https://nim-lang.org/docs/manual.html#package-level-objects)
for more information.
- Added support for casting between integers of same bitsize in VM (compile time and nimscript).
This allows to, among other things, reinterpret signed integers as unsigned.
- Custom pragmas are now supported using pragma ``pragma``, please see language
manual for details.
- Standard library modules can now also be imported via the ``std`` pseudo-directory.
This is useful in order to distinguish between standard library and nimble package
imports:
```nim
import std / [strutils, os, osproc]
import someNimblePackage / [strutils, os]
```
### Language changes
- The **unary** ``<`` is now deprecated, for ``.. <`` use ``..<`` for other usages
use the ``pred`` proc.
- Bodies of ``for`` loops now get their own scope:
```nim
# now compiles:
for i in 0..4:
let i = i + 1
echo i
```
- To make Nim even more robust the system iterators ``..`` and ``countup``
now only accept a single generic type ``T``. This means the following code
doesn't die with an "out of range" error anymore:
```nim
var b = 5.Natural
var a = -5
for i in a..b:
echo i
```
- ``atomic`` and ``generic`` are no longer keywords in Nim. ``generic`` used to be
an alias for ``concept``, ``atomic`` was not used for anything.
- The memory manager now uses a variant of the TLSF algorithm that has much
better memory fragmentation behaviour. According
to [http://www.gii.upv.es/tlsf/](http://www.gii.upv.es/tlsf/) the maximum
fragmentation measured is lower than 25%. As a nice bonus ``alloc`` and
``dealloc`` became O(1) operations.
- The compiler is now more consistent in its treatment of ambiguous symbols:
Types that shadow procs and vice versa are marked as ambiguous (bug #6693).
- codegenDecl pragma now works for the JavaScript backend. It returns an empty
string for function return type placeholders.
- Extra semantic checks for procs with noreturn pragma: return type is not allowed,
statements after call to noreturn procs are no longer allowed.
- Noreturn proc calls and raising exceptions branches are now skipped during common type
deduction in ``if`` and ``case`` expressions. The following code snippets now compile:
```nim
import strutils
let str = "Y"
let a = case str:
of "Y": true
of "N": false
else: raise newException(ValueError, "Invalid boolean")
let b = case str:
of nil, "": raise newException(ValueError, "Invalid boolean")
elif str.startsWith("Y"): true
elif str.startsWith("N"): false
else: false
let c = if str == "Y": true
elif str == "N": false
else:
echo "invalid bool"
quit("this is the end")
```
- Pragmas now support call syntax, for example: ``{.exportc"myname".}`` and
``{.exportc("myname").}``
- The ``deprecated`` pragma now supports a user-definable warning message for procs.
```nim
proc bar {.deprecated: "use foo instead".} =
return
bar()
```
### Tool changes
- The ``nim doc`` command is now an alias for ``nim doc2``, the second version of
the documentation generator. The old version 1 can still be accessed
via the new ``nim doc0`` command.
- Nim's ``rst2html`` command now supports the testing of code snippets via an RST
extension that we called ``:test:``::
```rst
.. code-block:: nim
:test:
# shows how the 'if' statement works
if true: echo "yes"
```
### Compiler changes
### Bugfixes
- Fixed "ReraiseError when using try/except within finally block"
([#5871](https://github.com/nim-lang/Nim/issues/5871))
- Fixed "Range type inference leads to counter-intuitive behvaiour"
([#5854](https://github.com/nim-lang/Nim/issues/5854))
- Fixed "JSON % operator can fail in extern procs with dynamic types"
([#6385](https://github.com/nim-lang/Nim/issues/6385))
- Fixed ""intVal is not accessible" in VM"
([#6083](https://github.com/nim-lang/Nim/issues/6083))
- Fixed "Add excl for OrderedSet"
([#2467](https://github.com/nim-lang/Nim/issues/2467))
- Fixed "newSeqOfCap actually doesn't reserve memory"
([#6403](https://github.com/nim-lang/Nim/issues/6403))
- Fixed "[Regression] Nim segfaults"
([#6435](https://github.com/nim-lang/Nim/issues/6435))
- Fixed "Seq assignment is slower than expected"
([#6433](https://github.com/nim-lang/Nim/issues/6433))
- Fixed "json module issues with empty dicts and lists"
([#6438](https://github.com/nim-lang/Nim/issues/6438))
- Fixed "mingw installed via finish.exe fails to link if Nim located in path with whitespace"
([#6452](https://github.com/nim-lang/Nim/issues/6452))
- Fixed "unittest.check does not perform short-circuit evaluation"
([#5784](https://github.com/nim-lang/Nim/issues/5784))
- Fixed "Error while concatenating an array of chars."
([#5861](https://github.com/nim-lang/Nim/issues/5861))
- Fixed "range initialization: [ProveInit] hint: Cannot prove that"
([#6474](https://github.com/nim-lang/Nim/issues/6474))
- Fixed "scanf can call procs with side-effects multiple times"
([#6487](https://github.com/nim-lang/Nim/issues/6487))
- Fixed "gcsafe detection problem"
([#5620](https://github.com/nim-lang/Nim/issues/5620))
- Fixed "C++ codegen: `mitems` generates invalid code."
([#4910](https://github.com/nim-lang/Nim/issues/4910))
- Fixed "strange runtime behavior on macOS"
([#6496](https://github.com/nim-lang/Nim/issues/6496))
- Fixed "stdtmpl: invalid indentation after a line ending in question mark"
([#5070](https://github.com/nim-lang/Nim/issues/5070))
- Fixed "Windows: NAN troubles on c backend"
([#6511](https://github.com/nim-lang/Nim/issues/6511))
- Fixed "lib/nim/system/cellsets.nim(33, 31) Error: type mismatch while attempting to compile for 16bit CPUs"
([#3558](https://github.com/nim-lang/Nim/issues/3558))
- Fixed "Can't compile dynlib with ``-d:useNimRtl`` and ``--threads:on``"
([#5143](https://github.com/nim-lang/Nim/issues/5143))
- Fixed "var s = @[0,1,2,...] can generate thousand of single assignments in C code"
([#5007](https://github.com/nim-lang/Nim/issues/5007))
- Fixed "`echo` discards everything after a null character"
([#1137](https://github.com/nim-lang/Nim/issues/1137))
- Fixed "Turn off reExtended by default"
([#5627](https://github.com/nim-lang/Nim/issues/5627))
- Fixed "Bad Links in docs/backends.html"
([#5914](https://github.com/nim-lang/Nim/issues/5914))
- Fixed "Index out of bounds error in db_postgres when executing non parameter-substituted queries containing "?""
([#6571](https://github.com/nim-lang/Nim/issues/6571))
- Fixed "Please add pipe2 support to posix stdlib"
([#6553](https://github.com/nim-lang/Nim/issues/6553))
- Fixed "Return semantics vary depending on return style"
([#6422](https://github.com/nim-lang/Nim/issues/6422))
- Fixed "parsecsv.open reports SIGSEGV when calling 'open' on missing file"
([#6148](https://github.com/nim-lang/Nim/issues/6148))
- Fixed "VCC: Nim generates non-compilable code for system.nim"
([#6606](https://github.com/nim-lang/Nim/issues/6606))
- Fixed "Generic subtype matches worse than a generic"
([#6526](https://github.com/nim-lang/Nim/issues/6526))
- Fixed "formatFloat inconsistent scientific notation"
([#6589](https://github.com/nim-lang/Nim/issues/6589))
- Fixed "Generated c code calls function twice"
([#6292](https://github.com/nim-lang/Nim/issues/6292))
- Fixed "Range type inference leads to counter-intuitive behvaiour"
([#5854](https://github.com/nim-lang/Nim/issues/5854))
- Fixed "New backward indexing is too limited"
([#6631](https://github.com/nim-lang/Nim/issues/6631))
- Fixed "Table usage in a macro (SIGSEGV: Illegal storage access.)"
([#1860](https://github.com/nim-lang/Nim/issues/1860))
- Fixed "Incorrect deprecation error"
([#6634](https://github.com/nim-lang/Nim/issues/6634))
- Fixed "Wrong indices in arrays not starting with 0"
([#6675](https://github.com/nim-lang/Nim/issues/6675))
- Fixed "if expressions"
([#6609](https://github.com/nim-lang/Nim/issues/6609))
- Fixed "BackwardsIndex: converter + `[]` + unrelated type[^1]: lib/system.nim(3536, 3) Error"
([#6692](https://github.com/nim-lang/Nim/issues/6692))
- Fixed "BackwardsIndex: converter + `[]` + unrelated type[^1]: lib/system.nim(3536, 3) Error"
([#6692](https://github.com/nim-lang/Nim/issues/6692))
- Fixed "js backend 0.17.3: array bounds check for non zero based arrays is buggy"
([#6532](https://github.com/nim-lang/Nim/issues/6532))
- Fixed "HttpClient's new API doesn't work through a proxy for https URLs"
([#6685](https://github.com/nim-lang/Nim/issues/6685))
- Fixed "isServing isn't declared and isn't compiling"
([#6707](https://github.com/nim-lang/Nim/issues/6707))
- Fixed "[Regression] value out of range"
([#6710](https://github.com/nim-lang/Nim/issues/6710))
- Fixed "Error when using `multisync` macro"
([#6708](https://github.com/nim-lang/Nim/issues/6708))
- Fixed "formatFloat inconsistent scientific notation"
([#6589](https://github.com/nim-lang/Nim/issues/6589))
- Fixed "Using : (constructor arguments) for passing values to functions with default arguments causes a compiler crash."
([#6765](https://github.com/nim-lang/Nim/issues/6765))
- Fixed "In-place object initialization leads to vcc incompatible code"
([#6757](https://github.com/nim-lang/Nim/issues/6757))
- Fixed "Improve parseCookies doc"
([#5721](https://github.com/nim-lang/Nim/issues/5721))
- Fixed "Parser regression with nested do notation inside conditional"
([#6166](https://github.com/nim-lang/Nim/issues/6166))
- Fixed "Request for better error message"
([#6776](https://github.com/nim-lang/Nim/issues/6776))
- Fixed "Testament tester does not execute test with `exitcode` only"
([#6775](https://github.com/nim-lang/Nim/issues/6775))
- Fixed "JS integer division off by one"
([#6753](https://github.com/nim-lang/Nim/issues/6753))
- Fixed "Regression: cannot prove not nil"
([#5781](https://github.com/nim-lang/Nim/issues/5781))
- Fixed "SIGSEGV: Illegal storage access. (Attempt to read from nil?) in generic proc"
([#6073](https://github.com/nim-lang/Nim/issues/6073))
- Fixed "Request for better error message"
([#6776](https://github.com/nim-lang/Nim/issues/6776))
- Fixed "Nim #head: sorting via reference hangs compiler"
([#6724](https://github.com/nim-lang/Nim/issues/6724))
- Fixed "Cannot cast pointer to char in cpp"
([#5979](https://github.com/nim-lang/Nim/issues/5979))
- Fixed "asynchttpserver replies with several errors on single request"
([#6386](https://github.com/nim-lang/Nim/issues/6386))
- Fixed "object variants superclass trigger bad codegen"
([#5521](https://github.com/nim-lang/Nim/issues/5521))
- Fixed "JS integer division off by one"
([#6753](https://github.com/nim-lang/Nim/issues/6753))
- Fixed "js backend compiler crash with tables indexed by certain types"
([#6568](https://github.com/nim-lang/Nim/issues/6568))
- Fixed "Jsgen bug with is"
([#6445](https://github.com/nim-lang/Nim/issues/6445))
- Fixed "Subrange definition with ..<"
([#6788](https://github.com/nim-lang/Nim/issues/6788))
- Fixed "fields not initialized: array with enum index type as object field."
([#6682](https://github.com/nim-lang/Nim/issues/6682))
- Fixed "Can not delete data in table when table's data type is kind of "not nil""
([#6555](https://github.com/nim-lang/Nim/issues/6555))
- Fixed "tables.nim: Cannot prove that 'n' is initialized"
([#6121](https://github.com/nim-lang/Nim/issues/6121))
- Fixed "issues with 'not nil' applied to a closure proc"
([#6489](https://github.com/nim-lang/Nim/issues/6489))
- Fixed "`not nil` not working in some cases"
([#4686](https://github.com/nim-lang/Nim/issues/4686))
- Fixed "Cannot prove '@[v]' is not nil"
([#3993](https://github.com/nim-lang/Nim/issues/3993))
- Fixed "Feature: support TCP_NODELAY in net.sockets"
([#6795](https://github.com/nim-lang/Nim/issues/6795))
- Fixed "Code that makes the compiler throw an error message and then hangs"
([#6820](https://github.com/nim-lang/Nim/issues/6820))
- Fixed "Code that makes the compiler throw an error message and then hangs"
([#6820](https://github.com/nim-lang/Nim/issues/6820))
- Fixed "Inconsistent behavior with sequence and string slicing"
([#6223](https://github.com/nim-lang/Nim/issues/6223))
- Fixed "Wrong behavior of "split" (proc and iterator)"
([#4377](https://github.com/nim-lang/Nim/issues/4377))
- Fixed "[Documentation] Invalid module name: [foo, bar]"
([#6831](https://github.com/nim-lang/Nim/issues/6831))
- Fixed "The destructor is not called for temporary objects"
([#4214](https://github.com/nim-lang/Nim/issues/4214))
- Fixed "Destructors does not work with implicit items iterator in for loop"
([#985](https://github.com/nim-lang/Nim/issues/985))
- Fixed "Error in template when using the type of the parameter inside it"
([#6756](https://github.com/nim-lang/Nim/issues/6756))
- Fixed "should json.to() respect parent attributes?"
([#5856](https://github.com/nim-lang/Nim/issues/5856))
- Fixed "json 'to' macro can not marshalize into tuples"
([#6095](https://github.com/nim-lang/Nim/issues/6095))
- Fixed "json.to fails with seq[T]"
([#6604](https://github.com/nim-lang/Nim/issues/6604))
- Fixed "json.to() is not worth using compared to marshal.to[T]"
([#5848](https://github.com/nim-lang/Nim/issues/5848))
- Fixed "Memory not being released in time, running out of memory"
([#6031](https://github.com/nim-lang/Nim/issues/6031))
- Fixed "[Regression] Bad C codegen for generic code"
([#6889](https://github.com/nim-lang/Nim/issues/6889))
- Fixed "rollingFileLogger deletes file on every start."
([#6264](https://github.com/nim-lang/Nim/issues/6264))
- Fixed "Remove/deprecate securehash module."
([#6033](https://github.com/nim-lang/Nim/issues/6033))
- Fixed "[bug or not] object construction for seq[T] failed without space after colon"
([#5999](https://github.com/nim-lang/Nim/issues/5999))
- Fixed "issues with the random module"
([#4726](https://github.com/nim-lang/Nim/issues/4726))
- Fixed "Reassigning local var to seq of objects results in nil element in Object's seq field"
([#668](https://github.com/nim-lang/Nim/issues/668))
- Fixed "Compilation error with "newseq[string]""
([#6726](https://github.com/nim-lang/Nim/issues/6726))
- Fixed "await inside array/dict literal produces invalid code - Part 2"
([#6626](https://github.com/nim-lang/Nim/issues/6626))
- Fixed "terminal.eraseline() gives OverflowError on Windows"
([#6931](https://github.com/nim-lang/Nim/issues/6931))
- Fixed "[Regression] `sequtils.any` conflicts with `system.any`"
([#6932](https://github.com/nim-lang/Nim/issues/6932))
- Fixed "C++ codegen: `mitems` generates invalid code."
([#4910](https://github.com/nim-lang/Nim/issues/4910))
- Fixed "seq.mitems produces invalid cpp codegen"
([#6892](https://github.com/nim-lang/Nim/issues/6892))
- Fixed "Concepts regression"
([#6108](https://github.com/nim-lang/Nim/issues/6108))
- Fixed "Generic iterable concept with array crashes compiler"
([#6277](https://github.com/nim-lang/Nim/issues/6277))
- Fixed "C code generation "a is a pointer; did you mean to use ->?""
([#6462](https://github.com/nim-lang/Nim/issues/6462))
- Fixed "`--NimblePath` fails if a `-` in path which is not followed by a number"
([#6949](https://github.com/nim-lang/Nim/issues/6949))
- Fixed ""not registered in the selector" in asyncfile.close() for something that clearly was registered"
([#6906](https://github.com/nim-lang/Nim/issues/6906))
- Fixed "strange frexp behavior"
([#6353](https://github.com/nim-lang/Nim/issues/6353))
- Fixed "noreturn branches of case statements shouldn't contribute to type"
([#6885](https://github.com/nim-lang/Nim/issues/6885))
- Fixed "Type inference for 'if' statements changed"
([#6980](https://github.com/nim-lang/Nim/issues/6980))
- Fixed "newest asyncdispatch recursion"
([#6100](https://github.com/nim-lang/Nim/issues/6100))
- Fixed "Ambiguous identifier between set type and proc"
([#6965](https://github.com/nim-lang/Nim/issues/6965))
- Fixed "Inconsistent behavior with sequence and string slicing"
([#6223](https://github.com/nim-lang/Nim/issues/6223))
- Fixed "Unsupported OpenSSL library imported dynamically"
([#5000](https://github.com/nim-lang/Nim/issues/5000))
- Fixed "`nim check` segfaults"
([#6972](https://github.com/nim-lang/Nim/issues/6972))
- Fixed "GC deadlock"
([#6988](https://github.com/nim-lang/Nim/issues/6988))
- Fixed "Create a seq without memory initialization"
([#6401](https://github.com/nim-lang/Nim/issues/6401))
- Fixed "Fix bug for getch on Windows while using the arrow keys"
([#6966](https://github.com/nim-lang/Nim/issues/6966))
- Fixed "runnableExamples doesn't work in templates"
([#7018](https://github.com/nim-lang/Nim/issues/7018))
- Fixed "runnableExamples doesn't work with untyped statement blocks"
([#7019](https://github.com/nim-lang/Nim/issues/7019))
- Fixed "Critical bug in parseBiggestFloat"
([#7060](https://github.com/nim-lang/Nim/issues/7060))
- Fixed "[RFC] strformat.% should be gone"
([#7078](https://github.com/nim-lang/Nim/issues/7078))
- Fixed "compiler crash on simple macro"
([#7093](https://github.com/nim-lang/Nim/issues/7093))
- Fixed "Make newlines sane again"
([#7089](https://github.com/nim-lang/Nim/issues/7089))
- Fixed "JS - Unicode enum string representation issue"
([#6741](https://github.com/nim-lang/Nim/issues/6741))
- Fixed "Strange behaviour of 0.17.3 (working ok in 0.17.2)"
([#6989](https://github.com/nim-lang/Nim/issues/6989))
- Fixed "Strange behaviour of 0.17.3 (working ok in 0.17.2)"
([#6989](https://github.com/nim-lang/Nim/issues/6989))
- Fixed "Compiler crash: try expression with infix as"
([#7116](https://github.com/nim-lang/Nim/issues/7116))
- Fixed "nimsuggest crash"
([#7140](https://github.com/nim-lang/Nim/issues/7140))
- Fixed "[RFC] Reintroduce readChar"
([#7072](https://github.com/nim-lang/Nim/issues/7072))
- Fixed "Copyright line needs updating"
([#7129](https://github.com/nim-lang/Nim/issues/7129))
- Fixed "-0.0 doesn't result in negative zero in VM"
([#7079](https://github.com/nim-lang/Nim/issues/7079))
- Fixed "Windows large filesize"
([#7121](https://github.com/nim-lang/Nim/issues/7121))
- Fixed "Securehash is not parsimonious with MD5 and other hash modules"
([#6961](https://github.com/nim-lang/Nim/issues/6961))
- Fixed "os.findExe() shouldn't look in current directory on posix, unless exe has a /"
([#6939](https://github.com/nim-lang/Nim/issues/6939))
- Fixed "`compiles(...)` with `fatal` pragma causes compiler to exit early"
([#7080](https://github.com/nim-lang/Nim/issues/7080))
- Fixed "NPE when compile macro that returns concrete value"
([#5450](https://github.com/nim-lang/Nim/issues/5450))
- Fixed "Using a variable of type `int | float` causes internal compiler error"
([#6946](https://github.com/nim-lang/Nim/issues/6946))
- Fixed "Unsigned integers could not be used as array indexes."
([#7153](https://github.com/nim-lang/Nim/issues/7153))
- Fixed "countdown with uint causes underflow"
([#4220](https://github.com/nim-lang/Nim/issues/4220))
- Fixed "Inconsistent method call syntax"
([#7200](https://github.com/nim-lang/Nim/issues/7200))
- Fixed "Impossible to create an empty const array"
([#6853](https://github.com/nim-lang/Nim/issues/6853))
- Fixed "Strange UINT handling"
([#3985](https://github.com/nim-lang/Nim/issues/3985))
- Fixed "Bad codegen when passing arg that is part of return value destination"
([#6960](https://github.com/nim-lang/Nim/issues/6960))
- Fixed "No info about gcsafety in error message when global var is accessed in async proc"
([#6186](https://github.com/nim-lang/Nim/issues/6186))
- Fixed "Resolving package vs. local import ambiguities"
([#2819](https://github.com/nim-lang/Nim/issues/2819))
- Fixed "Internal error with type() operator"
([#3711](https://github.com/nim-lang/Nim/issues/3711))
- Fixed "newAsyncSocket should raise an OS error plus other inconsistencies"
([#4995](https://github.com/nim-lang/Nim/issues/4995))
- Fixed "mapLiterals fails with negative values"
([#7215](https://github.com/nim-lang/Nim/issues/7215))
- Fixed "fmWrite doesn't truncate file with openAsync, unlike open()"
([#5531](https://github.com/nim-lang/Nim/issues/5531))
- Fixed "Move libsvm to an external nimble module"
([#5786](https://github.com/nim-lang/Nim/issues/5786))
- Fixed "Prevent acceptAddr gotcha with newSocket"
([#7227](https://github.com/nim-lang/Nim/issues/7227))
- Fixed "strtabs.getOrDefault is inconsistent with tables.getOrDefault"
([#4265](https://github.com/nim-lang/Nim/issues/4265))
- Fixed "Code falling through into exception handler when no exception thrown."
([#7232](https://github.com/nim-lang/Nim/issues/7232))
- Fixed "the new generic inference rules are broken"
([#7247](https://github.com/nim-lang/Nim/issues/7247))
- Fixed "Odd `..<` regression"
([#6992](https://github.com/nim-lang/Nim/issues/6992))
- Fixed "Different proc type inferred from default parameter"
([#4659](https://github.com/nim-lang/Nim/issues/4659))
- Fixed "Different proc type inferred from default parameter"
([#4659](https://github.com/nim-lang/Nim/issues/4659))
- Fixed "Testament sometimes ignores test failures"
([#7236](https://github.com/nim-lang/Nim/issues/7236))
- Fixed "New Allocator Fails On >=4GB Requests"
([#7120](https://github.com/nim-lang/Nim/issues/7120))
- Fixed "User pragmas hide effect specifications from sempass2"
([#7216](https://github.com/nim-lang/Nim/issues/7216))
- Fixed "C++: SIGABRT instead of IndexError for out-of-bounds"
([#6512](https://github.com/nim-lang/Nim/issues/6512))
- Fixed "An uncaught exception in cpp mode doesn't show the exception name/msg"
([#6431](https://github.com/nim-lang/Nim/issues/6431))

View File

@@ -0,0 +1,253 @@
## v0.19.X - XX/XX/2018
### Changes affecting backwards compatibility
- The stdlib module ``future`` has been renamed to ``sugar``.
- ``macros.callsite`` is now deprecated. Since the introduction of ``varargs``
parameters this became unnecessary.
- Anonymous tuples with a single element can now be written as ``(1,)`` with a
trailing comma. The underlying AST is ``nnkTupleConstr(newLit 1)`` for this
example. ``nnkTupleConstr`` is a new node kind your macros need to be able
to deal with!
- Indexing into a ``cstring`` for the JS target is now mapped
to ``charCodeAt``.
- Assignments that would "slice" an object into its supertype are now prevented
at runtime. Use ``ref object`` with inheritance rather than ``object`` with
inheritance to prevent this issue.
- The ``not nil`` type annotation now has to be enabled explicitly
via ``{.experimental: "notnil"}`` as we are still not pleased with how this
feature works with Nim's containers.
- The parser now warns about inconsistent spacing around binary operators as
these can easily be confused with unary operators. This warning will likely
become an error in the future.
- The ``'c`` and ``'C'`` suffix for octal literals is now deprecated to
bring the language in line with the standard library (e.g. ``parseOct``).
- The dot style for import paths (e.g ``import path.to.module`` instead of
``import path/to/module``) has been deprecated.
#### Breaking changes in the standard library
- ``re.split`` for empty regular expressions now yields every character in
the string which is what other programming languages chose to do.
- The returned tuple of ``system.instantiationInfo`` now has a third field
containing the column of the instantiation.
- ``cookies.setCookie`` no longer assumes UTC for the expiration date.
- ``strutils.formatEng`` does not distinguish between ``nil`` and ``""``
strings anymore for its ``unit`` parameter. Instead the space is controlled
by a new parameter ``useUnitSpace``.
- The ``times.parse`` and ``times.format`` procs have been rewritten.
The proc signatures are the same so it should generally not break anything.
However, the new implementation is a bit stricter, which is a breaking change.
For example ``parse("2017-01-01 foo", "yyyy-MM-dd")`` will now raise an error.
- ``proc `-`*(a, b: Time): int64`` in the ``times`` module has changed return type
to ``times.Duration`` in order to support higher time resolutions.
The proc is no longer deprecated.
- The ``times.Timezone`` is now an immutable ref-type that must be initialized
with an explicit constructor (``newTimezone``).
- ``posix.Timeval.tv_sec`` has changed type to ``posix.Time``.
- ``math.`mod` `` for floats now behaves the same as ``mod`` for integers
(previously it used floor division like Python). Use ``math.floorMod`` for the old behavior.
- For string inputs, ``unicode.isUpper`` and ``unicode.isLower`` now require a
second mandatory parameter ``skipNonAlpha``.
- For string inputs, ``strutils.isUpperAscii`` and ``strutils.isLowerAscii`` now
require a second mandatory parameter ``skipNonAlpha``.
- ``osLastError`` is now marked with ``sideEffect``
- The procs ``parseHexInt`` and ``parseOctInt`` now fail on empty strings
and strings containing only valid prefixes, e.g. "0x" for hex integers.
- ``terminal.setCursorPos`` and ``terminal.setCursorXPos`` now work correctly
with 0-based coordinates on POSIX (previously, you needed to use
1-based coordinates on POSIX for correct behaviour; the Windows behaviour
was always correct).
- ``lineInfoObj`` now returns absolute path instead of project path.
It's used by ``lineInfo``, ``check``, ``expect``, ``require``, etc.
- ``net.sendTo`` no longer returns an int and now raises an ``OSError``.
- `threadpool`'s `await` and derivatives have been renamed to `blockUntil`
to avoid confusions with `await` from the `async` macro.
#### Breaking changes in the compiler
- The undocumented ``#? braces`` parsing mode was removed.
- The undocumented PHP backend was removed.
- The default location of ``nimcache`` for the native code targets was
changed. Read [the compiler user guide](https://nim-lang.org/docs/nimc.html#generated-c-code-directory)
for more information.
### Library additions
- ``re.split`` now also supports the ``maxsplit`` parameter for consistency
with ``strutils.split``.
- Added ``system.toOpenArray`` in order to support zero-copy slicing
operations. This is currently not yet available for the JavaScript target.
- Added ``getCurrentDir``, ``findExe``, ``cpDir`` and ``mvDir`` procs to
``nimscript``.
- The ``times`` module now supports up to nanosecond time resolution when available.
- Added the type ``times.Duration`` for representing fixed durations of time.
- Added the proc ``times.convert`` for converting between different time units,
e.g days to seconds.
- Added the proc ``algorithm.binarySearch[T, K]`` with the ```cmp``` parameter.
- Added the proc ``algorithm.upperBound``.
- Added inverse hyperbolic functions, ``math.arcsinh``, ``math.arccosh`` and ``math.arctanh`` procs.
- Added cotangent, secant and cosecant procs ``math.cot``, ``math.sec`` and ``math.csc``; and their hyperbolic, inverse and inverse hyperbolic functions, ``math.coth``, ``math.sech``, ``math.csch``, ``math.arccot``, ``math.arcsec``, ``math.arccsc``, ``math.arccoth``, ``math.arcsech`` and ``math.arccsch`` procs.
- Added the procs ``math.floorMod`` and ``math.floorDiv`` for floor based integer division.
- Added the procs ``rationals.`div```, ``rationals.`mod```, ``rationals.floorDiv`` and ``rationals.floorMod`` for rationals.
- Added the proc ``math.prod`` for product of elements in openArray.
- Added the proc ``parseBinInt`` to parse a binary integer from a string, which returns the value.
- ``parseOct`` and ``parseBin`` in parseutils now also support the ``maxLen`` argument similar to ``parseHexInt``.
- Added the proc ``flush`` for memory mapped files.
- Added the ``MemMapFileStream``.
- Added a simple interpreting event parser template ``eventParser`` to the ``pegs`` module.
- Added ``macros.copyLineInfo`` to copy lineInfo from other node.
- Added ``system.ashr`` an arithmetic right shift for integers.
### Library changes
- ``macros.astGenRepr``, ``macros.lispRepr`` and ``macros.treeRepr``
now escapes the content of string literals consistently.
- ``macros.NimSym`` and ``macros.NimIdent`` is now deprecated in favor
of the more general ``NimNode``.
- ``macros.getImpl`` now includes the pragmas of types, instead of omitting them.
- ``macros.hasCustomPragma`` and ``macros.getCustomPragmaVal`` now
also support ``ref`` and ``ptr`` types, pragmas on types and variant
fields.
- ``system.SomeReal`` is now called ``SomeFloat`` for consistency and
correctness.
- ``algorithm.smartBinarySearch`` and ``algorithm.binarySearch`` is
now joined in ``binarySearch``. ``smartbinarySearch`` is now
deprecated.
- The `terminal` module now exports additional procs for generating ANSI color
codes as strings.
- Added the parameter ``val`` for the ``CritBitTree[int].inc`` proc.
- An exception raised from a ``test`` block of ``unittest`` now shows its type in
error message.
- The ``compiler/nimeval`` API was rewritten to simplify the "compiler as an
API". Using the Nim compiler and its VM as a scripting engine has never been
easier. See ``tests/compilerapi/tcompilerapi.nim`` for an example of how to
use the Nim VM in a native Nim application.
- Added the parameter ``val`` for the ``CritBitTree[T].incl`` proc.
- The proc ``tgamma`` was renamed to ``gamma``. ``tgamma`` is deprecated.
- The ``pegs`` module now exports getters for the fields of its ``Peg`` and ``NonTerminal``
object types. ``Peg``s with child nodes now have the standard ``items`` and ``pairs``
iterators.
- The ``accept`` socket procedure defined in the ``net`` module can now accept
a nil socket.
### Language additions
- Dot calls combined with explicit generic instantiations can now be written
as ``x.y[:z]`` which is transformed into ``y[z](x)`` by the parser.
- ``func`` is now an alias for ``proc {.noSideEffect.}``.
- In order to make ``for`` loops and iterators more flexible to use Nim now
supports so called "for-loop macros". See
the [manual](manual.html#macros-for-loop-macros) for more details.
This feature enables a Python-like generic ``enumerate`` implementation.
- Case statements can now be rewritten via macros. See the [manual](manual.html#macros-case-statement-macros) for more information.
This feature enables custom pattern matchers.
- the `typedesc` special type has been renamed to just `type`.
- `static` and `type` are now also modifiers similar to `ref` and `ptr`.
They denote the special types `static[T]` and `type[T]`.
- Forcing compile-time evaluation with `static` now supports specifying
the desired target type (as a concrete type or as a type class)
- The `type` operator now supports checking that the supplied expression
matches an expected type constraint.
### Language changes
- The `importcpp` pragma now allows importing the listed fields of generic
C++ types. Support for numeric parameters have also been added through
the use of `static[T]` types.
(#6415)
- Native C++ exceptions can now be imported with `importcpp` pragma.
Imported exceptions can be raised and caught just like Nim exceptions.
More details in language manual.
- ``nil`` for strings/seqs is finally gone. Instead the default value for
these is ``"" / @[]``. Use ``--nilseqs:on`` for a transition period.
- Accessing the binary zero terminator in Nim's native strings
is now invalid. Internally a Nim string still has the trailing zero for
zero-copy interoperability with ``cstring``. Compile your code with the
new switch ``--laxStrings:on`` if you need a transition period.
- The command syntax now supports keyword arguments after the first comma.
- Thread-local variables can now be declared inside procs. This implies all
the effects of the ``global`` pragma.
- Nim now supports the ``except`` clause in the export statement.
- Range float types, example ``range[0.0 .. Inf]``. More details in language manual.
- The ``{.this.}`` pragma has been deprecated. It never worked within generics and
we found the resulting code harder to read than the more explicit ``obj.field``
syntax.
- "Memory regions" for pointer types have been deprecated, they were hardly used
anywhere. Note that this has **nothing** to do with the ``--gc:regions`` switch
of managing memory.
- The exception hierarchy was slightly reworked, ``SystemError`` was renamed to
``CatchableError`` and is the new base class for any exception that is guaranteed to
be catchable. This change should have minimal impact on most existing Nim code.
### Tool changes
- ``jsondoc2`` has been renamed ``jsondoc``, similar to how ``doc2`` was renamed
``doc``. The old ``jsondoc`` can still be invoked with ``jsondoc0``.
### Compiler changes
- The VM's instruction count limit was raised to 3 million instructions in
order to support more complex computations at compile-time.
- Support for hot code reloading has been implemented for the JavaScript
target. To use it, compile your code with `--hotCodeReloading:on` and use a
helper library such as LiveReload or BrowserSync.
- A new compiler option `--cppCompileToNamespace` puts the generated C++ code
into the namespace "Nim" in order to avoid naming conflicts with existing
C++ code. This is done for all Nim code - internal and exported.
- Added ``macros.getProjectPath`` and ``os.putEnv`` procs to Nim's virtual
machine.
- The ``deadCodeElim`` option is now always turned on and the switch has no
effect anymore, but is recognized for backwards compatibility.
- ``experimental`` is now a pragma / command line switch that can enable specific
language extensions, it is not an all-or-nothing switch anymore.
- Nintendo Switch was added as a new platform target. See [the compiler user guide](https://nim-lang.org/docs/nimc.html)
for more info.
- macros.bindSym now capable to accepts not only literal string or string constant expression.
bindSym enhancement make it also can accepts computed string or ident node inside macros /
compile time functions / static blocks. Only in templates / regular code it retains it's old behavior.
This new feature can be accessed via {.experimental: "dynamicBindSym".} pragma/switch.
- On Posix systems the global system wide configuration is now put under ``/etc/nim/nim.cfg``,
it used to be ``/etc/nim.cfg``. Usually it does not exist, however.
- On Posix systems the user configuration is now looked under ``$XDG_CONFIG_HOME/nim/nim.cfg``
(if ``XDG_CONFIG_HOME`` is not defined, then under ``~/.config/nim/nim.cfg``). It used to be
``$XDG_CONFIG_DIR/nim.cfg`` (and ``~/.config/nim.cfg``).
Similarly, on Windows, the user configuration is now looked under ``%APPDATA%/nim/nim.cfg``.
This used to be ``%APPDATA%/nim.cfg``.
### Bugfixes

View File

@@ -0,0 +1,294 @@
## v0.20.0 - 2019-06-06
### Changes affecting backwards compatibility
- `shr` is now sign preserving. Use `-d:nimOldShiftRight` to enable
the old behavior globally.
- The ``isLower``, ``isUpper`` family of procs in strutils/unicode
operating on **strings** have been
deprecated since it was unclear what these do. Note that the much more
useful procs that operate on ``char`` or ``Rune`` are not affected.
- `strutils.editDistance` has been deprecated,
use `editdistance.editDistance` or `editdistance.editDistanceAscii`
instead.
- The OpenMP parallel iterator \``||`\` now supports any `#pragma omp directive`
and not just `#pragma omp parallel for`. See
[OpenMP documentation](https://www.openmp.org/wp-content/uploads/OpenMP-4.5-1115-CPP-web.pdf).
The default annotation is `parallel for`, if you used OpenMP without annotation
the change is transparent, if you used annotations you will have to prefix
your previous annotations with `parallel for`.
Furthermore, an overload with positive stepping is available.
- The `unchecked` pragma was removed, instead use `system.UncheckedArray`.
- The undocumented ``#? strongSpaces`` parsing mode has been removed.
- The `not` operator is now always a unary operator, this means that code like
``assert not isFalse(3)`` compiles.
- `getImpl` on a `var` or `let` symbol will now return the full `IdentDefs`
tree from the symbol declaration instead of just the initializer portion.
- Methods are now ordinary "single" methods, only the first parameter is
used to select the variant at runtime. For backwards compatibility
use the new `--multimethods:on` switch.
- Generic methods are now deprecated; they never worked well.
- Compile time checks for integer and float conversions are now stricter.
For example, `const x = uint32(-1)` now gives a compile time error instead
of being equivalent to `const x = 0xFFFFFFFF'u32`.
- Using `typed` as the result type in templates/macros now means
"expression with a type". The old meaning of `typed` is preserved
as `void` or no result type at all.
- A bug allowed `macro foo(): int = 123` to compile even though a
macro has to return a `NimNode`. This has been fixed.
- With the exception of `uint` and `uint64`, conversion to unsigned types
are now range checked during runtime.
- Macro arguments of type `typedesc` are now passed to the macro as
`NimNode` like every other type except `static`. Use `typed` for a
behavior that is identical in new and old
Nim. See the RFC [Pass typedesc as NimNode to macros](https://github.com/nim-lang/RFCs/issues/148)
for more details.
#### Breaking changes in the standard library
- `osproc.execProcess` now also takes a `workingDir` parameter.
- `std/sha1.secureHash` now accepts `openArray[char]`, not `string`. (Former
successful matches should keep working, though former failures will not.)
- `options.UnpackError` is no longer a ref type and inherits from `system.Defect`
instead of `system.ValueError`.
- `system.ValueError` now inherits from `system.CatchableError` instead of `system.Defect`.
- The procs `parseutils.parseBiggestInt`, `parseutils.parseInt`,
`parseutils.parseBiggestUInt` and `parseutils.parseUInt` now raise a
`ValueError` when the parsed integer is outside of the valid range.
Previously they sometimes raised an `OverflowError` and sometimes they
returned `0`.
- The procs `parseutils.parseBin`, `parseutils.parseOct` and `parseutils.parseHex`
were not clearing their `var` parameter `number` and used to push its value to
the left when storing the parsed string into it. Now they always set the value
of the parameter to `0` before storing the result of the parsing, unless the
string to parse is not valid (then the value of `number` is not changed).
- `streams.StreamObject` now restricts its fields to only raise `system.Defect`,
`system.IOError` and `system.OSError`.
This change only affects custom stream implementations.
- nre's `RegexMatch.{captureBounds,captures}[]` no longer return `Option` or
`nil`/`""`, respectively. Use the newly added `n in p.captures` method to
check if a group is captured, otherwise you'll receive an exception.
- nre's `RegexMatch.{captureBounds,captures}.toTable` no longer accept a
default parameter. Instead uncaptured entries are left empty. Use
`Table.getOrDefault()` if you need defaults.
- nre's `RegexMatch.captures.{items,toSeq}` now returns an `Option[string]`
instead of a `string`. With the removal of `nil` strings, this is the only
way to indicate a missing match. Inside your loops, instead
of `capture == ""` or `capture == nil`, use `capture.isSome` to check if a capture is
present, and `capture.get` to get its value.
- nre's `replace()` no longer throws `ValueError` when the replacement string
has missing captures. It instead throws `KeyError` for named captures, and
`IndexError` for unnamed captures. This is consistent with
`RegexMatch.{captureBounds,captures}[]`.
- `splitFile` now correctly handles edge cases, see #10047.
- `isNil` is no longer false for undefined in the JavaScript backend:
now it's true for both nil and undefined.
Use `isNull` or `isUndefined` if you need exact equality:
`isNil` is consistent with `===`, `isNull` and `isUndefined` with `==`.
- several deprecated modules were removed: `ssl`, `matchers`, `httpserver`,
`unsigned`, `actors`, `parseurl`
- two poorly documented and not used modules (`subexes`, `scgi`) were moved to
graveyard (they are available as Nimble packages)
- procs `string.add(int)` and `string.add(float)` which implicitly convert
ints and floats to string have been deprecated.
Use `string.addInt(int)` and `string.addFloat(float)` instead.
- ``case object`` branch transitions via ``system.reset`` are deprecated.
Compile your code with ``-d:nimOldCaseObjects`` for a transition period.
- base64 module: The default parameter `newLine` for the `encode` procs
was changed from `"\13\10"` to the empty string `""`.
#### Breaking changes in the compiler
- The compiler now implements the "generic symbol prepass" for `when` statements
in generics, see bug #8603. This means that code like this does not compile
anymore:
```nim
proc enumToString*(enums: openArray[enum]): string =
# typo: 'e' instead 'enums'
when e.low.ord >= 0 and e.high.ord < 256:
result = newString(enums.len)
else:
result = newString(enums.len * 2)
```
- ``discard x`` is now illegal when `x` is a function symbol.
- Implicit imports via ``--import: module`` in a config file are now restricted
to the main package.
### Library additions
- There is a new stdlib module `std/editdistance` as a replacement for the
deprecated `strutils.editDistance`.
- There is a new stdlib module `std/wordwrap` as a replacement for the
deprecated `strutils.wordwrap`.
- Added `split`, `splitWhitespace`, `size`, `alignLeft`, `align`,
`strip`, `repeat` procs and iterators to `unicode.nim`.
- Added `or` for `NimNode` in `macros`.
- Added `system.typeof` for more control over how `type` expressions
can be deduced.
- Added `macros.isInstantiationOf` for checking if the proc symbol
is instantiation of generic proc symbol.
- Added the parameter ``isSorted`` for the ``sequtils.deduplicate`` proc.
- There is a new stdlib module `std/diff` to compute the famous "diff"
of two texts by line.
- Added `os.relativePath`.
- Added `parseopt.remainingArgs`.
- Added `os.getCurrentCompilerExe` (implemented as `getAppFilename` at CT),
can be used to retrieve the currently executing compiler.
- Added `xmltree.toXmlAttributes`.
- Added ``std/sums`` module for fast summation functions.
- Added `Rusage`, `getrusage`, `wait4` to the posix interface.
- Added the `posix_utils` module.
- Added `system.default`.
- Added `sequtils.items` for closure iterators, allows closure iterators
to be used by the `mapIt`, `filterIt`, `allIt`, `anyIt`, etc.
### Library changes
- The string output of `macros.lispRepr` proc has been tweaked
slightly. The `dumpLisp` macro in this module now outputs an
indented proper Lisp, devoid of commas.
- Added `macros.signatureHash` that returns a stable identifier
derived from the signature of a symbol.
- In `strutils` empty strings now no longer matched as substrings
anymore.
- The `Complex` type is now a generic object and not a tuple anymore.
- The `ospaths` module is now deprecated, use `os` instead. Note that
`os` is available in a NimScript environment but unsupported
operations produce a compile-time error.
- The `parseopt` module now supports a new flag `allowWhitespaceAfterColon`
(default value: true) that can be set to `false` for better Posix
interoperability. (Bug #9619.)
- `os.joinPath` and `os.normalizePath` handle edge cases like ``"a/b/../../.."``
differently.
- `securehash` was moved to `lib/deprecated`.
- The switch ``-d:useWinAnsi`` is not supported anymore.
- In `times` module, procs `format` and `parse` accept a new optional
`DateTimeLocale` argument for formatting/parsing dates in other languages.
### Language additions
- Vm support for float32<->int32 and float64<->int64 casts was added.
- There is a new pragma block `noSideEffect` that works like
the `gcsafe` pragma block.
- added `os.getCurrentProcessId`.
- User defined pragmas are now allowed in the pragma blocks.
- Pragma blocks are no longer eliminated from the typed AST tree to preserve
pragmas for further analysis by macros.
- Custom pragmas are now supported for `var` and `let` symbols.
- Tuple unpacking is now supported for constants and for loop variables.
- Case object branches can be initialized with a runtime discriminator if
possible discriminator values are constrained within a case statement.
### Language changes
- The standard extension for SCF (source code filters) files was changed from
``.tmpl`` to ``.nimf``,
it's more recognizable and allows tools like Github to recognize it as Nim,
see [#9647](https://github.com/nim-lang/Nim/issues/9647).
The previous extension will continue to work.
- Pragma syntax is now consistent. Previous syntax where type pragmas did not
follow the type name is now deprecated. Also pragma before generic parameter
list is deprecated to be consistent with how pragmas are used with a proc. See
[#8514](https://github.com/nim-lang/Nim/issues/8514) and
[#1872](https://github.com/nim-lang/Nim/issues/1872) for further details.
- Hash sets and tables are initialized by default. The explicit `initHashSet`,
`initTable`, etc. are not needed anymore.
### Tool changes
- `jsondoc` now includes a `moduleDescription` field with the module
description. `jsondoc0` shows comments as its own objects as shown in the
documentation.
- `nimpretty`: --backup now defaults to `off` instead of `on` and the flag was
undocumented; use `git` instead of relying on backup files.
- `koch` now defaults to build the latest *stable* Nimble version unless you
explicitly ask for the latest master version via `--latest`.
### Compiler changes
- The deprecated `fmod` proc is now unavailable on the VM.
- A new `--outdir` option was added.
- The compiled JavaScript file for the project produced by executing `nim js`
will no longer be placed in the nimcache directory.
- The `--hotCodeReloading` has been implemented for the native targets.
The compiler also provides a new more flexible API for handling the
hot code reloading events in the code.
- The compiler now supports a ``--expandMacro:macroNameHere`` switch
for easy introspection into what a macro expands into.
- The `-d:release` switch now does not disable runtime checks anymore.
For a release build that also disables runtime checks
use `-d:release -d:danger` or simply `-d:danger`.
### Bugfixes

View File

@@ -0,0 +1,55 @@
# v0.20.2 - 2019-07-17
## Changes affecting backwards compatibility
- All `strutils.rfind` procs now take `start` and `last` like `strutils.find`
with the same data slice/index meaning. This is backwards compatible for
calls *not* changing the `rfind` `start` parameter from its default. (#11487)
In the unlikely case that you were using `rfind X, start=N`, or `rfind X, N`,
then you need to change that to `rfind X, last=N` or `rfind X, 0, N`. (This
should minimize gotchas porting code from other languages like Python or C++.)
- On Windows stderr/stdout/stdin are not opened as binary files anymore. Use the switch
`-d:nimBinaryStdFiles` for a transition period.
### Breaking changes in the standard library
- Mac OS X / BSD: TSa_Family is now the ``uint8`` type, so type
conversions like ``x.sin_family = uint16 toInt(nativesockets.AF_INET)``
need to be changed into ``x.sin_family = TSa_Family toInt(nativesockets.AF_INET)``.
### Breaking changes in the compiler
## Library additions
- `toOpenArray` is now available for the JS target.
## Library changes
- Fix async IO operations stalling even after socket is closed. (#11232)
- More informative error message for `streams.openFileStream`. (#11438)
## Language additions
## Language changes
### Tool changes
### Compiler changes
- Better error message for IndexError for empty containers. (#11476)
- Fix regression in semfold for old right shift. (#11477)
- Fix for passing tuples as static params to macros. (#11423)
## Bugfixes

View File

@@ -0,0 +1,138 @@
# v1.0 - 2019-09-23
## Changes affecting backwards compatibility
- The switch ``-d:nimBinaryStdFiles`` does not exist anymore. Instead
stdin/stdout/stderr are binary files again. This change only affects
Windows.
- On Windows console applications the code-page is set at program startup
to UTF-8. Use the new switch `-d:nimDontSetUtf8CodePage` to disable this
feature.
- The language definition and compiler are now stricter about ``gensym``'ed
symbols in hygienic templates. See the section in the
[manual](https://nim-lang.org/docs/manual.html#templates-hygiene-in-templates)
for further details. Use the compiler switch `--oldgensym:on` for a
transition period.
### Breaking changes in the standard library
- We removed `unicode.Rune16` without any deprecation period as the name
was wrong (see the [RFC](https://github.com/nim-lang/RFCs/issues/151) for details)
and we didn't find any usages of it in the wild. If you still need it, add this
piece of code to your project:
```nim
type
Rune16* = distinct int16
```
- `exportc` now uses C instead of C++ mangling with `nim cpp`, matching behavior
of `importc`, see #10578.
Use the new `exportcpp` to mangle as C++ when using `nim cpp`.
### Breaking changes in the compiler
- A bug allowing `int` to be implicitly converted to range types of smaller size
(e.g `range[0'i8..10'i8]`) has been fixed.
## Library additions
- `encodings.getCurrentEncoding` now distinguishes between the console's
encoding and the OS's encoding. This distinction is only meaningful on
Windows.
- Added `system.getOsFileHandle` which is usually more useful
than `system.getFileHandle`. This distinction is only meaningful on
Windows.
- Added a `json.parseJsonFragments` iterator that can be used to speedup
JSON processing substantially when there are JSON fragments separated
by whitespace.
## Library changes
- Added `os.delEnv` and `nimscript.delEnv`. (#11466)
- Enabled Oid usage in hashtables. (#11472)
- Added `unsafeColumnAt` procs, that return unsafe cstring from InstantRow. (#11647)
- Make public `Sha1Digest` and `Sha1State` types and `newSha1State`,
`update` and `finalize` procedures from `sha1` module. (#11694)
- Added the `std/monotimes` module which implements monotonic timestamps.
- Consistent error handling of two `exec` overloads. (#10967)
- Officially the following modules now have an unstable API:
- std/varints
- core/allocators
- core/hotcodereloading
- asyncstreams
- base64
- browsers
- collections/rtarrays
- collections/sharedlist
- collections/sharedtable
- concurrency/atomics
- concurrency/cpuload
- concurrency/threadpool
- coro
- endians
- httpcore
- parsesql
- pathnorm
- reservedmem
- typetraits
Every other stdlib module is API stable with respect to version 1.
## Language additions
- Inline iterators returning `lent T` types are now supported, similarly to
iterators returning `var T`:
```nim
iterator myitems[T](x: openarray[T]): lent T
iterator mypairs[T](x: openarray[T]): tuple[idx: int, val: lent T]
```
- Added an `importjs` pragma that can now be used instead of `importcpp`
and `importc` to import symbols from JavaScript. `importjs` for routines always
takes a "pattern" for maximum flexibility.
## Language changes
- `uint64` is now finally a regular ordinal type. This means `high(uint64)` compiles
and yields the correct value.
### Tool changes
- The Nim compiler now does not recompile the Nim project via ``nim c -r`` if
no dependent Nim file changed. This feature can be overridden by
the ``--forceBuild`` command line option.
- The Nim compiler now warns about unused module imports. You can use a
top level ``{.used.}`` pragma in the module that you want to be importable
without producing this warning.
- The "testament" testing tool's name was changed
from `tester` to `testament` and is generally available as a tool to run Nim
tests automatically.
### Compiler changes
- VM can now cast integer type arbitrarily. (#11459)
## Bugfixes

View File

@@ -0,0 +1,56 @@
# v1.0.2 - 2019-10-23
## Bugfixes
* fixes the --verbosity:2 regression
* Fixed "Fail to compile a file twice under Windows (v1.0 bug)." [#12242](https://github.com/nim-lang/Nim/issues/12242)
* fix nimpretty removing space before pragma
* JS: gensym is stricter for 'this'
* Fixed "VM Assertion Error with newruntime" [#12294](https://github.com/nim-lang/Nim/issues/12294)
* Fixed "Assertion error when running `nim check` on compiler/nim.nim" [#12281](https://github.com/nim-lang/Nim/issues/12281)
* Fixed "Compiler crash with empty array and generic instantiation with int as parameter" [#12264](https://github.com/nim-lang/Nim/issues/12264)
* Fixed "Regression in JS backend codegen "Error: request to generate code for .compileTime proc"" [#12240](https://github.com/nim-lang/Nim/issues/12240)
* Fix how `relativePath` handle case sensitiviy
* Fixed "SIGSEGV in compiler when using generic types and seqs" [#12336](https://github.com/nim-lang/Nim/issues/12336)
* Fixed "[1.0.0] weird interaction between `import os` and casting integer to char on macosx trigger bad codegen" [#12291](https://github.com/nim-lang/Nim/issues/12291)
* VM: no special casing for big endian machines
* Fixed "`internal error: environment misses` with a simple template inside one of Jester macros" [#12323](https://github.com/nim-lang/Nim/issues/12323)
* nimsuggest: fix tcp socket leak
* nimsuggest: fix tcp socket leak for epc backend
* Fixed "`writeFile` and `write(f, str)` skip null bytes on Windows" [#12315](https://github.com/nim-lang/Nim/issues/12315)
* Fixed "Crash in intsets symmetric_difference" [#12366](https://github.com/nim-lang/Nim/issues/12366)
* Fixed "[regression] VM crash when dealing with var param of a proc result" [#12244](https://github.com/nim-lang/Nim/issues/12244)
* fixes a koch regression that made 'koch boot --listcmd' not work anymore
* Fixed "[regression] inconsistent signed int `mod` operator between runtime, compiletime, and semfold" [#12332](https://github.com/nim-lang/Nim/issues/12332)
* Fixed "Boehm disables interior pointer checking" [#12286](https://github.com/nim-lang/Nim/issues/12286)
* Fixes semCustomPragma when nkSym
* Fixed yield in nkCheckedFieldExpr
* Fixed "`randomize()` from `random` not working on JS" [#12418](https://github.com/nim-lang/Nim/issues/12418)
* Fixed "Compiler crash with invalid object variant" [#12379](https://github.com/nim-lang/Nim/issues/12379)
* fix type's case in random.nim
* Fixed "Update docs with a better way to signal unimplemented methods" [#10804](https://github.com/nim-lang/Nim/issues/10804)
* Fixed "Nim language manual, push pragma is not explained well" [#10824](https://github.com/nim-lang/Nim/issues/10824)
* Fixed "[regression] Importing more than one module with same name from different packages produce bad codegen" [#12420](https://github.com/nim-lang/Nim/issues/12420)
* Namespace unittest enums to avoid name conflicts
* Fixed "VM checks unsigned integers for overflow." [#12310](https://github.com/nim-lang/Nim/issues/12310)
* Fixed "line directive is not generated for first line of function definition" [#12426](https://github.com/nim-lang/Nim/issues/12426)
## Documentation improvements
* threadpool: fix link in docs (#12258)
* Fix spellings (#12277)
* fix #12278, don't expose internal PCRE documentation
* Fixed "Documentation of quitprocs is wrong" [#12279(https://github.com/nim-lang/Nim/issues/12279)
* Fix typo in docs
* Fix reference to parseSpec proc in readme
* [doc/tut1] removed discard discussion in comments
* Documentation improvements around the db interface
* Easier build instructions for windows - just run `build_all.bat`.
* fix a few dead links and a missing sentence in documentation
* Macro docs additions
* Updated the code example in the os module to use better grammar.
* Mention "lambdas" and `=>` in the manual
* Better documentation on Garbage Collector

View File

@@ -0,0 +1,532 @@
# v1.2.0 - 2020-04-02
## Standard library additions and changes
- Added overloaded `strformat.fmt` macro that use specified characters as
delimiter instead of '{' and '}'.
- Added new procs in `tables.nim`: `OrderedTable.pop`, `CountTable.del`,
`CountTable.pop`, `Table.pop`.
- Added `strtabs.clear` overload that reuses the existing mode.
- Added `browsers.osOpen` const alias for the operating system specific *"open"* command.
- Added `sugar.dup` for turning in-place algorithms like `sort` and `shuffle`
into operations that work on a copy of the data and return the mutated copy,
like the existing `sorted` does.
- Added `sugar.collect` that does comprehension for seq/set/table collections.
- Added `sugar.capture` for capturing some local loop variables when creating a
closure. This is an enhanced version of `closureScope`.
- Added `typetraits.tupleLen` to get number of elements of a tuple/type tuple,
and `typetraits.get` to get the ith element of a type tuple.
- Added `typetraits.genericParams` to return a tuple of generic params from a
generic instantiation.
- `options` now treats `proc` like other pointer types, meaning `nil` proc variables
are converted to `None`.
- Added `os.normalizePathEnd` for additional path sanitization.
- Added `times.fromUnixFloat,toUnixFloat`, sub-second resolution versions of
`fromUnix`,`toUnixFloat`.
- Added `wrapnils` module for chains of field-access and indexing where the LHS
can be nil. This simplifies code by reducing need for if-else branches around
intermediate maybe nil values. E.g. `echo ?.n.typ.kind`.
- Added `minIndex`, `maxIndex` and `unzip` to the `sequtils` module.
- Added `os.isRelativeTo` to tell whether a path is relative to another.
- Added `resetOutputFormatters` to `unittest`.
- Added `expectIdent` to the `macros` module.
- Added `os.isValidFilename` that returns `true` if `filename` argument is valid
for cross-platform use.
- Added `times.isLeapDay`
- `base64` adds URL-Safe Base64, implements RFC-4648 Section-7.
- Added a new module, `std / compilesettings` for querying the compiler about
diverse configuration settings.
- Added `net.getPeerCertificates` and `asyncnet.getPeerCertificates` for
retrieving the verified certificate chain of the peer we are connected to
through an SSL-wrapped `Socket`/`AsyncSocket`.
- Added `browsers.openDefaultBrowser` without URL, implements IETF RFC-6694 Section-3.
- Added `jsconsole.trace`, `jsconsole.table`, `jsconsole.exception` for JavaScript target.
- Added `distinctBase` overload for values: `assert 12.MyInt.distinctBase == 12`
- Added new module `std/stackframes`, in particular `setFrameMsg`, which enables
custom runtime annotation of stackframes, see #13351 for examples.
Turn on/off via `--stackTraceMsgs:on/off`.
- Added `sequtils.countIt`, allowing for counting items using a predicate.
- Added a `with` macro for easy function chaining that's available everywhere,
there is no need to concern your APIs with returning the first argument
to enable "chaining", instead use the dedicated macro `with` that
was designed for it. For example:
```nim
type
Foo = object
col, pos: string
proc setColor(f: var Foo; r, g, b: int) = f.col = $(r, g, b)
proc setPosition(f: var Foo; x, y: float) = f.pos = $(x, y)
var f: Foo
with(f, setColor(2, 3, 4), setPosition(0.0, 1.0))
echo f
```
- `macros.newLit` now works for ref object types.
- `macro pragmas` can now be used in type sections.
- 5 new pragmas were added to Nim in order to make the upcoming tooling more
convenient to use. Nim compiler checks these pragmas for syntax but otherwise
ignores them. The pragmas are `requires`, `ensures`, `assume`, `assert`, `invariant`.
- `system.writeFile` has been overloaded to also support `openarray[byte]`.
- `asyncdispatch.drain` now properly takes into account `selector.hasPendingOperations`
and only returns once all pending async operations are guaranteed to have completed.
- `sequtils.zip` now returns a sequence of anonymous tuples i.e. those tuples
now do not have fields named "a" and "b".
- `distinctBase` has been moved from `sugar` to `typetraits` and now it is
implemented as compiler type trait instead of macro. `distinctBase` in sugar
module is now deprecated.
- `CountTable.mget` has been removed from `tables.nim`. It didn't work, and it
was an oversight to be included in v1.0.
- `tables.merge(CountTable, CountTable): CountTable` has been removed.
It didn't work well together with the existing inplace version of the same proc
(`tables.merge(var CountTable, CountTable)`).
It was an oversight to be included in v1.0.
- `asyncdispatch.drain` now consistently uses the passed timeout value for all
iterations of the event loop, and not just the first iteration.
This is more consistent with the other asyncdispatch APIs, and allows
`asyncdispatch.drain` to be more efficient.
- `base64.encode` and `base64.decode` were made faster by about 50%.
- `htmlgen` adds [MathML](https://wikipedia.org/wiki/MathML) support
(ISO 40314).
- `macros.eqIdent` is now invariant to export markers and backtick quotes.
- `htmlgen.html` allows `lang` in the `<html>` tag and common valid attributes.
- `macros.basename` and `basename=` got support for `PragmaExpr`,
so that an expression like `MyEnum {.pure.}` is handled correctly.
- `httpclient.maxredirects` changed from `int` to `Natural`, because negative values
serve no purpose whatsoever.
- `httpclient.newHttpClient` and `httpclient.newAsyncHttpClient` added `headers`
argument to set initial HTTP Headers, instead of a hardcoded empty `newHttpHeader()`.
- `parseutils.parseUntil` has now a different behaviour if the `until` parameter is
empty. This was required for intuitive behaviour of the strscans module
(see bug #13605).
- `strutils.formatFloat` with `precision = 0` has the same behavior in all
backends, and it is compatible with Python's behavior,
e.g. `formatFloat(3.14159, precision = 0)` is now `3`, not `3.`.
- `times.parse` now only uses input to compute its result, and not `now`:
`parse("2020", "YYYY", utc())` is now `2020-01-01T00:00:00Z` instead of
`2020-03-02T00:00:00Z` if run on 03-02; it also doesn't crash anymore when
used on 29th, 30th, 31st of each month.
- `httpcore.==(string, HttpCode)` is now deprecated due to lack of practical
usage. The `$` operator can be used to obtain the string form of `HttpCode`
for comparison if desired.
- `std/oswalkdir` was buggy, it's now deprecated and reuses `std/os` procs.
- `net.newContext` now performs SSL Certificate checking on Linux and OSX.
Define `nimDisableCertificateValidation` to disable it globally.
- `os.walkDir` and `os.walkDirRec` now have new flag, `checkDir` (default: false).
If it is set to true, it will throw if input dir is invalid instead of a noop
(which is the default behaviour, as it was before this change),
`os.walkDirRec` only throws if top-level dir is invalid, but ignores errors for
subdirs, otherwise it would be impossible to resume iteration.
- The `FD` variant of `selector.unregister` for `ioselector_epoll` and
`ioselector_select` now properly handle the `Event.User` select event type.
- `joinPath` path normalization when `/` is the first argument works correctly:
`assert "/" / "/a" == "/a"`. Fixed the edge case: `assert "" / "" == ""`.
- `xmltree` now adds indentation consistently to child nodes for any number
of children nodes.
- `os.splitPath()` behavior synchronized with `os.splitFile()` to return "/"
as the dir component of `/root_sub_dir` instead of the empty string.
- The deprecated `lc` macro has been removed from `sugar`. It is now replaced with the
more powerful `collect` macro.
- `os.relativePath("foo", "foo")` is now `"."`, not `""`, as `""` means invalid
path and shouldn't be conflated with `"."`; use `-d:nimOldRelativePathBehavior`
to restore the old behavior.
- `os.joinPath(a, b)` now honors trailing slashes in `b` (or `a` if `b` = "").
- `base64.encode` no longer supports `lineLen` and `newLine`.
Use `base64.encodeMime` instead.
## Language changes
- An `align` pragma can now be used for variables and object fields, similar
to the `alignas` declaration modifier in C/C++.
- `=sink` type bound operator is now optional. Compiler can now use combination
of `=destroy` and `copyMem` to move objects efficiently.
- Unsigned integer operators have been fixed to allow promotion of the first operand.
- Conversions to unsigned integers are unchecked at runtime, imitating earlier Nim
versions. The documentation was improved to acknowledge this special case.
See https://github.com/nim-lang/RFCs/issues/175 for more details.
- New syntax for lvalue references: `var b {.byaddr.} = expr` enabled by
`import std/decls`.
- `var a {.foo.}: MyType = expr` now lowers to `foo(a, MyType, expr)` for
non-builtin pragmas, enabling things like lvalue references (see `decls.byaddr`).
## Compiler changes
- Generated JS code uses spaces, instead of mixed spaces and tabs.
- The Nim compiler now supports the ``--asm`` command option for easier
inspection of the produced assembler code.
- The Nim compiler now supports a new pragma called ``.localPassc`` to
pass specific compiler options to the C(++) backend for the C(++) file
that was produced from the current Nim module.
- The compiler now inferes "sink parameters". To disable this for a specific routine,
annotate it with `.nosinks`. To disable it for a section of code, use
`{.push sinkInference: off.}`...`{.pop.}`.
- The compiler now supports a new switch `--panics:on` that turns runtime
errors like `IndexError` or `OverflowError` into fatal errors that **cannot**
be caught via Nim's `try` statement. `--panics:on` can improve the
runtime efficiency and code size of your program significantly.
- The compiler now warns about inheriting directly from `system.Exception` as
this is **very bad** style. You should inherit from `ValueError`, `IOError`,
`OSError` or from a different specific exception type that inherits from
`CatchableError` and cannot be confused with a `Defect`.
- The error reporting for Nim's effect system has been improved.
- Implicit conversions for `const` behave correctly now, meaning that code like
`const SOMECONST = 0.int; procThatTakesInt32(SOMECONST)` will be illegal now.
Simply write `const SOMECONST = 0` instead.
- The `{.dynlib.}` pragma is now required for exporting symbols when making
shared objects on POSIX and macOS, which make it consistent with the behavior
on Windows.
- The compiler is now more strict about type conversions concerning proc
types: Type conversions cannot be used to hide `.raise` effects or side
effects, instead a `cast` must be used. With the flag `--useVersion:1.0` the
old behaviour is emulated.
- The Nim compiler now implements a faster way to detect overflows based
on GCC's `__builtin_sadd_overflow` family of functions. (Clang also
supports these). Some versions of GCC lack this feature and unfortunately
we cannot detect this case reliably. So if you get compilation errors like
"undefined reference to `__builtin_saddll_overflow`" compile your programs
with `-d:nimEmulateOverflowChecks`.
## Tool changes
- Nimpretty doesn't accept negative indentation argument anymore, because it was
breaking files.
## Bugfixes
- Fixed "`nimgrep --nocolor` is ignored on posix; should be instead: `--nimgrep --color=[auto]|true|false`"
([#7591](https://github.com/nim-lang/Nim/issues/7591))
- Fixed "Runtime index on const array (of converted obj) causes C-compiler error"
([#10514](https://github.com/nim-lang/Nim/issues/10514))
- Fixed "windows x86 with vcc compile error with "asmNoStackFrame""
([#12298](https://github.com/nim-lang/Nim/issues/12298))
- Fixed "[TODO] regression: Error: Locks requires --threads:on option"
([#12330](https://github.com/nim-lang/Nim/issues/12330))
- Fixed "Add --cc option to --help or --fullhelp output"
([#12010](https://github.com/nim-lang/Nim/issues/12010))
- Fixed "questionable `csize` definition in `system.nim`"
([#12187](https://github.com/nim-lang/Nim/issues/12187))
- Fixed "os.getAppFilename() returns incorrect results on OpenBSD"
([#12389](https://github.com/nim-lang/Nim/issues/12389))
- Fixed "HashSet[uint64] slow insertion depending on values"
([#11764](https://github.com/nim-lang/Nim/issues/11764))
- Fixed "Differences between compiling 'classic call syntax' vs 'method call syntax' ."
([#12453](https://github.com/nim-lang/Nim/issues/12453))
- Fixed "c -d:nodejs --> SIGSEGV: Illegal storage access"
([#12502](https://github.com/nim-lang/Nim/issues/12502))
- Fixed "Closure iterator crashes on --newruntime due to "dangling references""
([#12443](https://github.com/nim-lang/Nim/issues/12443))
- Fixed "No `=destroy` for elements of closure environments other than for latest devel --gc:destructors"
([#12577](https://github.com/nim-lang/Nim/issues/12577))
- Fixed "strutils:formatBiggestFloat() gives different results in JS mode"
([#8242](https://github.com/nim-lang/Nim/issues/8242))
- Fixed "Regression (devel): the new `csize_t` definition isn't consistently used, nor tested thoroughly..."
([#12597](https://github.com/nim-lang/Nim/issues/12597))
- Fixed "tables.take() is defined only for `Table` and missed for other table containers"
([#12519](https://github.com/nim-lang/Nim/issues/12519))
- Fixed "`pthread_key_t` errors on OpenBSD"
([#12135](https://github.com/nim-lang/Nim/issues/12135))
- Fixed "newruntime: simple seq pop at ct results in compile error"
([#12644](https://github.com/nim-lang/Nim/issues/12644))
- Fixed "[Windows] finish.exe C:\Users\<USERNAME>\.nimble\bin is not in your PATH environment variable."
([#12319](https://github.com/nim-lang/Nim/issues/12319))
- Fixed "Error with strformat + asyncdispatch + const"
([#12612](https://github.com/nim-lang/Nim/issues/12612))
- Fixed "MultipartData needs $"
([#11863](https://github.com/nim-lang/Nim/issues/11863))
- Fixed "Nim stdlib style issues with --styleCheck:error"
([#12687](https://github.com/nim-lang/Nim/issues/12687))
- Fixed "new $nimbleDir path substitution yields unexpected search paths"
([#12767](https://github.com/nim-lang/Nim/issues/12767))
- Fixed "Regression: inlined procs now get multiple rounds of destructor injection"
([#12766](https://github.com/nim-lang/Nim/issues/12766))
- Fixed "newruntime: compiler generates defective code"
([#12669](https://github.com/nim-lang/Nim/issues/12669))
- Fixed "broken windows modules path handling because of 'os.relativePath' breaking changes"
([#12734](https://github.com/nim-lang/Nim/issues/12734))
- Fixed "for loop tuple syntax not rendered correctly"
([#12740](https://github.com/nim-lang/Nim/issues/12740))
- Fixed "Crash when trying to use `type.name[0]`"
([#12804](https://github.com/nim-lang/Nim/issues/12804))
- Fixed "Enums should be considered Trivial types in Atomics"
([#12812](https://github.com/nim-lang/Nim/issues/12812))
- Fixed "Produce static/const initializations for variables when possible"
([#12216](https://github.com/nim-lang/Nim/issues/12216))
- Fixed "Assigning descriminator field leads to internal assert with --gc:destructors"
([#12821](https://github.com/nim-lang/Nim/issues/12821))
- Fixed "nimsuggest `use` command does not return all instances of symbol"
([#12832](https://github.com/nim-lang/Nim/issues/12832))
- Fixed "@[] is a problem for --gc:destructors"
([#12820](https://github.com/nim-lang/Nim/issues/12820))
- Fixed "Codegen ICE in allPathsAsgnResult"
([#12827](https://github.com/nim-lang/Nim/issues/12827))
- Fixed "seq[Object with ref and destructor type] doesn't work in old runtime"
([#12882](https://github.com/nim-lang/Nim/issues/12882))
- Fixed "Destructor not invoked because it is instantiated too late, old runtime"
([#12883](https://github.com/nim-lang/Nim/issues/12883))
- Fixed "The collect macro does not handle if/case correctly"
([#12874](https://github.com/nim-lang/Nim/issues/12874))
- Fixed "allow typed/untyped params in magic procs (even if not in stdlib)"
([#12911](https://github.com/nim-lang/Nim/issues/12911))
- Fixed "ARC/newruntime memory corruption"
([#12899](https://github.com/nim-lang/Nim/issues/12899))
- Fixed "tasyncclosestall.nim still flaky test: Address already in use"
([#12919](https://github.com/nim-lang/Nim/issues/12919))
- Fixed "newruntime and computed goto: variables inside the loop are in generated code uninitialised"
([#12785](https://github.com/nim-lang/Nim/issues/12785))
- Fixed "osx: dsymutil needs to be called for debug builds to keep debug info"
([#12735](https://github.com/nim-lang/Nim/issues/12735))
- Fixed "codegen ICE with ref objects, gc:destructors"
([#12826](https://github.com/nim-lang/Nim/issues/12826))
- Fixed "mutable iterator cannot yield named tuples"
([#12945](https://github.com/nim-lang/Nim/issues/12945))
- Fixed "parsecfg stores "\r\n" line breaks just as "\n""
([#12970](https://github.com/nim-lang/Nim/issues/12970))
- Fixed "db_postgres.getValue issues warning when no rows found"
([#12973](https://github.com/nim-lang/Nim/issues/12973))
- Fixed "ARC: Unpacking tuple with seq causes segfault"
([#12989](https://github.com/nim-lang/Nim/issues/12989))
- Fixed "ARC/newruntime: strutils.join on seq with only empty strings causes segfault"
([#12965](https://github.com/nim-lang/Nim/issues/12965))
- Fixed "regression (1.0.4): `{.push exportc.}` wrongly affects generic instantiations, causing codegen errors"
([#12985](https://github.com/nim-lang/Nim/issues/12985))
- Fixed "cdt, crash with --gc:arc, works fine with default gc"
([#12978](https://github.com/nim-lang/Nim/issues/12978))
- Fixed "ARC: No indexError thrown on out-of-bound seq access, SIGSEGV instead"
([#12961](https://github.com/nim-lang/Nim/issues/12961))
- Fixed "ARC/async: Returning in a try-block results in wrong codegen"
([#12956](https://github.com/nim-lang/Nim/issues/12956))
- Fixed "asm keyword is generating wrong output C code when --cc:tcc"
([#12988](https://github.com/nim-lang/Nim/issues/12988))
- Fixed "Destructor not invoked"
([#13026](https://github.com/nim-lang/Nim/issues/13026))
- Fixed "ARC/newruntime: Adding inherited var ref object to seq with base type causes segfault"
([#12964](https://github.com/nim-lang/Nim/issues/12964))
- Fixed "Style check error with JS compiler target"
([#13032](https://github.com/nim-lang/Nim/issues/13032))
- Fixed "regression(1.0.4): undeclared identifier: 'readLines'; plus another regression and bug"
([#13013](https://github.com/nim-lang/Nim/issues/13013))
- Fixed "regression(1.04) `invalid pragma: since` with nim js"
([#12996](https://github.com/nim-lang/Nim/issues/12996))
- Fixed "Sink to MemMove optimization in injectdestructors"
([#13002](https://github.com/nim-lang/Nim/issues/13002))
- Fixed "--gc:arc: `catch` doesn't work with exception subclassing"
([#13072](https://github.com/nim-lang/Nim/issues/13072))
- Fixed "nim c --gc:arc --exceptions:{setjmp,goto} incorrectly handles raise; `nim cpp --gc:arc` is ok"
([#13070](https://github.com/nim-lang/Nim/issues/13070))
- Fixed "typetraits feature request - get subtype of a generic type"
([#6454](https://github.com/nim-lang/Nim/issues/6454))
- Fixed "CountTable inconsistencies between keys() and len() after setting value to 0"
([#12813](https://github.com/nim-lang/Nim/issues/12813))
- Fixed "{.align.} pragma is not applied if there is a generic field"
([#13122](https://github.com/nim-lang/Nim/issues/13122))
- Fixed "ARC, finalizer, allow rebinding the same function multiple times"
([#13112](https://github.com/nim-lang/Nim/issues/13112))
- Fixed "`nim doc` treats `export localSymbol` incorrectly"
([#13100](https://github.com/nim-lang/Nim/issues/13100))
- Fixed "--gc:arc SIGSEGV (double free?)"
([#13119](https://github.com/nim-lang/Nim/issues/13119))
- Fixed "codegen bug with arc"
([#13105](https://github.com/nim-lang/Nim/issues/13105))
- Fixed "symbols not defined in the grammar"
([#10665](https://github.com/nim-lang/Nim/issues/10665))
- Fixed "[JS] Move is not defined"
([#9674](https://github.com/nim-lang/Nim/issues/9674))
- Fixed "[TODO] pathutils.`/` can return invalid AbsoluteFile"
([#13121](https://github.com/nim-lang/Nim/issues/13121))
- Fixed "regression(1.04) `nim doc main.nim` generates broken html (no css)"
([#12998](https://github.com/nim-lang/Nim/issues/12998))
- Fixed "Wrong supportsCopyMem on string in type section"
([#13095](https://github.com/nim-lang/Nim/issues/13095))
- Fixed "Arc, finalizer, out of memory"
([#13157](https://github.com/nim-lang/Nim/issues/13157))
- Fixed "`--genscript` messes up nimcache and future nim invocations"
([#13144](https://github.com/nim-lang/Nim/issues/13144))
- Fixed "--gc:arc with --exceptions:goto for "nim c" generate invalid c code"
([#13186](https://github.com/nim-lang/Nim/issues/13186))
- Fixed "[regression] duplicate member `_i1` codegen bug"
([#13195](https://github.com/nim-lang/Nim/issues/13195))
- Fixed "RTree investigations with valgrind for --gc:arc"
([#13110](https://github.com/nim-lang/Nim/issues/13110))
- Fixed "relativePath("foo", ".") returns wrong path"
([#13211](https://github.com/nim-lang/Nim/issues/13211))
- Fixed "asyncftpclient - problem with welcome.msg"
([#4684](https://github.com/nim-lang/Nim/issues/4684))
- Fixed "Unclear error message, lowest priority"
([#13256](https://github.com/nim-lang/Nim/issues/13256))
- Fixed "Channel messages are corrupted"
([#13219](https://github.com/nim-lang/Nim/issues/13219))
- Fixed "Codegen bug with exportc and case objects"
([#13281](https://github.com/nim-lang/Nim/issues/13281))
- Fixed "[bugfix] fix #11590: c compiler warnings silently ignored, giving undefined behavior"
([#11591](https://github.com/nim-lang/Nim/issues/11591))
- Fixed "[CI] tnetdial flaky test"
([#13132](https://github.com/nim-lang/Nim/issues/13132))
- Fixed "Cross-Compiling with -d:mingw fails to locate compiler under OSX"
([#10717](https://github.com/nim-lang/Nim/issues/10717))
- Fixed "`nim doc --project` broken with imports below main project file or duplicate names"
([#13150](https://github.com/nim-lang/Nim/issues/13150))
- Fixed "regression: isNamedTuple(MyGenericTuple[int]) is false, should be true"
([#13349](https://github.com/nim-lang/Nim/issues/13349))
- Fixed "--gc:arc codegen bug copying objects bound to C structs with missing C struct fields"
([#13269](https://github.com/nim-lang/Nim/issues/13269))
- Fixed "write requires conversion to string"
([#13182](https://github.com/nim-lang/Nim/issues/13182))
- Fixed "Some remarks to stdlib documentation"
([#13352](https://github.com/nim-lang/Nim/issues/13352))
- Fixed "a `check` in unittest generated by template doesn't show actual value"
([#6736](https://github.com/nim-lang/Nim/issues/6736))
- Fixed "Implicit return with case expression fails with 'var' return."
([#3339](https://github.com/nim-lang/Nim/issues/3339))
- Fixed "Segfault with closure on arc"
([#13314](https://github.com/nim-lang/Nim/issues/13314))
- Fixed "[Macro] Crash on malformed case statement with multiple else"
([#13255](https://github.com/nim-lang/Nim/issues/13255))
- Fixed "regression: `echo 'discard' | nim c -r -` generates a file '-' ; `-` should be treated specially"
([#13374](https://github.com/nim-lang/Nim/issues/13374))
- Fixed "on OSX, debugging (w gdb or lldb) a nim program crashes at the 1st call to `execCmdEx`"
([#9634](https://github.com/nim-lang/Nim/issues/9634))
- Fixed "Internal error in getTypeDescAux"
([#13378](https://github.com/nim-lang/Nim/issues/13378))
- Fixed "gc:arc mode breaks tuple let"
([#13368](https://github.com/nim-lang/Nim/issues/13368))
- Fixed "Nim compiler hangs for certain C/C++ compiler errors"
([#8648](https://github.com/nim-lang/Nim/issues/8648))
- Fixed "htmlgen does not support `data-*` attributes"
([#13444](https://github.com/nim-lang/Nim/issues/13444))
- Fixed "[gc:arc] setLen will cause string not to be null-terminated."
([#13457](https://github.com/nim-lang/Nim/issues/13457))
- Fixed "joinPath("", "") is "/" ; should be """
([#13455](https://github.com/nim-lang/Nim/issues/13455))
- Fixed "[CI] flaky test on windows: tests/osproc/texitcode.nim"
([#13449](https://github.com/nim-lang/Nim/issues/13449))
- Fixed "Casting to float32 on NimVM is broken"
([#13479](https://github.com/nim-lang/Nim/issues/13479))
- Fixed "`--hints:off` doesn't work (doesn't override ~/.config/nim.cfg)"
([#8312](https://github.com/nim-lang/Nim/issues/8312))
- Fixed "joinPath("", "") is "/" ; should be """
([#13455](https://github.com/nim-lang/Nim/issues/13455))
- Fixed "tables.values is broken"
([#13496](https://github.com/nim-lang/Nim/issues/13496))
- Fixed "global user config can override project specific config"
([#9405](https://github.com/nim-lang/Nim/issues/9405))
- Fixed "Non deterministic macros and id consistency problem"
([#12627](https://github.com/nim-lang/Nim/issues/12627))
- Fixed "try expression doesn't work with return on expect branch"
([#13490](https://github.com/nim-lang/Nim/issues/13490))
- Fixed "CI will break every 4 years on feb 28: times doesn't handle leap years properly"
([#13543](https://github.com/nim-lang/Nim/issues/13543))
- Fixed "[minor] `nimgrep --word` doesn't work with operators (eg misses `1 +% 2`)"
([#13528](https://github.com/nim-lang/Nim/issues/13528))
- Fixed "`as` is usable as infix operator but its existence and precedence are not documented"
([#13409](https://github.com/nim-lang/Nim/issues/13409))
- Fixed "JSON unmarshalling drops seq's items"
([#13531](https://github.com/nim-lang/Nim/issues/13531))
- Fixed "os.joinPath returns wrong path when head ends '\' or '/' and tail starts '..'."
([#13579](https://github.com/nim-lang/Nim/issues/13579))
- Fixed "Block-local types with the same name lead to bad codegen (sighashes regression)"
([#5170](https://github.com/nim-lang/Nim/issues/5170))
- Fixed "tuple codegen error"
([#12704](https://github.com/nim-lang/Nim/issues/12704))
- Fixed "newHttpHeaders does not accept repeated headers"
([#13573](https://github.com/nim-lang/Nim/issues/13573))
- Fixed "regression: --incremental:on fails on simplest example"
([#13319](https://github.com/nim-lang/Nim/issues/13319))
- Fixed "strscan can't get value of last element in format"
([#13605](https://github.com/nim-lang/Nim/issues/13605))
- Fixed "hashes_examples crashes with "Bus Error" (unaligned access) on sparc64"
([#12508](https://github.com/nim-lang/Nim/issues/12508))
- Fixed "gc:arc bug with re-used `seq[T]`"
([#13596](https://github.com/nim-lang/Nim/issues/13596))
- Fixed "`raise CatchableError` is broken with --gc:arc when throwing inside a proc"
([#13599](https://github.com/nim-lang/Nim/issues/13599))
- Fixed "cpp --gc:arc --exceptions:goto fails to raise with discard"
([#13436](https://github.com/nim-lang/Nim/issues/13436))
- Fixed "terminal doesn't compile with -d:useWinAnsi"
([#13607](https://github.com/nim-lang/Nim/issues/13607))
- Fixed "Parsing "sink ptr T" - region needs to be an object type"
([#12757](https://github.com/nim-lang/Nim/issues/12757))
- Fixed "gc:arc + threads:on + closures compilation error"
([#13519](https://github.com/nim-lang/Nim/issues/13519))
- Fixed "[ARC] segmentation fault"
([#13240](https://github.com/nim-lang/Nim/issues/13240))
- Fixed "times.toDateTime buggy on 29th, 30th and 31th of each month"
([#13558](https://github.com/nim-lang/Nim/issues/13558))
- Fixed "Deque misbehaves on VM"
([#13310](https://github.com/nim-lang/Nim/issues/13310))
- Fixed "Nimscript listFiles should throw exception when path is not found"
([#12676](https://github.com/nim-lang/Nim/issues/12676))
- Fixed "koch boot fails if even an empty config.nims is present in ~/.config/nims/ [devel regression]"
([#13633](https://github.com/nim-lang/Nim/issues/13633))
- Fixed "nim doc generates lots of false positive LockLevel warnings"
([#13218](https://github.com/nim-lang/Nim/issues/13218))
- Fixed "Arrays are passed by copy to iterators, causing crashes, unnecessary allocations and slowdowns"
([#12747](https://github.com/nim-lang/Nim/issues/12747))
- Fixed "Range types always uses signed integer as a base type"
([#13646](https://github.com/nim-lang/Nim/issues/13646))
- Fixed "Generate c code cannot compile with recent devel version"
([#13645](https://github.com/nim-lang/Nim/issues/13645))
- Fixed "[regression] VM: Error: cannot convert -1 to uint64"
([#13661](https://github.com/nim-lang/Nim/issues/13661))
- Fixed "Spurious raiseException(Exception) detected"
([#13654](https://github.com/nim-lang/Nim/issues/13654))
- Fixed "gc:arc memory leak"
([#13659](https://github.com/nim-lang/Nim/issues/13659))
- Fixed "Error: cannot convert -1 to uint (inside tuples)"
([#13671](https://github.com/nim-lang/Nim/issues/13671))
- Fixed "strformat issue with --gc:arc"
([#13622](https://github.com/nim-lang/Nim/issues/13622))
- Fixed "astToStr doesn't work inside generics"
([#13524](https://github.com/nim-lang/Nim/issues/13524))
- Fixed "oswalkdir.walkDirRec wont return folders"
([#11458](https://github.com/nim-lang/Nim/issues/11458))
- Fixed "`echo 'echo 1' | nim c -r -` silently gives wrong results (nimBetterRun not updated for stdin)"
([#13412](https://github.com/nim-lang/Nim/issues/13412))
- Fixed "gc:arc destroys the global variable accidentally."
([#13691](https://github.com/nim-lang/Nim/issues/13691))
- Fixed "[minor] sigmatch errors should be sorted, for reproducible errors"
([#13538](https://github.com/nim-lang/Nim/issues/13538))
- Fixed "Exception when converting csize to clong"
([#13698](https://github.com/nim-lang/Nim/issues/13698))
- Fixed "ARC: variables are no copied on the thread spawn causing crashes"
([#13708](https://github.com/nim-lang/Nim/issues/13708))
- Fixed "Illegal distinct seq causes compiler crash"
([#13720](https://github.com/nim-lang/Nim/issues/13720))
- Fixed "cyclic seq definition crashes the compiler"
([#13715](https://github.com/nim-lang/Nim/issues/13715))
- Fixed "Iterator with openArray parameter make the argument evaluated many times"
([#13417](https://github.com/nim-lang/Nim/issues/13417))
- Fixed "net/asyncnet: Unable to access peer's certificate chain"
([#13299](https://github.com/nim-lang/Nim/issues/13299))
- Fixed "Accidentally "SIGSEGV: Illegal storage access" error after arc optimizations (#13325)"
([#13709](https://github.com/nim-lang/Nim/issues/13709))
- Fixed "Base64 Regression"
([#13722](https://github.com/nim-lang/Nim/issues/13722))
- Fixed "A regression (?) with --gc:arc and repr"
([#13731](https://github.com/nim-lang/Nim/issues/13731))
- Fixed "Internal compiler error when using the new variable pragmas"
([#13737](https://github.com/nim-lang/Nim/issues/13737))
- Fixed "bool conversion produces vcc 2019 warning at cpp compilation stage"
([#13744](https://github.com/nim-lang/Nim/issues/13744))
- Fixed "Compiler "does not detect" a type recursion error in the wrong code, remaining frozen"
([#13763](https://github.com/nim-lang/Nim/issues/13763))
- Fixed "[minor] regression: `Foo[0.0] is Foo[-0.0]` is now false"
([#13730](https://github.com/nim-lang/Nim/issues/13730))
- Fixed "`nim doc` - only whitespace on first line causes segfault"
([#13631](https://github.com/nim-lang/Nim/issues/13631))
- Fixed "hashset regression"
([#13794](https://github.com/nim-lang/Nim/issues/13794))
- Fixed "`os.getApplFreebsd` could return incorrect paths in the case of a long path"
([#13806](https://github.com/nim-lang/Nim/issues/13806))
- Fixed "Destructors are not inherited"
([#13810](https://github.com/nim-lang/Nim/issues/13810))
- Fixed "io.readLines AssertionError on devel"
([#13829](https://github.com/nim-lang/Nim/issues/13829))
- Fixed "exceptions:goto accidentally reset the variable during exception handling"
([#13782](https://github.com/nim-lang/Nim/issues/13782))

View File

@@ -0,0 +1,20 @@
# v1.xx.x - yyyy-mm-dd
This is an example file.
The changes should go to changelog.md!
## Standard library additions and changes
- Added `example.exampleProc`.
- Changed `example.foo` to take additional `bar` parameter.
## Language changes
## Compiler changes
## Tool changes

61
changelogs/readme.md Normal file
View File

@@ -0,0 +1,61 @@
# Update changelog
After each release, call:
```
git mv changelog.md changelogs/changelog_0_19_0.md # use correct version
cp changelogs/changelog_X_XX_X.md changelog.md
git add changelog.md
```
## Recent changelogs are saved here (with their git history)
## Older changelogs are stored in https://github.com/nim-lang/website
## source files:
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2009-12-21-version-086-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2010-03-14-version-088-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2010-10-20-version-0810-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2011-07-10-version-0812-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2012-02-09-version-0814-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2012-09-23-version-090-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2013-05-20-version-092-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2014-04-21-version-094-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2014-10-19-version-096-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2014-12-29-version-0102-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2015-04-30-version-0110-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2015-05-04-version-0112-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2015-10-27-version-0120-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2016-01-18-version-0130-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2016-06-07-version-0140-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2016-06-09-version-0142-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2016-09-30-version-0150-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2016-10-23-version-0152-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2017-01-08-version-0160-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2017-05-17-version-0170-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2017-09-07-version-0172-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2018-03-01-version-0180-released.md
* https://github.com/nim-lang/website/blob/master/jekyll/_posts/2018-09-26-version-0190-released.md
## urls:
* https://nim-lang.org/blog/2009/12/21/version-086-released.html
* https://nim-lang.org/blog/2010/03/14/version-088-released.html
* https://nim-lang.org/blog/2010/10/20/version-0810-released.html
* https://nim-lang.org/blog/2011/07/10/version-0812-released.html
* https://nim-lang.org/blog/2012/02/09/version-0814-released.html
* https://nim-lang.org/blog/2012/09/23/version-090-released.html
* https://nim-lang.org/blog/2013/05/20/version-092-released.html
* https://nim-lang.org/blog/2014/04/21/version-094-released.html
* https://nim-lang.org/blog/2014/10/19/version-096-released.html
* https://nim-lang.org/blog/2014/12/29/version-0102-released.html
* https://nim-lang.org/blog/2015/04/30/version-0110-released.html
* https://nim-lang.org/blog/2015/05/04/version-0112-released.html
* https://nim-lang.org/blog/2015/10/27/version-0120-released.html
* https://nim-lang.org/blog/2016/01/18/version-0130-released.html
* https://nim-lang.org/blog/2016/06/07/version-0140-released.html
* https://nim-lang.org/blog/2016/06/09/version-0142-released.html
* https://nim-lang.org/blog/2016/09/30/version-0150-released.html
* https://nim-lang.org/blog/2016/10/23/version-0152-released.html
* https://nim-lang.org/blog/2017/01/08/version-0160-released.html
* https://nim-lang.org/blog/2017/05/17/version-0170-released.html
* https://nim-lang.org/blog/2017/09/07/version-0172-released.html
* https://nim-lang.org/blog/2018/03/01/version-0180-released.html
* https://nim-lang.org/blog/2018/09/26/version-0190-released.html

View File

@@ -1,4 +1,4 @@
REM - Run the full testsuite; tests\testament\tester all
REM - Run the full testsuite; testament\tester all
REM - Uncomment the list of changes in news.txt
REM - write a news ticker entry

View File

@@ -4,6 +4,6 @@ author = "Andreas Rumpf"
description = "Compiler package providing the compiler sources as a library."
license = "MIT"
installDirs = @["compiler"]
installDirs = @["compiler", "nimsuggest"]
requires "nim >= 0.14.0"

View File

@@ -10,7 +10,7 @@
## Simple alias analysis for the HLO and the code generators.
import
ast, astalgo, types, trees, intsets, msgs
ast, astalgo, types, trees, intsets
type
TAnalysisResult* = enum
@@ -22,17 +22,17 @@ proc isPartOfAux(n: PNode, b: PType, marker: var IntSet): TAnalysisResult =
result = arNo
case n.kind
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
result = isPartOfAux(n.sons[i], b, marker)
for i in 0..<n.len:
result = isPartOfAux(n[i], b, marker)
if result == arYes: return
of nkRecCase:
assert(n.sons[0].kind == nkSym)
result = isPartOfAux(n.sons[0], b, marker)
assert(n[0].kind == nkSym)
result = isPartOfAux(n[0], b, marker)
if result == arYes: return
for i in countup(1, sonsLen(n) - 1):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
result = isPartOfAux(lastSon(n.sons[i]), b, marker)
result = isPartOfAux(lastSon(n[i]), b, marker)
if result == arYes: return
else: discard "isPartOfAux(record case branch)"
of nkSym:
@@ -46,14 +46,14 @@ proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
if compareTypes(a, b, dcEqIgnoreDistinct): return arYes
case a.kind
of tyObject:
if a.sons[0] != nil:
result = isPartOfAux(a.sons[0].skipTypes(skipPtrs), b, marker)
if a[0] != nil:
result = isPartOfAux(a[0].skipTypes(skipPtrs), b, marker)
if result == arNo: result = isPartOfAux(a.n, b, marker)
of tyGenericInst, tyDistinct, tyAlias, tySink:
result = isPartOfAux(lastSon(a), b, marker)
of tyArray, tySet, tyTuple:
for i in countup(0, sonsLen(a) - 1):
result = isPartOfAux(a.sons[i], b, marker)
for i in 0..<a.len:
result = isPartOfAux(a[i], b, marker)
if result == arYes: return
else: discard
@@ -108,7 +108,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
result = arMaybe
of nkBracketExpr:
result = isPartOf(a[0], b[0])
if len(a) >= 2 and len(b) >= 2:
if a.len >= 2 and b.len >= 2:
# array accesses:
if result == arYes and isDeepConstExpr(a[1]) and isDeepConstExpr(b[1]):
# we know it's the same array and we have 2 constant indexes;
@@ -186,4 +186,14 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
if res != arNo:
result = res
if res == arYes: break
of nkCallKinds:
result = arNo
for i in 1..<b.len:
let res = isPartOf(a, b[i])
if res != arNo:
result = res
if res == arYes: break
of nkBracket:
if b.len > 0:
result = isPartOf(a, b[0])
else: discard

83
compiler/asciitables.nim Normal file
View File

@@ -0,0 +1,83 @@
#[
move to std/asciitables.nim once stable, or to a nimble paackage
once compiler can depend on nimble
]#
type Cell* = object
text*: string
width*, row*, col*, ncols*, nrows*: int
iterator parseTableCells*(s: string, delim = '\t'): Cell =
## iterates over all cells in a `delim`-delimited `s`, after a 1st
## pass that computes number of rows, columns, and width of each column.
var widths: seq[int]
var cell: Cell
template update() =
if widths.len<=cell.col:
widths.setLen cell.col+1
widths[cell.col] = cell.width
else:
widths[cell.col] = max(widths[cell.col], cell.width)
cell.width = 0
for a in s:
case a
of '\n':
update()
cell.col = 0
cell.row.inc
elif a == delim:
update()
cell.col.inc
else:
# todo: consider multi-width chars when porting to non-ascii implementation
cell.width.inc
if s.len > 0 and s[^1] != '\n':
update()
cell.ncols = widths.len
cell.nrows = cell.row + 1
cell.row = 0
cell.col = 0
cell.width = 0
template update2() =
cell.width = widths[cell.col]
yield cell
cell.text = ""
cell.width = 0
cell.col.inc
template finishRow() =
for col in cell.col..<cell.ncols:
cell.col = col
update2()
cell.col = 0
for a in s:
case a
of '\n':
finishRow()
cell.row.inc
elif a == delim:
update2()
else:
cell.width.inc
cell.text.add a
if s.len > 0 and s[^1] != '\n':
finishRow()
proc alignTable*(s: string, delim = '\t', fill = ' ', sep = " "): string =
## formats a `delim`-delimited `s` representing a table; each cell is aligned
## to a width that's computed for each column; consecutive columns are
## delimited by `sep`, and alignment space is filled using `fill`.
## More customized formatting can be done by calling `parseTableCells` directly.
for cell in parseTableCells(s, delim):
result.add cell.text
for i in cell.text.len..<cell.width:
result.add fill
if cell.col < cell.ncols-1:
result.add sep
if cell.col == cell.ncols-1 and cell.row < cell.nrows - 1:
result.add '\n'

File diff suppressed because it is too large Load Diff

View File

@@ -24,46 +24,55 @@ proc typeToYaml*(conf: ConfigRef; n: PType, indent: int = 0, maxRecDepth: int =
proc symToYaml*(conf: ConfigRef; n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope
proc lineInfoToStr*(conf: ConfigRef; info: TLineInfo): Rope
when declared(echo):
# these are for debugging only: They are not really deprecated, but I want
# the warning so that release versions do not contain debugging statements:
proc debug*(n: PSym; conf: ConfigRef = nil) {.exportc: "debugSym", deprecated.}
proc debug*(n: PType; conf: ConfigRef = nil) {.exportc: "debugType", deprecated.}
proc debug*(n: PNode; conf: ConfigRef = nil) {.exportc: "debugNode", deprecated.}
template debug*(x: PSym|PType|PNode) {.deprecated.} =
when compiles(c.config):
debug(c.config, x)
elif compiles(c.graph.config):
debug(c.graph.config, x)
# these are for debugging only: They are not really deprecated, but I want
# the warning so that release versions do not contain debugging statements:
proc debug*(n: PSym; conf: ConfigRef = nil) {.exportc: "debugSym", deprecated.}
proc debug*(n: PType; conf: ConfigRef = nil) {.exportc: "debugType", deprecated.}
proc debug*(n: PNode; conf: ConfigRef = nil) {.exportc: "debugNode", deprecated.}
proc typekinds*(t: PType) {.deprecated.} =
var t = t
var s = ""
while t != nil and t.len > 0:
s.add $t.kind
s.add " "
t = t.lastSon
echo s
template debug*(x: PSym|PType|PNode) {.deprecated.} =
when compiles(c.config):
debug(c.config, x)
elif compiles(c.graph.config):
debug(c.graph.config, x)
else:
error()
template debug*(x: auto) {.deprecated.} =
echo x
template mdbg*: bool {.deprecated.} =
when compiles(c.graph):
c.module.fileIdx == c.graph.config.projectMainIdx
elif compiles(c.module):
c.module.fileIdx == c.config.projectMainIdx
elif compiles(c.c.module):
c.c.module.fileIdx == c.c.config.projectMainIdx
elif compiles(m.c.module):
m.c.module.fileIdx == m.c.config.projectMainIdx
elif compiles(cl.c.module):
cl.c.module.fileIdx == cl.c.config.projectMainIdx
elif compiles(p):
when compiles(p.lex):
p.lex.fileIdx == p.lex.config.projectMainIdx
else:
error()
template debug*(x: auto) {.deprecated.} =
echo x
template mdbg*: bool {.deprecated.} =
when compiles(c.graph):
c.module.fileIdx == c.graph.config.projectMainIdx
elif compiles(c.module):
c.module.fileIdx == c.config.projectMainIdx
elif compiles(c.c.module):
c.c.module.fileIdx == c.c.config.projectMainIdx
elif compiles(m.c.module):
m.c.module.fileIdx == m.c.config.projectMainIdx
elif compiles(cl.c.module):
cl.c.module.fileIdx == cl.c.config.projectMainIdx
elif compiles(p):
when compiles(p.lex):
p.lex.fileIdx == p.lex.config.projectMainIdx
else:
p.module.module.fileIdx == p.config.projectMainIdx
elif compiles(m.module.fileIdx):
m.module.fileIdx == m.config.projectMainIdx
elif compiles(L.fileIdx):
L.fileIdx == L.config.projectMainIdx
else:
error()
p.module.module.fileIdx == p.config.projectMainIdx
elif compiles(m.module.fileIdx):
m.module.fileIdx == m.config.projectMainIdx
elif compiles(L.fileIdx):
L.fileIdx == L.config.projectMainIdx
else:
error()
# --------------------------- ident tables ----------------------------------
proc idTableGet*(t: TIdTable, key: PIdObj): RootRef
@@ -77,7 +86,6 @@ proc idNodeTablePut*(t: var TIdNodeTable, key: PIdObj, val: PNode)
# ---------------------------------------------------------------------------
proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym
proc lookupInRecord*(n: PNode, field: PIdent): PSym
proc mustRehash*(length, counter: int): bool
proc nextTry*(h, maxHash: Hash): Hash {.inline.}
@@ -108,16 +116,16 @@ proc skipConvAndClosure*(n: PNode): PNode =
case result.kind
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64,
nkClosure:
result = result.sons[0]
result = result[0]
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = result.sons[1]
result = result[1]
else: break
proc sameValue*(a, b: PNode): bool =
result = false
case a.kind
of nkCharLit..nkUInt64Lit:
if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal
if b.kind in {nkCharLit..nkUInt64Lit}: result = getInt(a) == getInt(b)
of nkFloatLit..nkFloat64Lit:
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
of nkStrLit..nkTripleStrLit:
@@ -131,8 +139,8 @@ proc leValue*(a, b: PNode): bool =
# a <= b?
result = false
case a.kind
of nkCharLit..nkUInt32Lit:
if b.kind in {nkCharLit..nkUInt32Lit}: result = a.intVal <= b.intVal
of nkCharLit..nkUInt64Lit:
if b.kind in {nkCharLit..nkUInt64Lit}: result = getInt(a) <= getInt(b)
of nkFloatLit..nkFloat64Lit:
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal <= b.floatVal
of nkStrLit..nkTripleStrLit:
@@ -152,17 +160,17 @@ proc lookupInRecord(n: PNode, field: PIdent): PSym =
result = nil
case n.kind
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
result = lookupInRecord(n.sons[i], field)
for i in 0..<n.len:
result = lookupInRecord(n[i], field)
if result != nil: return
of nkRecCase:
if (n.sons[0].kind != nkSym): return nil
result = lookupInRecord(n.sons[0], field)
if (n[0].kind != nkSym): return nil
result = lookupInRecord(n[0], field)
if result != nil: return
for i in countup(1, sonsLen(n) - 1):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
result = lookupInRecord(lastSon(n.sons[i]), field)
result = lookupInRecord(lastSon(n[i]), field)
if result != nil: return
else: return nil
of nkSym:
@@ -174,14 +182,55 @@ proc getModule*(s: PSym): PSym =
assert((result.kind == skModule) or (result.owner != result))
while result != nil and result.kind != skModule: result = result.owner
proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
for i in countup(start, sonsLen(list) - 1):
if list.sons[i].kind == nkSym:
result = list.sons[i].sym
proc fromSystem*(op: PSym): bool {.inline.} = sfSystemModule in getModule(op).flags
proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym =
for i in start..<list.len:
if list[i].kind == nkSym:
result = list[i].sym
if result.name.id == ident.id: return
else: return nil
result = nil
proc sameIgnoreBacktickGensymInfo(a, b: string): bool =
if a[0] != b[0]: return false
var alen = a.len - 1
while alen > 0 and a[alen] != '`': dec(alen)
if alen <= 0: alen = a.len
var i = 1
var j = 1
while true:
while i < alen and a[i] == '_': inc i
while j < b.len and b[j] == '_': inc j
var aa = if i < alen: toLowerAscii(a[i]) else: '\0'
var bb = if j < b.len: toLowerAscii(b[j]) else: '\0'
if aa != bb: return false
# the characters are identical:
if i >= alen:
# both cursors at the end:
if j >= b.len: return true
# not yet at the end of 'b':
return false
elif j >= b.len:
return false
inc i
inc j
proc getNamedParamFromList*(list: PNode, ident: PIdent): PSym =
## Named parameters are special because a named parameter can be
## gensym'ed and then they have '\`<number>' suffix that we need to
## ignore, see compiler / evaltempl.nim, snippet:
##
##..code-block:: nim
##
## result.add newIdentNode(getIdent(c.ic, x.name.s & "\`gensym" & $x.id),
## if c.instLines: actual.info else: templ.info)
for i in 1..<list.len:
let it = list[i].sym
if it.name.id == ident.id or
sameIgnoreBacktickGensymInfo(it.name.s, ident.s): return it
proc hashNode(p: RootRef): Hash =
result = hash(cast[pointer](p))
@@ -206,15 +255,15 @@ proc makeYamlString*(s: string): Rope =
const MaxLineLength = 64
result = nil
var res = "\""
for i in 0 ..< s.len:
for i in 0..<s.len:
if (i + 1) mod MaxLineLength == 0:
add(res, '\"')
add(res, "\n")
add(result, rope(res))
res.add('\"')
res.add("\n")
result.add(rope(res))
res = "\"" # reset
add(res, toYamlChar(s[i]))
add(res, '\"')
add(result, rope(res))
res.add(toYamlChar(s[i]))
res.add('\"')
result.add(rope(res))
proc flagsToStr[T](flags: set[T]): Rope =
if flags == {}:
@@ -222,8 +271,8 @@ proc flagsToStr[T](flags: set[T]): Rope =
else:
result = nil
for x in items(flags):
if result != nil: add(result, ", ")
add(result, makeYamlString($x))
if result != nil: result.add(", ")
result.add(makeYamlString($x))
result = "[" & result & "]"
proc lineInfoToStr(conf: ConfigRef; info: TLineInfo): Rope =
@@ -238,65 +287,68 @@ proc symToYamlAux(conf: ConfigRef; n: PSym, marker: var IntSet,
proc typeToYamlAux(conf: ConfigRef; n: PType, marker: var IntSet,
indent, maxRecDepth: int): Rope
proc ropeConstr(indent: int, c: openArray[Rope]): Rope =
# array of (name, value) pairs
var istr = rspaces(indent + 2)
result = rope("{")
var i = 0
while i <= high(c):
if i > 0: add(result, ",")
addf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]])
inc(i, 2)
addf(result, "$N$1}", [rspaces(indent)])
proc symToYamlAux(conf: ConfigRef; n: PSym, marker: var IntSet, indent: int,
maxRecDepth: int): Rope =
if n == nil:
result = rope("null")
elif containsOrIncl(marker, n.id):
result = "\"$1 @$2\"" % [rope(n.name.s), rope(
strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))]
result = "\"$1\"" % [rope(n.name.s)]
else:
var ast = treeToYamlAux(conf, n.ast, marker, indent + 2, maxRecDepth - 1)
result = ropeConstr(indent, [rope("kind"),
makeYamlString($n.kind),
rope("name"), makeYamlString(n.name.s),
rope("typ"), typeToYamlAux(conf, n.typ, marker,
indent + 2, maxRecDepth - 1),
rope("info"), lineInfoToStr(conf, n.info),
rope("flags"), flagsToStr(n.flags),
rope("magic"), makeYamlString($n.magic),
rope("ast"), ast, rope("options"),
flagsToStr(n.options), rope("position"),
rope(n.position)])
#rope("typ"), typeToYamlAux(conf, n.typ, marker,
# indent + 2, maxRecDepth - 1),
let istr = rspaces(indent + 2)
result = rope("{")
result.addf("$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
result.addf("$N$1\"name\": $2", [istr, makeYamlString(n.name.s)])
result.addf("$N$1\"typ\": $2", [istr, typeToYamlAux(conf, n.typ, marker, indent + 2, maxRecDepth - 1)])
if conf != nil:
# if we don't pass the config, we probably don't care about the line info
result.addf("$N$1\"info\": $2", [istr, lineInfoToStr(conf, n.info)])
if card(n.flags) > 0:
result.addf("$N$1\"flags\": $2", [istr, flagsToStr(n.flags)])
result.addf("$N$1\"magic\": $2", [istr, makeYamlString($n.magic)])
result.addf("$N$1\"ast\": $2", [istr, ast])
result.addf("$N$1\"options\": $2", [istr, flagsToStr(n.options)])
result.addf("$N$1\"position\": $2", [istr, rope(n.position)])
result.addf("$N$1\"k\": $2", [istr, makeYamlString($n.loc.k)])
result.addf("$N$1\"storage\": $2", [istr, makeYamlString($n.loc.storage)])
if card(n.loc.flags) > 0:
result.addf("$N$1\"flags\": $2", [istr, makeYamlString($n.loc.flags)])
result.addf("$N$1\"r\": $2", [istr, n.loc.r])
result.addf("$N$1\"lode\": $2", [istr, treeToYamlAux(conf, n.loc.lode, marker, indent + 2, maxRecDepth - 1)])
result.addf("$N$1}", [rspaces(indent)])
proc typeToYamlAux(conf: ConfigRef; n: PType, marker: var IntSet, indent: int,
maxRecDepth: int): Rope =
var sonsRope: Rope
if n == nil:
result = rope("null")
sonsRope = rope("null")
elif containsOrIncl(marker, n.id):
result = "\"$1 @$2\"" % [rope($n.kind), rope(
sonsRope = "\"$1 @$2\"" % [rope($n.kind), rope(
strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))]
else:
if sonsLen(n) > 0:
result = rope("[")
for i in countup(0, sonsLen(n) - 1):
if i > 0: add(result, ",")
addf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(conf, n.sons[i],
if n.len > 0:
sonsRope = rope("[")
for i in 0..<n.len:
if i > 0: sonsRope.add(",")
sonsRope.addf("$N$1$2", [rspaces(indent + 4), typeToYamlAux(conf, n[i],
marker, indent + 4, maxRecDepth - 1)])
addf(result, "$N$1]", [rspaces(indent + 2)])
sonsRope.addf("$N$1]", [rspaces(indent + 2)])
else:
result = rope("null")
result = ropeConstr(indent, [rope("kind"),
makeYamlString($n.kind),
rope("sym"), symToYamlAux(conf, n.sym, marker,
indent + 2, maxRecDepth - 1), rope("n"), treeToYamlAux(conf, n.n, marker,
indent + 2, maxRecDepth - 1), rope("flags"), flagsToStr(n.flags),
rope("callconv"),
makeYamlString(CallingConvToStr[n.callConv]),
rope("size"), rope(n.size),
rope("align"), rope(n.align),
rope("sons"), result])
sonsRope = rope("null")
let istr = rspaces(indent + 2)
result = rope("{")
result.addf("$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
result.addf("$N$1\"sym\": $2", [istr, symToYamlAux(conf, n.sym, marker, indent + 2, maxRecDepth - 1)])
result.addf("$N$1\"n\": $2", [istr, treeToYamlAux(conf, n.n, marker, indent + 2, maxRecDepth - 1)])
if card(n.flags) > 0:
result.addf("$N$1\"flags\": $2", [istr, flagsToStr(n.flags)])
result.addf("$N$1\"callconv\": $2", [istr, makeYamlString(CallingConvToStr[n.callConv])])
result.addf("$N$1\"size\": $2", [istr, rope(n.size)])
result.addf("$N$1\"align\": $2", [istr, rope(n.align)])
result.addf("$N$1\"sons\": $2", [istr, sonsRope])
proc treeToYamlAux(conf: ConfigRef; n: PNode, marker: var IntSet, indent: int,
maxRecDepth: int): Rope =
@@ -306,34 +358,35 @@ proc treeToYamlAux(conf: ConfigRef; n: PNode, marker: var IntSet, indent: int,
var istr = rspaces(indent + 2)
result = "{$N$1\"kind\": $2" % [istr, makeYamlString($n.kind)]
if maxRecDepth != 0:
addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(conf, n.info)])
if conf != nil:
result.addf(",$N$1\"info\": $2", [istr, lineInfoToStr(conf, n.info)])
case n.kind
of nkCharLit..nkInt64Lit:
addf(result, ",$N$1\"intVal\": $2", [istr, rope(n.intVal)])
result.addf(",$N$1\"intVal\": $2", [istr, rope(n.intVal)])
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
addf(result, ",$N$1\"floatVal\": $2",
result.addf(",$N$1\"floatVal\": $2",
[istr, rope(n.floatVal.toStrMaxPrecision)])
of nkStrLit..nkTripleStrLit:
addf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
result.addf(",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
of nkSym:
addf(result, ",$N$1\"sym\": $2",
result.addf(",$N$1\"sym\": $2",
[istr, symToYamlAux(conf, n.sym, marker, indent + 2, maxRecDepth)])
of nkIdent:
if n.ident != nil:
addf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
result.addf(",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
else:
addf(result, ",$N$1\"ident\": null", [istr])
result.addf(",$N$1\"ident\": null", [istr])
else:
if sonsLen(n) > 0:
addf(result, ",$N$1\"sons\": [", [istr])
for i in countup(0, sonsLen(n) - 1):
if i > 0: add(result, ",")
addf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(conf, n.sons[i],
if n.len > 0:
result.addf(",$N$1\"sons\": [", [istr])
for i in 0..<n.len:
if i > 0: result.add(",")
result.addf("$N$1$2", [rspaces(indent + 4), treeToYamlAux(conf, n[i],
marker, indent + 4, maxRecDepth - 1)])
addf(result, "$N$1]", [istr])
addf(result, ",$N$1\"typ\": $2",
result.addf("$N$1]", [istr])
result.addf(",$N$1\"typ\": $2",
[istr, typeToYamlAux(conf, n.typ, marker, indent + 2, maxRecDepth)])
addf(result, "$N$1}", [rspaces(indent)])
result.addf("$N$1}", [rspaces(indent)])
proc treeToYaml(conf: ConfigRef; n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope =
var marker = initIntSet()
@@ -347,93 +400,258 @@ proc symToYaml(conf: ConfigRef; n: PSym, indent: int = 0, maxRecDepth: int = - 1
var marker = initIntSet()
result = symToYamlAux(conf, n, marker, indent, maxRecDepth)
proc debugTree*(conf: ConfigRef; n: PNode, indent: int, maxRecDepth: int; renderType=false): Rope
proc debugType(conf: ConfigRef; n: PType, maxRecDepth=100): Rope =
import tables
const backrefStyle = "\e[90m"
const enumStyle = "\e[34m"
const numberStyle = "\e[33m"
const stringStyle = "\e[32m"
const resetStyle = "\e[0m"
type
DebugPrinter = object
conf: ConfigRef
visited: Table[pointer, int]
renderSymType: bool
indent: int
currentLine: int
firstItem: bool
useColor: bool
res: string
proc indentMore(this: var DebugPrinter) =
this.indent += 2
proc indentLess(this: var DebugPrinter) =
this.indent -= 2
proc newlineAndIndent(this: var DebugPrinter) =
this.res.add "\n"
this.currentLine += 1
for i in 0..<this.indent:
this.res.add ' '
proc openCurly(this: var DebugPrinter) =
this.res.add "{"
this.indentMore
this.firstItem = true
proc closeCurly(this: var DebugPrinter) =
this.indentLess
this.newlineAndIndent
this.res.add "}"
proc comma(this: var DebugPrinter) =
this.res.add ", "
proc openBracket(this: var DebugPrinter) =
this.res.add "["
#this.indentMore
proc closeBracket(this: var DebugPrinter) =
#this.indentLess
this.res.add "]"
proc key(this: var DebugPrinter; key: string) =
if not this.firstItem:
this.res.add ","
this.firstItem = false
this.newlineAndIndent
this.res.add "\""
this.res.add key
this.res.add "\": "
proc value(this: var DebugPrinter; value: string) =
if this.useColor:
this.res.add stringStyle
this.res.add "\""
this.res.add value
this.res.add "\""
if this.useColor:
this.res.add resetStyle
proc value(this: var DebugPrinter; value: BiggestInt) =
if this.useColor:
this.res.add numberStyle
this.res.addInt value
if this.useColor:
this.res.add resetStyle
proc value[T: enum](this: var DebugPrinter; value: T) =
if this.useColor:
this.res.add enumStyle
this.res.add "\""
this.res.add $value
this.res.add "\""
if this.useColor:
this.res.add resetStyle
proc value[T: enum](this: var DebugPrinter; value: set[T]) =
this.openBracket
let high = card(value)-1
var i = 0
for v in value:
this.value v
if i != high:
this.comma
inc i
this.closeBracket
template earlyExit(this: var DebugPrinter; n: PType | PNode | PSym) =
if n == nil:
result = rope("null")
this.res.add "null"
return
let index = this.visited.getOrDefault(cast[pointer](n), -1)
if index < 0:
this.visited[cast[pointer](n)] = this.currentLine
else:
result = rope($n.kind)
if n.sym != nil:
add(result, " ")
add(result, n.sym.name.s)
if n.kind in IntegralTypes and n.n != nil:
add(result, ", node: ")
add(result, debugTree(conf, n.n, 2, maxRecDepth-1, renderType=true))
if (n.kind != tyString) and (sonsLen(n) > 0) and maxRecDepth != 0:
add(result, "(")
for i in countup(0, sonsLen(n) - 1):
if i > 0: add(result, ", ")
if n.sons[i] == nil:
add(result, "null")
else:
add(result, debugType(conf, n.sons[i], maxRecDepth-1))
if n.kind == tyObject and n.n != nil:
add(result, ", node: ")
add(result, debugTree(conf, n.n, 2, maxRecDepth-1, renderType=true))
add(result, ")")
if this.useColor:
this.res.add backrefStyle
this.res.add "<defined "
this.res.addInt(this.currentLine - index)
this.res.add " lines upwards>"
if this.useColor:
this.res.add resetStyle
return
proc debugTree(conf: ConfigRef; n: PNode, indent: int, maxRecDepth: int;
renderType=false): Rope =
if n == nil:
result = rope("null")
proc value(this: var DebugPrinter; value: PType)
proc value(this: var DebugPrinter; value: PNode)
proc value(this: var DebugPrinter; value: PSym) =
earlyExit(this, value)
this.openCurly
this.key("kind")
this.value(value.kind)
this.key("name")
this.value(value.name.s)
this.key("id")
this.value(value.id)
if value.kind in {skField, skEnumField, skParam}:
this.key("position")
this.value(value.position)
if card(value.flags) > 0:
this.key("flags")
this.value(value.flags)
if this.renderSymType and value.typ != nil:
this.key "typ"
this.value(value.typ)
this.closeCurly
proc value(this: var DebugPrinter; value: PType) =
earlyExit(this, value)
this.openCurly
this.key "kind"
this.value value.kind
this.key "id"
this.value value.id
if value.sym != nil:
this.key "sym"
this.value value.sym
#this.value value.sym.name.s
if card(value.flags) > 0:
this.key "flags"
this.value value.flags
if value.kind in IntegralTypes and value.n != nil:
this.key "n"
this.value value.n
if value.len > 0:
this.key "sons"
this.openBracket
for i in 0..<value.len:
this.value value[i]
if i != value.len - 1:
this.comma
this.closeBracket
if value.n != nil:
this.key "n"
this.value value.n
this.closeCurly
proc value(this: var DebugPrinter; value: PNode) =
earlyExit(this, value)
this.openCurly
this.key "kind"
this.value value.kind
when defined(useNodeIds):
this.key "id"
this.value value.id
if this.conf != nil:
this.key "info"
this.value $lineInfoToStr(this.conf, value.info)
if card(value.flags) > 0:
this.key "flags"
this.value value.flags
case value.kind
of nkCharLit..nkUInt64Lit:
this.key "intVal"
this.value value.intVal
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
this.key "floatVal"
this.value value.floatVal.toStrMaxPrecision
of nkStrLit..nkTripleStrLit:
this.key "strVal"
this.value value.strVal
of nkSym:
this.key "sym"
this.value value.sym
#this.value value.sym.name.s
of nkIdent:
if value.ident != nil:
this.key "ident"
this.value value.ident.s
else:
var istr = rspaces(indent + 2)
result = "{$N$1\"kind\": $2" %
[istr, makeYamlString($n.kind)]
when defined(useNodeIds):
addf(result, ",$N$1\"id\": $2", [istr, rope(n.id)])
addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(conf, n.info)])
if maxRecDepth != 0:
addf(result, ",$N$1\"flags\": $2", [istr, rope($n.flags)])
case n.kind
of nkCharLit..nkUInt64Lit:
addf(result, ",$N$1\"intVal\": $2", [istr, rope(n.intVal)])
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
addf(result, ",$N$1\"floatVal\": $2",
[istr, rope(n.floatVal.toStrMaxPrecision)])
of nkStrLit..nkTripleStrLit:
addf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
of nkSym:
addf(result, ",$N$1\"sym\": $2_$3",
[istr, rope(n.sym.name.s), rope(n.sym.id)])
# [istr, symToYaml(n.sym, indent, maxRecDepth),
# rope(n.sym.id)])
if renderType and n.sym.typ != nil:
addf(result, ",$N$1\"typ\": $2", [istr, debugType(conf, n.sym.typ, 2)])
of nkIdent:
if n.ident != nil:
addf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
else:
addf(result, ",$N$1\"ident\": null", [istr])
else:
if renderType and n.typ != nil:
addf(result, ",$N$1\"typ\": $2", [istr, debugType(conf, n.typ, 2)])
if sonsLen(n) > 0:
addf(result, ",$N$1\"sons\": [", [istr])
for i in countup(0, sonsLen(n) - 1):
if i > 0: add(result, ",")
addf(result, "$N$1$2", [rspaces(indent + 4), debugTree(conf, n.sons[i],
indent + 4, maxRecDepth - 1, renderType)])
addf(result, "$N$1]", [istr])
addf(result, "$N$1}", [rspaces(indent)])
if this.renderSymType and value.typ != nil:
this.key "typ"
this.value value.typ
if value.len > 0:
this.key "sons"
this.openBracket
for i in 0..<value.len:
this.value value[i]
if i != value.len - 1:
this.comma
this.closeBracket
when declared(echo):
proc debug(n: PSym; conf: ConfigRef) =
if n == nil:
echo("null")
elif n.kind == skUnknown:
echo("skUnknown")
else:
#writeLine(stdout, $symToYaml(n, 0, 1))
echo("$1_$2: $3, $4, $5, $6" % [
n.name.s, $n.id, $flagsToStr(n.flags), $flagsToStr(n.loc.flags),
$lineInfoToStr(conf, n.info), $n.kind])
this.closeCurly
proc debug(n: PType; conf: ConfigRef) =
echo($debugType(conf, n))
proc debug(n: PNode; conf: ConfigRef) =
echo($debugTree(conf, n, 0, 100))
proc debug(n: PSym; conf: ConfigRef) =
var this: DebugPrinter
this.visited = initTable[pointer, int]()
this.renderSymType = true
this.useColor = not defined(windows)
this.value(n)
echo($this.res)
proc debug(n: PType; conf: ConfigRef) =
var this: DebugPrinter
this.visited = initTable[pointer, int]()
this.renderSymType = true
this.useColor = not defined(windows)
this.value(n)
echo($this.res)
proc debug(n: PNode; conf: ConfigRef) =
var this: DebugPrinter
this.visited = initTable[pointer, int]()
#this.renderSymType = true
this.useColor = not defined(windows)
this.value(n)
echo($this.res)
proc nextTry(h, maxHash: Hash): Hash =
result = ((5 * h) + 1) and maxHash
@@ -460,13 +678,13 @@ proc objectSetRawInsert(data: var TObjectSeq, obj: RootRef) =
proc objectSetEnlarge(t: var TObjectSet) =
var n: TObjectSeq
newSeq(n, len(t.data) * GrowthFactor)
for i in countup(0, high(t.data)):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(t.data):
if t.data[i] != nil: objectSetRawInsert(n, t.data[i])
swap(t.data, n)
proc objectSetIncl*(t: var TObjectSet, obj: RootRef) =
if mustRehash(len(t.data), t.counter): objectSetEnlarge(t)
if mustRehash(t.data.len, t.counter): objectSetEnlarge(t)
objectSetRawInsert(t.data, obj)
inc(t.counter)
@@ -479,7 +697,7 @@ proc objectSetContainsOrIncl*(t: var TObjectSet, obj: RootRef): bool =
if it == obj:
return true # found it
h = nextTry(h, high(t.data))
if mustRehash(len(t.data), t.counter):
if mustRehash(t.data.len, t.counter):
objectSetEnlarge(t)
objectSetRawInsert(t.data, obj)
else:
@@ -496,35 +714,18 @@ proc strTableContains*(t: TStrTable, n: PSym): bool =
h = nextTry(h, high(t.data))
result = false
proc strTableRawInsert(data: var TSymSeq, n: PSym) =
proc strTableRawInsert(data: var seq[PSym], n: PSym) =
var h: Hash = n.name.h and high(data)
if sfImmediate notin n.flags:
# fast path:
while data[h] != nil:
if data[h] == n:
# allowed for 'export' feature:
#InternalError(n.info, "StrTableRawInsert: " & n.name.s)
return
h = nextTry(h, high(data))
assert(data[h] == nil)
data[h] = n
else:
# slow path; we have to ensure immediate symbols are preferred for
# symbol lookups.
# consider the chain: foo (immediate), foo, bar, bar (immediate)
# then bar (immediate) gets replaced with foo (immediate) and the non
# immediate foo is picked! Thus we need to replace it with the first
# slot that has in fact the same identifier stored in it!
var favPos = -1
while data[h] != nil:
if data[h] == n: return
if favPos < 0 and data[h].name.id == n.name.id: favPos = h
h = nextTry(h, high(data))
assert(data[h] == nil)
data[h] = n
if favPos >= 0: swap data[h], data[favPos]
while data[h] != nil:
if data[h] == n:
# allowed for 'export' feature:
#InternalError(n.info, "StrTableRawInsert: " & n.name.s)
return
h = nextTry(h, high(data))
assert(data[h] == nil)
data[h] = n
proc symTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) =
proc symTabReplaceRaw(data: var seq[PSym], prevSym: PSym, newSym: PSym) =
assert prevSym.name.h == newSym.name.h
var h: Hash = prevSym.name.h and high(data)
while data[h] != nil:
@@ -538,14 +739,14 @@ proc symTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) =
symTabReplaceRaw(t.data, prevSym, newSym)
proc strTableEnlarge(t: var TStrTable) =
var n: TSymSeq
newSeq(n, len(t.data) * GrowthFactor)
for i in countup(0, high(t.data)):
var n: seq[PSym]
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(t.data):
if t.data[i] != nil: strTableRawInsert(n, t.data[i])
swap(t.data, n)
proc strTableAdd*(t: var TStrTable, n: PSym) =
if mustRehash(len(t.data), t.counter): strTableEnlarge(t)
if mustRehash(t.data.len, t.counter): strTableEnlarge(t)
strTableRawInsert(t.data, n)
inc(t.counter)
@@ -572,7 +773,7 @@ proc strTableInclReportConflict*(t: var TStrTable, n: PSym;
if not onConflictKeepOld:
t.data[replaceSlot] = n # overwrite it with newer definition!
return t.data[replaceSlot] # found it
elif mustRehash(len(t.data), t.counter):
elif mustRehash(t.data.len, t.counter):
strTableEnlarge(t)
strTableRawInsert(t.data, n)
else:
@@ -676,7 +877,7 @@ iterator items*(tab: TStrTable): PSym =
s = nextIter(it, tab)
proc hasEmptySlot(data: TIdPairSeq): bool =
for h in countup(0, high(data)):
for h in 0..high(data):
if data[h].key == nil:
return true
result = false
@@ -729,9 +930,9 @@ proc idTablePut(t: var TIdTable, key: PIdObj, val: RootRef) =
assert(t.data[index].key != nil)
t.data[index].val = val
else:
if mustRehash(len(t.data), t.counter):
newSeq(n, len(t.data) * GrowthFactor)
for i in countup(0, high(t.data)):
if mustRehash(t.data.len, t.counter):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(t.data):
if t.data[i].key != nil:
idTableRawInsert(n, t.data[i].key, t.data[i].val)
assert(hasEmptySlot(n))
@@ -740,7 +941,7 @@ proc idTablePut(t: var TIdTable, key: PIdObj, val: RootRef) =
inc(t.counter)
iterator idTablePairs*(t: TIdTable): tuple[key: PIdObj, val: RootRef] =
for i in 0 .. high(t.data):
for i in 0..high(t.data):
if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val)
proc idNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int =
@@ -774,10 +975,10 @@ proc idNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) =
assert(t.data[index].key != nil)
t.data[index].val = val
else:
if mustRehash(len(t.data), t.counter):
if mustRehash(t.data.len, t.counter):
var n: TIdNodePairSeq
newSeq(n, len(t.data) * GrowthFactor)
for i in countup(0, high(t.data)):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(t.data):
if t.data[i].key != nil:
idNodeTableRawInsert(n, t.data[i].key, t.data[i].val)
swap(t.data, n)
@@ -785,13 +986,13 @@ proc idNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) =
inc(t.counter)
iterator pairs*(t: TIdNodeTable): tuple[key: PIdObj, val: PNode] =
for i in 0 .. high(t.data):
for i in 0..high(t.data):
if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val)
proc initIITable(x: var TIITable) =
x.counter = 0
newSeq(x.data, StartSize)
for i in countup(0, StartSize - 1): x.data[i].key = InvalidKey
for i in 0..<StartSize: x.data[i].key = InvalidKey
proc iiTableRawGet(t: TIITable, key: int): int =
var h: Hash
@@ -822,13 +1023,28 @@ proc iiTablePut(t: var TIITable, key, val: int) =
assert(t.data[index].key != InvalidKey)
t.data[index].val = val
else:
if mustRehash(len(t.data), t.counter):
if mustRehash(t.data.len, t.counter):
var n: TIIPairSeq
newSeq(n, len(t.data) * GrowthFactor)
for i in countup(0, high(n)): n[i].key = InvalidKey
for i in countup(0, high(t.data)):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(n): n[i].key = InvalidKey
for i in 0..high(t.data):
if t.data[i].key != InvalidKey:
iiTableRawInsert(n, t.data[i].key, t.data[i].val)
swap(t.data, n)
iiTableRawInsert(t.data, key, val)
inc(t.counter)
proc isAddrNode*(n: PNode): bool =
case n.kind
of nkAddr, nkHiddenAddr: true
of nkCallKinds:
if n[0].kind == nkSym and n[0].sym.magic == mAddr: true
else: false
else: false
proc listSymbolNames*(symbols: openArray[PSym]): string =
for sym in symbols:
if result.len > 0:
result.add ", "
result.add sym.name.s

View File

@@ -11,12 +11,17 @@
# the code here should be reused in the Nim standard library
type
TBitSet* = seq[int8] # we use byte here to avoid issues with
ElemType = byte
TBitSet* = seq[ElemType] # we use byte here to avoid issues with
# cross-compiling; uint would be more efficient
# however
const
ElemSize* = sizeof(int8) * 8
ElemSize* = 8
One = ElemType(1)
Zero = ElemType(0)
template modElemSize(arg: untyped): untyped = arg and 7
template divElemSize(arg: untyped): untyped = arg shr 3
proc bitSetInit*(b: var TBitSet, length: int)
proc bitSetUnion*(x: var TBitSet, y: TBitSet)
@@ -32,66 +37,65 @@ proc bitSetCard*(x: TBitSet): BiggestInt
# implementation
proc bitSetIn(x: TBitSet, e: BiggestInt): bool =
result = (x[int(e div ElemSize)] and toU8(int(1 shl (e mod ElemSize)))) !=
toU8(0)
result = (x[int(e.divElemSize)] and (One shl e.modElemSize)) != Zero
proc bitSetIncl(x: var TBitSet, elem: BiggestInt) =
assert(elem >= 0)
x[int(elem div ElemSize)] = x[int(elem div ElemSize)] or
toU8(int(1 shl (elem mod ElemSize)))
x[int(elem.divElemSize)] = x[int(elem.divElemSize)] or
(One shl elem.modElemSize)
proc bitSetExcl(x: var TBitSet, elem: BiggestInt) =
x[int(elem div ElemSize)] = x[int(elem div ElemSize)] and
not toU8(int(1 shl (elem mod ElemSize)))
x[int(elem.divElemSize)] = x[int(elem.divElemSize)] and
not(One shl elem.modElemSize)
proc bitSetInit(b: var TBitSet, length: int) =
newSeq(b, length)
proc bitSetUnion(x: var TBitSet, y: TBitSet) =
for i in countup(0, high(x)): x[i] = x[i] or y[i]
for i in 0..high(x): x[i] = x[i] or y[i]
proc bitSetDiff(x: var TBitSet, y: TBitSet) =
for i in countup(0, high(x)): x[i] = x[i] and not y[i]
for i in 0..high(x): x[i] = x[i] and not y[i]
proc bitSetSymDiff(x: var TBitSet, y: TBitSet) =
for i in countup(0, high(x)): x[i] = x[i] xor y[i]
for i in 0..high(x): x[i] = x[i] xor y[i]
proc bitSetIntersect(x: var TBitSet, y: TBitSet) =
for i in countup(0, high(x)): x[i] = x[i] and y[i]
for i in 0..high(x): x[i] = x[i] and y[i]
proc bitSetEquals(x, y: TBitSet): bool =
for i in countup(0, high(x)):
for i in 0..high(x):
if x[i] != y[i]:
return false
result = true
proc bitSetContains(x, y: TBitSet): bool =
for i in countup(0, high(x)):
if (x[i] and not y[i]) != int8(0):
for i in 0..high(x):
if (x[i] and not y[i]) != Zero:
return false
result = true
# Number of set bits for all values of int8
const populationCount: array[low(int8)..high(int8), int8] = block:
var arr: array[low(int8)..high(int8), int8]
const populationCount: array[uint8, uint8] = block:
var arr: array[uint8, uint8]
proc countSetBits(x: int8): int8 =
proc countSetBits(x: uint8): uint8 =
return
( x and 0b00000001'i8) +
((x and 0b00000010'i8) shr 1) +
((x and 0b00000100'i8) shr 2) +
((x and 0b00001000'i8) shr 3) +
((x and 0b00010000'i8) shr 4) +
((x and 0b00100000'i8) shr 5) +
((x and 0b01000000'i8) shr 6) +
((x and 0b10000000'i8) shr 7)
( x and 0b00000001'u8) +
((x and 0b00000010'u8) shr 1) +
((x and 0b00000100'u8) shr 2) +
((x and 0b00001000'u8) shr 3) +
((x and 0b00010000'u8) shr 4) +
((x and 0b00100000'u8) shr 5) +
((x and 0b01000000'u8) shr 6) +
((x and 0b10000000'u8) shr 7)
for it in low(int8)..high(int8):
arr[it] = countSetBits(it)
for it in low(uint8)..high(uint8):
arr[it] = countSetBits(cast[uint8](it))
arr
proc bitSetCard(x: TBitSet): BiggestInt =
for it in x:
result.inc populationCount[it]
result.inc int(populationCount[it])

View File

@@ -37,34 +37,34 @@ template eq(a, b): bool = cmp(a, b) == 0
proc getOrDefault*[Key, Val](b: BTree[Key, Val], key: Key): Val =
var x = b.root
while x.isInternal:
for j in 0 ..< x.entries:
for j in 0..<x.entries:
if j+1 == x.entries or less(key, x.keys[j+1]):
x = x.links[j]
break
assert(not x.isInternal)
for j in 0 ..< x.entries:
for j in 0..<x.entries:
if eq(key, x.keys[j]): return x.vals[j]
proc contains*[Key, Val](b: BTree[Key, Val], key: Key): bool =
var x = b.root
while x.isInternal:
for j in 0 ..< x.entries:
for j in 0..<x.entries:
if j+1 == x.entries or less(key, x.keys[j+1]):
x = x.links[j]
break
assert(not x.isInternal)
for j in 0 ..< x.entries:
for j in 0..<x.entries:
if eq(key, x.keys[j]): return true
return false
proc copyHalf[Key, Val](h, result: Node[Key, Val]) =
for j in 0 ..< Mhalf:
for j in 0..<Mhalf:
result.keys[j] = h.keys[Mhalf + j]
if h.isInternal:
for j in 0 ..< Mhalf:
for j in 0..<Mhalf:
result.links[j] = h.links[Mhalf + j]
else:
for j in 0 ..< Mhalf:
for j in 0..<Mhalf:
shallowCopy(result.vals[j], h.vals[Mhalf + j])
proc split[Key, Val](h: Node[Key, Val]): Node[Key, Val] =
@@ -191,7 +191,7 @@ when isMainModule:
st.add("www.yahoo.com", "216.109.118.65")
assert st.getOrDefault("www.cs.princeton.edu") == "abc"
assert st.getOrDefault("www.harvardsucks.com") == nil
assert st.getOrDefault("www.harvardsucks.com") == ""
assert st.getOrDefault("www.simpsons.com") == "209.052.165.60"
assert st.getOrDefault("www.apple.com") == "17.112.152.32"

View File

@@ -102,7 +102,7 @@ proc hashTree(c: var MD5Context, n: PNode) =
of nkStrLit..nkTripleStrLit:
c &= n.strVal
else:
for i in 0..<n.len: hashTree(c, n.sons[i])
for i in 0..<n.len: hashTree(c, n[i])
proc hashType(c: var MD5Context, t: PType) =
# modelled after 'typeToString'
@@ -120,44 +120,44 @@ proc hashType(c: var MD5Context, t: PType) =
case t.kind
of tyGenericBody, tyGenericInst, tyGenericInvocation:
for i in countup(0, sonsLen(t) -1 -ord(t.kind != tyGenericInvocation)):
c.hashType t.sons[i]
for i in 0..<t.len-ord(t.kind != tyGenericInvocation):
c.hashType t[i]
of tyUserTypeClass:
internalAssert t.sym != nil and t.sym.owner != nil
c &= t.sym.owner.name.s
of tyUserTypeClassInst:
let body = t.base
c.hashSym body.sym
for i in countup(1, sonsLen(t) - 2):
c.hashType t.sons[i]
for i in 1..<t.len-1:
c.hashType t[i]
of tyFromExpr:
c.hashTree(t.n)
of tyArray:
c.hashTree(t.sons[0].n)
c.hashType(t.sons[1])
c.hashTree(t[0].n)
c.hashType(t[1])
of tyTuple:
if t.n != nil:
assert(sonsLen(t.n) == sonsLen(t))
for i in countup(0, sonsLen(t.n) - 1):
assert(t.n.sons[i].kind == nkSym)
c &= t.n.sons[i].sym.name.s
assert(t.n.len == t.len)
for i in 0..<t.n.len:
assert(t.n[i].kind == nkSym)
c &= t.n[i].sym.name.s
c &= ":"
c.hashType(t.sons[i])
c.hashType(t[i])
c &= ","
else:
for i in countup(0, sonsLen(t) - 1): c.hashType t.sons[i]
for i in 0..<t.len: c.hashType t[i]
of tyRange:
c.hashTree(t.n)
c.hashType(t.sons[0])
c.hashType(t[0])
of tyProc:
c &= (if tfIterator in t.flags: "iterator " else: "proc ")
for i in 0..<t.len: c.hashType(t.sons[i])
for i in 0..<t.len: c.hashType(t[i])
md5Update(c, cast[cstring](addr(t.callConv)), 1)
if tfNoSideEffect in t.flags: c &= ".noSideEffect"
if tfThread in t.flags: c &= ".thread"
else:
for i in 0..<t.len: c.hashType(t.sons[i])
for i in 0..<t.len: c.hashType(t[i])
if tfNotNil in t.flags: c &= "not nil"
proc canonConst(n: PNode): TUid =
@@ -238,35 +238,35 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode,
encodeVInt(n.sym.id, result)
pushSym(w, n.sym)
else:
for i in countup(0, sonsLen(n) - 1):
encodeNode(w, n.info, n.sons[i], result)
add(result, ')')
for i in 0..<n.len:
encodeNode(w, n.info, n[i], result)
result.add(')')
proc encodeLoc(w: PRodWriter, loc: TLoc, result: var string) =
var oldLen = result.len
result.add('<')
if loc.k != low(loc.k): encodeVInt(ord(loc.k), result)
if loc.s != low(loc.s):
add(result, '*')
result.add('*')
encodeVInt(ord(loc.s), result)
if loc.flags != {}:
add(result, '$')
result.add('$')
encodeVInt(cast[int32](loc.flags), result)
if loc.t != nil:
add(result, '^')
result.add('^')
encodeVInt(cast[int32](loc.t.id), result)
pushType(w, loc.t)
if loc.r != nil:
add(result, '!')
result.add('!')
encodeStr($loc.r, result)
if loc.a != 0:
add(result, '?')
result.add('?')
encodeVInt(loc.a, result)
if oldLen + 1 == result.len:
# no data was necessary, so remove the '<' again:
setLen(result, oldLen)
else:
add(result, '>')
result.add('>')
proc encodeType(w: PRodWriter, t: PType, result: var string) =
if t == nil:
@@ -277,47 +277,47 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) =
if t.kind == tyForward: internalError("encodeType: tyForward")
# for the new rodfile viewer we use a preceding [ so that the data section
# can easily be disambiguated:
add(result, '[')
result.add('[')
encodeVInt(ord(t.kind), result)
add(result, '+')
result.add('+')
encodeVInt(t.id, result)
if t.n != nil:
encodeNode(w, unknownLineInfo(), t.n, result)
encodeNode(w, unknownLineInfo, t.n, result)
if t.flags != {}:
add(result, '$')
result.add('$')
encodeVInt(cast[int32](t.flags), result)
if t.callConv != low(t.callConv):
add(result, '?')
result.add('?')
encodeVInt(ord(t.callConv), result)
if t.owner != nil:
add(result, '*')
result.add('*')
encodeVInt(t.owner.id, result)
pushSym(w, t.owner)
if t.sym != nil:
add(result, '&')
result.add('&')
encodeVInt(t.sym.id, result)
pushSym(w, t.sym)
if t.size != - 1:
add(result, '/')
result.add('/')
encodeVBiggestInt(t.size, result)
if t.align != 2:
add(result, '=')
if t.align != - 1:
result.add('=')
encodeVInt(t.align, result)
encodeLoc(w, t.loc, result)
for i in countup(0, sonsLen(t) - 1):
if t.sons[i] == nil:
add(result, "^()")
for i in 0..<t.len:
if t[i] == nil:
result.add("^()")
else:
add(result, '^')
encodeVInt(t.sons[i].id, result)
pushType(w, t.sons[i])
result.add('^')
encodeVInt(t[i].id, result)
pushType(w, t[i])
proc encodeLib(w: PRodWriter, lib: PLib, info: TLineInfo, result: var string) =
add(result, '|')
result.add('|')
encodeVInt(ord(lib.kind), result)
add(result, '|')
result.add('|')
encodeStr($lib.name, result)
add(result, '|')
result.add('|')
encodeNode(w, info, lib.path, result)
proc encodeSym(w: PRodWriter, s: PSym, result: var string) =
@@ -363,8 +363,8 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) =
encodeLoc(w, s.loc, result)
if s.annex != nil: encodeLib(w, s.annex, s.info, result)
if s.constraint != nil:
add(result, '#')
encodeNode(w, unknownLineInfo(), s.constraint, result)
result.add('#')
encodeNode(w, unknownLineInfo, s.constraint, result)
# lazy loading will soon reload the ast lazily, so the ast needs to be
# the last entry of a symbol:
if s.ast != nil:

View File

@@ -9,88 +9,126 @@
#
# included from cgen.nim
proc canRaiseDisp(p: BProc; n: PNode): bool =
# we assume things like sysFatal cannot raise themselves
if n.kind == nkSym and {sfNeverRaises, sfImportc, sfCompilerProc} * n.sym.flags != {}:
result = false
elif optPanics in p.config.globalOptions or
(n.kind == nkSym and sfSystemModule in getModule(n.sym).flags):
# we know we can be strict:
result = canRaise(n)
else:
# we have to be *very* conservative:
result = canRaiseConservative(n)
proc leftAppearsOnRightSide(le, ri: PNode): bool =
if le != nil:
for i in 1 ..< ri.len:
for i in 1..<ri.len:
let r = ri[i]
if isPartOf(le, r) != arNo: return true
proc hasNoInit(call: PNode): bool {.inline.} =
result = call.sons[0].kind == nkSym and sfNoInit in call.sons[0].sym.flags
result = call[0].kind == nkSym and sfNoInit in call[0].sym.flags
proc isHarmlessStore(p: BProc; canRaise: bool; d: TLoc): bool =
if d.k in {locTemp, locNone} or not canRaise:
result = true
elif d.k == locLocalVar and p.withinTryWithExcept == 0:
# we cannot observe a store to a local variable if the current proc
# has no error handler:
result = true
else:
result = false
proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
callee, params: Rope) =
let canRaise = p.config.exc == excGoto and canRaiseDisp(p, ri[0])
genLineDir(p, ri)
var pl = callee & ~"(" & params
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
if typ.sons[0] != nil:
if isInvalidReturnType(p.config, typ.sons[0]):
var typ = skipTypes(ri[0].typ, abstractInst)
if typ[0] != nil:
if isInvalidReturnType(p.config, typ[0]):
if params != nil: pl.add(~", ")
# beware of 'result = p(result)'. We may need to allocate a temporary:
if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri):
# Great, we can use 'd':
if d.k == locNone: getTemp(p, typ.sons[0], d, needsInit=true)
if d.k == locNone: getTemp(p, typ[0], d, needsInit=true)
elif d.k notin {locTemp} and not hasNoInit(ri):
# reset before pass as 'result' var:
discard "resetLoc(p, d)"
add(pl, addrLoc(p.config, d))
add(pl, ~");$n")
pl.add(addrLoc(p.config, d))
pl.add(~");$n")
line(p, cpsStmts, pl)
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp, needsInit=true)
add(pl, addrLoc(p.config, tmp))
add(pl, ~");$n")
getTemp(p, typ[0], tmp, needsInit=true)
pl.add(addrLoc(p.config, tmp))
pl.add(~");$n")
line(p, cpsStmts, pl)
genAssignment(p, d, tmp, {}) # no need for deep copying
if canRaise: raiseExit(p)
else:
add(pl, ~")")
if p.module.compileToCpp and lfSingleUse in d.flags:
# do not generate spurious temporaries for C++! For C we're better off
# with them to prevent undefined behaviour and because the codegen
# is free to emit expressions multiple times!
d.k = locCall
d.r = pl
excl d.flags, lfSingleUse
else:
if d.k == locNone: getTemp(p, typ.sons[0], d)
pl.add(~")")
if p.module.compileToCpp:
if lfSingleUse in d.flags:
# do not generate spurious temporaries for C++! For C we're better off
# with them to prevent undefined behaviour and because the codegen
# is free to emit expressions multiple times!
d.k = locCall
d.r = pl
excl d.flags, lfSingleUse
else:
if d.k == locNone and p.splitDecls == 0:
getTempCpp(p, typ[0], d, pl)
else:
if d.k == locNone: getTemp(p, typ[0], d)
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
if canRaise: raiseExit(p)
elif isHarmlessStore(p, canRaise, d):
if d.k == locNone: getTemp(p, typ[0], d)
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
if canRaise: raiseExit(p)
else:
var tmp: TLoc
getTemp(p, typ[0], tmp, needsInit=true)
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
list.r = pl
genAssignment(p, tmp, list, {}) # no need for deep copying
if canRaise: raiseExit(p)
genAssignment(p, d, tmp, {})
else:
add(pl, ~");$n")
pl.add(~");$n")
line(p, cpsStmts, pl)
proc isInCurrentFrame(p: BProc, n: PNode): bool =
# checks if `n` is an expression that refers to the current frame;
# this does not work reliably because of forwarding + inlining can break it
case n.kind
of nkSym:
if n.sym.kind in {skVar, skResult, skTemp, skLet} and p.prc != nil:
result = p.prc.id == n.sym.owner.id
of nkDotExpr, nkBracketExpr:
if skipTypes(n.sons[0].typ, abstractInst).kind notin {tyVar,tyLent,tyPtr,tyRef}:
result = isInCurrentFrame(p, n.sons[0])
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = isInCurrentFrame(p, n.sons[1])
of nkHiddenDeref, nkDerefExpr:
# what about: var x = addr(y); callAsOpenArray(x[])?
# *shrug* ``addr`` is unsafe anyway.
result = false
of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
result = isInCurrentFrame(p, n.sons[0])
else: discard
if canRaise: raiseExit(p)
proc genBoundsCheck(p: BProc; arr, a, b: TLoc)
proc openArrayLoc(p: BProc, n: PNode): Rope =
var a: TLoc
let q = skipConv(n)
var q = skipConv(n)
var skipped = false
while q.kind == nkStmtListExpr and q.len > 0:
skipped = true
q = q.lastSon
if getMagic(q) == mSlice:
# magic: pass slice to openArray:
if skipped:
q = skipConv(n)
while q.kind == nkStmtListExpr and q.len > 0:
for i in 0..<q.len-1:
genStmts(p, q[i])
q = q.lastSon
var b, c: TLoc
initLocExpr(p, q[1], a)
initLocExpr(p, q[2], b)
@@ -99,21 +137,23 @@ proc openArrayLoc(p: BProc, n: PNode): Rope =
if optBoundsCheck in p.options:
genBoundsCheck(p, a, b, c)
let ty = skipTypes(a.t, abstractVar+{tyPtr})
let dest = getTypeDesc(p.module, n.typ[0])
case ty.kind
of tyArray:
let first = firstOrd(p.config, ty)
let first = toInt64(firstOrd(p.config, ty))
if first == 0:
result = "($1)+($2), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c)]
result = "($4*)(($1)+($2)), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c), dest]
else:
result = "($1)+(($2)-($4)), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c), intLiteral(first)]
of tyOpenArray, tyVarargs:
result = "($1)+($2), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c)]
result = "($5*)($1)+(($2)-($4)), ($3)-($2)+1" %
[rdLoc(a), rdLoc(b), rdLoc(c), intLiteral(first), dest]
of tyOpenArray, tyVarargs, tyUncheckedArray, tyCString:
result = "($4*)($1)+($2), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c), dest]
of tyString, tySequence:
if skipTypes(n.typ, abstractInst).kind == tyVar and
not compileToCpp(p.module):
result = "(*$1)$4+($2), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c), dataField(p)]
result = "($5*)(*$1)$4+($2), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c), dataField(p), dest]
else:
result = "$1$4+($2), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c), dataField(p)]
result = "($5*)$1$4+($2), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c), dataField(p), dest]
else:
internalError(p.config, "openArrayLoc: " & typeToString(a.t))
else:
@@ -145,7 +185,7 @@ proc openArrayLoc(p: BProc, n: PNode): Rope =
proc genArgStringToCString(p: BProc, n: PNode): Rope {.inline.} =
var a: TLoc
initLocExpr(p, n.sons[0], a)
initLocExpr(p, n[0], a)
result = ropecg(p.module, "#nimToCStringConv($1)", [a.rdLoc])
proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): Rope =
@@ -153,19 +193,19 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): Rope =
if n.kind == nkStringToCString:
result = genArgStringToCString(p, n)
elif skipTypes(param.typ, abstractVar).kind in {tyOpenArray, tyVarargs}:
var n = if n.kind != nkHiddenAddr: n else: n.sons[0]
var n = if n.kind != nkHiddenAddr: n else: n[0]
result = openArrayLoc(p, n)
elif ccgIntroducedPtr(p.config, param):
elif ccgIntroducedPtr(p.config, param, call[0].typ[0]):
initLocExpr(p, n, a)
result = addrLoc(p.config, a)
elif p.module.compileToCpp and param.typ.kind == tyVar and
n.kind == nkHiddenAddr:
initLocExprSingleUse(p, n.sons[0], a)
initLocExprSingleUse(p, n[0], a)
# if the proc is 'importc'ed but not 'importcpp'ed then 'var T' still
# means '*T'. See posix.nim for lots of examples that do that in the wild.
let callee = call.sons[0]
let callee = call[0]
if callee.kind == nkSym and
{sfImportC, sfInfixCall, sfCompilerProc} * callee.sym.flags == {sfImportC} and
{sfImportc, sfInfixCall, sfCompilerProc} * callee.sym.flags == {sfImportc} and
{lfHeader, lfNoDecl} * callee.sym.loc.flags != {}:
result = addrLoc(p.config, a)
else:
@@ -183,29 +223,36 @@ proc genArgNoParam(p: BProc, n: PNode): Rope =
result = rdLoc(a)
template genParamLoop(params) {.dirty.} =
if i < sonsLen(typ):
assert(typ.n.sons[i].kind == nkSym)
let paramType = typ.n.sons[i]
if i < typ.len:
assert(typ.n[i].kind == nkSym)
let paramType = typ.n[i]
if not paramType.typ.isCompileTimeOnly:
if params != nil: add(params, ~", ")
add(params, genArg(p, ri.sons[i], paramType.sym, ri))
if params != nil: params.add(~", ")
params.add(genArg(p, ri[i], paramType.sym, ri))
else:
if params != nil: add(params, ~", ")
add(params, genArgNoParam(p, ri.sons[i]))
if params != nil: params.add(~", ")
params.add(genArgNoParam(p, ri[i]))
proc addActualSuffixForHCR(res: var Rope, module: PSym, sym: PSym) =
if sym.flags * {sfImportc, sfNonReloadable} == {} and sym.loc.k == locProc and
(sym.typ.callConv == ccInline or sym.owner.id == module.id):
res = res & "_actual".rope
proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op: TLoc
# this is a hotspot in the compiler
initLocExpr(p, ri.sons[0], op)
initLocExpr(p, ri[0], op)
var params: Rope
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
var typ = skipTypes(ri[0].typ, abstractInstOwned)
assert(typ.kind == tyProc)
assert(sonsLen(typ) == sonsLen(typ.n))
var length = sonsLen(ri)
for i in countup(1, length - 1):
assert(typ.len == typ.n.len)
for i in 1..<ri.len:
genParamLoop(params)
fixupCall(p, le, ri, d, op.r, params)
var callee = rdLoc(op)
if p.hcrOn and ri[0].kind == nkSym:
callee.addActualSuffixForHCR(p.module.module, ri[0].sym)
fixupCall(p, le, ri, d, callee, params)
proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
@@ -218,68 +265,89 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
const PatProc = "$1.ClE_0? $1.ClP_0($3$1.ClE_0):(($4)($1.ClP_0))($2)"
const PatIter = "$1.ClP_0($3$1.ClE_0)" # we know the env exists
var op: TLoc
initLocExpr(p, ri.sons[0], op)
initLocExpr(p, ri[0], op)
var pl: Rope
var typ = skipTypes(ri.sons[0].typ, abstractInst)
var typ = skipTypes(ri[0].typ, abstractInst)
assert(typ.kind == tyProc)
var length = sonsLen(ri)
for i in countup(1, length - 1):
assert(sonsLen(typ) == sonsLen(typ.n))
for i in 1..<ri.len:
assert(typ.len == typ.n.len)
genParamLoop(pl)
template genCallPattern {.dirty.} =
lineF(p, cpsStmts, callPattern & ";$n", [op.r, pl, pl.addComma, rawProc])
if tfIterator in typ.flags:
lineF(p, cpsStmts, PatIter & ";$n", [rdLoc(op), pl, pl.addComma, rawProc])
else:
lineF(p, cpsStmts, PatProc & ";$n", [rdLoc(op), pl, pl.addComma, rawProc])
let rawProc = getRawProcType(p, typ)
let callPattern = if tfIterator in typ.flags: PatIter else: PatProc
if typ.sons[0] != nil:
if isInvalidReturnType(p.config, typ.sons[0]):
if sonsLen(ri) > 1: add(pl, ~", ")
let canRaise = p.config.exc == excGoto and canRaiseDisp(p, ri[0])
if typ[0] != nil:
if isInvalidReturnType(p.config, typ[0]):
if ri.len > 1: pl.add(~", ")
# beware of 'result = p(result)'. We may need to allocate a temporary:
if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri):
# Great, we can use 'd':
if d.k == locNone:
getTemp(p, typ.sons[0], d, needsInit=true)
getTemp(p, typ[0], d, needsInit=true)
elif d.k notin {locTemp} and not hasNoInit(ri):
# reset before pass as 'result' var:
discard "resetLoc(p, d)"
add(pl, addrLoc(p.config, d))
pl.add(addrLoc(p.config, d))
genCallPattern()
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp, needsInit=true)
add(pl, addrLoc(p.config, tmp))
getTemp(p, typ[0], tmp, needsInit=true)
pl.add(addrLoc(p.config, tmp))
genCallPattern()
if canRaise: raiseExit(p)
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
if d.k == locNone: getTemp(p, typ.sons[0], d)
elif isHarmlessStore(p, canRaise, d):
if d.k == locNone: getTemp(p, typ[0], d)
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
list.r = callPattern % [op.r, pl, pl.addComma, rawProc]
if tfIterator in typ.flags:
list.r = PatIter % [rdLoc(op), pl, pl.addComma, rawProc]
else:
list.r = PatProc % [rdLoc(op), pl, pl.addComma, rawProc]
genAssignment(p, d, list, {}) # no need for deep copying
if canRaise: raiseExit(p)
else:
var tmp: TLoc
getTemp(p, typ[0], tmp)
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
if tfIterator in typ.flags:
list.r = PatIter % [rdLoc(op), pl, pl.addComma, rawProc]
else:
list.r = PatProc % [rdLoc(op), pl, pl.addComma, rawProc]
genAssignment(p, tmp, list, {})
if canRaise: raiseExit(p)
genAssignment(p, d, tmp, {})
else:
genCallPattern()
if canRaise: raiseExit(p)
proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType): Rope =
if i < sonsLen(typ):
if i < typ.len:
# 'var T' is 'T&' in C++. This means we ignore the request of
# any nkHiddenAddr when it's a 'var T'.
let paramType = typ.n.sons[i]
let paramType = typ.n[i]
assert(paramType.kind == nkSym)
if paramType.typ.isCompileTimeOnly:
result = nil
elif typ.sons[i].kind == tyVar and ri.sons[i].kind == nkHiddenAddr:
result = genArgNoParam(p, ri.sons[i][0])
elif typ[i].kind == tyVar and ri[i].kind == nkHiddenAddr:
result = genArgNoParam(p, ri[i][0])
else:
result = genArgNoParam(p, ri.sons[i]) #, typ.n.sons[i].sym)
result = genArgNoParam(p, ri[i]) #, typ.n[i].sym)
else:
if tfVarargs notin typ.flags:
localError(p.config, ri.info, "wrong argument count")
result = nil
else:
result = genArgNoParam(p, ri.sons[i])
result = genArgNoParam(p, ri[i])
discard """
Dot call syntax in C++
@@ -323,16 +391,16 @@ proc skipAddrDeref(node: PNode): PNode =
var isAddr = false
case n.kind
of nkAddr, nkHiddenAddr:
n = n.sons[0]
n = n[0]
isAddr = true
of nkDerefExpr, nkHiddenDeref:
n = n.sons[0]
n = n[0]
else: return n
if n.kind == nkObjDownConv: n = n.sons[0]
if n.kind == nkObjDownConv: n = n[0]
if isAddr and n.kind in {nkDerefExpr, nkHiddenDeref}:
result = n.sons[0]
result = n[0]
elif n.kind in {nkAddr, nkHiddenAddr}:
result = n.sons[0]
result = n[0]
else:
result = node
@@ -340,13 +408,13 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): Rope =
# for better or worse c2nim translates the 'this' argument to a 'var T'.
# However manual wrappers may also use 'ptr T'. In any case we support both
# for convenience.
internalAssert p.config, i < sonsLen(typ)
assert(typ.n.sons[i].kind == nkSym)
internalAssert p.config, i < typ.len
assert(typ.n[i].kind == nkSym)
# if the parameter is lying (tyVar) and thus we required an additional deref,
# skip the deref:
var ri = ri[i]
while ri.kind == nkObjDownConv: ri = ri[0]
let t = typ.sons[i].skipTypes({tyGenericInst, tyAlias, tySink})
let t = typ[i].skipTypes({tyGenericInst, tyAlias, tySink})
if t.kind == tyVar:
let x = if ri.kind == nkHiddenAddr: ri[0] else: ri
if x.typ.kind == tyPtr:
@@ -368,7 +436,7 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): Rope =
else:
ri = skipAddrDeref(ri)
if ri.kind in {nkAddr, nkHiddenAddr}: ri = ri[0]
result = genArgNoParam(p, ri) #, typ.n.sons[i].sym)
result = genArgNoParam(p, ri) #, typ.n[i].sym)
result.add(".")
proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
@@ -377,33 +445,36 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
while i < pat.len:
case pat[i]
of '@':
if j < ri.len:
result.add genOtherArg(p, ri, j, typ)
for k in j+1 ..< ri.len:
result.add(~", ")
result.add genOtherArg(p, ri, k, typ)
var first = true
for k in j..<ri.len:
let arg = genOtherArg(p, ri, k, typ)
if arg.len > 0:
if not first:
result.add(~", ")
first = false
result.add arg
inc i
of '#':
if pat[i+1] in {'+', '@'}:
if i+1 < pat.len and pat[i+1] in {'+', '@'}:
let ri = ri[j]
if ri.kind in nkCallKinds:
let typ = skipTypes(ri.sons[0].typ, abstractInst)
if pat[i+1] == '+': result.add genArgNoParam(p, ri.sons[0])
let typ = skipTypes(ri[0].typ, abstractInst)
if pat[i+1] == '+': result.add genArgNoParam(p, ri[0])
result.add(~"(")
if 1 < ri.len:
result.add genOtherArg(p, ri, 1, typ)
for k in j+1 ..< ri.len:
for k in j+1..<ri.len:
result.add(~", ")
result.add genOtherArg(p, ri, k, typ)
result.add(~")")
else:
localError(p.config, ri.info, "call expression expected for C++ pattern")
inc i
elif pat[i+1] == '.':
elif i+1 < pat.len and pat[i+1] == '.':
result.add genThisArg(p, ri, j, typ)
inc i
elif pat[i+1] == '[':
var arg = ri.sons[j].skipAddrDeref
elif i+1 < pat.len and pat[i+1] == '[':
var arg = ri[j].skipAddrDeref
while arg.kind in {nkAddr, nkHiddenAddr, nkObjDownConv}: arg = arg[0]
result.add genArgNoParam(p, arg)
#result.add debugTree(arg, 0, 10)
@@ -423,24 +494,23 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
if pat[i] notin {'@', '#', '\''}: inc(i)
else: break
if i - 1 >= start:
add(result, substr(pat, start, i - 1))
result.add(substr(pat, start, i - 1))
proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op: TLoc
initLocExpr(p, ri.sons[0], op)
initLocExpr(p, ri[0], op)
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
var typ = skipTypes(ri[0].typ, abstractInst)
assert(typ.kind == tyProc)
var length = sonsLen(ri)
assert(sonsLen(typ) == sonsLen(typ.n))
assert(typ.len == typ.n.len)
# don't call '$' here for efficiency:
let pat = ri.sons[0].sym.loc.r.data
let pat = ri[0].sym.loc.r.data
internalAssert p.config, pat.len > 0
if pat.contains({'#', '(', '@', '\''}):
var pl = genPatternCall(p, ri, pat, typ)
# simpler version of 'fixupCall' that works with the pl+params combination:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
if typ.sons[0] != nil:
var typ = skipTypes(ri[0].typ, abstractInst)
if typ[0] != nil:
if p.module.compileToCpp and lfSingleUse in d.flags:
# do not generate spurious temporaries for C++! For C we're better off
# with them to prevent undefined behaviour and because the codegen
@@ -449,115 +519,114 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
d.r = pl
excl d.flags, lfSingleUse
else:
if d.k == locNone: getTemp(p, typ.sons[0], d)
if d.k == locNone: getTemp(p, typ[0], d)
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
add(pl, ~";$n")
pl.add(~";$n")
line(p, cpsStmts, pl)
else:
var pl: Rope = nil
#var param = typ.n.sons[1].sym
#var param = typ.n[1].sym
if 1 < ri.len:
add(pl, genThisArg(p, ri, 1, typ))
add(pl, op.r)
pl.add(genThisArg(p, ri, 1, typ))
pl.add(op.r)
var params: Rope
for i in countup(2, length - 1):
for i in 2..<ri.len:
if params != nil: params.add(~", ")
assert(sonsLen(typ) == sonsLen(typ.n))
add(params, genOtherArg(p, ri, i, typ))
assert(typ.len == typ.n.len)
params.add(genOtherArg(p, ri, i, typ))
fixupCall(p, le, ri, d, pl, params)
proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
# generates a crappy ObjC call
var op: TLoc
initLocExpr(p, ri.sons[0], op)
initLocExpr(p, ri[0], op)
var pl = ~"["
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
var typ = skipTypes(ri[0].typ, abstractInst)
assert(typ.kind == tyProc)
var length = sonsLen(ri)
assert(sonsLen(typ) == sonsLen(typ.n))
assert(typ.len == typ.n.len)
# don't call '$' here for efficiency:
let pat = ri.sons[0].sym.loc.r.data
let pat = ri[0].sym.loc.r.data
internalAssert p.config, pat.len > 0
var start = 3
if ' ' in pat:
start = 1
add(pl, op.r)
if length > 1:
add(pl, ~": ")
add(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri))
pl.add(op.r)
if ri.len > 1:
pl.add(~": ")
pl.add(genArg(p, ri[1], typ.n[1].sym, ri))
start = 2
else:
if length > 1:
add(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri))
add(pl, ~" ")
add(pl, op.r)
if length > 2:
add(pl, ~": ")
add(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri))
for i in countup(start, length-1):
assert(sonsLen(typ) == sonsLen(typ.n))
if i >= sonsLen(typ):
if ri.len > 1:
pl.add(genArg(p, ri[1], typ.n[1].sym, ri))
pl.add(~" ")
pl.add(op.r)
if ri.len > 2:
pl.add(~": ")
pl.add(genArg(p, ri[2], typ.n[2].sym, ri))
for i in start..<ri.len:
assert(typ.len == typ.n.len)
if i >= typ.len:
internalError(p.config, ri.info, "varargs for objective C method?")
assert(typ.n.sons[i].kind == nkSym)
var param = typ.n.sons[i].sym
add(pl, ~" ")
add(pl, param.name.s)
add(pl, ~": ")
add(pl, genArg(p, ri.sons[i], param, ri))
if typ.sons[0] != nil:
if isInvalidReturnType(p.config, typ.sons[0]):
if sonsLen(ri) > 1: add(pl, ~" ")
assert(typ.n[i].kind == nkSym)
var param = typ.n[i].sym
pl.add(~" ")
pl.add(param.name.s)
pl.add(~": ")
pl.add(genArg(p, ri[i], param, ri))
if typ[0] != nil:
if isInvalidReturnType(p.config, typ[0]):
if ri.len > 1: pl.add(~" ")
# beware of 'result = p(result)'. We always allocate a temporary:
if d.k in {locTemp, locNone}:
# We already got a temp. Great, special case it:
if d.k == locNone: getTemp(p, typ.sons[0], d, needsInit=true)
add(pl, ~"Result: ")
add(pl, addrLoc(p.config, d))
add(pl, ~"];$n")
if d.k == locNone: getTemp(p, typ[0], d, needsInit=true)
pl.add(~"Result: ")
pl.add(addrLoc(p.config, d))
pl.add(~"];$n")
line(p, cpsStmts, pl)
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp, needsInit=true)
add(pl, addrLoc(p.config, tmp))
add(pl, ~"];$n")
getTemp(p, typ[0], tmp, needsInit=true)
pl.add(addrLoc(p.config, tmp))
pl.add(~"];$n")
line(p, cpsStmts, pl)
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
add(pl, ~"]")
if d.k == locNone: getTemp(p, typ.sons[0], d)
pl.add(~"]")
if d.k == locNone: getTemp(p, typ[0], d)
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
initLoc(list, locCall, ri, OnUnknown)
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
add(pl, ~"];$n")
pl.add(~"];$n")
line(p, cpsStmts, pl)
proc genCall(p: BProc, e: PNode, d: var TLoc) =
if e.sons[0].typ.skipTypes({tyGenericInst, tyAlias, tySink}).callConv == ccClosure:
if e[0].typ.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned}).callConv == ccClosure:
genClosureCall(p, nil, e, d)
elif e.sons[0].kind == nkSym and sfInfixCall in e.sons[0].sym.flags:
elif e[0].kind == nkSym and sfInfixCall in e[0].sym.flags:
genInfixCall(p, nil, e, d)
elif e.sons[0].kind == nkSym and sfNamedParamCall in e.sons[0].sym.flags:
elif e[0].kind == nkSym and sfNamedParamCall in e[0].sym.flags:
genNamedParamCall(p, e, d)
else:
genPrefixCall(p, nil, e, d)
postStmtActions(p)
proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) =
if ri.sons[0].typ.skipTypes({tyGenericInst, tyAlias, tySink}).callConv == ccClosure:
if ri[0].typ.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned}).callConv == ccClosure:
genClosureCall(p, le, ri, d)
elif ri.sons[0].kind == nkSym and sfInfixCall in ri.sons[0].sym.flags:
elif ri[0].kind == nkSym and sfInfixCall in ri[0].sym.flags:
genInfixCall(p, le, ri, d)
elif ri.sons[0].kind == nkSym and sfNamedParamCall in ri.sons[0].sym.flags:
elif ri[0].kind == nkSym and sfNamedParamCall in ri[0].sym.flags:
genNamedParamCall(p, ri, d)
else:
genPrefixCall(p, le, ri, d)

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,8 @@
# distribution, for details about the copyright.
#
# included from cgen.nim
## This include file contains the logic to produce constant string
## and seq literals. The code here is responsible that
## ``const x = ["a", "b"]`` works without hidden runtime creation code.
@@ -19,7 +21,7 @@ template detectVersion(field, corename) =
if core == nil or core.kind != skConst:
m.g.field = 1
else:
m.g.field = int ast.getInt(core.ast)
m.g.field = toInt(ast.getInt(core.ast))
result = m.g.field
proc detectStrVersion(m: BModule): int =
@@ -33,8 +35,8 @@ proc detectSeqVersion(m: BModule): int =
proc genStringLiteralDataOnlyV1(m: BModule, s: string): Rope =
discard cgsym(m, "TGenericSeq")
result = getTempName(m)
addf(m.s[cfsData], "STRING_LITERAL($1, $2, $3);$n",
[result, makeCString(s), rope(len(s))])
m.s[cfsData].addf("STRING_LITERAL($1, $2, $3);$n",
[result, makeCString(s), rope(s.len)])
proc genStringLiteralV1(m: BModule; n: PNode): Rope =
if s.isNil:
@@ -47,61 +49,65 @@ proc genStringLiteralV1(m: BModule; n: PNode): Rope =
[genStringLiteralDataOnlyV1(m, n.strVal)])
else:
result = ropecg(m, "((#NimStringDesc*) &$1$2)",
[m.tmpBase, rope(id)])
[m.tmpBase, id])
# ------ Version 2: destructor based strings and seqs -----------------------
proc genStringLiteralDataOnlyV2(m: BModule, s: string): Rope =
result = getTempName(m)
addf(m.s[cfsData], "static const struct {$n" &
" NI cap; void* allocator; NIM_CHAR data[$2];$n" &
"} $1 = { $2, NIM_NIL, $3 };$n",
[result, rope(len(s)), makeCString(s)])
proc genStringLiteralDataOnlyV2(m: BModule, s: string; result: Rope; isConst: bool) =
m.s[cfsData].addf("static $4 struct {$n" &
" NI cap; NIM_CHAR data[$2+1];$n" &
"} $1 = { $2 | NIM_STRLIT_FLAG, $3 };$n",
[result, rope(s.len), makeCString(s),
rope(if isConst: "const" else: "")])
proc genStringLiteralV2(m: BModule; n: PNode): Rope =
proc genStringLiteralV2(m: BModule; n: PNode; isConst: bool): Rope =
let id = nodeTableTestOrSet(m.dataCache, n, m.labels)
if id == m.labels:
let pureLit = getTempName(m)
genStringLiteralDataOnlyV2(m, n.strVal, pureLit, isConst)
result = getTempName(m)
discard cgsym(m, "NimStrPayload")
discard cgsym(m, "NimStringV2")
# string literal not found in the cache:
let pureLit = genStringLiteralDataOnlyV2(m, n.strVal)
result = getTempName(m)
addf(m.s[cfsData], "static const NimStringV2 $1 = {$2, (NimStrPayload*)&$3};$n",
[result, rope(len(n.strVal)), pureLit])
m.s[cfsData].addf("static $4 NimStringV2 $1 = {$2, (NimStrPayload*)&$3};$n",
[result, rope(n.strVal.len), pureLit, rope(if isConst: "const" else: "")])
else:
result = m.tmpBase & rope(id)
result = getTempName(m)
m.s[cfsData].addf("static $4 NimStringV2 $1 = {$2, (NimStrPayload*)&$3};$n",
[result, rope(n.strVal.len), m.tmpBase & rope(id),
rope(if isConst: "const" else: "")])
proc genStringLiteralV2Const(m: BModule; n: PNode): Rope =
proc genStringLiteralV2Const(m: BModule; n: PNode; isConst: bool): Rope =
let id = nodeTableTestOrSet(m.dataCache, n, m.labels)
var pureLit: Rope
if id == m.labels:
pureLit = getTempName(m)
discard cgsym(m, "NimStrPayload")
discard cgsym(m, "NimStringV2")
# string literal not found in the cache:
pureLit = genStringLiteralDataOnlyV2(m, n.strVal)
genStringLiteralDataOnlyV2(m, n.strVal, pureLit, isConst)
else:
pureLit = m.tmpBase & rope(id)
result = "{$1, (NimStrPayload*)&$2}" % [rope(len(n.strVal)), pureLit]
result = "{$1, (NimStrPayload*)&$2}" % [rope(n.strVal.len), pureLit]
# ------ Version selector ---------------------------------------------------
proc genStringLiteralDataOnly(m: BModule; s: string; info: TLineInfo): Rope =
proc genStringLiteralDataOnly(m: BModule; s: string; info: TLineInfo;
isConst: bool): Rope =
case detectStrVersion(m)
of 0, 1: result = genStringLiteralDataOnlyV1(m, s)
of 2: result = genStringLiteralDataOnlyV2(m, s)
of 2:
result = getTempName(m)
genStringLiteralDataOnlyV2(m, s, result, isConst)
else:
localError(m.config, info, "cannot determine how to produce code for string literal")
proc genStringLiteralFromData(m: BModule; data: Rope; info: TLineInfo): Rope =
result = ropecg(m, "((#NimStringDesc*) &$1)",
[data])
proc genNilStringLiteral(m: BModule; info: TLineInfo): Rope =
result = ropecg(m, "((#NimStringDesc*) NIM_NIL)", [])
proc genStringLiteral(m: BModule; n: PNode): Rope =
case detectStrVersion(m)
of 0, 1: result = genStringLiteralV1(m, n)
of 2: result = genStringLiteralV2(m, n)
of 2: result = genStringLiteralV2(m, n, isConst = true)
else:
localError(m.config, n.info, "cannot determine how to produce code for string literal")

View File

@@ -11,8 +11,8 @@
## is needed for incremental compilation.
import
ast, astalgo, ropes, options, strutils, nimlexbase, msgs, cgendata, rodutils,
intsets, platform, llstream, tables, sighashes, pathutils
ast, ropes, options, strutils, nimlexbase, cgendata, rodutils,
intsets, llstream, tables, modulegraphs, pathutils
# Careful! Section marks need to contain a tabulator so that they cannot
# be part of C string literals.
@@ -21,16 +21,18 @@ const
CFileSectionNames: array[TCFileSection, string] = [
cfsMergeInfo: "",
cfsHeaders: "NIM_merge_HEADERS",
cfsFrameDefines: "NIM_merge_FRAME_DEFINES",
cfsForwardTypes: "NIM_merge_FORWARD_TYPES",
cfsTypes: "NIM_merge_TYPES",
cfsSeqTypes: "NIM_merge_SEQ_TYPES",
cfsFieldInfo: "NIM_merge_FIELD_INFO",
cfsTypeInfo: "NIM_merge_TYPE_INFO",
cfsProcHeaders: "NIM_merge_PROC_HEADERS",
cfsVars: "NIM_merge_VARS",
cfsData: "NIM_merge_DATA",
cfsVars: "NIM_merge_VARS",
cfsProcs: "NIM_merge_PROCS",
cfsInitProc: "NIM_merge_INIT_PROC",
cfsDatInitProc: "NIM_merge_DATINIT_PROC",
cfsTypeInit1: "NIM_merge_TYPE_INIT1",
cfsTypeInit2: "NIM_merge_TYPE_INIT2",
cfsTypeInit3: "NIM_merge_TYPE_INIT3",
@@ -48,9 +50,9 @@ const
proc genSectionStart*(fs: TCFileSection; conf: ConfigRef): Rope =
if compilationCachePresent(conf):
result = nil
add(result, "\n/*\t")
add(result, CFileSectionNames[fs])
add(result, ":*/\n")
result.add("\n/*\t")
result.add(CFileSectionNames[fs])
result.add(":*/\n")
proc genSectionEnd*(fs: TCFileSection; conf: ConfigRef): Rope =
if compilationCachePresent(conf):
@@ -59,9 +61,9 @@ proc genSectionEnd*(fs: TCFileSection; conf: ConfigRef): Rope =
proc genSectionStart*(ps: TCProcSection; conf: ConfigRef): Rope =
if compilationCachePresent(conf):
result = rope("")
add(result, "\n/*\t")
add(result, CProcSectionNames[ps])
add(result, ":*/\n")
result.add("\n/*\t")
result.add(CProcSectionNames[ps])
result.add(":*/\n")
proc genSectionEnd*(ps: TCProcSection; conf: ConfigRef): Rope =
if compilationCachePresent(conf):
@@ -144,38 +146,34 @@ proc atEndMark(buf: cstring, pos: int): bool =
proc readVerbatimSection(L: var TBaseLexer): Rope =
var pos = L.bufpos
var buf = L.buf
var r = newStringOfCap(30_000)
while true:
case buf[pos]
case L.buf[pos]
of CR:
pos = nimlexbase.handleCR(L, pos)
buf = L.buf
r.add('\L')
of LF:
pos = nimlexbase.handleLF(L, pos)
buf = L.buf
r.add('\L')
of '\0':
doAssert(false, "ccgmerge: expected: " & NimMergeEndMark)
break
else:
if atEndMark(buf, pos):
if atEndMark(L.buf, pos):
inc pos, NimMergeEndMark.len
break
r.add(buf[pos])
r.add(L.buf[pos])
inc pos
L.bufpos = pos
result = r.rope
proc readKey(L: var TBaseLexer, result: var string) =
var pos = L.bufpos
var buf = L.buf
setLen(result, 0)
while buf[pos] in IdentChars:
result.add(buf[pos])
while L.buf[pos] in IdentChars:
result.add(L.buf[pos])
inc pos
if buf[pos] != ':': doAssert(false, "ccgmerge: ':' expected")
if L.buf[pos] != ':': doAssert(false, "ccgmerge: ':' expected")
L.bufpos = pos + 1 # skip ':'
proc newFakeType(id: int): PType =

File diff suppressed because it is too large Load Diff

View File

@@ -16,12 +16,12 @@ proc emulatedThreadVars(conf: ConfigRef): bool =
result = {optThreads, optTlsEmulation} <= conf.globalOptions
proc accessThreadLocalVar(p: BProc, s: PSym) =
if emulatedThreadVars(p.config) and not p.threadVarAccessed:
p.threadVarAccessed = true
if emulatedThreadVars(p.config) and threadVarAccessed notin p.flags:
p.flags.incl threadVarAccessed
incl p.module.flags, usesThreadVars
addf(p.procSec(cpsLocals), "\tNimThreadVars* NimTV_;$n", [])
add(p.procSec(cpsInit),
ropecg(p.module, "\tNimTV_ = (NimThreadVars*) #GetThreadLocalVars();$n"))
p.procSec(cpsLocals).addf("\tNimThreadVars* NimTV_;$n", [])
p.procSec(cpsInit).add(
ropecg(p.module, "\tNimTV_ = (NimThreadVars*) #GetThreadLocalVars();$n", []))
proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) =
if emulatedThreadVars(m.config):
@@ -30,23 +30,25 @@ proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) =
# allocator for it :-(
if not containsOrIncl(m.g.nimtvDeclared, s.id):
m.g.nimtvDeps.add(s.loc.t)
addf(m.g.nimtv, "$1 $2;$n", [getTypeDesc(m, s.loc.t), s.loc.r])
m.g.nimtv.addf("$1 $2;$n", [getTypeDesc(m, s.loc.t), s.loc.r])
else:
if isExtern: add(m.s[cfsVars], "extern ")
if optThreads in m.config.globalOptions: add(m.s[cfsVars], "NIM_THREADVAR ")
add(m.s[cfsVars], getTypeDesc(m, s.loc.t))
addf(m.s[cfsVars], " $1;$n", [s.loc.r])
if isExtern: m.s[cfsVars].add("extern ")
elif lfExportLib in s.loc.flags: m.s[cfsVars].add("N_LIB_EXPORT_VAR ")
else: m.s[cfsVars].add("N_LIB_PRIVATE ")
if optThreads in m.config.globalOptions: m.s[cfsVars].add("NIM_THREADVAR ")
m.s[cfsVars].add(getTypeDesc(m, s.loc.t))
m.s[cfsVars].addf(" $1;$n", [s.loc.r])
proc generateThreadLocalStorage(m: BModule) =
if m.g.nimtv != nil and (usesThreadVars in m.flags or sfMainModule in m.module.flags):
for t in items(m.g.nimtvDeps): discard getTypeDesc(m, t)
addf(m.s[cfsSeqTypes], "typedef struct {$1} NimThreadVars;$n", [m.g.nimtv])
m.s[cfsSeqTypes].addf("typedef struct {$1} NimThreadVars;$n", [m.g.nimtv])
proc generateThreadVarsSize(m: BModule) =
if m.g.nimtv != nil:
let externc = if m.config.cmd == cmdCompileToCpp or
sfCompileToCpp in m.module.flags: "extern \"C\" "
else: ""
addf(m.s[cfsProcs],
m.s[cfsProcs].addf(
"$#NI NimThreadVarsSize(){return (NI)sizeof(NimThreadVars);}$n",
[externc.rope])

View File

@@ -16,6 +16,9 @@ type
p: BProc
visitorFrmt: string
const
visitorFrmt = "#nimGCvisit((void*)$1, $2);$n"
proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType)
proc genCaseRange(p: BProc, branch: PNode)
proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false)
@@ -25,18 +28,18 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, n: PNode;
if n == nil: return
case n.kind
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
genTraverseProc(c, accessor, n.sons[i], typ)
for i in 0..<n.len:
genTraverseProc(c, accessor, n[i], typ)
of nkRecCase:
if (n.sons[0].kind != nkSym): internalError(c.p.config, n.info, "genTraverseProc")
if (n[0].kind != nkSym): internalError(c.p.config, n.info, "genTraverseProc")
var p = c.p
let disc = n.sons[0].sym
let disc = n[0].sym
if disc.loc.r == nil: fillObjectFields(c.p.module, typ)
if disc.loc.t == nil:
internalError(c.p.config, n.info, "genTraverseProc()")
lineF(p, cpsStmts, "switch ($1.$2) {$n", [accessor, disc.loc.r])
for i in countup(1, sonsLen(n) - 1):
let branch = n.sons[i]
for i in 1..<n.len:
let branch = n[i]
assert branch.kind in {nkOfBranch, nkElse}
if branch.kind == nkOfBranch:
genCaseRange(c.p, branch)
@@ -67,47 +70,48 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) =
var p = c.p
case typ.kind
of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred,
tySink:
tySink, tyOwned:
genTraverseProc(c, accessor, lastSon(typ))
of tyArray:
let arraySize = lengthOrd(c.p.config, typ.sons[0])
let arraySize = lengthOrd(c.p.config, typ[0])
var i: TLoc
getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo(), tyInt), i)
getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo, tyInt), i)
let oldCode = p.s(cpsStmts)
linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
i.r, arraySize.rope)
[i.r, arraySize])
let oldLen = p.s(cpsStmts).len
genTraverseProc(c, ropecg(c.p.module, "$1[$2]", accessor, i.r), typ.sons[1])
genTraverseProc(c, ropecg(c.p.module, "$1[$2]", [accessor, i.r]), typ[1])
if p.s(cpsStmts).len == oldLen:
# do not emit dummy long loops for faster debug builds:
p.s(cpsStmts) = oldCode
else:
lineF(p, cpsStmts, "}$n", [])
of tyObject:
for i in countup(0, sonsLen(typ) - 1):
var x = typ.sons[i]
for i in 0..<typ.len:
var x = typ[i]
if x != nil: x = x.skipTypes(skipPtrs)
genTraverseProc(c, accessor.parentObj(c.p.module), x)
if typ.n != nil: genTraverseProc(c, accessor, typ.n, typ)
of tyTuple:
let typ = getUniqueType(typ)
for i in countup(0, sonsLen(typ) - 1):
genTraverseProc(c, ropecg(c.p.module, "$1.Field$2", accessor, i.rope), typ.sons[i])
for i in 0..<typ.len:
genTraverseProc(c, ropecg(c.p.module, "$1.Field$2", [accessor, i]), typ[i])
of tyRef:
lineCg(p, cpsStmts, c.visitorFrmt, accessor)
lineCg(p, cpsStmts, visitorFrmt, [accessor, c.visitorFrmt])
of tySequence:
if tfHasAsgn notin typ.flags:
lineCg(p, cpsStmts, c.visitorFrmt, accessor)
if optSeqDestructors notin c.p.module.config.globalOptions:
lineCg(p, cpsStmts, visitorFrmt, [accessor, c.visitorFrmt])
elif containsGarbageCollectedRef(typ.lastSon):
# destructor based seqs are themselves not traced but their data is, if
# they contain a GC'ed type:
genTraverseProcSeq(c, accessor, typ)
lineCg(p, cpsStmts, "#nimGCvisitSeq((void*)$1, $2);$n", [accessor, c.visitorFrmt])
#genTraverseProcSeq(c, accessor, typ)
of tyString:
if tfHasAsgn notin typ.flags:
lineCg(p, cpsStmts, c.visitorFrmt, accessor)
lineCg(p, cpsStmts, visitorFrmt, [accessor, c.visitorFrmt])
of tyProc:
if typ.callConv == ccClosure:
lineCg(p, cpsStmts, c.visitorFrmt, ropecg(c.p.module, "$1.ClE_0", accessor))
lineCg(p, cpsStmts, visitorFrmt, [ropecg(c.p.module, "$1.ClE_0", [accessor]), c.visitorFrmt])
else:
discard
@@ -115,7 +119,7 @@ proc genTraverseProcSeq(c: TTraversalClosure, accessor: Rope, typ: PType) =
var p = c.p
assert typ.kind == tySequence
var i: TLoc
getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo(), tyInt), i)
getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo, tyInt), i)
let oldCode = p.s(cpsStmts)
var a: TLoc
a.r = accessor
@@ -123,7 +127,7 @@ proc genTraverseProcSeq(c: TTraversalClosure, accessor: Rope, typ: PType) =
lineF(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
[i.r, lenExpr(c.p, a)])
let oldLen = p.s(cpsStmts).len
genTraverseProc(c, "$1$3[$2]" % [accessor, i.r, dataField(c.p)], typ.sons[0])
genTraverseProc(c, "$1$3[$2]" % [accessor, i.r, dataField(c.p)], typ[0])
if p.s(cpsStmts).len == oldLen:
# do not emit dummy long loops for faster debug builds:
p.s(cpsStmts) = oldCode
@@ -134,46 +138,53 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope =
var c: TTraversalClosure
var p = newProc(nil, m)
result = "Marker_" & getTypeName(m, origTyp, sig)
var typ = origTyp.skipTypes(abstractInst)
let
hcrOn = m.hcrOn
typ = origTyp.skipTypes(abstractInstOwned)
markerName = if hcrOn: result & "_actual" else: result
header = "static N_NIMCALL(void, $1)(void* p, NI op)" % [markerName]
t = getTypeDesc(m, typ)
let header = "static N_NIMCALL(void, $1)(void* p, NI op)" % [result]
let t = getTypeDesc(m, typ)
lineF(p, cpsLocals, "$1 a;$n", [t])
lineF(p, cpsInit, "a = ($1)p;$n", [t])
c.p = p
c.visitorFrmt = "#nimGCvisit((void*)$1, op);$n"
c.visitorFrmt = "op" # "#nimGCvisit((void*)$1, op);$n"
assert typ.kind != tyTypeDesc
if typ.kind == tySequence:
genTraverseProcSeq(c, "a".rope, typ)
else:
if skipTypes(typ.sons[0], typedescInst).kind == tyArray:
if skipTypes(typ[0], typedescInst+{tyOwned}).kind == tyArray:
# C's arrays are broken beyond repair:
genTraverseProc(c, "a".rope, typ.sons[0])
genTraverseProc(c, "a".rope, typ[0])
else:
genTraverseProc(c, "(*a)".rope, typ.sons[0])
genTraverseProc(c, "(*a)".rope, typ[0])
let generatedProc = "$1 {$n$2$3$4}$n" %
let generatedProc = "$1 {$n$2$3$4}\n" %
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)]
m.s[cfsProcHeaders].addf("$1;$n", [header])
m.s[cfsProcHeaders].addf("$1;\n", [header])
m.s[cfsProcs].add(generatedProc)
if hcrOn:
m.s[cfsProcHeaders].addf("N_NIMCALL_PTR(void, $1)(void*, NI);\n", [result])
m.s[cfsDynLibInit].addf("\t$1 = (N_NIMCALL_PTR(void, )(void*, NI)) hcrRegisterProc($3, \"$1\", (void*)$2);\n",
[result, markerName, getModuleDllPath(m)])
proc genTraverseProcForGlobal(m: BModule, s: PSym; info: TLineInfo): Rope =
discard genTypeInfo(m, s.loc.t, info)
var c: TTraversalClosure
var p = newProc(nil, m)
var sLoc = s.loc.r
var sLoc = rdLoc(s.loc)
result = getTempName(m)
if sfThread in s.flags and emulatedThreadVars(m.config):
accessThreadLocalVar(p, s)
sLoc = "NimTV_->" & sLoc
c.visitorFrmt = "#nimGCvisit((void*)$1, 0);$n"
c.visitorFrmt = "0" # "#nimGCvisit((void*)$1, 0);$n"
c.p = p
let header = "static N_NIMCALL(void, $1)(void)" % [result]
genTraverseProc(c, sLoc, s.loc.t)

File diff suppressed because it is too large Load Diff

View File

@@ -10,17 +10,17 @@
# This module declares some helpers for the C code generator.
import
ast, astalgo, ropes, hashes, strutils, types, msgs, wordrecg,
ast, hashes, strutils, msgs, wordrecg,
platform, trees, options
proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
case n.kind
of nkStmtList:
for i in 0 ..< n.len:
for i in 0..<n.len:
result = getPragmaStmt(n[i], w)
if result != nil: break
of nkPragma:
for i in 0 ..< n.len:
for i in 0..<n.len:
if whichPragma(n[i]) == w: return n[i]
else: discard
@@ -28,29 +28,29 @@ proc stmtsContainPragma*(n: PNode, w: TSpecialWord): bool =
result = getPragmaStmt(n, w) != nil
proc hashString*(conf: ConfigRef; s: string): BiggestInt =
# has to be the same algorithm as system.hashString!
# has to be the same algorithm as strmantle.hashString!
if CPU[conf.target.targetCPU].bit == 64:
# we have to use the same bitwidth
# as the target CPU
var b = 0'i64
for i in countup(0, len(s) - 1):
b = b +% ord(s[i])
b = b +% `shl`(b, 10)
b = b xor `shr`(b, 6)
b = b +% `shl`(b, 3)
b = b xor `shr`(b, 11)
b = b +% `shl`(b, 15)
result = b
var b = 0'u64
for i in 0..<s.len:
b = b + uint(s[i])
b = b + (b shl 10)
b = b xor (b shr 6)
b = b + (b shl 3)
b = b xor (b shr 11)
b = b + (b shl 15)
result = cast[Hash](b)
else:
var a = 0'i32
for i in countup(0, len(s) - 1):
a = a +% ord(s[i]).int32
a = a +% `shl`(a, 10'i32)
a = a xor `shr`(a, 6'i32)
a = a +% `shl`(a, 3'i32)
a = a xor `shr`(a, 11'i32)
a = a +% `shl`(a, 15'i32)
result = a
var a = 0'u32
for i in 0..<s.len:
a = a + uint32(s[i])
a = a + (a shl 10)
a = a xor (a shr 6)
a = a + (a shl 3)
a = a xor (a shr 11)
a = a + (a shl 15)
result = cast[Hash](a)
template getUniqueType*(key: PType): PType = key
@@ -70,18 +70,18 @@ proc mangle*(name: string): string =
template special(x) =
result.add x
requiresUnderscore = true
for i in start..(name.len-1):
for i in start..<name.len:
let c = name[i]
case c
of 'a'..'z', '0'..'9', 'A'..'Z':
add(result, c)
result.add(c)
of '_':
# we generate names like 'foo_9' for scope disambiguations and so
# disallow this here:
if i > 0 and i < name.len-1 and name[i+1] in Digits:
discard
else:
add(result, c)
result.add(c)
of '$': special "dollar"
of '%': special "percent"
of '&': special "amp"
@@ -102,7 +102,7 @@ proc mangle*(name: string): string =
of '@': special "at"
of '|': special "bar"
else:
add(result, "X" & toHex(ord(c), 2))
result.add("X" & toHex(ord(c), 2))
requiresUnderscore = true
if requiresUnderscore:
result.add "_"

File diff suppressed because it is too large Load Diff

View File

@@ -10,16 +10,15 @@
## This module contains the data structures for the C code generation phase.
import
ast, astalgo, ropes, passes, options, intsets, platform, sighashes,
tables, ndi, lineinfos, pathutils
from modulegraphs import ModuleGraph
ast, ropes, options, intsets,
tables, ndi, lineinfos, pathutils, modulegraphs
type
TLabel* = Rope # for the C generator a label is just a rope
TCFileSection* = enum # the sections a generated C file consists of
cfsMergeInfo, # section containing merge information
cfsHeaders, # section for C include file headers
cfsFrameDefines # section for nim frame macros
cfsForwardTypes, # section for C forward typedefs
cfsTypes, # section for C typedefs
cfsSeqTypes, # section for sequence types only
@@ -28,10 +27,11 @@ type
cfsFieldInfo, # section for field information
cfsTypeInfo, # section for type information
cfsProcHeaders, # section for C procs prototypes
cfsVars, # section for C variable declarations
cfsData, # section for C constant data
cfsVars, # section for C variable declarations
cfsProcs, # section for C procs that are not inline
cfsInitProc, # section for the C init proc
cfsDatInitProc, # section for the C datInit proc
cfsTypeInit1, # section 1 for declarations of type information
cfsTypeInit2, # section 2 for init of type information
cfsTypeInit3, # section 3 for init of type information
@@ -58,21 +58,26 @@ type
id*: int # the ID of the label; positive means that it
label*: Rope # generated text for the label
# nil if label is not used
sections*: TCProcSections # the code beloging
sections*: TCProcSections # the code belonging
isLoop*: bool # whether block is a loop
nestedTryStmts*: int16 # how many try statements is it nested into
nestedExceptStmts*: int16 # how many except statements is it nested into
frameLen*: int16
TCProcFlag* = enum
beforeRetNeeded,
threadVarAccessed,
hasCurFramePointer,
noSafePoints,
nimErrorFlagAccessed,
nimErrorFlagDeclared
TCProc = object # represents C proc that is currently generated
prc*: PSym # the Nim proc that this C proc belongs to
beforeRetNeeded*: bool # true iff 'BeforeRet' label for proc is needed
threadVarAccessed*: bool # true if the proc already accessed some threadvar
hasCurFramePointer*: bool # true if _nimCurFrame var needed to recover after
# exception is generated
flags*: set[TCProcFlag]
lastLineInfo*: TLineInfo # to avoid generating excessive 'nimln' statements
currLineInfo*: TLineInfo # AST codegen will make this superfluous
nestedTryStmts*: seq[tuple[n: PNode, inExcept: bool]]
nestedTryStmts*: seq[tuple[fin: PNode, inExcept: bool, label: Natural]]
# in how many nested try statements we are
# (the vars must be volatile then)
# bool is true when are in the except part of a try block
@@ -85,20 +90,19 @@ type
options*: TOptions # options that should be used for code
# generation; this is the same as prc.options
# unless prc == nil
maxFrameLen*: int # max length of frame descriptor
module*: BModule # used to prevent excessive parameter passing
withinLoop*: int # > 0 if we are within a loop
splitDecls*: int # > 0 if we are in some context for C++ that
# requires 'T x = T()' to become 'T x; x = T()'
# (yes, C++ is weird like that)
gcFrameId*: Natural # for the GC stack marking
gcFrameType*: Rope # the struct {} we put the GC markers into
withinTryWithExcept*: int # required for goto based exception handling
sigConflicts*: CountTable[string]
TTypeSeq* = seq[PType]
TypeCache* = Table[SigHash, Rope]
TypeCacheWithOwner* = Table[SigHash, tuple[str: Rope, owner: PSym]]
Codegenflag* = enum
CodegenFlag* = enum
preventStackTrace, # true if stack traces need to be prevented
usesThreadVars, # true if the module uses a thread var
frameDeclared, # hack for ROD support so that we don't declare
@@ -112,11 +116,10 @@ type
mainModProcs*, mainModInit*, otherModsInit*, mainDatInit*: Rope
mapping*: Rope # the generated mapping file (if requested)
modules*: seq[BModule] # list of all compiled modules
forwardedProcsCounter*: int
modulesClosed*: seq[BModule] # list of the same compiled modules, but in the order they were closed
forwardedProcs*: seq[PSym] # proc:s that did not yet have a body
generatedHeader*: BModule
breakPointId*: int
breakpoints*: Rope # later the breakpoints are inserted into the main proc
typeInfoMarker*: TypeCache
typeInfoMarker*: TypeCacheWithOwner
config*: ConfigRef
graph*: ModuleGraph
strVersion*, seqVersion*: int # version of the string/seq implementation to use
@@ -132,9 +135,9 @@ type
# nimtvDeps is VERY hard to cache because it's
# not a list of IDs nor can it be made to be one.
TCGen = object of TPassContext # represents a C source file
TCGen = object of PPassContext # represents a C source file
s*: TCFileSections # sections of the C file
flags*: set[Codegenflag]
flags*: set[CodegenFlag]
module*: PSym
filename*: AbsoluteFile
cfilename*: AbsoluteFile # filename of the module (including path,
@@ -148,14 +151,15 @@ type
typeInfoMarker*: TypeCache # needed for generating type information
initProc*: BProc # code for init procedure
preInitProc*: BProc # code executed before the init proc
hcrCreateTypeInfosProc*: Rope # type info globals are in here when HCR=on
inHcrInitGuard*: bool # We are currently within a HCR reloading guard.
typeStack*: TTypeSeq # used for type generation
dataCache*: TNodeTable
forwardedProcs*: TSymSeq # keep forwarded procs here
typeNodes*, nimTypes*: int # used for type info generation
typeNodesName*, nimTypesName*: Rope # used for type info generation
labels*: Natural # for generating unique module-scope names
extensionLoaders*: array['0'..'9', Rope] # special procs for the
# OpenGL wrapper
# OpenGL wrapper
injectStmt*: Rope
sigConflicts*: CountTable[SigHash]
g*: BModuleList
@@ -170,7 +174,7 @@ proc includeHeader*(this: BModule; header: string) =
proc s*(p: BProc, s: TCProcSection): var Rope {.inline.} =
# section in the current block
result = p.blocks[p.blocks.len-1].sections[s]
result = p.blocks[^1].sections[s]
proc procSec*(p: BProc, s: TCProcSection): var Rope {.inline.} =
# top level proc sections
@@ -188,12 +192,10 @@ proc newProc*(prc: PSym, module: BModule): BProc =
result.sigConflicts = initCountTable[string]()
proc newModuleList*(g: ModuleGraph): BModuleList =
BModuleList(modules: @[], typeInfoMarker: initTable[SigHash, Rope](), config: g.config,
graph: g, nimtvDeps: @[], nimtvDeclared: initIntSet())
BModuleList(typeInfoMarker: initTable[SigHash, tuple[str: Rope, owner: PSym]](),
config: g.config, graph: g, nimtvDeclared: initIntSet())
iterator cgenModules*(g: BModuleList): BModule =
for i in 0..high(g.modules):
# ultimately, we are iterating over the file ids here.
# some "files" won't have an associated cgen module (like stdin)
# and we must skip over them.
if g.modules[i] != nil: yield g.modules[i]
for m in g.modulesClosed:
# iterate modules in the order they were closed
yield m

View File

@@ -7,10 +7,10 @@
# distribution, for details about the copyright.
#
## This module implements code generation for multi methods.
## This module implements code generation for methods.
import
intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys,
intsets, options, ast, msgs, idents, renderer, types, magicsys,
sempass2, strutils, modulegraphs, lineinfos
proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
@@ -23,11 +23,11 @@ proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
result = n
elif diff < 0:
result = newNodeIT(nkObjUpConv, n.info, d)
addSon(result, n)
result.add n
if downcast: internalError(conf, n.info, "cgmeth.genConv: no upcast allowed")
elif diff > 0:
result = newNodeIT(nkObjDownConv, n.info, d)
addSon(result, n)
result.add n
if not downcast:
internalError(conf, n.info, "cgmeth.genConv: no downcast allowed")
else:
@@ -37,34 +37,33 @@ proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
proc getDispatcher*(s: PSym): PSym =
## can return nil if is has no dispatcher.
let dispn = lastSon(s.ast)
if dispn.kind == nkSym:
let disp = dispn.sym
if sfDispatcher in disp.flags: result = disp
if dispatcherPos < s.ast.len:
result = s.ast[dispatcherPos].sym
doAssert sfDispatcher in result.flags
proc methodCall*(n: PNode; conf: ConfigRef): PNode =
result = n
# replace ordinary method by dispatcher method:
let disp = getDispatcher(result.sons[0].sym)
let disp = getDispatcher(result[0].sym)
if disp != nil:
result.sons[0].sym = disp
result[0].sym = disp
# change the arguments to up/downcasts to fit the dispatcher's parameters:
for i in countup(1, sonsLen(result)-1):
result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true, conf)
for i in 1..<result.len:
result[i] = genConv(result[i], disp.typ[i], true, conf)
else:
localError(conf, n.info, "'" & $result.sons[0] & "' lacks a dispatcher")
localError(conf, n.info, "'" & $result[0] & "' lacks a dispatcher")
type
MethodResult = enum No, Invalid, Yes
proc sameMethodBucket(a, b: PSym): MethodResult =
proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
if a.name.id != b.name.id: return
if sonsLen(a.typ) != sonsLen(b.typ):
if a.typ.len != b.typ.len:
return
for i in countup(1, sonsLen(a.typ) - 1):
var aa = a.typ.sons[i]
var bb = b.typ.sons[i]
for i in 1..<a.typ.len:
var aa = a.typ[i]
var bb = b.typ[i]
while true:
aa = skipTypes(aa, {tyGenericInst, tyAlias})
bb = skipTypes(bb, {tyGenericInst, tyAlias})
@@ -73,10 +72,10 @@ proc sameMethodBucket(a, b: PSym): MethodResult =
bb = bb.lastSon
else:
break
if sameType(a.typ.sons[i], b.typ.sons[i]):
if sameType(a.typ[i], b.typ[i]):
if aa.kind == tyObject and result != Invalid:
result = Yes
elif aa.kind == tyObject and bb.kind == tyObject:
elif aa.kind == tyObject and bb.kind == tyObject and (i == 1 or multiMethods):
let diff = inheritanceDiff(bb, aa)
if diff < 0:
if result != Invalid:
@@ -91,21 +90,22 @@ proc sameMethodBucket(a, b: PSym): MethodResult =
return No
if result == Yes:
# check for return type:
if not sameTypeOrNil(a.typ.sons[0], b.typ.sons[0]):
if b.typ.sons[0] != nil and b.typ.sons[0].kind == tyExpr:
if not sameTypeOrNil(a.typ[0], b.typ[0]):
if b.typ[0] != nil and b.typ[0].kind == tyUntyped:
# infer 'auto' from the base to make it consistent:
b.typ.sons[0] = a.typ.sons[0]
b.typ[0] = a.typ[0]
else:
return No
proc attachDispatcher(s: PSym, dispatcher: PNode) =
var L = s.ast.len-1
var x = s.ast.sons[L]
if x.kind == nkSym and sfDispatcher in x.sym.flags:
if dispatcherPos < s.ast.len:
# we've added a dispatcher already, so overwrite it
s.ast.sons[L] = dispatcher
s.ast[dispatcherPos] = dispatcher
else:
s.ast.add(dispatcher)
setLen(s.ast.sons, dispatcherPos+1)
if s.ast[resultPos] == nil:
s.ast[resultPos] = newNodeI(nkEmpty, s.info)
s.ast[dispatcherPos] = dispatcher
proc createDispatcher(s: PSym): PSym =
var disp = copySym(s)
@@ -115,16 +115,16 @@ proc createDispatcher(s: PSym): PSym =
# we can't inline the dispatcher itself (for now):
if disp.typ.callConv == ccInline: disp.typ.callConv = ccDefault
disp.ast = copyTree(s.ast)
disp.ast.sons[bodyPos] = newNodeI(nkEmpty, s.info)
disp.ast[bodyPos] = newNodeI(nkEmpty, s.info)
disp.loc.r = nil
if s.typ.sons[0] != nil:
if disp.ast.sonsLen > resultPos:
disp.ast.sons[resultPos].sym = copySym(s.ast.sons[resultPos].sym)
if s.typ[0] != nil:
if disp.ast.len > resultPos:
disp.ast[resultPos].sym = copySym(s.ast[resultPos].sym)
else:
# We've encountered a method prototype without a filled-in
# resultPos slot. We put a placeholder in there that will
# be updated in fixupDispatcher().
disp.ast.addSon(newNodeI(nkEmpty, s.info))
disp.ast.add newNodeI(nkEmpty, s.info)
attachDispatcher(s, newSymNode(disp))
# attach to itself to prevent bugs:
attachDispatcher(disp, newSymNode(disp))
@@ -136,9 +136,9 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) =
# from later definitions, particularly the resultPos slot. Also,
# the lock level of the dispatcher needs to be updated/checked
# against that of the method.
if disp.ast.sonsLen > resultPos and meth.ast.sonsLen > resultPos and
disp.ast.sons[resultPos].kind == nkEmpty:
disp.ast.sons[resultPos] = copyTree(meth.ast.sons[resultPos])
if disp.ast.len > resultPos and meth.ast.len > resultPos and
disp.ast[resultPos].kind == nkEmpty:
disp.ast[resultPos] = copyTree(meth.ast[resultPos])
# The following code works only with lock levels, so we disable
# it when they're not available.
@@ -158,14 +158,13 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) =
disp.typ.lockLevel = meth.typ.lockLevel
proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
let L = len(g.methods)
var witness: PSym
for i in countup(0, L - 1):
for i in 0..<g.methods.len:
let disp = g.methods[i].dispatcher
case sameMethodBucket(disp, s)
case sameMethodBucket(disp, s, multimethods = optMultiMethods in g.config.globalOptions)
of Yes:
add(g.methods[i].methods, s)
attachDispatcher(s, lastSon(disp.ast))
g.methods[i].methods.add(s)
attachDispatcher(s, disp.ast[dispatcherPos])
fixupDispatcher(s, disp, g.config)
#echo "fixup ", disp.name.s, " ", disp.id
when useEffectSystem: checkMethodEffects(g, disp, s)
@@ -178,7 +177,7 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
of Invalid:
if witness.isNil: witness = g.methods[i].methods[0]
# create a new dispatcher:
add(g.methods, (methods: @[s], dispatcher: createDispatcher(s)))
g.methods.add((methods: @[s], dispatcher: createDispatcher(s)))
#echo "adding ", s.info
#if fromCache:
# internalError(s.info, "no method dispatcher found")
@@ -188,34 +187,34 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
elif sfBase notin s.flags:
message(g.config, s.info, warnUseBase)
proc relevantCol(methods: TSymSeq, col: int): bool =
proc relevantCol(methods: seq[PSym], col: int): bool =
# returns true iff the position is relevant
var t = methods[0].typ.sons[col].skipTypes(skipPtrs)
var t = methods[0].typ[col].skipTypes(skipPtrs)
if t.kind == tyObject:
for i in countup(1, high(methods)):
let t2 = skipTypes(methods[i].typ.sons[col], skipPtrs)
for i in 1..high(methods):
let t2 = skipTypes(methods[i].typ[col], skipPtrs)
if not sameType(t2, t):
return true
proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int =
for col in countup(1, sonsLen(a.typ) - 1):
for col in 1..<a.typ.len:
if contains(relevantCols, col):
var aa = skipTypes(a.typ.sons[col], skipPtrs)
var bb = skipTypes(b.typ.sons[col], skipPtrs)
var aa = skipTypes(a.typ[col], skipPtrs)
var bb = skipTypes(b.typ[col], skipPtrs)
var d = inheritanceDiff(aa, bb)
if (d != high(int)) and d != 0:
return d
proc sortBucket(a: var TSymSeq, relevantCols: IntSet) =
proc sortBucket(a: var seq[PSym], relevantCols: IntSet) =
# we use shellsort here; fast and simple
var n = len(a)
var n = a.len
var h = 1
while true:
h = 3 * h + 1
if h > n: break
while true:
h = h div 3
for i in countup(h, n - 1):
for i in h..<n:
var v = a[i]
var j = i
while cmpSignatures(a[j - h], v, relevantCols) >= 0:
@@ -225,70 +224,73 @@ proc sortBucket(a: var TSymSeq, relevantCols: IntSet) =
a[j] = v
if h == 1: break
proc genDispatcher(g: ModuleGraph; methods: TSymSeq, relevantCols: IntSet): PSym =
var base = lastSon(methods[0].ast).sym
proc genDispatcher(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet): PSym =
var base = methods[0].ast[dispatcherPos].sym
result = base
var paramLen = sonsLen(base.typ)
var paramLen = base.typ.len
var nilchecks = newNodeI(nkStmtList, base.info)
var disp = newNodeI(nkIfStmt, base.info)
var ands = getSysMagic(g, unknownLineInfo(), "and", mAnd)
var iss = getSysMagic(g, unknownLineInfo(), "of", mOf)
let boolType = getSysType(g, unknownLineInfo(), tyBool)
for col in countup(1, paramLen - 1):
var ands = getSysMagic(g, unknownLineInfo, "and", mAnd)
var iss = getSysMagic(g, unknownLineInfo, "of", mOf)
let boolType = getSysType(g, unknownLineInfo, tyBool)
for col in 1..<paramLen:
if contains(relevantCols, col):
let param = base.typ.n.sons[col].sym
let param = base.typ.n[col].sym
if param.typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}:
addSon(nilchecks, newTree(nkCall,
newSymNode(getCompilerProc(g, "chckNilDisp")), newSymNode(param)))
for meth in countup(0, high(methods)):
nilchecks.add newTree(nkCall,
newSymNode(getCompilerProc(g, "chckNilDisp")), newSymNode(param))
for meth in 0..high(methods):
var curr = methods[meth] # generate condition:
var cond: PNode = nil
for col in countup(1, paramLen - 1):
for col in 1..<paramLen:
if contains(relevantCols, col):
var isn = newNodeIT(nkCall, base.info, boolType)
addSon(isn, newSymNode(iss))
let param = base.typ.n.sons[col].sym
addSon(isn, newSymNode(param))
addSon(isn, newNodeIT(nkType, base.info, curr.typ.sons[col]))
isn.add newSymNode(iss)
let param = base.typ.n[col].sym
isn.add newSymNode(param)
isn.add newNodeIT(nkType, base.info, curr.typ[col])
if cond != nil:
var a = newNodeIT(nkCall, base.info, boolType)
addSon(a, newSymNode(ands))
addSon(a, cond)
addSon(a, isn)
a.add newSymNode(ands)
a.add cond
a.add isn
cond = a
else:
cond = isn
let retTyp = base.typ.sons[0]
let retTyp = base.typ[0]
let call = newNodeIT(nkCall, base.info, retTyp)
addSon(call, newSymNode(curr))
for col in countup(1, paramLen - 1):
addSon(call, genConv(newSymNode(base.typ.n.sons[col].sym),
curr.typ.sons[col], false, g.config))
call.add newSymNode(curr)
for col in 1..<paramLen:
call.add genConv(newSymNode(base.typ.n[col].sym),
curr.typ[col], false, g.config)
var ret: PNode
if retTyp != nil:
var a = newNodeI(nkFastAsgn, base.info)
addSon(a, newSymNode(base.ast.sons[resultPos].sym))
addSon(a, call)
a.add newSymNode(base.ast[resultPos].sym)
a.add call
ret = newNodeI(nkReturnStmt, base.info)
addSon(ret, a)
ret.add a
else:
ret = call
if cond != nil:
var a = newNodeI(nkElifBranch, base.info)
addSon(a, cond)
addSon(a, ret)
addSon(disp, a)
a.add cond
a.add ret
disp.add a
else:
disp = ret
nilchecks.add disp
result.ast.sons[bodyPos] = nilchecks
nilchecks.flags.incl nfTransf # should not be further transformed
result.ast[bodyPos] = nilchecks
proc generateMethodDispatchers*(g: ModuleGraph): PNode =
result = newNode(nkStmtList)
for bucket in countup(0, len(g.methods) - 1):
for bucket in 0..<g.methods.len:
var relevantCols = initIntSet()
for col in countup(1, sonsLen(g.methods[bucket].methods[0].typ) - 1):
for col in 1..<g.methods[bucket].methods[0].typ.len:
if relevantCol(g.methods[bucket].methods, col): incl(relevantCols, col)
if optMultiMethods notin g.config.globalOptions:
# if multi-methods are not enabled, we are interested only in the first field
break
sortBucket(g.methods[bucket].methods, relevantCols)
addSon(result,
newSymNode(genDispatcher(g, g.methods[bucket].methods, relevantCols)))
result.add newSymNode(genDispatcher(g, g.methods[bucket].methods, relevantCols))

View File

@@ -90,9 +90,6 @@
# :unrollFinally = true
# goto nearestFinally (or -1 if not exists)
#
# Every finally block calls closureIterEndFinally() upon its successful
# completion.
#
# Example:
#
# try:
@@ -126,13 +123,14 @@
# if :curExc.isNil:
# return :tmpResult
# else:
# closureIterSetupExc(nil)
# raise
# state = -1 # Goto next state. In this case we just exit
# break :stateLoop
import
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, idents,
renderer, types, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos
ast, msgs, idents,
renderer, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos
type
Ctx = object
@@ -156,8 +154,8 @@ type
# is their finally. For finally it is parent finally. Otherwise -1
const
nkSkip = { nkEmpty..nkNilLit, nkTemplateDef, nkTypeSection, nkStaticStmt,
nkCommentStmt } + procDefs
nkSkip = {nkEmpty..nkNilLit, nkTemplateDef, nkTypeSection, nkStaticStmt,
nkCommentStmt} + procDefs
proc newStateAccess(ctx: var Ctx): PNode =
if ctx.stateVarSym.isNil:
@@ -174,7 +172,7 @@ proc newStateAssgn(ctx: var Ctx, toValue: PNode): PNode =
proc newStateAssgn(ctx: var Ctx, stateNo: int = -2): PNode =
# Creates state assignment:
# :state = stateNo
ctx.newStateAssgn(newIntTypeNode(nkIntLit, stateNo, ctx.g.getSysType(TLineInfo(), tyInt)))
ctx.newStateAssgn(newIntTypeNode(stateNo, ctx.g.getSysType(TLineInfo(), tyInt)))
proc newEnvVar(ctx: var Ctx, name: string, typ: PType): PSym =
result = newSym(skVar, getIdent(ctx.g.cache, name), ctx.fn, ctx.fn.info)
@@ -210,7 +208,7 @@ proc newUnrollFinallyAccess(ctx: var Ctx, info: TLineInfo): PNode =
proc newCurExcAccess(ctx: var Ctx): PNode =
if ctx.curExcSym.isNil:
ctx.curExcSym = ctx.newEnvVar(":curExc", ctx.g.callCodegenProc("getCurrentException", ctx.g.emptyNode).typ)
ctx.curExcSym = ctx.newEnvVar(":curExc", ctx.g.callCodegenProc("getCurrentException").typ)
ctx.newEnvVarAccess(ctx.curExcSym)
proc newState(ctx: var Ctx, n, gotoOut: PNode): int =
@@ -239,7 +237,7 @@ proc toStmtList(n: PNode): PNode =
proc addGotoOut(n: PNode, gotoOut: PNode): PNode =
# Make sure `n` is a stmtlist, and ends with `gotoOut`
result = toStmtList(n)
if result.len == 0 or result.sons[^1].kind != nkGotoState:
if result.len == 0 or result[^1].kind != nkGotoState:
result.add(gotoOut)
proc newTempVar(ctx: var Ctx, typ: PType): PSym =
@@ -275,7 +273,7 @@ proc transformBreaksAndContinuesInWhile(ctx: var Ctx, n: PNode, before, after: P
if ctx.blockLevel == 0:
result = after
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.transformBreaksAndContinuesInWhile(n[i], before, after)
proc transformBreaksInBlock(ctx: var Ctx, n: PNode, label, after: PNode): PNode =
@@ -295,7 +293,7 @@ proc transformBreaksInBlock(ctx: var Ctx, n: PNode, label, after: PNode): PNode
if label.kind == nkSym and n[0].sym == label.sym:
result = after
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.transformBreaksInBlock(n[i], label, after)
proc newNullifyCurExc(ctx: var Ctx, info: TLineInfo): PNode =
@@ -320,11 +318,11 @@ proc collectExceptState(ctx: var Ctx, n: PNode): PNode {.inline.} =
if c.len > 1:
var cond: PNode
for i in 0 .. c.len - 2:
for i in 0..<c.len - 1:
assert(c[i].kind == nkType)
let nextCond = newTree(nkCall,
newSymNode(g.getSysMagic(c.info, "of", mOf)),
g.callCodegenProc("getCurrentException", ctx.g.emptyNode),
g.callCodegenProc("getCurrentException"),
c[i])
nextCond.typ = ctx.g.getSysType(c.info, tyBool)
nextCond.info = c.info
@@ -359,12 +357,12 @@ proc addElseToExcept(ctx: var Ctx, n: PNode) =
block: # :unrollFinally = true
branchBody.add(newTree(nkAsgn,
ctx.newUnrollFinallyAccess(n.info),
newIntTypeNode(nkIntLit, 1, ctx.g.getSysType(n.info, tyBool))))
newIntTypeNode(1, ctx.g.getSysType(n.info, tyBool))))
block: # :curExc = getCurrentException()
branchBody.add(newTree(nkAsgn,
ctx.newCurExcAccess(),
ctx.g.callCodegenProc("getCurrentException", ctx.g.emptyNode)))
ctx.g.callCodegenProc("getCurrentException")))
block: # goto nearestFinally
branchBody.add(newTree(nkGotoState, ctx.g.newIntLit(n.info, ctx.nearestFinally)))
@@ -403,7 +401,7 @@ proc exprToStmtList(n: PNode): tuple[s, res: PNode] =
var n = n
while n.kind == nkStmtListExpr:
result.s.sons.add(n.sons)
result.s.sons.setLen(result.s.sons.len - 1) # delete last son
result.s.sons.setLen(result.s.len - 1) # delete last son
n = n[^1]
result.res = n
@@ -437,7 +435,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkYieldStmt:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@@ -451,7 +449,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkPar, nkObjConstr, nkTupleConstr, nkBracket:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@@ -461,16 +459,23 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
if n.typ.isNil: internalError(ctx.g.config, "lowerStmtListExprs: constr typ.isNil")
result.typ = n.typ
for i in 0 ..< n.len:
if n[i].kind == nkStmtListExpr:
for i in 0..<n.len:
case n[i].kind
of nkExprColonExpr:
if n[i][1].kind == nkStmtListExpr:
let (st, ex) = exprToStmtList(n[i][1])
result.add(st)
n[i][1] = ex
of nkStmtListExpr:
let (st, ex) = exprToStmtList(n[i])
result.add(st)
n[i] = ex
else: discard
result.add(n)
of nkIfStmt, nkIfExpr:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@@ -534,9 +539,9 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
if isExpr: result.add(ctx.newEnvVarAccess(tmp))
of nkTryStmt:
of nkTryStmt, nkHiddenTryStmt:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@@ -549,7 +554,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
let tmp = ctx.newTempVar(n.typ)
n[0] = ctx.convertExprBodyToAsgn(n[0], tmp)
for i in 1 ..< n.len:
for i in 1..<n.len:
let branch = n[i]
case branch.kind
of nkExceptBranch:
@@ -566,7 +571,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkCaseStmt:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@@ -584,7 +589,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
result.add(st)
n[0] = ex
for i in 1 ..< n.len:
for i in 1..<n.len:
let branch = n[i]
case branch.kind
of nkOfBranch:
@@ -596,9 +601,9 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
result.add(n)
result.add(ctx.newEnvVarAccess(tmp))
of nkCallKinds:
of nkCallKinds, nkChckRange, nkChckRangeF, nkChckRange64:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@@ -638,7 +643,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
result.add(ifNode)
result.add(ctx.newEnvVarAccess(tmp))
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
if n[i].kind == nkStmtListExpr:
let (st, ex) = exprToStmtList(n[i])
result.add(st)
@@ -667,7 +672,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkDiscardStmt, nkReturnStmt, nkRaiseStmt:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@@ -678,9 +683,10 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
n[0] = ex
result.add(n)
of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv, nkObjDownConv:
of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv, nkObjDownConv,
nkDerefExpr, nkHiddenDeref:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@@ -694,7 +700,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkAsgn, nkFastAsgn:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@@ -752,7 +758,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
n[0] = newSymNode(ctx.g.getSysSym(n[0].info, "true"))
n[1] = newBody
of nkDotExpr:
of nkDotExpr, nkCheckedFieldExpr:
var ns = false
n[0] = ctx.lowerStmtListExprs(n[0], ns)
if ns:
@@ -772,14 +778,14 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
result = newNodeI(nkStmtListExpr, n.info)
result.typ = n.typ
let (st, ex) = exprToStmtList(n[1])
n.kind = nkBlockStmt
n.transitionSonsKind(nkBlockStmt)
n.typ = nil
n[1] = st
result.add(n)
result.add(ex)
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], needsSplit)
proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
@@ -802,10 +808,11 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
let retStmt = newTree(nkReturnStmt, asgn)
let branch = newTree(nkElifBranch, cmp, retStmt)
# The C++ backend requires `getCurrentException` here.
let raiseStmt = newTree(nkRaiseStmt, ctx.g.callCodegenProc("getCurrentException", ctx.g.emptyNode))
let nullifyExc = newTree(nkCall, newSymNode(ctx.g.getCompilerProc("closureIterSetupExc")), nilnode)
nullifyExc.info = info
let raiseStmt = newTree(nkRaiseStmt, curExc)
raiseStmt.info = info
let elseBranch = newTree(nkElse, raiseStmt)
let elseBranch = newTree(nkElse, newTree(nkStmtList, nullifyExc, raiseStmt))
let ifBody = newTree(nkIfStmt, branch, elseBranch)
let elifBranch = newTree(nkElifBranch, ctx.newUnrollFinallyAccess(info), ifBody)
@@ -825,13 +832,14 @@ proc transformReturnsInTry(ctx: var Ctx, n: PNode): PNode =
block: # :unrollFinally = true
let asgn = newNodeI(nkAsgn, n.info)
asgn.add(ctx.newUnrollFinallyAccess(n.info))
asgn.add(newIntTypeNode(nkIntLit, 1, ctx.g.getSysType(n.info, tyBool)))
asgn.add(newIntTypeNode(1, ctx.g.getSysType(n.info, tyBool)))
result.add(asgn)
if n[0].kind != nkEmpty:
let asgnTmpResult = newNodeI(nkAsgn, n.info)
asgnTmpResult.add(ctx.newTmpResultAccess())
asgnTmpResult.add(n[0])
let x = if n[0].kind in {nkAsgn, nkFastAsgn}: n[0][1] else: n[0]
asgnTmpResult.add(x)
result.add(asgnTmpResult)
result.add(ctx.newNullifyCurExc(n.info))
@@ -842,174 +850,166 @@ proc transformReturnsInTry(ctx: var Ctx, n: PNode): PNode =
of nkSkip:
discard
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.transformReturnsInTry(n[i])
proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode =
result = n
case n.kind:
of nkSkip:
discard
case n.kind
of nkSkip: discard
of nkStmtList, nkStmtListExpr:
assert(isEmptyType(n.typ), "nkStmtListExpr not lowered")
of nkStmtList, nkStmtListExpr:
result = addGotoOut(result, gotoOut)
for i in 0..<n.len:
if n[i].hasYields:
# Create a new split
let go = newNodeI(nkGotoState, n[i].info)
n[i] = ctx.transformClosureIteratorBody(n[i], go)
result = addGotoOut(result, gotoOut)
for i in 0 ..< n.len:
if n[i].hasYieldsInExpressions:
# Lower nkStmtListExpr nodes inside `n[i]` first
var ns = false
n[i] = ctx.lowerStmtListExprs(n[i], ns)
let s = newNodeI(nkStmtList, n[i + 1].info)
for j in i + 1..<n.len:
s.add(n[j])
if n[i].hasYields:
# Create a new split
let go = newNodeI(nkGotoState, n[i].info)
n[i] = ctx.transformClosureIteratorBody(n[i], go)
n.sons.setLen(i + 1)
discard ctx.newState(s, go)
if ctx.transformClosureIteratorBody(s, gotoOut) != s:
internalError(ctx.g.config, "transformClosureIteratorBody != s")
break
let s = newNodeI(nkStmtList, n[i + 1].info)
for j in i + 1 ..< n.len:
s.add(n[j])
of nkYieldStmt:
result = newNodeI(nkStmtList, n.info)
result.add(n)
result.add(gotoOut)
n.sons.setLen(i + 1)
discard ctx.newState(s, go)
if ctx.transformClosureIteratorBody(s, gotoOut) != s:
internalError(ctx.g.config, "transformClosureIteratorBody != s")
break
of nkElse, nkElseExpr:
result[0] = addGotoOut(result[0], gotoOut)
result[0] = ctx.transformClosureIteratorBody(result[0], gotoOut)
of nkYieldStmt:
result = newNodeI(nkStmtList, n.info)
result.add(n)
result.add(gotoOut)
of nkElse, nkElseExpr:
result[0] = addGotoOut(result[0], gotoOut)
result[0] = ctx.transformClosureIteratorBody(result[0], gotoOut)
of nkElifBranch, nkElifExpr, nkOfBranch:
result[^1] = addGotoOut(result[^1], gotoOut)
result[^1] = ctx.transformClosureIteratorBody(result[^1], gotoOut)
of nkIfStmt, nkCaseStmt:
for i in 0 ..< n.len:
n[i] = ctx.transformClosureIteratorBody(n[i], gotoOut)
if n[^1].kind != nkElse:
# We don't have an else branch, but every possible branch has to end with
# gotoOut, so add else here.
let elseBranch = newTree(nkElse, gotoOut)
n.add(elseBranch)
of nkWhileStmt:
# while e:
# s
# ->
# BEGIN_STATE:
# if e:
# s
# goto BEGIN_STATE
# else:
# goto OUT
result = newNodeI(nkGotoState, n.info)
let s = newNodeI(nkStmtList, n.info)
discard ctx.newState(s, result)
let ifNode = newNodeI(nkIfStmt, n.info)
let elifBranch = newNodeI(nkElifBranch, n.info)
elifBranch.add(n[0])
var body = addGotoOut(n[1], result)
body = ctx.transformBreaksAndContinuesInWhile(body, result, gotoOut)
body = ctx.transformClosureIteratorBody(body, result)
elifBranch.add(body)
ifNode.add(elifBranch)
of nkElifBranch, nkElifExpr, nkOfBranch:
result[^1] = addGotoOut(result[^1], gotoOut)
result[^1] = ctx.transformClosureIteratorBody(result[^1], gotoOut)
of nkIfStmt, nkCaseStmt:
for i in 0..<n.len:
n[i] = ctx.transformClosureIteratorBody(n[i], gotoOut)
if n[^1].kind != nkElse:
# We don't have an else branch, but every possible branch has to end with
# gotoOut, so add else here.
let elseBranch = newTree(nkElse, gotoOut)
ifNode.add(elseBranch)
s.add(ifNode)
n.add(elseBranch)
of nkBlockStmt:
result[1] = addGotoOut(result[1], gotoOut)
result[1] = ctx.transformBreaksInBlock(result[1], result[0], gotoOut)
result[1] = ctx.transformClosureIteratorBody(result[1], gotoOut)
of nkWhileStmt:
# while e:
# s
# ->
# BEGIN_STATE:
# if e:
# s
# goto BEGIN_STATE
# else:
# goto OUT
of nkTryStmt:
# See explanation above about how this works
ctx.hasExceptions = true
result = newNodeI(nkGotoState, n.info)
result = newNodeI(nkGotoState, n.info)
var tryBody = toStmtList(n[0])
var exceptBody = ctx.collectExceptState(n)
var finallyBody = newTree(nkStmtList, getFinallyNode(ctx, n))
finallyBody = ctx.transformReturnsInTry(finallyBody)
finallyBody.add(ctx.newEndFinallyNode(finallyBody.info))
let s = newNodeI(nkStmtList, n.info)
discard ctx.newState(s, result)
let ifNode = newNodeI(nkIfStmt, n.info)
let elifBranch = newNodeI(nkElifBranch, n.info)
elifBranch.add(n[0])
# The following index calculation is based on the knowledge how state
# indexes are assigned
let tryIdx = ctx.states.len
var exceptIdx, finallyIdx: int
if exceptBody.kind != nkEmpty:
exceptIdx = -(tryIdx + 1)
finallyIdx = tryIdx + 2
else:
exceptIdx = tryIdx + 1
finallyIdx = tryIdx + 1
var body = addGotoOut(n[1], result)
let outToFinally = newNodeI(nkGotoState, finallyBody.info)
body = ctx.transformBreaksAndContinuesInWhile(body, result, gotoOut)
body = ctx.transformClosureIteratorBody(body, result)
block: # Create initial states.
let oldExcHandlingState = ctx.curExcHandlingState
ctx.curExcHandlingState = exceptIdx
let realTryIdx = ctx.newState(tryBody, result)
assert(realTryIdx == tryIdx)
elifBranch.add(body)
ifNode.add(elifBranch)
if exceptBody.kind != nkEmpty:
ctx.curExcHandlingState = finallyIdx
let realExceptIdx = ctx.newState(exceptBody, nil)
assert(realExceptIdx == -exceptIdx)
let elseBranch = newTree(nkElse, gotoOut)
ifNode.add(elseBranch)
s.add(ifNode)
ctx.curExcHandlingState = oldExcHandlingState
let realFinallyIdx = ctx.newState(finallyBody, outToFinally)
assert(realFinallyIdx == finallyIdx)
of nkBlockStmt:
result[1] = addGotoOut(result[1], gotoOut)
result[1] = ctx.transformBreaksInBlock(result[1], result[0], gotoOut)
result[1] = ctx.transformClosureIteratorBody(result[1], gotoOut)
block: # Subdivide the states
let oldNearestFinally = ctx.nearestFinally
ctx.nearestFinally = finallyIdx
of nkTryStmt, nkHiddenTryStmt:
# See explanation above about how this works
ctx.hasExceptions = true
let oldExcHandlingState = ctx.curExcHandlingState
ctx.curExcHandlingState = exceptIdx
if ctx.transformReturnsInTry(tryBody) != tryBody:
internalError(ctx.g.config, "transformReturnsInTry != tryBody")
if ctx.transformClosureIteratorBody(tryBody, outToFinally) != tryBody:
internalError(ctx.g.config, "transformClosureIteratorBody != tryBody")
ctx.curExcHandlingState = finallyIdx
ctx.addElseToExcept(exceptBody)
if ctx.transformReturnsInTry(exceptBody) != exceptBody:
internalError(ctx.g.config, "transformReturnsInTry != exceptBody")
if ctx.transformClosureIteratorBody(exceptBody, outToFinally) != exceptBody:
internalError(ctx.g.config, "transformClosureIteratorBody != exceptBody")
ctx.curExcHandlingState = oldExcHandlingState
ctx.nearestFinally = oldNearestFinally
if ctx.transformClosureIteratorBody(finallyBody, gotoOut) != finallyBody:
internalError(ctx.g.config, "transformClosureIteratorBody != finallyBody")
of nkGotoState, nkForStmt:
internalError(ctx.g.config, "closure iter " & $n.kind)
result = newNodeI(nkGotoState, n.info)
var tryBody = toStmtList(n[0])
var exceptBody = ctx.collectExceptState(n)
var finallyBody = newTree(nkStmtList, getFinallyNode(ctx, n))
finallyBody = ctx.transformReturnsInTry(finallyBody)
finallyBody.add(ctx.newEndFinallyNode(finallyBody.info))
# The following index calculation is based on the knowledge how state
# indexes are assigned
let tryIdx = ctx.states.len
var exceptIdx, finallyIdx: int
if exceptBody.kind != nkEmpty:
exceptIdx = -(tryIdx + 1)
finallyIdx = tryIdx + 2
else:
for i in 0 ..< n.len:
n[i] = ctx.transformClosureIteratorBody(n[i], gotoOut)
exceptIdx = tryIdx + 1
finallyIdx = tryIdx + 1
let outToFinally = newNodeI(nkGotoState, finallyBody.info)
block: # Create initial states.
let oldExcHandlingState = ctx.curExcHandlingState
ctx.curExcHandlingState = exceptIdx
let realTryIdx = ctx.newState(tryBody, result)
assert(realTryIdx == tryIdx)
if exceptBody.kind != nkEmpty:
ctx.curExcHandlingState = finallyIdx
let realExceptIdx = ctx.newState(exceptBody, nil)
assert(realExceptIdx == -exceptIdx)
ctx.curExcHandlingState = oldExcHandlingState
let realFinallyIdx = ctx.newState(finallyBody, outToFinally)
assert(realFinallyIdx == finallyIdx)
block: # Subdivide the states
let oldNearestFinally = ctx.nearestFinally
ctx.nearestFinally = finallyIdx
let oldExcHandlingState = ctx.curExcHandlingState
ctx.curExcHandlingState = exceptIdx
if ctx.transformReturnsInTry(tryBody) != tryBody:
internalError(ctx.g.config, "transformReturnsInTry != tryBody")
if ctx.transformClosureIteratorBody(tryBody, outToFinally) != tryBody:
internalError(ctx.g.config, "transformClosureIteratorBody != tryBody")
ctx.curExcHandlingState = finallyIdx
ctx.addElseToExcept(exceptBody)
if ctx.transformReturnsInTry(exceptBody) != exceptBody:
internalError(ctx.g.config, "transformReturnsInTry != exceptBody")
if ctx.transformClosureIteratorBody(exceptBody, outToFinally) != exceptBody:
internalError(ctx.g.config, "transformClosureIteratorBody != exceptBody")
ctx.curExcHandlingState = oldExcHandlingState
ctx.nearestFinally = oldNearestFinally
if ctx.transformClosureIteratorBody(finallyBody, gotoOut) != finallyBody:
internalError(ctx.g.config, "transformClosureIteratorBody != finallyBody")
of nkGotoState, nkForStmt:
internalError(ctx.g.config, "closure iter " & $n.kind)
else:
for i in 0..<n.len:
n[i] = ctx.transformClosureIteratorBody(n[i], gotoOut)
proc stateFromGotoState(n: PNode): int =
assert(n.kind == nkGotoState)
result = n[0].intVal.int
proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode =
proc transformStateAssignments(ctx: var Ctx, n: PNode): PNode =
# This transforms 3 patterns:
########################## 1
# yield e
@@ -1039,19 +1039,19 @@ proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode =
result.add(ctx.newStateAssgn(stateFromGotoState(n[1])))
var retStmt = newNodeI(nkReturnStmt, n.info)
if n[0].sons[0].kind != nkEmpty:
var a = newNodeI(nkAsgn, n[0].sons[0].info)
var retVal = n[0].sons[0] #liftCapturedVars(n.sons[0], owner, d, c)
addSon(a, newSymNode(getClosureIterResult(ctx.g, ctx.fn)))
addSon(a, retVal)
if n[0][0].kind != nkEmpty:
var a = newNodeI(nkAsgn, n[0][0].info)
var retVal = n[0][0] #liftCapturedVars(n[0], owner, d, c)
a.add newSymNode(getClosureIterResult(ctx.g, ctx.fn))
a.add retVal
retStmt.add(a)
else:
retStmt.add(ctx.g.emptyNode)
result.add(retStmt)
else:
for i in 0 ..< n.len:
n[i] = ctx.tranformStateAssignments(n[i])
for i in 0..<n.len:
n[i] = ctx.transformStateAssignments(n[i])
of nkSkip:
discard
@@ -1070,8 +1070,8 @@ proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode =
result.add(breakState)
else:
for i in 0 ..< n.len:
n[i] = ctx.tranformStateAssignments(n[i])
for i in 0..<n.len:
n[i] = ctx.transformStateAssignments(n[i])
proc skipStmtList(ctx: Ctx; n: PNode): PNode =
result = n
@@ -1111,7 +1111,7 @@ proc skipThroughEmptyStates(ctx: var Ctx, n: PNode): PNode =
result = copyTree(n)
result[0].intVal = ctx.skipEmptyStates(result[0].intVal.int)
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.skipThroughEmptyStates(n[i])
proc newArrayType(g: ModuleGraph; n: int, t: PType, owner: PSym): PType =
@@ -1149,7 +1149,6 @@ proc newCatchBody(ctx: var Ctx, info: TLineInfo): PNode {.inline.} =
# :state = exceptionTable[:state]
block:
# exceptionTable[:state]
let getNextState = newTree(nkBracketExpr,
ctx.createExceptionTable(),
@@ -1164,7 +1163,7 @@ proc newCatchBody(ctx: var Ctx, info: TLineInfo): PNode {.inline.} =
let cond = newTree(nkCall,
ctx.g.getSysMagic(info, "==", mEqI).newSymNode(),
ctx.newStateAccess(),
newIntTypeNode(nkIntLit, 0, intTyp))
newIntTypeNode(0, intTyp))
cond.typ = boolTyp
let raiseStmt = newTree(nkRaiseStmt, ctx.g.emptyNode)
@@ -1176,7 +1175,7 @@ proc newCatchBody(ctx: var Ctx, info: TLineInfo): PNode {.inline.} =
block:
let cond = newTree(nkCall,
ctx.g.getSysMagic(info, "<", mLtI).newSymNode,
newIntTypeNode(nkIntLit, 0, intTyp),
newIntTypeNode(0, intTyp),
ctx.newStateAccess())
cond.typ = boolTyp
@@ -1188,7 +1187,7 @@ proc newCatchBody(ctx: var Ctx, info: TLineInfo): PNode {.inline.} =
let cond = newTree(nkCall,
ctx.g.getSysMagic(info, "<", mLtI).newSymNode,
ctx.newStateAccess(),
newIntTypeNode(nkIntLit, 0, intTyp))
newIntTypeNode(0, intTyp))
cond.typ = boolTyp
let negateState = newTree(nkCall,
@@ -1204,7 +1203,7 @@ proc newCatchBody(ctx: var Ctx, info: TLineInfo): PNode {.inline.} =
block:
result.add(newTree(nkAsgn,
ctx.newCurExcAccess(),
ctx.g.callCodegenProc("getCurrentException", ctx.g.emptyNode)))
ctx.g.callCodegenProc("getCurrentException")))
proc wrapIntoTryExcept(ctx: var Ctx, n: PNode): PNode {.inline.} =
let setupExc = newTree(nkCall,
@@ -1220,18 +1219,20 @@ proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode =
# while true:
# block :stateLoop:
# gotoState :state
# local vars decl (if needed)
# body # Might get wrapped in try-except
let loopBody = newNodeI(nkStmtList, n.info)
result = newTree(nkWhileStmt, newSymNode(ctx.g.getSysSym(n.info, "true")), loopBody)
result.info = n.info
let localVars = newNodeI(nkStmtList, n.info)
if not ctx.stateVarSym.isNil:
let varSect = newNodeI(nkVarSection, n.info)
addVar(varSect, newSymNode(ctx.stateVarSym))
loopBody.add(varSect)
localVars.add(varSect)
if not ctx.tempVars.isNil:
loopBody.add(ctx.tempVars)
localVars.add(ctx.tempVars)
let blockStmt = newNodeI(nkBlockStmt, n.info)
blockStmt.add(newSymNode(ctx.stateLoopLabel))
@@ -1240,7 +1241,7 @@ proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode =
gs.add(ctx.newStateAccess())
gs.add(ctx.g.newIntLit(n.info, ctx.states.len - 1))
var blockBody = newTree(nkStmtList, gs, n)
var blockBody = newTree(nkStmtList, gs, localVars, n)
if ctx.hasExceptions:
blockBody = ctx.wrapIntoTryExcept(blockBody)
@@ -1287,25 +1288,30 @@ proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode =
ctx.fn = fn
if getEnvParam(fn).isNil:
# Lambda lifting was not done yet. Use temporary :state sym, which
# Lambda lifting was not done yet. Use temporary :state sym, which will
# be handled specially by lambda lifting. Local temp vars (if needed)
# should folllow the same logic.
# should follow the same logic.
ctx.stateVarSym = newSym(skVar, getIdent(ctx.g.cache, ":state"), fn, fn.info)
ctx.stateVarSym.typ = g.createClosureIterStateType(fn)
ctx.stateLoopLabel = newSym(skLabel, getIdent(ctx.g.cache, ":stateLoop"), fn, fn.info)
let n = n.toStmtList
var n = n.toStmtList
discard ctx.newState(n, nil)
let gotoOut = newTree(nkGotoState, g.newIntLit(n.info, -1))
var ns = false
n = ctx.lowerStmtListExprs(n, ns)
if n.hasYieldsInExpressions():
internalError(ctx.g.config, "yield in expr not lowered")
# Splitting transformation
discard ctx.transformClosureIteratorBody(n, gotoOut)
# Optimize empty states away
ctx.deleteEmptyStates()
# Make new body by concating the list of states
# Make new body by concatenating the list of states
result = newNodeI(nkStmtList, n.info)
for s in ctx.states:
assert(s.len == 2)
@@ -1314,7 +1320,7 @@ proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode =
result.add(s)
result.add(body)
result = ctx.tranformStateAssignments(result)
result = ctx.transformStateAssignments(result)
result = ctx.wrapIntoStateLoop(result)
# echo "TRANSFORM TO STATES: "

View File

@@ -10,9 +10,11 @@
## Helpers for binaries that use compiler passes, eg: nim, nimsuggest, nimfix
import
options, idents, nimconf, scriptconfig, extccomp, commands, msgs,
options, idents, nimconf, extccomp, commands, msgs,
lineinfos, modulegraphs, condsyms, os, pathutils
from strutils import normalize
type
NimProg* = ref object
suggestMode*: bool
@@ -27,10 +29,7 @@ proc initDefinesProg*(self: NimProg, conf: ConfigRef, name: string) =
proc processCmdLineAndProjectPath*(self: NimProg, conf: ConfigRef) =
self.processCmdLine(passCmd1, "", conf)
if self.supportsStdinFile and conf.projectName == "-":
conf.projectName = "stdinfile"
conf.projectFull = AbsoluteFile "stdinfile"
conf.projectPath = AbsoluteDir getCurrentDir()
conf.projectIsStdin = true
handleStdinInput(conf)
elif conf.projectName != "":
try:
conf.projectFull = canonicalizePath(conf, AbsoluteFile conf.projectName)
@@ -44,44 +43,31 @@ proc processCmdLineAndProjectPath*(self: NimProg, conf: ConfigRef) =
conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile getCurrentDir())
proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: ConfigRef): bool =
loadConfigs(DefaultConfig, cache, conf) # load all config files
if self.suggestMode:
conf.command = "nimsuggest"
loadConfigs(DefaultConfig, cache, conf) # load all config files
proc runNimScriptIfExists(path: AbsoluteFile)=
if fileExists(path):
runNimScript(cache, path, freshDefines = false, conf)
# Caution: make sure this stays in sync with `loadConfigs`
if optSkipSystemConfigFile notin conf.globalOptions:
runNimScriptIfExists(getSystemConfigPath(conf, DefaultConfigNims))
if optSkipUserConfigFile notin conf.globalOptions:
runNimScriptIfExists(getUserConfigPath(DefaultConfigNims))
if optSkipParentConfigFiles notin conf.globalOptions:
for dir in parentDirs(conf.projectPath.string, fromRoot = true, inclusive = false):
runNimScriptIfExists(AbsoluteDir(dir) / DefaultConfigNims)
if optSkipProjConfigFile notin conf.globalOptions:
runNimScriptIfExists(conf.projectPath / DefaultConfigNims)
block:
let scriptFile = conf.projectFull.changeFileExt("nims")
if not self.suggestMode:
runNimScriptIfExists(scriptFile)
# 'nim foo.nims' means to just run the NimScript file and do nothing more:
if fileExists(scriptFile) and scriptFile == conf.projectFull:
return false
else:
if scriptFile != conf.projectFull:
runNimScriptIfExists(scriptFile)
else:
# 'nimsuggest foo.nims' means to just auto-complete the NimScript file
discard
if conf.command == "":
conf.command = "e"
return false
elif conf.command.normalize == "e":
return false
# now process command line arguments again, because some options in the
# command line can overwite the config file's settings
# command line can overwrite the config file's settings
extccomp.initVars(conf)
# XXX This is hacky. We need to find a better way.
case conf.command
of "cpp", "compiletocpp":
conf.cmd = cmdCompileToCpp
else:
discard
self.processCmdLine(passCmd2, "", conf)
if conf.command == "":
rawMessage(conf, errGenerated, "command missing")

View File

@@ -17,7 +17,9 @@ template bootSwitch(name, expr, userString) =
const name = if expr: " " & userString else: ""
bootSwitch(usedRelease, defined(release), "-d:release")
bootSwitch(usedGnuReadline, defined(useLinenoise), "-d:useLinenoise")
bootSwitch(usedDanger, defined(danger), "-d:danger")
# `useLinenoise` deprecated in favor of `nimUseLinenoise`, kept for backward compatibility
bootSwitch(useLinenoise, defined(nimUseLinenoise) or defined(useLinenoise), "-d:nimUseLinenoise")
bootSwitch(usedBoehm, defined(boehmgc), "--gc:boehm")
bootSwitch(usedMarkAndSweep, defined(gcmarkandsweep), "--gc:markAndSweep")
bootSwitch(usedGenerational, defined(gcgenerational), "--gc:generational")
@@ -26,15 +28,18 @@ bootSwitch(usedNoGC, defined(nogc), "--gc:none")
import
os, msgs, options, nversion, condsyms, strutils, extccomp, platform,
wordrecg, parseutils, nimblecmd, idents, parseopt, sequtils, lineinfos,
pathutils
wordrecg, parseutils, nimblecmd, parseopt, sequtils, lineinfos,
pathutils, strtabs
from incremental import nimIncremental
from ast import eqTypeFlags, tfGcSafe, tfNoSideEffect
# but some have deps to imported modules. Yay.
bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc")
bootSwitch(usedNativeStacktrace,
defined(nativeStackTrace) and nativeStackTraceSupported,
"-d:nativeStackTrace")
bootSwitch(usedFFI, hasFFI, "-d:useFFI")
bootSwitch(usedFFI, hasFFI, "-d:nimHasLibFFI")
type
TCmdLinePass* = enum
@@ -47,15 +52,16 @@ const
"Compiled at $4\n" &
"Copyright (c) 2006-" & copyrightYear & " by Andreas Rumpf\n"
proc genFeatureDesc[T: enum](t: typedesc[T]): string {.compileTime.} =
var x = ""
for f in low(T)..high(T):
if x.len > 0: x.add "|"
x.add $f
x
const
Usage = slurp"../doc/basicopt.txt".replace("//", "")
FeatureDesc = block:
var x = ""
for f in low(Feature)..high(Feature):
if x.len > 0: x.add "|"
x.add $f
x
AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "") % FeatureDesc
Usage = slurp"../doc/basicopt.txt".replace(" //", " ")
AdvancedUsage = slurp"../doc/advopt.txt".replace(" //", " ") % [genFeatureDesc(Feature), genFeatureDesc(LegacyFeature)]
proc getCommandLineDesc(conf: ConfigRef): string =
result = (HelpMessage % [VersionAsString, platform.OS[conf.target.hostOS].name,
@@ -96,25 +102,24 @@ proc writeVersionInfo(conf: ConfigRef; pass: TCmdLinePass) =
when gitHash.len == 40:
msgWriteln(conf, "git hash: " & gitHash, {msgStdout})
msgWriteln(conf, "active boot switches:" & usedRelease &
usedTinyC & usedGnuReadline & usedNativeStacktrace &
msgWriteln(conf, "active boot switches:" & usedRelease & usedDanger &
usedTinyC & useLinenoise & usedNativeStacktrace &
usedFFI & usedBoehm & usedMarkAndSweep & usedGenerational & usedGoGC & usedNoGC,
{msgStdout})
msgQuit(0)
proc writeCommandLineUsage*(conf: ConfigRef; helpWritten: var bool) =
if not helpWritten:
msgWriteln(conf, getCommandLineDesc(conf), {msgStdout})
helpWritten = true
proc writeCommandLineUsage*(conf: ConfigRef) =
msgWriteln(conf, getCommandLineDesc(conf), {msgStdout})
proc addPrefix(switch: string): string =
if len(switch) == 1: result = "-" & switch
if switch.len <= 1: result = "-" & switch
else: result = "--" & switch
const
errInvalidCmdLineOption = "invalid command line option: '$1'"
errOnOrOffExpectedButXFound = "'on' or 'off' expected, but '$1' found"
errOnOffOrListExpectedButXFound = "'on', 'off' or 'list' expected, but '$1' found"
errOffHintsError = "'off', 'hint' or 'error' expected, but '$1' found"
proc invalidCmdLineOption(conf: ConfigRef; pass: TCmdLinePass, switch: string, info: TLineInfo) =
if switch == " ": localError(conf, info, errInvalidCmdLineOption % "-")
@@ -124,14 +129,14 @@ proc splitSwitch(conf: ConfigRef; switch: string, cmd, arg: var string, pass: TC
info: TLineInfo) =
cmd = ""
var i = 0
if i < len(switch) and switch[i] == '-': inc(i)
if i < len(switch) and switch[i] == '-': inc(i)
while i < len(switch):
if i < switch.len and switch[i] == '-': inc(i)
if i < switch.len and switch[i] == '-': inc(i)
while i < switch.len:
case switch[i]
of 'a'..'z', 'A'..'Z', '0'..'9', '_', '.': add(cmd, switch[i])
of 'a'..'z', 'A'..'Z', '0'..'9', '_', '.': cmd.add(switch[i])
else: break
inc(i)
if i >= len(switch): arg = ""
if i >= switch.len: arg = ""
# cmd:arg => (cmd,arg)
elif switch[i] in {':', '='}: arg = substr(switch, i + 1)
# cmd[sub]:rest => (cmd,[sub]:rest)
@@ -141,7 +146,7 @@ proc splitSwitch(conf: ConfigRef; switch: string, cmd, arg: var string, pass: TC
proc processOnOffSwitch(conf: ConfigRef; op: TOptions, arg: string, pass: TCmdLinePass,
info: TLineInfo) =
case arg.normalize
of "on": conf.options = conf.options + op
of "","on": conf.options = conf.options + op
of "off": conf.options = conf.options - op
else: localError(conf, info, errOnOrOffExpectedButXFound % arg)
@@ -157,7 +162,7 @@ proc processOnOffSwitchOrList(conf: ConfigRef; op: TOptions, arg: string, pass:
proc processOnOffSwitchG(conf: ConfigRef; op: TGlobalOptions, arg: string, pass: TCmdLinePass,
info: TLineInfo) =
case arg.normalize
of "on": conf.globalOptions = conf.globalOptions + op
of "", "on": conf.globalOptions = conf.globalOptions + op
of "off": conf.globalOptions = conf.globalOptions - op
else: localError(conf, info, errOnOrOffExpectedButXFound % arg)
@@ -175,17 +180,17 @@ proc processSpecificNote*(arg: string, state: TSpecialWord, pass: TCmdLinePass,
var i = 0
var n = hintMin
var isBracket = false
if i < len(arg) and arg[i] == '[':
if i < arg.len and arg[i] == '[':
isBracket = true
inc(i)
while i < len(arg) and (arg[i] notin {':', '=', ']'}):
add(id, arg[i])
while i < arg.len and (arg[i] notin {':', '=', ']'}):
id.add(arg[i])
inc(i)
if isBracket:
if i < len(arg) and arg[i] == ']': inc(i)
if i < arg.len and arg[i] == ']': inc(i)
else: invalidCmdLineOption(conf, pass, orig, info)
if i < len(arg) and (arg[i] in {':', '='}): inc(i)
if i < arg.len and (arg[i] in {':', '='}): inc(i)
else: invalidCmdLineOption(conf, pass, orig, info)
if state == wHint:
let x = findStr(lineinfos.HintsToStr, id)
@@ -195,17 +200,21 @@ proc processSpecificNote*(arg: string, state: TSpecialWord, pass: TCmdLinePass,
let x = findStr(lineinfos.WarningsToStr, id)
if x >= 0: n = TNoteKind(x + ord(warnMin))
else: localError(conf, info, "unknown warning: " & id)
case substr(arg, i).normalize
of "on":
incl(conf.notes, n)
incl(conf.mainPackageNotes, n)
incl(conf.enableNotes, n)
of "off":
excl(conf.notes, n)
excl(conf.mainPackageNotes, n)
incl(conf.disableNotes, n)
excl(conf.foreignPackageNotes, n)
else: localError(conf, info, errOnOrOffExpectedButXFound % arg)
let val = substr(arg, i).normalize
if val notin ["on", "off"]:
localError(conf, info, errOnOrOffExpectedButXFound % arg)
elif n notin conf.cmdlineNotes or pass == passCmd1:
if pass == passCmd1: incl(conf.cmdlineNotes, n)
incl(conf.modifiedyNotes, n)
case val
of "on":
incl(conf.notes, n)
incl(conf.mainPackageNotes, n)
of "off":
excl(conf.notes, n)
excl(conf.mainPackageNotes, n)
excl(conf.foreignPackageNotes, n)
proc processCompile(conf: ConfigRef; filename: string) =
var found = findFile(conf, filename)
@@ -216,19 +225,22 @@ const
errNoneBoehmRefcExpectedButXFound = "'none', 'boehm' or 'refc' expected, but '$1' found"
errNoneSpeedOrSizeExpectedButXFound = "'none', 'speed' or 'size' expected, but '$1' found"
errGuiConsoleOrLibExpectedButXFound = "'gui', 'console' or 'lib' expected, but '$1' found"
errInvalidExceptionSystem = "'goto', 'setjump', 'cpp' or 'quirky' expected, but '$1' found"
proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo): bool =
case switch.normalize
of "gc":
case arg.normalize
of "boehm": result = conf.selectedGC == gcBoehm
of "refc": result = conf.selectedGC == gcRefc
of "v2": result = conf.selectedGC == gcV2
of "boehm": result = conf.selectedGC == gcBoehm
of "refc": result = conf.selectedGC == gcRefc
of "v2": result = false
of "markandsweep": result = conf.selectedGC == gcMarkAndSweep
of "generational": result = false
of "destructors": result = conf.selectedGC == gcDestructors
of "go": result = conf.selectedGC == gcGo
of "none": result = conf.selectedGC == gcNone
of "destructors", "arc": result = conf.selectedGC == gcArc
of "orc": result = conf.selectedGC == gcOrc
of "hooks": result = conf.selectedGC == gcHooks
of "go": result = conf.selectedGC == gcGo
of "none": result = conf.selectedGC == gcNone
of "stack", "regions": result = conf.selectedGC == gcRegions
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
of "opt":
@@ -240,15 +252,22 @@ proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo
of "verbosity": result = $conf.verbosity == arg
of "app":
case arg.normalize
of "gui": result = contains(conf.globalOptions, optGenGuiApp)
of "console": result = not contains(conf.globalOptions, optGenGuiApp)
of "lib": result = contains(conf.globalOptions, optGenDynLib) and
of "gui": result = contains(conf.globalOptions, optGenGuiApp)
of "console": result = not contains(conf.globalOptions, optGenGuiApp)
of "lib": result = contains(conf.globalOptions, optGenDynLib) and
not contains(conf.globalOptions, optGenGuiApp)
of "staticlib": result = contains(conf.globalOptions, optGenStaticLib) and
not contains(conf.globalOptions, optGenGuiApp)
else: localError(conf, info, errGuiConsoleOrLibExpectedButXFound % arg)
of "dynliboverride":
result = isDynlibOverride(conf, arg)
of "exceptions":
case arg.normalize
of "cpp": result = conf.exc == excCpp
of "setjmp": result = conf.exc == excSetjmp
of "quirky": result = conf.exc == excQuirky
of "goto": result = conf.exc == excGoto
else: localError(conf, info, errInvalidExceptionSystem % arg)
else: invalidCmdLineOption(conf, passCmd1, switch, info)
proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool =
@@ -262,8 +281,9 @@ proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool
of "hints": result = contains(conf.options, optHints)
of "threadanalysis": result = contains(conf.globalOptions, optThreadAnalysis)
of "stacktrace": result = contains(conf.options, optStackTrace)
of "stacktracemsgs": result = contains(conf.options, optStackTraceMsgs)
of "linetrace": result = contains(conf.options, optLineTrace)
of "debugger": result = contains(conf.options, optEndb)
of "debugger": result = contains(conf.globalOptions, optCDebug)
of "profiler": result = contains(conf.options, optProfiler)
of "memtracker": result = contains(conf.options, optMemTracker)
of "checks", "x": result = conf.options * ChecksOptions == ChecksOptions
@@ -276,8 +296,10 @@ proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool
of "fieldchecks": result = contains(conf.options, optFieldCheck)
of "rangechecks": result = contains(conf.options, optRangeCheck)
of "boundchecks": result = contains(conf.options, optBoundsCheck)
of "refchecks": result = contains(conf.options, optRefCheck)
of "overflowchecks": result = contains(conf.options, optOverflowCheck)
of "movechecks": result = contains(conf.options, optMoveCheck)
of "staticboundchecks": result = contains(conf.options, optStaticBoundsCheck)
of "stylechecks": result = contains(conf.options, optStyleCheck)
of "linedir": result = contains(conf.options, optLineDir)
of "assertions", "a": result = contains(conf.options, optAssert)
of "run", "r": result = contains(conf.globalOptions, optRun)
@@ -287,9 +309,10 @@ proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool
of "taintmode": result = contains(conf.globalOptions, optTaintMode)
of "tlsemulation": result = contains(conf.globalOptions, optTlsEmulation)
of "implicitstatic": result = contains(conf.options, optImplicitStatic)
of "patterns": result = contains(conf.options, optPatterns)
of "patterns", "trmacros": result = contains(conf.options, optTrMacros)
of "excessivestacktrace": result = contains(conf.globalOptions, optExcessiveStackTrace)
of "nilseqs": result = contains(conf.options, optNilSeqs)
of "oldast": result = contains(conf.options, optOldAst)
else: invalidCmdLineOption(conf, passCmd1, switch, info)
proc processPath(conf: ConfigRef; path: string, info: TLineInfo,
@@ -354,6 +377,14 @@ proc dynlibOverride(conf: ConfigRef; switch, arg: string, pass: TCmdLinePass, in
expectArg(conf, switch, arg, pass, info)
options.inclDynlibOverride(conf, arg)
proc handleStdinInput*(conf: ConfigRef) =
conf.projectName = "stdinfile"
conf.projectFull = conf.projectName.AbsoluteFile
conf.projectPath = AbsoluteDir getCurrentDir()
conf.projectIsStdin = true
if conf.outDir.isEmpty:
conf.outDir = getNimcacheDir(conf)
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
conf: ConfigRef) =
var
@@ -361,8 +392,9 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
case switch.normalize
of "path", "p":
expectArg(conf, switch, arg, pass, info)
addPath(conf, if pass == passPP: processCfgPath(conf, arg, info)
else: processPath(conf, arg, info), info)
for path in nimbleSubs(conf, arg):
addPath(conf, if pass == passPP: processCfgPath(conf, path, info)
else: processPath(conf, path, info), info)
of "nimblepath", "babelpath":
# keep the old name for compat
if pass in {passCmd2, passPP} and optNoNimblePath notin conf.globalOptions:
@@ -375,6 +407,9 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "nonimblepath", "nobabelpath":
expectNoArg(conf, switch, arg, pass, info)
disableNimblePath(conf)
of "clearnimblepath":
expectNoArg(conf, switch, arg, pass, info)
clearNimblePath(conf)
of "excludepath":
expectArg(conf, switch, arg, pass, info)
let path = processPath(conf, arg, info)
@@ -382,21 +417,32 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
conf.lazyPaths.keepItIf(it != path)
of "nimcache":
expectArg(conf, switch, arg, pass, info)
conf.nimcacheDir = processPath(conf, arg, info, true)
conf.nimcacheDir = processPath(conf, arg, info, notRelativeToProj=true)
of "out", "o":
expectArg(conf, switch, arg, pass, info)
conf.outFile = AbsoluteFile arg
let f = splitFile(processPath(conf, arg, info, notRelativeToProj=true).string)
conf.outFile = RelativeFile f.name & f.ext
conf.outDir = toAbsoluteDir f.dir
of "outdir":
expectArg(conf, switch, arg, pass, info)
conf.outDir = processPath(conf, arg, info, notRelativeToProj=true)
of "docseesrcurl":
expectArg(conf, switch, arg, pass, info)
conf.docSeeSrcUrl = arg
of "docroot":
conf.docRoot = if arg.len == 0: "@default" else: arg
of "mainmodule", "m":
discard "allow for backwards compatibility, but don't do anything"
of "define", "d":
expectArg(conf, switch, arg, pass, info)
if {':', '='} in arg:
splitSwitch(conf, arg, key, val, pass, info)
if cmpIgnoreStyle(key, "nimQuirky") == 0:
conf.exc = excQuirky
defineSymbol(conf.symbols, key, val)
else:
if cmpIgnoreStyle(arg, "nimQuirky") == 0:
conf.exc = excQuirky
defineSymbol(conf.symbols, arg)
of "undef", "u":
expectArg(conf, switch, arg, pass, info)
@@ -412,52 +458,72 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
if pass in {passCmd2, passPP}:
addExternalFileToLink(conf, AbsoluteFile arg)
of "debuginfo":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optCDebug)
processOnOffSwitchG(conf, {optCDebug}, arg, pass, info)
of "embedsrc":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optEmbedOrigSrc)
processOnOffSwitchG(conf, {optEmbedOrigSrc}, arg, pass, info)
of "compileonly", "c":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optCompileOnly)
processOnOffSwitchG(conf, {optCompileOnly}, arg, pass, info)
of "nolinking":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optNoLinking)
processOnOffSwitchG(conf, {optNoLinking}, arg, pass, info)
of "nomain":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optNoMain)
processOnOffSwitchG(conf, {optNoMain}, arg, pass, info)
of "forcebuild", "f":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optForceFullMake)
processOnOffSwitchG(conf, {optForceFullMake}, arg, pass, info)
of "project":
expectNoArg(conf, switch, arg, pass, info)
incl conf.globalOptions, optWholeProject
processOnOffSwitchG(conf, {optWholeProject}, arg, pass, info)
of "gc":
expectArg(conf, switch, arg, pass, info)
case arg.normalize
of "boehm":
conf.selectedGC = gcBoehm
defineSymbol(conf.symbols, "boehmgc")
of "refc":
conf.selectedGC = gcRefc
of "v2":
conf.selectedGC = gcV2
of "markandsweep":
conf.selectedGC = gcMarkAndSweep
defineSymbol(conf.symbols, "gcmarkandsweep")
of "destructors":
conf.selectedGC = gcDestructors
defineSymbol(conf.symbols, "gcdestructors")
of "go":
conf.selectedGC = gcGo
defineSymbol(conf.symbols, "gogc")
of "none":
conf.selectedGC = gcNone
defineSymbol(conf.symbols, "nogc")
of "stack", "regions":
conf.selectedGC= gcRegions
defineSymbol(conf.symbols, "gcregions")
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
if pass in {passCmd2, passPP}:
case arg.normalize
of "boehm":
conf.selectedGC = gcBoehm
defineSymbol(conf.symbols, "boehmgc")
of "refc":
conf.selectedGC = gcRefc
of "v2":
message(conf, info, warnDeprecated, "--gc:v2 is deprecated; using default gc")
of "markandsweep":
conf.selectedGC = gcMarkAndSweep
defineSymbol(conf.symbols, "gcmarkandsweep")
of "destructors", "arc":
conf.selectedGC = gcArc
if conf.cmd != cmdCompileToCpp:
conf.exc = excGoto
defineSymbol(conf.symbols, "gcdestructors")
defineSymbol(conf.symbols, "gcarc")
incl conf.globalOptions, optSeqDestructors
incl conf.globalOptions, optTinyRtti
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
defineSymbol(conf.symbols, "nimV2")
of "orc":
conf.selectedGC = gcOrc
if conf.cmd != cmdCompileToCpp:
conf.exc = excGoto
defineSymbol(conf.symbols, "gcdestructors")
defineSymbol(conf.symbols, "gcorc")
incl conf.globalOptions, optSeqDestructors
incl conf.globalOptions, optTinyRtti
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
defineSymbol(conf.symbols, "nimV2")
of "hooks":
conf.selectedGC = gcHooks
defineSymbol(conf.symbols, "gchooks")
incl conf.globalOptions, optSeqDestructors
processOnOffSwitchG(conf, {optSeqDestructors}, arg, pass, info)
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
of "go":
conf.selectedGC = gcGo
defineSymbol(conf.symbols, "gogc")
of "none":
conf.selectedGC = gcNone
defineSymbol(conf.symbols, "nogc")
of "stack", "regions":
conf.selectedGC = gcRegions
defineSymbol(conf.symbols, "gcregions")
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
of "warnings", "w":
if processOnOffSwitchOrList(conf, {optWarns}, arg, pass, info): listWarnings(conf)
of "warning": processSpecificNote(arg, wWarning, pass, info, switch, conf)
@@ -466,23 +532,23 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
if processOnOffSwitchOrList(conf, {optHints}, arg, pass, info): listHints(conf)
of "threadanalysis": processOnOffSwitchG(conf, {optThreadAnalysis}, arg, pass, info)
of "stacktrace": processOnOffSwitch(conf, {optStackTrace}, arg, pass, info)
of "stacktracemsgs": processOnOffSwitch(conf, {optStackTraceMsgs}, arg, pass, info)
of "excessivestacktrace": processOnOffSwitchG(conf, {optExcessiveStackTrace}, arg, pass, info)
of "linetrace": processOnOffSwitch(conf, {optLineTrace}, arg, pass, info)
of "debugger":
case arg.normalize
of "on", "endb":
conf.options.incl optEndb
defineSymbol(conf.symbols, "endb")
of "on", "native", "gdb":
conf.globalOptions.incl optCDebug
conf.options.incl optLineDir
#defineSymbol(conf.symbols, "nimTypeNames") # type names are used in gdb pretty printing
of "off":
conf.options.excl optEndb
undefSymbol(conf.symbols, "endb")
of "native", "gdb":
incl(conf.globalOptions, optCDebug)
conf.options = conf.options + {optLineDir} - {optEndb}
defineSymbol(conf.symbols, "nimTypeNames") # type names are used in gdb pretty printing
undefSymbol(conf.symbols, "endb")
conf.globalOptions.excl optCDebug
else:
localError(conf, info, "expected endb|gdb but found " & arg)
localError(conf, info, "expected native|gdb|on|off but found " & arg)
of "g": # alias for --debugger:native
conf.globalOptions.incl optCDebug
conf.options.incl optLineDir
#defineSymbol(conf.symbols, "nimTypeNames") # type names are used in gdb pretty printing
of "profiler":
processOnOffSwitch(conf, {optProfiler}, arg, pass, info)
if optProfiler in conf.options: defineSymbol(conf.symbols, "profiler")
@@ -492,12 +558,20 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
if optMemTracker in conf.options: defineSymbol(conf.symbols, "memtracker")
else: undefSymbol(conf.symbols, "memtracker")
of "hotcodereloading":
processOnOffSwitch(conf, {optHotCodeReloading}, arg, pass, info)
if optHotCodeReloading in conf.options: defineSymbol(conf.symbols, "hotcodereloading")
else: undefSymbol(conf.symbols, "hotcodereloading")
processOnOffSwitchG(conf, {optHotCodeReloading}, arg, pass, info)
if conf.hcrOn:
defineSymbol(conf.symbols, "hotcodereloading")
defineSymbol(conf.symbols, "useNimRtl")
# hardcoded linking with dynamic runtime for MSVC for smaller binaries
# should do the same for all compilers (wherever applicable)
if isVSCompatible(conf):
extccomp.addCompileOptionCmd(conf, "/MD")
else:
undefSymbol(conf.symbols, "hotcodereloading")
undefSymbol(conf.symbols, "useNimRtl")
of "oldnewlines":
case arg.normalize
of "on":
of "", "on":
conf.oldNewlines = true
defineSymbol(conf.symbols, "nimOldNewlines")
of "off":
@@ -507,6 +581,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
localError(conf, info, errOnOrOffExpectedButXFound % arg)
of "laxstrings": processOnOffSwitch(conf, {optLaxStrings}, arg, pass, info)
of "nilseqs": processOnOffSwitch(conf, {optNilSeqs}, arg, pass, info)
of "oldast": processOnOffSwitch(conf, {optOldAst}, arg, pass, info)
of "checks", "x": processOnOffSwitch(conf, ChecksOptions, arg, pass, info)
of "floatchecks":
processOnOffSwitch(conf, {optNaNCheck, optInfCheck}, arg, pass, info)
@@ -517,20 +592,22 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "fieldchecks": processOnOffSwitch(conf, {optFieldCheck}, arg, pass, info)
of "rangechecks": processOnOffSwitch(conf, {optRangeCheck}, arg, pass, info)
of "boundchecks": processOnOffSwitch(conf, {optBoundsCheck}, arg, pass, info)
of "refchecks": processOnOffSwitch(conf, {optRefCheck}, arg, pass, info)
of "overflowchecks": processOnOffSwitch(conf, {optOverflowCheck}, arg, pass, info)
of "movechecks": processOnOffSwitch(conf, {optMoveCheck}, arg, pass, info)
of "staticboundchecks": processOnOffSwitch(conf, {optStaticBoundsCheck}, arg, pass, info)
of "stylechecks": processOnOffSwitch(conf, {optStyleCheck}, arg, pass, info)
of "linedir": processOnOffSwitch(conf, {optLineDir}, arg, pass, info)
of "assertions", "a": processOnOffSwitch(conf, {optAssert}, arg, pass, info)
of "deadcodeelim": discard # deprecated, dead code elim always on
of "threads":
processOnOffSwitchG(conf, {optThreads}, arg, pass, info)
#if optThreads in conf.globalOptions: incl(conf.notes, warnGcUnsafe)
#if optThreads in conf.globalOptions: conf.setNote(warnGcUnsafe)
of "tlsemulation": processOnOffSwitchG(conf, {optTlsEmulation}, arg, pass, info)
of "taintmode": processOnOffSwitchG(conf, {optTaintMode}, arg, pass, info)
of "implicitstatic":
processOnOffSwitch(conf, {optImplicitStatic}, arg, pass, info)
of "patterns":
processOnOffSwitch(conf, {optPatterns}, arg, pass, info)
of "patterns", "trmacros":
processOnOffSwitch(conf, {optTrMacros}, arg, pass, info)
of "opt":
expectArg(conf, switch, arg, pass, info)
case arg.normalize
@@ -589,42 +666,57 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
processOnOffSwitchG(conf, {optGenIndex}, arg, pass, info)
of "import":
expectArg(conf, switch, arg, pass, info)
if pass in {passCmd2, passPP}: conf.implicitImports.add arg
if pass in {passCmd2, passPP}:
conf.implicitImports.add findModule(conf, arg, toFullPath(conf, info)).string
of "include":
expectArg(conf, switch, arg, pass, info)
if pass in {passCmd2, passPP}: conf.implicitIncludes.add arg
if pass in {passCmd2, passPP}:
conf.implicitIncludes.add findModule(conf, arg, toFullPath(conf, info)).string
of "listcmd":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optListCmd)
processOnOffSwitchG(conf, {optListCmd}, arg, pass, info)
of "asm":
processOnOffSwitchG(conf, {optProduceAsm}, arg, pass, info)
of "genmapping":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optGenMapping)
processOnOffSwitchG(conf, {optGenMapping}, arg, pass, info)
of "os":
expectArg(conf, switch, arg, pass, info)
if pass in {passCmd1, passPP}:
let theOS = platform.nameToOS(arg)
if theOS == osNone: localError(conf, info, "unknown OS: '$1'" % arg)
elif theOS != conf.target.hostOS:
setTarget(conf.target, theOS, conf.target.targetCPU)
let theOS = platform.nameToOS(arg)
if theOS == osNone:
let osList = platform.listOSnames().join(", ")
localError(conf, info, "unknown OS: '$1'. Available options are: $2" % [arg, $osList])
else:
setTarget(conf.target, theOS, conf.target.targetCPU)
of "cpu":
expectArg(conf, switch, arg, pass, info)
if pass in {passCmd1, passPP}:
let cpu = platform.nameToCPU(arg)
if cpu == cpuNone: localError(conf, info, "unknown CPU: '$1'" % arg)
elif cpu != conf.target.hostCPU:
setTarget(conf.target, conf.target.targetOS, cpu)
let cpu = platform.nameToCPU(arg)
if cpu == cpuNone:
let cpuList = platform.listCPUnames().join(", ")
localError(conf, info, "unknown CPU: '$1'. Available options are: $2" % [ arg, cpuList])
else:
setTarget(conf.target, conf.target.targetOS, cpu)
of "run", "r":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optRun)
processOnOffSwitchG(conf, {optRun}, arg, pass, info)
of "maxloopiterationsvm":
expectArg(conf, switch, arg, pass, info)
conf.maxLoopIterationsVM = parseInt(arg)
of "errormax":
expectArg(conf, switch, arg, pass, info)
# Note: `nim check` (etc) can overwrite this.
# `0` is meaningless, give it a useful meaning as in clang's -ferror-limit
# If user doesn't set this flag and the code doesn't either, it'd
# have the same effect as errorMax = 1
let ret = parseInt(arg)
conf.errorMax = if ret == 0: high(int) else: ret
of "verbosity":
expectArg(conf, switch, arg, pass, info)
let verbosity = parseInt(arg)
if verbosity notin {0..3}:
localError(conf, info, "invalid verbosity level: '$1'" % arg)
conf.verbosity = verbosity
conf.notes = NotesVerbosity[conf.verbosity]
incl(conf.notes, conf.enableNotes)
excl(conf.notes, conf.disableNotes)
var verb = NotesVerbosity[conf.verbosity]
## We override the default `verb` by explicitly modified (set/unset) notes.
conf.notes = (conf.modifiedyNotes * conf.notes + verb) -
(conf.modifiedyNotes * verb - conf.notes)
conf.mainPackageNotes = conf.notes
of "parallelbuild":
expectArg(conf, switch, arg, pass, info)
@@ -641,30 +733,30 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "help", "h":
expectNoArg(conf, switch, arg, pass, info)
helpOnError(conf, pass)
of "symbolfiles", "incremental":
of "symbolfiles": discard "ignore for backwards compat"
of "incremental":
when not nimIncremental:
localError(conf, info, "the compiler was not built with " &
"incremental compilation features; bootstrap with " &
"-d:nimIncremental to enable")
case arg.normalize
of "on": conf.symbolFiles = v2Sf
of "off": conf.symbolFiles = disabledSf
of "writeonly": conf.symbolFiles = writeOnlySf
of "readonly": conf.symbolFiles = readOnlySf
of "v2": conf.symbolFiles = v2Sf
else: localError(conf, info, "invalid option for --symbolFiles: " & arg)
else: localError(conf, info, "invalid option for --incremental: " & arg)
of "skipcfg":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optSkipSystemConfigFile)
processOnOffSwitchG(conf, {optSkipSystemConfigFile}, arg, pass, info)
of "skipprojcfg":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optSkipProjConfigFile)
processOnOffSwitchG(conf, {optSkipProjConfigFile}, arg, pass, info)
of "skipusercfg":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optSkipUserConfigFile)
processOnOffSwitchG(conf, {optSkipUserConfigFile}, arg, pass, info)
of "skipparentcfg":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optSkipParentConfigFiles)
processOnOffSwitchG(conf, {optSkipParentConfigFiles}, arg, pass, info)
of "genscript", "gendeps":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optGenScript)
incl(conf.globalOptions, optCompileOnly)
processOnOffSwitchG(conf, {optGenScript}, arg, pass, info)
processOnOffSwitchG(conf, {optCompileOnly}, arg, pass, info)
of "colors": processOnOffSwitchG(conf, {optUseColors}, arg, pass, info)
of "lib":
expectArg(conf, switch, arg, pass, info)
@@ -698,16 +790,13 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
expectNoArg(conf, switch, arg, pass, info)
conf.ideCmd = ideUse
of "stdout":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optStdout)
processOnOffSwitchG(conf, {optStdout}, arg, pass, info)
of "listfullpaths":
expectNoArg(conf, switch, arg, pass, info)
incl conf.globalOptions, optListFullPaths
processOnOffSwitchG(conf, {optListFullPaths}, arg, pass, info)
of "dynliboverride":
dynlibOverride(conf, switch, arg, pass, info)
of "dynliboverrideall":
expectNoArg(conf, switch, arg, pass, info)
incl conf.globalOptions, optDynlibOverrideAll
processOnOffSwitchG(conf, {optDynlibOverrideAll}, arg, pass, info)
of "cs":
# only supported for compatibility. Does nothing.
expectArg(conf, switch, arg, pass, info)
@@ -719,32 +808,99 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
conf.features.incl parseEnum[Feature](arg)
except ValueError:
localError(conf, info, "unknown experimental feature")
of "legacy":
try:
conf.legacyFeatures.incl parseEnum[LegacyFeature](arg)
except ValueError:
localError(conf, info, "unknown obsolete feature")
of "nocppexceptions":
expectNoArg(conf, switch, arg, pass, info)
incl(conf.globalOptions, optNoCppExceptions)
conf.exc = low(ExceptionSystem)
defineSymbol(conf.symbols, "noCppExceptions")
of "exceptions":
case arg.normalize
of "cpp": conf.exc = excCpp
of "setjmp": conf.exc = excSetjmp
of "quirky": conf.exc = excQuirky
of "goto": conf.exc = excGoto
else: localError(conf, info, errInvalidExceptionSystem % arg)
of "cppdefine":
expectArg(conf, switch, arg, pass, info)
if conf != nil:
conf.cppDefine(arg)
of "newruntime":
expectNoArg(conf, switch, arg, pass, info)
doAssert(conf != nil)
incl(conf.features, destructor)
defineSymbol(conf.symbols, "nimNewRuntime")
of "nep1":
processOnOffSwitchG(conf, {optCheckNep1}, arg, pass, info)
if pass in {passCmd2, passPP}:
doAssert(conf != nil)
incl(conf.features, destructor)
incl(conf.globalOptions, optTinyRtti)
incl(conf.globalOptions, optOwnedRefs)
incl(conf.globalOptions, optSeqDestructors)
defineSymbol(conf.symbols, "nimV2")
conf.selectedGC = gcHooks
defineSymbol(conf.symbols, "gchooks")
defineSymbol(conf.symbols, "nimSeqsV2")
defineSymbol(conf.symbols, "nimOwnedEnabled")
of "seqsv2":
processOnOffSwitchG(conf, {optSeqDestructors}, arg, pass, info)
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
of "stylecheck":
case arg.normalize
of "off": conf.globalOptions = conf.globalOptions - {optStyleHint, optStyleError}
of "hint": conf.globalOptions = conf.globalOptions + {optStyleHint} - {optStyleError}
of "error": conf.globalOptions = conf.globalOptions + {optStyleError}
else: localError(conf, info, errOffHintsError % arg)
of "showallmismatches":
processOnOffSwitchG(conf, {optShowAllMismatches}, arg, pass, info)
of "cppcompiletonamespace":
if arg.len > 0:
conf.cppCustomNamespace = arg
else:
conf.cppCustomNamespace = "Nim"
defineSymbol(conf.symbols, "cppCompileToNamespace", conf.cppCustomNamespace)
of "docinternal":
processOnOffSwitchG(conf, {optDocInternal}, arg, pass, info)
of "multimethods":
processOnOffSwitchG(conf, {optMultiMethods}, arg, pass, info)
of "expandmacro":
expectArg(conf, switch, arg, pass, info)
conf.macrosToExpand[arg] = "T"
of "oldgensym":
processOnOffSwitchG(conf, {optNimV019}, arg, pass, info)
of "useversion":
expectArg(conf, switch, arg, pass, info)
case arg
of "1.0":
defineSymbol(conf.symbols, "NimMajor", "1")
defineSymbol(conf.symbols, "NimMinor", "0")
# always be compatible with 1.0.100:
defineSymbol(conf.symbols, "NimPatch", "100")
# old behaviors go here:
defineSymbol(conf.symbols, "nimOldRelativePathBehavior")
ast.eqTypeFlags.excl {tfGcSafe, tfNoSideEffect}
conf.globalOptions.incl optNimV1Emulation
else:
localError(conf, info, "unknown Nim version; currently supported values are: {1.0}")
of "benchmarkvm":
processOnOffSwitchG(conf, {optBenchmarkVM}, arg, pass, info)
of "sinkinference":
processOnOffSwitch(conf, {optSinkInference}, arg, pass, info)
of "panics":
processOnOffSwitchG(conf, {optPanics}, arg, pass, info)
if optPanics in conf.globalOptions:
defineSymbol(conf.symbols, "nimPanics")
of "sourcemap":
conf.globalOptions.incl optSourcemap
conf.options.incl optLineDir
# processOnOffSwitchG(conf, {optSourcemap, opt}, arg, pass, info)
of "": # comes from "-" in for example: `nim c -r -` (gets stripped from -)
handleStdinInput(conf)
else:
if strutils.find(switch, '.') >= 0: options.setConfigVar(conf, switch, arg)
else: invalidCmdLineOption(conf, pass, switch, info)
template gCmdLineInfo*(): untyped = newLineInfo(config, AbsoluteFile"command line", 1, 1)
template gCmdLineInfo*(): untyped = newLineInfo(commandLineIdx, 1, 1)
proc processCommand*(switch: string, pass: TCmdLinePass; config: ConfigRef) =
var cmd, arg: string
@@ -767,8 +923,9 @@ proc processArgument*(pass: TCmdLinePass; p: OptParser;
argsCount: var int; config: ConfigRef): bool =
if argsCount == 0:
# nim filename.nims is the same as "nim e filename.nims":
if p.key.endswith(".nims"):
if p.key.endsWith(".nims"):
config.command = "e"
incl(config.globalOptions, optWasNimscript)
config.projectName = unixToNativePath(p.key)
config.arguments = cmdLineRest(p)
result = true
@@ -778,7 +935,8 @@ proc processArgument*(pass: TCmdLinePass; p: OptParser;
if pass == passCmd1: config.commandArgs.add p.key
if argsCount == 1:
# support UNIX style filenames everywhere for portable build scripts:
config.projectName = unixToNativePath(p.key)
if config.projectName.len == 0:
config.projectName = unixToNativePath(p.key)
config.arguments = cmdLineRest(p)
result = true
inc argsCount

View File

@@ -10,31 +10,26 @@
# This module handles the conditional symbols.
import
strtabs, platform, strutils, idents
strtabs
from options import Feature
from lineinfos import HintsToStr, WarningsToStr
const
catNone = "false"
proc defineSymbol*(symbols: StringTableRef; symbol: string, value: string = "true") =
symbols[symbol] = value
proc undefSymbol*(symbols: StringTableRef; symbol: string) =
symbols[symbol] = catNone
symbols.del(symbol)
#proc lookupSymbol*(symbols: StringTableRef; symbol: string): string =
# result = if isDefined(symbol): gSymbols[symbol] else: nil
iterator definedSymbolNames*(symbols: StringTableRef): string =
for key, val in pairs(symbols):
if val != catNone: yield key
yield key
proc countDefinedSymbols*(symbols: StringTableRef): int =
result = 0
for key, val in pairs(symbols):
if val != catNone: inc(result)
symbols.len
proc initDefines*(symbols: StringTableRef) =
# for bootstrapping purposes and old code:
@@ -53,13 +48,11 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimalias")
defineSymbol("nimlocks")
defineSymbol("nimnode")
defineSymbol("nimnomagic64")
defineSymbol("nimvarargstyped")
defineSymbol("nimtypedescfixed")
defineSymbol("nimKnowsNimvm")
defineSymbol("nimArrIdx")
defineSymbol("nimImmediateDeprecated")
defineSymbol("nimNewShiftOps")
defineSymbol("nimHasalignOf")
defineSymbol("nimDistros")
defineSymbol("nimHasCppDefine")
defineSymbol("nimGenericInOutFlags")
@@ -82,8 +75,17 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimNoNilSeqs")
defineSymbol("nimNoNilSeqs2")
defineSymbol("nimHasUserErrors")
defineSymbol("nimUncheckedArrayTyp")
defineSymbol("nimHasTypeof")
defineSymbol("nimErrorProcCanHaveBody")
defineSymbol("nimHasInstantiationOfInMacro")
defineSymbol("nimHasHotCodeReloading")
defineSymbol("nimHasNilSeqs")
defineSymbol("nimHasSignatureHashInMacro")
defineSymbol("nimHasDefault")
defineSymbol("nimMacrosSizealignof")
defineSymbol("nimNoZeroExtendMagic")
defineSymbol("nimMacrosGetNodeId")
for f in low(Feature)..high(Feature):
defineSymbol("nimHas" & $f)
@@ -91,3 +93,26 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasWarning" & s)
for s in HintsToStr:
defineSymbol("nimHasHint" & s)
defineSymbol("nimFixedOwned")
defineSymbol("nimHasStyleChecks")
defineSymbol("nimToOpenArrayCString")
defineSymbol("nimHasUsed")
defineSymbol("nimFixedForwardGeneric")
defineSymbol("nimnomagic64")
defineSymbol("nimNewShiftOps")
defineSymbol("nimHasCursor")
defineSymbol("nimHasExceptionsQuery")
defineSymbol("nimHasIsNamedTuple")
defineSymbol("nimHashOrdinalFixed")
when defined(nimHasLibFFI):
# Renaming as we can't conflate input vs output define flags; e.g. this
# will report the right thing regardless of whether user adds
# `-d:nimHasLibFFI` in his user config.
defineSymbol("nimHasLibFFIEnabled")
defineSymbol("nimHasSinkInference")
defineSymbol("nimNewIntegerOps")
defineSymbol("nimHasInvariant")
defineSymbol("nimHasStacktraceMsgs")

View File

@@ -1,6 +0,0 @@
## Use the module 'lineinfos' instead!
{.deprecated.}
import lineinfos
export lineinfos

View File

@@ -10,13 +10,12 @@
# This module implements a dependency file generator.
import
os, options, ast, astalgo, msgs, ropes, idents, passes, modulepaths,
pathutils
options, ast, ropes, idents, passes, modulepaths, pathutils
from modulegraphs import ModuleGraph
from modulegraphs import ModuleGraph, PPassContext
type
TGen = object of TPassContext
TGen = object of PPassContext
module: PSym
config: ConfigRef
graph: ModuleGraph
@@ -26,7 +25,7 @@ type
dotGraph: Rope
proc addDependencyAux(b: Backend; importing, imported: string) =
addf(b.dotGraph, "$1 -> \"$2\";$n", [rope(importing), rope(imported)])
b.dotGraph.addf("$1 -> \"$2\";$n", [rope(importing), rope(imported)])
# s1 -> s2_4[label="[0-9]"];
proc addDotDependency(c: PPassContext, n: PNode): PNode =
@@ -35,14 +34,14 @@ proc addDotDependency(c: PPassContext, n: PNode): PNode =
let b = Backend(g.graph.backend)
case n.kind
of nkImportStmt:
for i in countup(0, sonsLen(n) - 1):
var imported = getModuleName(g.config, n.sons[i])
for i in 0..<n.len:
var imported = getModuleName(g.config, n[i])
addDependencyAux(b, g.module.name.s, imported)
of nkFromStmt, nkImportExceptStmt:
var imported = getModuleName(g.config, n.sons[0])
var imported = getModuleName(g.config, n[0])
addDependencyAux(b, g.module.name.s, imported)
of nkStmtList, nkBlockStmt, nkStmtListExpr, nkBlockExpr:
for i in countup(0, sonsLen(n) - 1): discard addDotDependency(c, n.sons[i])
for i in 0..<n.len: discard addDotDependency(c, n[i])
else:
discard

View File

@@ -1,483 +0,0 @@
#
#
# The Nim Compiler
# (c) Copyright 2017 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Injects destructor calls into Nim code as well as
## an optimizer that optimizes copies to moves. This is implemented as an
## AST to AST transformation so that every backend benefits from it.
## Rules for destructor injections:
##
## foo(bar(X(), Y()))
## X and Y get destroyed after bar completes:
##
## foo( (tmpX = X(); tmpY = Y(); tmpBar = bar(tmpX, tmpY);
## destroy(tmpX); destroy(tmpY);
## tmpBar))
## destroy(tmpBar)
##
## var x = f()
## body
##
## is the same as:
##
## var x;
## try:
## move(x, f())
## finally:
## destroy(x)
##
## But this really just an optimization that tries to avoid to
## introduce too many temporaries, the 'destroy' is caused by
## the 'f()' call. No! That is not true for 'result = f()'!
##
## x = y where y is read only once
## is the same as: move(x, y)
##
## Actually the more general rule is: The *last* read of ``y``
## can become a move if ``y`` is the result of a construction.
##
## We also need to keep in mind here that the number of reads is
## control flow dependent:
## let x = foo()
## while true:
## y = x # only one read, but the 2nd iteration will fail!
## This also affects recursions! Only usages that do not cross
## a loop boundary (scope) and are not used in function calls
## are safe.
##
##
## x = f() is the same as: move(x, f())
##
## x = y
## is the same as: copy(x, y)
##
## Reassignment works under this scheme:
## var x = f()
## x = y
##
## is the same as:
##
## var x;
## try:
## move(x, f())
## copy(x, y)
## finally:
## destroy(x)
##
## result = f() must not destroy 'result'!
##
## The produced temporaries clutter up the code and might lead to
## inefficiencies. A better strategy is to collect all the temporaries
## in a single object that we put into a single try-finally that
## surrounds the proc body. This means the code stays quite efficient
## when compiled to C. In fact, we do the same for variables, so
## destructors are called when the proc returns, not at scope exit!
## This makes certains idioms easier to support. (Taking the slice
## of a temporary object.)
##
## foo(bar(X(), Y()))
## X and Y get destroyed after bar completes:
##
## var tmp: object
## foo( (move tmp.x, X(); move tmp.y, Y(); tmp.bar = bar(tmpX, tmpY);
## tmp.bar))
## destroy(tmp.bar)
## destroy(tmp.x); destroy(tmp.y)
##
##[
From https://github.com/nim-lang/Nim/wiki/Destructors
Rule Pattern Transformed into
---- ------- ----------------
1.1 var x: T; stmts var x: T; try stmts
finally: `=destroy`(x)
1.2 var x: sink T; stmts var x: sink T; stmts; ensureEmpty(x)
2 x = f() `=sink`(x, f())
3 x = lastReadOf z `=sink`(x, z); wasMoved(z)
4.1 y = sinkParam `=sink`(y, sinkParam)
4.2 x = y `=`(x, y) # a copy
5.1 f_sink(g()) f_sink(g())
5.2 f_sink(y) f_sink(copy y); # copy unless we can see it's the last read
5.3 f_sink(move y) f_sink(y); wasMoved(y) # explicit moves empties 'y'
5.4 f_noSink(g()) var tmp = bitwiseCopy(g()); f(tmp); `=destroy`(tmp)
Remarks: Rule 1.2 is not yet implemented because ``sink`` is currently
not allowed as a local variable.
``move`` builtin needs to be implemented.
]##
import
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
strutils, options, dfa, lowerings, tables, modulegraphs,
lineinfos
const
InterestingSyms = {skVar, skResult, skLet}
type
Con = object
owner: PSym
g: ControlFlowGraph
jumpTargets: IntSet
tmpObj: PType
tmp: PSym
destroys, topLevelVars: PNode
toDropBit: Table[int, PSym]
graph: ModuleGraph
emptyNode: PNode
proc getTemp(c: var Con; typ: PType; info: TLineInfo): PNode =
# XXX why are temps fields in an object here?
let f = newSym(skField, getIdent(c.graph.cache, ":d" & $c.tmpObj.n.len), c.owner, info)
f.typ = typ
rawAddField c.tmpObj, f
result = rawDirectAccess(c.tmp, f)
proc isHarmlessVar*(s: PSym; c: Con): bool =
# 's' is harmless if it used only once and its
# definition/usage are not split by any labels:
#
# let s = foo()
# while true:
# a[i] = s
#
# produces:
#
# def s
# L1:
# use s
# goto L1
#
# let s = foo()
# if cond:
# a[i] = s
# else:
# a[j] = s
#
# produces:
#
# def s
# fork L2
# use s
# goto L3
# L2:
# use s
# L3
#
# So this analysis is for now overly conservative, but correct.
var defsite = -1
var usages = 0
for i in 0..<c.g.len:
case c.g[i].kind
of def:
if c.g[i].sym == s:
if defsite < 0: defsite = i
else: return false
of use, useWithinCall:
if c.g[i].sym == s:
if defsite < 0: return false
for j in defsite .. i:
# not within the same basic block?
if j in c.jumpTargets: return false
# if we want to die after the first 'use':
if usages > 1: return false
inc usages
#of useWithinCall:
# if c.g[i].sym == s: return false
of goto, fork:
discard "we do not perform an abstract interpretation yet"
result = usages <= 1
template interestingSym(s: PSym): bool =
s.owner == c.owner and s.kind in InterestingSyms and hasDestructor(s.typ)
proc patchHead(n: PNode) =
if n.kind in nkCallKinds and n[0].kind == nkSym and n.len > 1:
let s = n[0].sym
if s.name.s[0] == '=' and s.name.s in ["=sink", "=", "=destroy"]:
if sfFromGeneric in s.flags:
excl(s.flags, sfFromGeneric)
patchHead(s.getBody)
if n[1].typ.isNil:
# XXX toptree crashes without this workaround. Figure out why.
return
let t = n[1].typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred})
template patch(op, field) =
if s.name.s == op and field != nil and field != s:
n.sons[0].sym = field
patch "=sink", t.sink
patch "=", t.assignment
patch "=destroy", t.destructor
for x in n:
patchHead(x)
proc patchHead(s: PSym) =
if sfFromGeneric in s.flags:
patchHead(s.ast[bodyPos])
proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string) =
var m = "'" & opname & "' is not available for type <" & typeToString(t) & ">"
if opname == "=" and ri != nil:
m.add "; requires a copy because it's not the last read of '"
m.add renderTree(ri)
m.add '\''
localError(c.graph.config, ri.info, errGenerated, m)
template genOp(opr, opname, ri) =
let op = opr
if op == nil:
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator not found for type " & typeToString(t))
elif op.ast[genericParamsPos].kind != nkEmpty:
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic")
patchHead op
if sfError in op.flags: checkForErrorPragma(c, t, ri, opname)
result = newTree(nkCall, newSymNode(op), newTree(nkHiddenAddr, dest))
proc genSink(c: Con; t: PType; dest, ri: PNode): PNode =
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
genOp(if t.sink != nil: t.sink else: t.assignment, "=sink", ri)
proc genCopy(c: Con; t: PType; dest, ri: PNode): PNode =
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
genOp(t.assignment, "=", ri)
proc genDestroy(c: Con; t: PType; dest: PNode): PNode =
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
genOp(t.destructor, "=destroy", nil)
proc addTopVar(c: var Con; v: PNode) =
c.topLevelVars.add newTree(nkIdentDefs, v, c.emptyNode, c.emptyNode)
proc dropBit(c: var Con; s: PSym): PSym =
result = c.toDropBit.getOrDefault(s.id)
assert result != nil
proc registerDropBit(c: var Con; s: PSym) =
let result = newSym(skTemp, getIdent(c.graph.cache, s.name.s & "_AliveBit"), c.owner, s.info)
result.typ = getSysType(c.graph, s.info, tyBool)
let trueVal = newIntTypeNode(nkIntLit, 1, result.typ)
c.topLevelVars.add newTree(nkIdentDefs, newSymNode result, c.emptyNode, trueVal)
c.toDropBit[s.id] = result
# generate:
# if not sinkParam_AliveBit: `=destroy`(sinkParam)
let t = s.typ.skipTypes({tyGenericInst, tyAlias, tySink})
if t.destructor != nil:
c.destroys.add newTree(nkIfStmt,
newTree(nkElifBranch, newSymNode result, genDestroy(c, t, newSymNode s)))
proc p(n: PNode; c: var Con): PNode
template recurse(n, dest) =
for i in 0..<n.len:
dest.add p(n[i], c)
proc isSinkParam(s: PSym): bool {.inline.} =
result = s.kind == skParam and s.typ.kind == tySink
const constrExprs = nkCallKinds+{nkObjConstr}
proc destructiveMoveSink(n: PNode; c: var Con): PNode =
# generate: (chckMove(sinkParam_AliveBit); sinkParam_AliveBit = false; sinkParam)
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
let bit = newSymNode dropBit(c, n.sym)
if optMoveCheck in c.owner.options:
result.add callCodegenProc(c.graph, "chckMove", bit)
result.add newTree(nkAsgn, bit,
newIntTypeNode(nkIntLit, 0, getSysType(c.graph, n.info, tyBool)))
result.add n
proc genMagicCall(n: PNode; c: var Con; magicname: string; m: TMagic): PNode =
result = newNodeI(nkCall, n.info)
result.add(newSymNode(createMagic(c.graph, magicname, m)))
result.add n
proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
if ri.kind in constrExprs:
result = genSink(c, dest.typ, dest, ri)
# watch out and no not transform 'ri' twice if it's a call:
let ri2 = copyNode(ri)
recurse(ri, ri2)
result.add ri2
elif ri.kind == nkSym and ri.sym.kind != skParam and isHarmlessVar(ri.sym, c):
# Rule 3: `=sink`(x, z); wasMoved(z)
var snk = genSink(c, dest.typ, dest, ri)
snk.add p(ri, c)
result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved))
elif ri.kind == nkSym and isSinkParam(ri.sym):
result = genSink(c, dest.typ, dest, ri)
result.add destructiveMoveSink(ri, c)
else:
result = genCopy(c, dest.typ, dest, ri)
result.add p(ri, c)
proc passCopyToSink(n: PNode; c: var Con): PNode =
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
let tmp = getTemp(c, n.typ, n.info)
if hasDestructor(n.typ):
var m = genCopy(c, n.typ, tmp, n)
m.add p(n, c)
result.add m
message(c.graph.config, n.info, hintPerformance,
("passing '$1' to a sink parameter introduces an implicit copy; " &
"use 'move($1)' to prevent it") % $n)
else:
result.add newTree(nkAsgn, tmp, p(n, c))
result.add tmp
proc genWasMoved(n: PNode; c: var Con): PNode =
# The mWasMoved builtin does not take the address.
result = genMagicCall(n, c, "wasMoved", mWasMoved)
proc destructiveMoveVar(n: PNode; c: var Con): PNode =
# generate: (let tmp = v; reset(v); tmp)
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
var temp = newSym(skLet, getIdent(c.graph.cache, "blitTmp"), c.owner, n.info)
temp.typ = n.typ
var v = newNodeI(nkLetSection, n.info)
let tempAsNode = newSymNode(temp)
var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3)
vpart.sons[0] = tempAsNode
vpart.sons[1] = c.emptyNode
vpart.sons[2] = n
add(v, vpart)
result.add v
result.add genWasMoved(n, c)
result.add tempAsNode
proc p(n: PNode; c: var Con): PNode =
case n.kind
of nkVarSection, nkLetSection:
discard "transform; var x = y to var x; x op y where op is a move or copy"
result = newNodeI(nkStmtList, n.info)
for i in 0..<n.len:
let it = n[i]
let L = it.len-1
let ri = it[L]
if it.kind == nkVarTuple and hasDestructor(ri.typ):
let x = lowerTupleUnpacking(c.graph, it, c.owner)
result.add p(x, c)
elif it.kind == nkIdentDefs and hasDestructor(it[0].typ):
for j in 0..L-2:
let v = it[j]
doAssert v.kind == nkSym
# move the variable declaration to the top of the frame:
c.addTopVar v
# make sure it's destroyed at the end of the proc:
c.destroys.add genDestroy(c, v.typ, v)
if ri.kind != nkEmpty:
let r = moveOrCopy(v, ri, c)
result.add r
else:
# keep it, but transform 'ri':
var varSection = copyNode(n)
var itCopy = copyNode(it)
for j in 0..L-1:
itCopy.add it[j]
itCopy.add p(ri, c)
varSection.add itCopy
result.add varSection
of nkCallKinds:
let parameters = n[0].typ
let L = if parameters != nil: parameters.len else: 0
for i in 1 ..< n.len:
let arg = n[i]
if i < L and parameters[i].kind == tySink:
if arg.kind in nkCallKinds:
# recurse but skip the call expression in order to prevent
# destructor injections: Rule 5.1 is different from rule 5.4!
let a = copyNode(arg)
recurse(arg, a)
n.sons[i] = a
elif arg.kind in {nkObjConstr, nkCharLit..nkFloat128Lit}:
discard "object construction to sink parameter: nothing to do"
elif arg.kind == nkSym and isHarmlessVar(arg.sym, c):
# if x is a variable and it its last read we eliminate its
# destructor invokation, but don't. We need to reset its memory
# to disable its destructor which we have not elided:
n.sons[i] = destructiveMoveVar(arg, c)
elif arg.kind == nkSym and isSinkParam(arg.sym):
# mark the sink parameter as used:
n.sons[i] = destructiveMoveSink(arg, c)
else:
# an object that is not temporary but passed to a 'sink' parameter
# results in a copy.
n.sons[i] = passCopyToSink(arg, c)
else:
n.sons[i] = p(arg, c)
if n.typ != nil and hasDestructor(n.typ):
discard "produce temp creation"
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
let tmp = getTemp(c, n.typ, n.info)
var sinkExpr = genSink(c, n.typ, tmp, n)
sinkExpr.add n
result.add sinkExpr
result.add tmp
c.destroys.add genDestroy(c, n.typ, tmp)
else:
result = n
of nkAsgn, nkFastAsgn:
if hasDestructor(n[0].typ):
result = moveOrCopy(n[0], n[1], c)
else:
result = copyNode(n)
recurse(n, result)
of nkNone..nkNilLit, nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef,
nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo, nkFuncDef:
result = n
else:
result = copyNode(n)
recurse(n, result)
proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
when defined(nimDebugDestroys):
echo "injecting into ", n
var c: Con
c.owner = owner
c.tmp = newSym(skTemp, getIdent(g.cache, ":d"), owner, n.info)
c.tmpObj = createObj(g, owner, n.info)
c.tmp.typ = c.tmpObj
c.destroys = newNodeI(nkStmtList, n.info)
c.topLevelVars = newNodeI(nkVarSection, n.info)
c.toDropBit = initTable[int, PSym]()
c.graph = g
c.emptyNode = newNodeI(nkEmpty, n.info)
let cfg = constructCfg(owner, n)
shallowCopy(c.g, cfg)
c.jumpTargets = initIntSet()
for i in 0..<c.g.len:
if c.g[i].kind in {goto, fork}:
c.jumpTargets.incl(i+c.g[i].dest)
if owner.kind in {skProc, skFunc, skMethod, skIterator, skConverter}:
let params = owner.typ.n
for i in 1 ..< params.len:
let param = params[i].sym
if param.typ.kind == tySink: registerDropBit(c, param)
let body = p(n, c)
if c.tmp.typ.n.len > 0:
c.addTopVar(newSymNode c.tmp)
result = newNodeI(nkStmtList, n.info)
if c.topLevelVars.len > 0:
result.add c.topLevelVars
if c.destroys.len > 0:
result.add newTryFinally(body, c.destroys)
else:
result.add body
when defined(nimDebugDestroys):
if owner.name.s == "main" or true:
echo "------------------------------------"
echo owner.name.s, " transformed to: "
echo result

View File

@@ -7,9 +7,7 @@
# distribution, for details about the copyright.
#
## Data flow analysis for Nim. For now the task is to prove that every
## usage of a local variable 'v' is covered by an initialization to 'v'
## first.
## Data flow analysis for Nim.
## We transform the AST into a linear list of instructions first to
## make this easier to handle: There are only 2 different branching
## instructions: 'goto X' is an unconditional goto, 'fork X'
@@ -17,26 +15,32 @@
## taken). Exhaustive case statements are translated
## so that the last branch is transformed into an 'else' branch.
## ``return`` and ``break`` are all covered by 'goto'.
## The case to detect is ``use v`` that is not dominated by
## a ``def v``.
##
## Control flow through exception handling:
## Contrary to popular belief, exception handling doesn't cause
## many problems for this DFA representation, ``raise`` is a statement
## that ``goes to`` the outer ``finally`` or ``except`` if there is one,
## otherwise it is the same as ``return``. Every call is treated as
## a call that can potentially ``raise``. However, without a surrounding
## ``try`` we don't emit these ``fork ReturnLabel`` instructions in order
## to speed up the dataflow analysis passes.
##
## The data structures and algorithms used here are inspired by
## "A GraphFree Approach to DataFlow Analysis" by Markus Mohnen.
## https://link.springer.com/content/pdf/10.1007/3-540-45937-5_6.pdf
import ast, astalgo, types, intsets, tables, msgs, options, lineinfos
import ast, types, intsets, lineinfos, renderer
from patterns import sameTrees
type
InstrKind* = enum
goto, fork, def, use,
useWithinCall # this strange special case is used to get more
# move optimizations out of regular code
# XXX This is still overly pessimistic in
# call(let x = foo; bar(x))
goto, fork, join, def, use
Instr* = object
n*: PNode
n*: PNode # contains the def/use location.
case kind*: InstrKind
of def, use, useWithinCall: sym*: PSym
of goto, fork: dest*: int
of goto, fork, join: dest*: int
else: discard
ControlFlowGraph* = seq[Instr]
@@ -45,13 +49,13 @@ type
label: PSym
fixups: seq[TPosition]
ValueKind = enum
undef, value, valueOrUndef
Con = object
code: ControlFlowGraph
inCall: int
inCall, inTryStmt: int
blocks: seq[TBlock]
tryStmtFixups: seq[TPosition]
forks: seq[TPosition]
owner: PSym
proc debugInfo(info: TLineInfo): string =
result = $info.line #info.toFilename & ":" & $info.line
@@ -62,55 +66,209 @@ proc codeListing(c: ControlFlowGraph, result: var string, start=0; last = -1) =
var jumpTargets = initIntSet()
let last = if last < 0: c.len-1 else: min(last, c.len-1)
for i in start..last:
if c[i].kind in {goto, fork}:
if c[i].kind in {goto, fork, join}:
jumpTargets.incl(i+c[i].dest)
var i = start
while i <= last:
if i in jumpTargets: result.add("L" & $i & ":\n")
result.add "\t"
result.add $c[i].kind
result.add ($i & " " & $c[i].kind)
result.add "\t"
case c[i].kind
of def, use, useWithinCall:
result.add c[i].sym.name.s
of goto, fork:
of def, use:
result.add renderTree(c[i].n)
of goto, fork, join:
result.add "L"
result.add c[i].dest+i
result.addInt c[i].dest+i
result.add("\t#")
result.add(debugInfo(c[i].n.info))
result.add("\n")
inc i
if i in jumpTargets: result.add("L" & $i & ": End\n")
# consider calling `asciitables.alignTable`
proc echoCfg*(c: ControlFlowGraph; start=0; last = -1) {.deprecated.} =
## echos the ControlFlowGraph for debugging purposes.
var buf = ""
codeListing(c, buf, start, last)
when declared(echo):
echo buf
echo buf
proc forkI(c: var Con; n: PNode): TPosition =
result = TPosition(c.code.len)
c.code.add Instr(n: n, kind: fork, dest: 0)
c.forks.add result
proc gotoI(c: var Con; n: PNode): TPosition =
result = TPosition(c.code.len)
c.code.add Instr(n: n, kind: goto, dest: 0)
#[
Design of join
==============
block:
if cond: break
def(x)
use(x)
Generates:
L0: fork lab1
join L0 # patched.
goto Louter
lab1:
def x
join L0
Louter:
use x
block outer:
while a:
while b:
if foo:
if bar:
break outer # --> we need to 'join' every pushed 'fork' here
This works and then our abstract interpretation needs to deal with 'fork'
differently. It really causes a split in execution. Two threads are
"spawned" and both need to reach the 'join L' instruction. Afterwards
the abstract interpretations are joined and execution resumes single
threaded.
Abstract Interpretation
-----------------------
proc interpret(pc, state, comesFrom): state =
result = state
# we need an explicit 'create' instruction (an explicit heap), in order
# to deal with 'var x = create(); var y = x; var z = y; destroy(z)'
while true:
case pc
of fork:
let a = interpret(pc+1, result, pc)
let b = interpret(forkTarget, result, pc)
result = a ++ b # ++ is a union operation
inc pc
of join:
if joinTarget == comesFrom: return result
else: inc pc
of use X:
if not result.contains(x):
error "variable not initialized " & x
inc pc
of def X:
if not result.contains(x):
result.incl X
else:
error "overwrite of variable causes memory leak " & x
inc pc
of destroy X:
result.excl X
This is correct but still can lead to false positives:
proc p(cond: bool) =
if cond:
new(x)
otherThings()
if cond:
destroy x
Is not a leak. We should find a way to model *data* flow, not just
control flow. One solution is to rewrite the 'if' without a fork
instruction. The unstructured aspect can now be easily dealt with
the 'goto' and 'join' instructions.
proc p(cond: bool) =
L0: fork Lend
new(x)
# do not 'join' here!
Lend:
otherThings()
join L0 # SKIP THIS FOR new(x) SOMEHOW
destroy x
join L0 # but here.
But if we follow 'goto Louter' we will never come to the join point.
We restore the bindings after popping pc from the stack then there
"no" problem?!
while cond:
prelude()
if not condB: break
postlude()
--->
var setFlag = true
while cond and not setFlag:
prelude()
if not condB:
setFlag = true # BUT: Dependency
if not setFlag: # HERE
postlude()
--->
var setFlag = true
while cond and not setFlag:
prelude()
if not condB:
postlude()
setFlag = true
-------------------------------------------------
while cond:
prelude()
if more:
if not condB: break
stuffHere()
postlude()
-->
var setFlag = true
while cond and not setFlag:
prelude()
if more:
if not condB:
setFlag = false
else:
stuffHere()
postlude()
else:
postlude()
This is getting complicated. Instead we keep the whole 'join' idea but
duplicate the 'join' instructions on breaks and return exits!
]#
proc joinI(c: var Con; fromFork: TPosition; n: PNode) =
let dist = fromFork.int - c.code.len
c.code.add Instr(n: n, kind: join, dest: dist)
proc genLabel(c: Con): TPosition =
result = TPosition(c.code.len)
proc jmpBack(c: var Con, n: PNode, p = TPosition(0)) =
let dist = p.int - c.code.len
doAssert(-0x7fff < dist and dist < 0x7fff)
doAssert(low(int) div 2 + 1 < dist and dist < high(int) div 2)
c.code.add Instr(n: n, kind: goto, dest: dist)
proc patch(c: var Con, p: TPosition) =
# patch with current index
let p = p.int
let diff = c.code.len - p
doAssert(-0x7fff < diff and diff < 0x7fff)
doAssert(low(int) div 2 + 1 < diff and diff < high(int) div 2)
c.code[p].dest = diff
proc popBlock(c: var Con; oldLen: int) =
@@ -130,134 +288,402 @@ proc isTrue(n: PNode): bool =
proc gen(c: var Con; n: PNode) # {.noSideEffect.}
proc genWhile(c: var Con; n: PNode) =
# L1:
# cond, tmp
# fork tmp, L2
# body
# jmp L1
# L2:
let L1 = c.genLabel
withBlock(nil):
if isTrue(n.sons[0]):
c.gen(n.sons[1])
c.jmpBack(n, L1)
when true:
proc genWhile(c: var Con; n: PNode) =
# We unroll every loop 3 times. We emulate 0, 1, 2 iterations
# through the loop. We need to prove this is correct for our
# purposes. But Herb Sutter claims it is. (Proof by authority.)
#[
while cond:
body
Becomes:
if cond:
body
if cond:
body
if cond:
body
We still need to ensure 'break' resolves properly, so an AST to AST
translation is impossible.
So the code to generate is:
cond
fork L4 # F1
body
cond
fork L5 # F2
body
cond
fork L6 # F3
body
L6:
join F3
L5:
join F2
L4:
join F1
]#
if isTrue(n[0]):
# 'while true' is an idiom in Nim and so we produce
# better code for it:
for i in 0..2:
withBlock(nil):
c.gen(n[1])
else:
c.gen(n.sons[0])
let L2 = c.forkI(n)
c.gen(n.sons[1])
c.jmpBack(n, L1)
c.patch(L2)
let oldForksLen = c.forks.len
var endings: array[3, TPosition]
for i in 0..2:
withBlock(nil):
c.gen(n[0])
endings[i] = c.forkI(n)
c.gen(n[1])
for i in countdown(endings.high, 0):
let endPos = endings[i]
c.patch(endPos)
c.joinI(c.forks.pop(), n)
doAssert(c.forks.len == oldForksLen)
else:
proc genWhile(c: var Con; n: PNode) =
# lab1:
# cond, tmp
# fork tmp, lab2
# body
# jmp lab1
# lab2:
let oldForksLen = c.forks.len
let lab1 = c.genLabel
withBlock(nil):
if isTrue(n[0]):
c.gen(n[1])
c.jmpBack(n, lab1)
else:
c.gen(n[0])
let lab2 = c.forkI(n)
c.gen(n[1])
c.jmpBack(n, lab1)
c.patch(lab2)
setLen(c.forks, oldForksLen)
proc genBlock(c: var Con; n: PNode) =
withBlock(n.sons[0].sym):
c.gen(n.sons[1])
withBlock(n[0].sym):
c.gen(n[1])
proc genJoins(c: var Con; n: PNode) =
for i in countdown(c.forks.high, 0): joinI(c, c.forks[i], n)
proc genBreak(c: var Con; n: PNode) =
let L1 = c.gotoI(n)
if n.sons[0].kind == nkSym:
#echo cast[int](n.sons[0].sym)
genJoins(c, n)
let lab1 = c.gotoI(n)
if n[0].kind == nkSym:
#echo cast[int](n[0].sym)
for i in countdown(c.blocks.len-1, 0):
if c.blocks[i].label == n.sons[0].sym:
c.blocks[i].fixups.add L1
if c.blocks[i].label == n[0].sym:
c.blocks[i].fixups.add lab1
return
#globalError(n.info, "VM problem: cannot find 'break' target")
else:
c.blocks[c.blocks.high].fixups.add L1
c.blocks[c.blocks.high].fixups.add lab1
template forkT(n, body) =
let oldLen = c.forks.len
let lab1 = c.forkI(n)
body
c.patch(lab1)
c.joinI(lab1, n)
setLen(c.forks, oldLen)
proc genIf(c: var Con, n: PNode) =
#[
if cond:
A
elif condB:
B
elif condC:
C
else:
D
cond
fork lab1
A
goto Lend
lab1:
condB
fork lab2
B
goto Lend2
lab2:
condC
fork L3
C
goto Lend3
L3:
D
goto Lend3 # not eliminated to simplify the join generation
Lend3:
join F3
Lend2:
join F2
Lend:
join F1
]#
let oldLen = c.forks.len
var endings: seq[TPosition] = @[]
for i in countup(0, len(n) - 1):
var it = n.sons[i]
c.gen(it.sons[0])
for i in 0..<n.len:
var it = n[i]
c.gen(it[0])
if it.len == 2:
let elsePos = c.forkI(it.sons[1])
c.gen(it.sons[1])
if i < sonsLen(n)-1:
endings.add(c.gotoI(it.sons[1]))
let elsePos = forkI(c, it[1])
c.gen(it[1])
endings.add(c.gotoI(it[1]))
c.patch(elsePos)
for endPos in endings: c.patch(endPos)
for i in countdown(endings.high, 0):
let endPos = endings[i]
c.patch(endPos)
c.joinI(c.forks.pop(), n)
doAssert(c.forks.len == oldLen)
proc genAndOr(c: var Con; n: PNode) =
# asgn dest, a
# fork L1
# fork lab1
# asgn dest, b
# L1:
c.gen(n.sons[1])
let L1 = c.forkI(n)
c.gen(n.sons[2])
c.patch(L1)
# lab1:
# join F1
c.gen(n[1])
forkT(n):
c.gen(n[2])
proc genCase(c: var Con; n: PNode) =
# if (!expr1) goto L1;
# if (!expr1) goto lab1;
# thenPart
# goto LEnd
# L1:
# if (!expr2) goto L2;
# lab1:
# if (!expr2) goto lab2;
# thenPart2
# goto LEnd
# L2:
# lab2:
# elsePart
# Lend:
let isExhaustive = skipTypes(n[0].typ,
abstractVarRange-{tyTypeDesc}).kind notin {tyFloat..tyFloat128, tyString}
var endings: seq[TPosition] = @[]
c.gen(n.sons[0])
for i in 1 ..< n.len:
let it = n.sons[i]
let oldLen = c.forks.len
c.gen(n[0])
for i in 1..<n.len:
let it = n[i]
if it.len == 1:
c.gen(it.sons[0])
c.gen(it[0])
elif i == n.len-1 and isExhaustive:
# treat the last branch as 'else' if this is an exhaustive case statement.
c.gen(it.lastSon)
else:
let elsePos = c.forkI(it.lastSon)
c.gen(it.lastSon)
if i < sonsLen(n)-1:
endings.add(c.gotoI(it.lastSon))
endings.add(c.gotoI(it.lastSon))
c.patch(elsePos)
for endPos in endings: c.patch(endPos)
for i in countdown(endings.high, 0):
let endPos = endings[i]
c.patch(endPos)
c.joinI(c.forks.pop(), n)
doAssert(c.forks.len == oldLen)
proc genTry(c: var Con; n: PNode) =
let oldLen = c.forks.len
var endings: seq[TPosition] = @[]
let elsePos = c.forkI(n)
c.gen(n.sons[0])
c.patch(elsePos)
for i in 1 ..< n.len:
let it = n.sons[i]
inc c.inTryStmt
let oldFixups = c.tryStmtFixups.len
#let elsePos = c.forkI(n)
c.gen(n[0])
dec c.inTryStmt
for i in oldFixups..c.tryStmtFixups.high:
let f = c.tryStmtFixups[i]
c.patch(f)
# we also need to produce join instructions
# for the 'fork' that might precede the goto instruction
if f.int-1 >= 0 and c.code[f.int-1].kind == fork:
c.joinI(TPosition(f.int-1), n)
setLen(c.tryStmtFixups, oldFixups)
#c.patch(elsePos)
for i in 1..<n.len:
let it = n[i]
if it.kind != nkFinally:
var blen = len(it)
let endExcept = c.forkI(it)
c.gen(it.lastSon)
if i < sonsLen(n)-1:
endings.add(c.gotoI(it))
endings.add(c.gotoI(it))
c.patch(endExcept)
for endPos in endings: c.patch(endPos)
for i in countdown(endings.high, 0):
let endPos = endings[i]
c.patch(endPos)
c.joinI(c.forks.pop(), n)
# join the 'elsePos' forkI instruction:
#c.joinI(c.forks.pop(), n)
let fin = lastSon(n)
if fin.kind == nkFinally:
c.gen(fin.sons[0])
c.gen(fin[0])
doAssert(c.forks.len == oldLen)
template genNoReturn(c: var Con; n: PNode) =
# leave the graph
c.code.add Instr(n: n, kind: goto, dest: high(int) - c.code.len)
proc genRaise(c: var Con; n: PNode) =
gen(c, n.sons[0])
c.code.add Instr(n: n, kind: goto, dest: high(int) - c.code.len)
genJoins(c, n)
gen(c, n[0])
if c.inTryStmt > 0:
c.tryStmtFixups.add c.gotoI(n)
else:
genNoReturn(c, n)
proc genImplicitReturn(c: var Con) =
if c.owner.kind in {skProc, skFunc, skMethod, skIterator, skConverter} and resultPos < c.owner.ast.len:
gen(c, c.owner.ast[resultPos])
proc genReturn(c: var Con; n: PNode) =
if n.sons[0].kind != nkEmpty: gen(c, n.sons[0])
c.code.add Instr(n: n, kind: goto, dest: high(int) - c.code.len)
genJoins(c, n)
if n[0].kind != nkEmpty:
gen(c, n[0])
else:
genImplicitReturn(c)
genNoReturn(c, n)
const
InterestingSyms = {skVar, skResult, skLet}
InterestingSyms = {skVar, skResult, skLet, skParam, skForVar, skTemp}
PathKinds0 = {nkDotExpr, nkCheckedFieldExpr,
nkBracketExpr, nkDerefExpr, nkHiddenDeref,
nkAddr, nkHiddenAddr,
nkObjDownConv, nkObjUpConv}
PathKinds1 = {nkHiddenStdConv, nkHiddenSubConv}
proc genUse(c: var Con; n: PNode) =
var n = n
while n.kind in {nkDotExpr, nkCheckedFieldExpr,
nkBracketExpr, nkDerefExpr, nkHiddenDeref,
nkAddr, nkHiddenAddr}:
n = n[0]
proc skipConvDfa*(n: PNode): PNode =
result = n
while true:
case result.kind
of nkObjDownConv, nkObjUpConv:
result = result[0]
of PathKinds1:
result = result[1]
else: break
proc genUse(c: var Con; orig: PNode) =
var n = orig
while true:
case n.kind
of PathKinds0 - {nkBracketExpr}:
n = n[0]
of nkBracketExpr:
gen(c, n[1])
n = n[0]
of PathKinds1:
n = n[1]
else: break
if n.kind in nkCallKinds:
gen(c, n)
if n.kind == nkSym and n.sym.kind in InterestingSyms:
if c.inCall > 0:
c.code.add Instr(n: n, kind: useWithinCall, sym: n.sym)
c.code.add Instr(n: orig, kind: use)
proc aliases*(obj, field: PNode): bool =
var n = field
var obj = obj
while obj.kind in {nkHiddenSubConv, nkHiddenStdConv, nkObjDownConv, nkObjUpConv}:
obj = obj[0]
while true:
if sameTrees(obj, n): return true
case n.kind
of PathKinds0, PathKinds1:
n = n[0]
else:
c.code.add Instr(n: n, kind: use, sym: n.sym)
break
proc useInstrTargets*(ins: Instr; loc: PNode): bool =
assert ins.kind == use
result = sameTrees(ins.n, loc) or
ins.n.aliases(loc) or loc.aliases(ins.n)
# We can come here if loc is 'x.f' and ins.n is 'x' or the other way round.
# use x.f; question: does it affect the full 'x'? No.
# use x; question does it affect 'x.f'? Yes.
proc defInstrTargets*(ins: Instr; loc: PNode): bool =
assert ins.kind == def
result = sameTrees(ins.n, loc) or ins.n.aliases(loc)
# We can come here if loc is 'x.f' and ins.n is 'x' or the other way round.
# def x.f; question: does it affect the full 'x'? No.
# def x; question: does it affect the 'x.f'? Yes.
proc isAnalysableFieldAccess*(orig: PNode; owner: PSym): bool =
var n = orig
while true:
case n.kind
of nkDotExpr, nkCheckedFieldExpr, nkHiddenSubConv, nkHiddenStdConv,
nkObjDownConv, nkObjUpConv, nkHiddenAddr, nkAddr:
n = n[0]
of nkBracketExpr:
# in a[i] the 'i' must be known
if n.len > 1 and n[1].kind in {nkCharLit..nkUInt64Lit}:
n = n[0]
else:
return false
of nkHiddenDeref, nkDerefExpr:
# We "own" sinkparam[].loc but not ourVar[].location as it is a nasty
# pointer indirection.
n = n[0]
return n.kind == nkSym and n.sym.owner == owner and (isSinkParam(n.sym) or
n.sym.typ.skipTypes(abstractInst-{tyOwned}).kind in {tyOwned})
else:
break
# XXX Allow closure deref operations here if we know
# the owner controlled the closure allocation?
result = n.kind == nkSym and n.sym.owner == owner and
owner.kind != skModule and
(n.sym.kind != skParam or isSinkParam(n.sym)) # or n.sym.typ.kind == tyVar)
# Note: There is a different move analyzer possible that checks for
# consume(param.key); param.key = newValue for all paths. Then code like
#
# let splited = split(move self.root, x)
# self.root = merge(splited.lower, splited.greater)
#
# could be written without the ``move self.root``. However, this would be
# wrong! Then the write barrier for the ``self.root`` assignment would
# free the old data and all is lost! Lesson: Don't be too smart, trust the
# lower level C++ optimizer to specialize this code.
proc genDef(c: var Con; n: PNode) =
var m = n
# XXX do something about this duplicated logic here.
while true:
case m.kind
of nkDotExpr, nkCheckedFieldExpr, nkHiddenSubConv, nkHiddenStdConv,
nkObjDownConv, nkObjUpConv, nkHiddenAddr, nkAddr:
m = m[0]
of nkBracketExpr:
gen(c, m[1])
m = m[0]
of nkHiddenDeref, nkDerefExpr:
m = m[0]
else:
break
if n.kind == nkSym and n.sym.kind in InterestingSyms:
c.code.add Instr(n: n, kind: def, sym: n.sym)
c.code.add Instr(n: n, kind: def)
elif isAnalysableFieldAccess(n, c.owner):
c.code.add Instr(n: n, kind: def)
else:
# bug #13314: An assignment to t5.w = -5 is a usage of 't5'
# we still need to gather the use information:
gen(c, n)
proc genCall(c: var Con; n: PNode) =
gen(c, n[0])
@@ -266,8 +692,23 @@ proc genCall(c: var Con; n: PNode) =
inc c.inCall
for i in 1..<n.len:
gen(c, n[i])
if t != nil and i < t.len and t.sons[i].kind == tyVar:
genDef(c, n[i])
when false:
if t != nil and i < t.len and t[i].kind == tyVar:
# This is wrong! Pass by var is a 'might def', not a 'must def'
# like the other defs we emit. This is not good enough for a move
# optimizer.
genDef(c, n[i])
# every call can potentially raise:
if c.inTryStmt > 0 and canRaiseConservative(n[0]):
# we generate the instruction sequence:
# fork lab1
# goto exceptionHandler (except or finally)
# lab1:
# join F1
let endGoto = c.forkI(n)
c.tryStmtFixups.add c.gotoI(n)
c.patch(endGoto)
c.joinI(c.forks.pop(), n)
dec c.inCall
proc genMagic(c: var Con; n: PNode; m: TMagic) =
@@ -276,171 +717,71 @@ proc genMagic(c: var Con; n: PNode; m: TMagic) =
of mNew, mNewFinalize:
genDef(c, n[1])
for i in 2..<n.len: gen(c, n[i])
of mExit:
genCall(c, n)
c.code.add Instr(n: n, kind: goto, dest: high(int) - c.code.len)
else:
genCall(c, n)
proc genVarSection(c: var Con; n: PNode) =
for a in n:
if a.kind == nkCommentStmt: continue
if a.kind == nkVarTuple:
if a.kind == nkCommentStmt:
discard
elif a.kind == nkVarTuple:
gen(c, a.lastSon)
for i in 0 .. a.len-3: genDef(c, a[i])
for i in 0..<a.len-2: genDef(c, a[i])
else:
gen(c, a.lastSon)
if a.lastSon.kind != nkEmpty:
genDef(c, a.sons[0])
genDef(c, a[0])
proc gen(c: var Con; n: PNode) =
case n.kind
of nkSym: genUse(c, n)
of nkCallKinds:
if n.sons[0].kind == nkSym:
let s = n.sons[0].sym
if n[0].kind == nkSym:
let s = n[0].sym
if s.magic != mNone:
genMagic(c, n, s.magic)
else:
genCall(c, n)
if sfNoReturn in n[0].sym.flags:
genNoReturn(c, n)
else:
genCall(c, n)
of nkCharLit..nkNilLit: discard
of nkAsgn, nkFastAsgn:
gen(c, n[1])
# watch out: 'obj[i].f2 = value' sets 'f2' but
# "uses" 'i'. But we are only talking about builtin array indexing so
# it doesn't matter and 'x = 34' is NOT a usage of 'x'.
genDef(c, n[0])
of nkDotExpr, nkCheckedFieldExpr, nkBracketExpr,
nkDerefExpr, nkHiddenDeref, nkAddr, nkHiddenAddr:
gen(c, n[0])
of PathKinds0 - {nkHiddenStdConv, nkHiddenSubConv, nkObjDownConv, nkObjUpConv}:
genUse(c, n)
of nkIfStmt, nkIfExpr: genIf(c, n)
of nkWhenStmt:
# This is "when nimvm" node. Chose the first branch.
gen(c, n.sons[0].sons[1])
gen(c, n[0][1])
of nkCaseStmt: genCase(c, n)
of nkWhileStmt: genWhile(c, n)
of nkBlockExpr, nkBlockStmt: genBlock(c, n)
of nkReturnStmt: genReturn(c, n)
of nkRaiseStmt: genRaise(c, n)
of nkBreakStmt: genBreak(c, n)
of nkTryStmt: genTry(c, n)
of nkTryStmt, nkHiddenTryStmt: genTry(c, n)
of nkStmtList, nkStmtListExpr, nkChckRangeF, nkChckRange64, nkChckRange,
nkBracket, nkCurly, nkPar, nkTupleConstr, nkClosure, nkObjConstr:
nkBracket, nkCurly, nkPar, nkTupleConstr, nkClosure, nkObjConstr, nkYieldStmt:
for x in n: gen(c, x)
of nkPragmaBlock: gen(c, n.lastSon)
of nkDiscardStmt: gen(c, n.sons[0])
of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkExprColonExpr, nkExprEqExpr,
nkCast:
gen(c, n.sons[1])
of nkObjDownConv, nkStringToCString, nkCStringToString: gen(c, n.sons[0])
of nkDiscardStmt, nkObjDownConv, nkObjUpConv: gen(c, n[0])
of nkConv, nkExprColonExpr, nkExprEqExpr, nkCast, nkHiddenSubConv, nkHiddenStdConv:
gen(c, n[1])
of nkStringToCString, nkCStringToString: gen(c, n[0])
of nkVarSection, nkLetSection: genVarSection(c, n)
of nkDefer:
doAssert false, "dfa construction pass requires the elimination of 'defer'"
else: discard
proc dfa(code: seq[Instr]; conf: ConfigRef) =
var u = newSeq[IntSet](code.len) # usages
var d = newSeq[IntSet](code.len) # defs
var c = newSeq[IntSet](code.len) # consumed
var backrefs = initTable[int, int]()
for i in 0..<code.len:
u[i] = initIntSet()
d[i] = initIntSet()
c[i] = initIntSet()
case code[i].kind
of use, useWithinCall: u[i].incl(code[i].sym.id)
of def: d[i].incl(code[i].sym.id)
of fork, goto:
let d = i+code[i].dest
backrefs.add(d, i)
var w = @[0]
var maxIters = 50
var someChange = true
var takenGotos = initIntSet()
var consuming = -1
while w.len > 0 and maxIters > 0: # and someChange:
dec maxIters
var pc = w.pop() # w[^1]
var prevPc = -1
# this simulates a single linear control flow execution:
while pc < code.len:
if prevPc >= 0:
someChange = false
# merge step and test for changes (we compute the fixpoints here):
# 'u' needs to be the union of prevPc, pc
# 'd' needs to be the intersection of 'pc'
for id in u[prevPc]:
if not u[pc].containsOrIncl(id):
someChange = true
# in (a; b) if ``a`` sets ``v`` so does ``b``. The intersection
# is only interesting on merge points:
for id in d[prevPc]:
if not d[pc].containsOrIncl(id):
someChange = true
# if this is a merge point, we take the intersection of the 'd' sets:
if backrefs.hasKey(pc):
var intersect = initIntSet()
assign(intersect, d[pc])
var first = true
for prevPc in backrefs.allValues(pc):
for def in d[pc]:
if def notin d[prevPc]:
excl(intersect, def)
someChange = true
when defined(debugDfa):
echo "Excluding ", pc, " prev ", prevPc
assign d[pc], intersect
if consuming >= 0:
if not c[pc].containsOrIncl(consuming):
someChange = true
consuming = -1
# our interpretation ![I!]:
prevPc = pc
case code[pc].kind
of goto:
# we must leave endless loops eventually:
if not takenGotos.containsOrIncl(pc) or someChange:
pc = pc + code[pc].dest
else:
inc pc
of fork:
# we follow the next instruction but push the dest onto our "work" stack:
#if someChange:
w.add pc + code[pc].dest
inc pc
of use, useWithinCall:
#if not d[prevPc].missingOrExcl():
# someChange = true
consuming = code[pc].sym.id
inc pc
of def:
if not d[pc].containsOrIncl(code[pc].sym.id):
someChange = true
inc pc
when defined(useDfa) and defined(debugDfa):
for i in 0..<code.len:
echo "PC ", i, ": defs: ", d[i], "; uses ", u[i], "; consumes ", c[i]
# now check the condition we're interested in:
for i in 0..<code.len:
case code[i].kind
of use, useWithinCall:
let s = code[i].sym
if s.id notin d[i]:
localError(conf, code[i].n.info, "usage of uninitialized variable: " & s.name.s)
if s.id in c[i]:
localError(conf, code[i].n.info, "usage of an already consumed variable: " & s.name.s)
else: discard
proc dataflowAnalysis*(s: PSym; body: PNode; conf: ConfigRef) =
var c = Con(code: @[], blocks: @[])
gen(c, body)
when defined(useDfa) and defined(debugDfa): echoCfg(c.code)
dfa(c.code, conf)
proc constructCfg*(s: PSym; body: PNode): ControlFlowGraph =
## constructs a control flow graph for ``body``.
var c = Con(code: @[], blocks: @[])
var c = Con(code: @[], blocks: @[], owner: s)
gen(c, body)
genImplicitReturn(c)
shallowCopy(result, c.code)

File diff suppressed because it is too large Load Diff

View File

@@ -11,25 +11,24 @@
# semantic checking.
import
os, options, ast, astalgo, msgs, ropes, idents, passes, docgen, lineinfos,
pathutils
options, ast, msgs, passes, docgen, lineinfos, pathutils
from modulegraphs import ModuleGraph
from modulegraphs import ModuleGraph, PPassContext
type
TGen = object of TPassContext
TGen = object of PPassContext
doc: PDoc
module: PSym
config: ConfigRef
PGen = ref TGen
template shouldProcess(g): bool =
(g.module.owner.id == g.doc.conf.mainPackageId and optWholeProject in g.doc.conf.globalOptions) or
sfMainModule in g.module.flags
proc shouldProcess(g: PGen): bool =
(optWholeProject in g.doc.conf.globalOptions and g.module.getnimblePkgId == g.doc.conf.mainPackageId) or
sfMainModule in g.module.flags or g.config.projectMainIdx == g.module.info.fileIndex
template closeImpl(body: untyped) {.dirty.} =
var g = PGen(p)
let useWarning = sfMainModule notin g.module.flags
#echo g.module.name.s, " ", g.module.owner.id, " ", gMainPackageId
if shouldProcess(g):
body
try:
@@ -55,20 +54,27 @@ proc processNodeJson(c: PPassContext, n: PNode): PNode =
result = n
var g = PGen(c)
if shouldProcess(g):
generateJson(g.doc, n)
generateJson(g.doc, n, false)
proc myOpen(graph: ModuleGraph; module: PSym): PPassContext =
template myOpenImpl(ext: untyped) {.dirty.} =
var g: PGen
new(g)
g.module = module
g.config = graph.config
var d = newDocumentor(AbsoluteFile toFullPath(graph.config, FileIndex module.position),
graph.cache, graph.config)
graph.cache, graph.config, ext, module)
d.hasToc = true
g.doc = d
result = g
proc myOpen(graph: ModuleGraph; module: PSym): PPassContext =
myOpenImpl(HtmlExt)
proc myOpenJson(graph: ModuleGraph; module: PSym): PPassContext =
myOpenImpl(JsonExt)
const docgen2Pass* = makePass(open = myOpen, process = processNode, close = close)
const docgen2JsonPass* = makePass(open = myOpen, process = processNodeJson,
const docgen2JsonPass* = makePass(open = myOpenJson, process = processNodeJson,
close = closeJson)
proc finishDoc2Pass*(project: string) =

105
compiler/enumtostr.nim Normal file
View File

@@ -0,0 +1,105 @@
import ast, idents, lineinfos, modulegraphs, magicsys
proc genEnumToStrProc*(t: PType; info: TLineInfo; g: ModuleGraph): PSym =
result = newSym(skProc, getIdent(g.cache, "$"), t.owner, info)
let dest = newSym(skParam, getIdent(g.cache, "e"), result, info)
dest.typ = t
let res = newSym(skResult, getIdent(g.cache, "result"), result, info)
res.typ = getSysType(g, info, tyString)
result.typ = newType(tyProc, t.owner)
result.typ.n = newNodeI(nkFormalParams, info)
rawAddSon(result.typ, res.typ)
result.typ.n.add newNodeI(nkEffectList, info)
result.typ.addParam dest
var body = newNodeI(nkStmtList, info)
var caseStmt = newNodeI(nkCaseStmt, info)
caseStmt.add(newSymNode dest)
# copy the branches over, but replace the fields with the for loop body:
for i in 0..<t.n.len:
assert(t.n[i].kind == nkSym)
var field = t.n[i].sym
let val = if field.ast == nil: field.name.s else: field.ast.strVal
caseStmt.add newTree(nkOfBranch, newSymNode(field),
newTree(nkStmtList, newTree(nkFastAsgn, newSymNode(res), newStrNode(val, info))))
#newIntTypeNode(nkIntLit, field.position, t)
body.add(caseStmt)
var n = newNodeI(nkProcDef, info, bodyPos+2)
for i in 0..<n.len: n[i] = newNodeI(nkEmpty, info)
n[namePos] = newSymNode(result)
n[paramsPos] = result.typ.n
n[bodyPos] = body
n[resultPos] = newSymNode(res)
result.ast = n
incl result.flags, sfFromGeneric
incl result.flags, sfNeverRaises
proc searchObjCaseImpl(obj: PNode; field: PSym): PNode =
case obj.kind
of nkSym:
result = nil
of nkElse, nkOfBranch:
result = searchObjCaseImpl(obj.lastSon, field)
else:
if obj.kind == nkRecCase and obj[0].kind == nkSym and obj[0].sym == field:
result = obj
else:
for x in obj:
result = searchObjCaseImpl(x, field)
if result != nil: break
proc searchObjCase(t: PType; field: PSym): PNode =
result = searchObjCaseImpl(t.n, field)
if result == nil and t.len > 0:
result = searchObjCase(t[0].skipTypes({tyAlias, tyGenericInst, tyRef, tyPtr}), field)
doAssert result != nil
proc genCaseObjDiscMapping*(t: PType; field: PSym; info: TLineInfo; g: ModuleGraph): PSym =
result = newSym(skProc, getIdent(g.cache, "objDiscMapping"), t.owner, info)
let dest = newSym(skParam, getIdent(g.cache, "e"), result, info)
dest.typ = field.typ
let res = newSym(skResult, getIdent(g.cache, "result"), result, info)
res.typ = getSysType(g, info, tyUInt8)
result.typ = newType(tyProc, t.owner)
result.typ.n = newNodeI(nkFormalParams, info)
rawAddSon(result.typ, res.typ)
result.typ.n.add newNodeI(nkEffectList, info)
result.typ.addParam dest
var body = newNodeI(nkStmtList, info)
var caseStmt = newNodeI(nkCaseStmt, info)
caseStmt.add(newSymNode dest)
let subObj = searchObjCase(t, field)
for i in 1..<subObj.len:
let ofBranch = subObj[i]
var newBranch = newNodeI(ofBranch.kind, ofBranch.info)
for j in 0..<ofBranch.len-1:
newBranch.add ofBranch[j]
newBranch.add newTree(nkStmtList, newTree(nkFastAsgn, newSymNode(res), newIntNode(nkInt8Lit, i)))
caseStmt.add newBranch
body.add(caseStmt)
var n = newNodeI(nkProcDef, info, bodyPos+2)
for i in 0..<n.len: n[i] = newNodeI(nkEmpty, info)
n[namePos] = newSymNode(result)
n[paramsPos] = result.typ.n
n[bodyPos] = body
n[resultPos] = newSymNode(res)
result.ast = n
incl result.flags, sfFromGeneric
incl result.flags, sfNeverRaises

View File

@@ -9,76 +9,80 @@
## This file implements the FFI part of the evaluator for Nim code.
import ast, astalgo, ropes, types, options, tables, dynlib, libffi, msgs, os
import ast, types, options, tables, dynlib, msgs, lineinfos
from os import getAppFilename
import pkg/libffi
when defined(windows):
const libcDll = "msvcrt.dll"
else:
elif defined(linux):
const libcDll = "libc.so(.6|.5|)"
elif defined(bsd):
const libcDll = "/lib/libc.so.7"
elif defined(osx):
const libcDll = "/usr/lib/libSystem.dylib"
else:
{.error: "`libcDll` not implemented on this platform".}
type
TDllCache = tables.TTable[string, TLibHandle]
TDllCache = tables.Table[string, LibHandle]
var
gDllCache = initTable[string, TLibHandle]()
gDllCache = initTable[string, LibHandle]()
when defined(windows):
var gExeHandle = loadLib(os.getAppFilename())
var gExeHandle = loadLib(getAppFilename())
else:
var gExeHandle = loadLib()
proc getDll(cache: var TDllCache; dll: string; info: TLineInfo): pointer =
result = cache[dll]
proc getDll(conf: ConfigRef, cache: var TDllCache; dll: string; info: TLineInfo): pointer =
if dll in cache:
return cache[dll]
var libs: seq[string]
libCandidates(dll, libs)
for c in libs:
result = loadLib(c)
if not result.isNil: break
if result.isNil:
var libs: seq[string] = @[]
libCandidates(dll, libs)
for c in libs:
result = loadLib(c)
if not result.isNil: break
if result.isNil:
globalError(info, "cannot load: " & dll)
cache[dll] = result
globalError(conf, info, "cannot load: " & dll)
cache[dll] = result
const
nkPtrLit = nkIntLit # hopefully we can get rid of this hack soon
var myerrno {.importc: "errno", header: "<errno.h>".}: cint ## error variable
proc importcSymbol*(sym: PSym): PNode =
let name = ropeToStr(sym.loc.r)
proc importcSymbol*(conf: ConfigRef, sym: PSym): PNode =
let name = sym.cname # $sym.loc.r would point to internal name
# the AST does not support untyped pointers directly, so we use an nkIntLit
# that contains the address instead:
result = newNodeIT(nkPtrLit, sym.info, sym.typ)
case name
of "stdin": result.intVal = cast[ByteAddress](system.stdin)
of "stdout": result.intVal = cast[ByteAddress](system.stdout)
of "stderr": result.intVal = cast[ByteAddress](system.stderr)
of "vmErrnoWrapper": result.intVal = cast[ByteAddress](myerrno)
else:
when true:
var libPathMsg = ""
let lib = sym.annex
if lib != nil and lib.path.kind notin {nkStrLit..nkTripleStrLit}:
globalError(sym.info, "dynlib needs to be a string lit for the REPL")
globalError(conf, sym.info, "dynlib needs to be a string lit")
var theAddr: pointer
if lib.isNil and not gExehandle.isNil:
if (lib.isNil or lib.kind == libHeader) and not gExeHandle.isNil:
libPathMsg = "current exe: " & getAppFilename() & " nor libc: " & libcDll
# first try this exe itself:
theAddr = gExehandle.symAddr(name)
theAddr = gExeHandle.symAddr(name)
# then try libc:
if theAddr.isNil:
let dllhandle = gDllCache.getDll(libcDll, sym.info)
let dllhandle = getDll(conf, gDllCache, libcDll, sym.info)
theAddr = dllhandle.symAddr(name)
elif not lib.isNil:
let dllhandle = gDllCache.getDll(if lib.kind == libHeader: libcDll
else: lib.path.strVal, sym.info)
let dll = if lib.kind == libHeader: libcDll else: lib.path.strVal
libPathMsg = dll
let dllhandle = getDll(conf, gDllCache, dll, sym.info)
theAddr = dllhandle.symAddr(name)
if theAddr.isNil: globalError(sym.info, "cannot import: " & sym.name.s)
if theAddr.isNil: globalError(conf, sym.info,
"cannot import symbol: " & name & " from " & libPathMsg)
result.intVal = cast[ByteAddress](theAddr)
proc mapType(t: ast.PType): ptr libffi.TType =
proc mapType(conf: ConfigRef, t: ast.PType): ptr libffi.Type =
if t == nil: return addr libffi.type_void
case t.kind
of tyBool, tyEnum, tyChar, tyInt..tyInt64, tyUInt..tyUInt64, tySet:
case t.getSize
case getSize(conf, t)
of 1: result = addr libffi.type_uint8
of 2: result = addr libffi.type_sint16
of 4: result = addr libffi.type_sint32
@@ -86,91 +90,91 @@ proc mapType(t: ast.PType): ptr libffi.TType =
else: result = nil
of tyFloat, tyFloat64: result = addr libffi.type_double
of tyFloat32: result = addr libffi.type_float
of tyVar, tyLent, tyPointer, tyPtr, tyRef, tyCString, tySequence, tyString, tyExpr,
tyStmt, tyTypeDesc, tyProc, tyArray, tyStatic, tyNil:
of tyVar, tyLent, tyPointer, tyPtr, tyRef, tyCString, tySequence, tyString, tyUntyped,
tyTyped, tyTypeDesc, tyProc, tyArray, tyStatic, tyNil:
result = addr libffi.type_pointer
of tyDistinct, tyAlias, tySink:
result = mapType(t.sons[0])
result = mapType(conf, t[0])
else:
result = nil
# too risky:
#of tyFloat128: result = addr libffi.type_longdouble
proc mapCallConv(cc: TCallingConvention, info: TLineInfo): TABI =
proc mapCallConv(conf: ConfigRef, cc: TCallingConvention, info: TLineInfo): TABI =
case cc
of ccDefault: result = DEFAULT_ABI
of ccStdCall: result = when defined(windows): STDCALL else: DEFAULT_ABI
of ccStdCall: result = when defined(windows) and defined(x86): STDCALL else: DEFAULT_ABI
of ccCDecl: result = DEFAULT_ABI
else:
globalError(info, "cannot map calling convention to FFI")
globalError(conf, info, "cannot map calling convention to FFI")
template rd(T, p: untyped): untyped = (cast[ptr T](p))[]
template wr(T, p, v: untyped): untyped = (cast[ptr T](p))[] = v
template `+!`(x, y: untyped): untyped =
cast[pointer](cast[ByteAddress](x) + y)
proc packSize(v: PNode, typ: PType): int =
proc packSize(conf: ConfigRef, v: PNode, typ: PType): int =
## computes the size of the blob
case typ.kind
of tyPtr, tyRef, tyVar, tyLent:
if v.kind in {nkNilLit, nkPtrLit}:
result = sizeof(pointer)
else:
result = sizeof(pointer) + packSize(v.sons[0], typ.lastSon)
result = sizeof(pointer) + packSize(conf, v[0], typ.lastSon)
of tyDistinct, tyGenericInst, tyAlias, tySink:
result = packSize(v, typ.sons[0])
result = packSize(conf, v, typ[0])
of tyArray:
# consider: ptr array[0..1000_000, int] which is common for interfacing;
# we use the real length here instead
if v.kind in {nkNilLit, nkPtrLit}:
result = sizeof(pointer)
elif v.len != 0:
result = v.len * packSize(v.sons[0], typ.sons[1])
result = v.len * packSize(conf, v[0], typ[1])
else:
result = typ.getSize.int
result = getSize(conf, typ).int
proc pack(v: PNode, typ: PType, res: pointer)
proc pack(conf: ConfigRef, v: PNode, typ: PType, res: pointer)
proc getField(n: PNode; position: int): PSym =
proc getField(conf: ConfigRef, n: PNode; position: int): PSym =
case n.kind
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
result = getField(n.sons[i], position)
for i in 0..<n.len:
result = getField(conf, n[i], position)
if result != nil: return
of nkRecCase:
result = getField(n.sons[0], position)
result = getField(conf, n[0], position)
if result != nil: return
for i in countup(1, sonsLen(n) - 1):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
result = getField(lastSon(n.sons[i]), position)
result = getField(conf, lastSon(n[i]), position)
if result != nil: return
else: internalError(n.info, "getField(record case branch)")
else: internalError(conf, n.info, "getField(record case branch)")
of nkSym:
if n.sym.position == position: result = n.sym
else: discard
proc packObject(x: PNode, typ: PType, res: pointer) =
internalAssert x.kind in {nkObjConstr, nkPar, nkTupleConstr}
proc packObject(conf: ConfigRef, x: PNode, typ: PType, res: pointer) =
internalAssert conf, x.kind in {nkObjConstr, nkPar, nkTupleConstr}
# compute the field's offsets:
discard typ.getSize
for i in countup(ord(x.kind == nkObjConstr), sonsLen(x) - 1):
var it = x.sons[i]
discard getSize(conf, typ)
for i in ord(x.kind == nkObjConstr)..<x.len:
var it = x[i]
if it.kind == nkExprColonExpr:
internalAssert it.sons[0].kind == nkSym
let field = it.sons[0].sym
pack(it.sons[1], field.typ, res +! field.offset)
internalAssert conf, it[0].kind == nkSym
let field = it[0].sym
pack(conf, it[1], field.typ, res +! field.offset)
elif typ.n != nil:
let field = getField(typ.n, i)
pack(it, field.typ, res +! field.offset)
let field = getField(conf, typ.n, i)
pack(conf, it, field.typ, res +! field.offset)
else:
# XXX: todo
globalError(x.info, "cannot pack unnamed tuple")
globalError(conf, x.info, "cannot pack unnamed tuple")
const maxPackDepth = 20
var packRecCheck = 0
proc pack(v: PNode, typ: PType, res: pointer) =
proc pack(conf: ConfigRef, v: PNode, typ: PType, res: pointer) =
template awr(T, v: untyped): untyped =
wr(T, res, v)
@@ -188,13 +192,13 @@ proc pack(v: PNode, typ: PType, res: pointer) =
of tyUInt32: awr(uint32, v.intVal.uint32)
of tyUInt64: awr(uint64, v.intVal.uint64)
of tyEnum, tySet:
case v.typ.getSize
case getSize(conf, v.typ)
of 1: awr(uint8, v.intVal.uint8)
of 2: awr(uint16, v.intVal.uint16)
of 4: awr(int32, v.intVal.int32)
of 8: awr(int64, v.intVal.int64)
else:
globalError(v.info, "cannot map value to FFI (tyEnum, tySet)")
globalError(conf, v.info, "cannot map value to FFI (tyEnum, tySet)")
of tyFloat: awr(float, v.floatVal)
of tyFloat32: awr(float32, v.floatVal)
of tyFloat64: awr(float64, v.floatVal)
@@ -208,7 +212,7 @@ proc pack(v: PNode, typ: PType, res: pointer) =
elif v.kind in {nkStrLit..nkTripleStrLit}:
awr(cstring, cstring(v.strVal))
else:
globalError(v.info, "cannot map pointer/proc value to FFI")
globalError(conf, v.info, "cannot map pointer/proc value to FFI")
of tyPtr, tyRef, tyVar, tyLent:
if v.kind == nkNilLit:
# nothing to do since the memory is 0 initialized anyway
@@ -218,44 +222,44 @@ proc pack(v: PNode, typ: PType, res: pointer) =
else:
if packRecCheck > maxPackDepth:
packRecCheck = 0
globalError(v.info, "cannot map value to FFI " & typeToString(v.typ))
globalError(conf, v.info, "cannot map value to FFI " & typeToString(v.typ))
inc packRecCheck
pack(v.sons[0], typ.lastSon, res +! sizeof(pointer))
pack(conf, v[0], typ.lastSon, res +! sizeof(pointer))
dec packRecCheck
awr(pointer, res +! sizeof(pointer))
of tyArray:
let baseSize = typ.sons[1].getSize
for i in 0 ..< v.len:
pack(v.sons[i], typ.sons[1], res +! i * baseSize)
let baseSize = getSize(conf, typ[1])
for i in 0..<v.len:
pack(conf, v[i], typ[1], res +! i * baseSize)
of tyObject, tyTuple:
packObject(v, typ, res)
packObject(conf, v, typ, res)
of tyNil:
discard
of tyDistinct, tyGenericInst, tyAlias, tySink:
pack(v, typ.sons[0], res)
pack(conf, v, typ[0], res)
else:
globalError(v.info, "cannot map value to FFI " & typeToString(v.typ))
globalError(conf, v.info, "cannot map value to FFI " & typeToString(v.typ))
proc unpack(x: pointer, typ: PType, n: PNode): PNode
proc unpack(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode
proc unpackObjectAdd(x: pointer, n, result: PNode) =
proc unpackObjectAdd(conf: ConfigRef, x: pointer, n, result: PNode) =
case n.kind
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
unpackObjectAdd(x, n.sons[i], result)
for i in 0..<n.len:
unpackObjectAdd(conf, x, n[i], result)
of nkRecCase:
globalError(result.info, "case objects cannot be unpacked")
globalError(conf, result.info, "case objects cannot be unpacked")
of nkSym:
var pair = newNodeI(nkExprColonExpr, result.info, 2)
pair.sons[0] = n
pair.sons[1] = unpack(x +! n.sym.offset, n.sym.typ, nil)
pair[0] = n
pair[1] = unpack(conf, x +! n.sym.offset, n.sym.typ, nil)
#echo "offset: ", n.sym.name.s, " ", n.sym.offset
result.add pair
else: discard
proc unpackObject(x: pointer, typ: PType, n: PNode): PNode =
proc unpackObject(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode =
# compute the field's offsets:
discard typ.getSize
discard getSize(conf, typ)
# iterate over any actual field of 'n' ... if n is nil we need to create
# the nkPar node:
@@ -263,36 +267,36 @@ proc unpackObject(x: pointer, typ: PType, n: PNode): PNode =
result = newNode(nkTupleConstr)
result.typ = typ
if typ.n.isNil:
internalError("cannot unpack unnamed tuple")
unpackObjectAdd(x, typ.n, result)
internalError(conf, "cannot unpack unnamed tuple")
unpackObjectAdd(conf, x, typ.n, result)
else:
result = n
if result.kind notin {nkObjConstr, nkPar, nkTupleConstr}:
globalError(n.info, "cannot map value from FFI")
globalError(conf, n.info, "cannot map value from FFI")
if typ.n.isNil:
globalError(n.info, "cannot unpack unnamed tuple")
for i in countup(ord(n.kind == nkObjConstr), sonsLen(n) - 1):
var it = n.sons[i]
globalError(conf, n.info, "cannot unpack unnamed tuple")
for i in ord(n.kind == nkObjConstr)..<n.len:
var it = n[i]
if it.kind == nkExprColonExpr:
internalAssert it.sons[0].kind == nkSym
let field = it.sons[0].sym
it.sons[1] = unpack(x +! field.offset, field.typ, it.sons[1])
internalAssert conf, it[0].kind == nkSym
let field = it[0].sym
it[1] = unpack(conf, x +! field.offset, field.typ, it[1])
else:
let field = getField(typ.n, i)
n.sons[i] = unpack(x +! field.offset, field.typ, it)
let field = getField(conf, typ.n, i)
n[i] = unpack(conf, x +! field.offset, field.typ, it)
proc unpackArray(x: pointer, typ: PType, n: PNode): PNode =
proc unpackArray(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode =
if n.isNil:
result = newNode(nkBracket)
result.typ = typ
newSeq(result.sons, lengthOrd(typ).int)
newSeq(result.sons, lengthOrd(conf, typ).toInt)
else:
result = n
if result.kind != nkBracket:
globalError(n.info, "cannot map value from FFI")
let baseSize = typ.sons[1].getSize
for i in 0 ..< result.len:
result.sons[i] = unpack(x +! i * baseSize, typ.sons[1], result.sons[i])
globalError(conf, n.info, "cannot map value from FFI")
let baseSize = getSize(conf, typ[1])
for i in 0..<result.len:
result[i] = unpack(conf, x +! i * baseSize, typ[1], result[i])
proc canonNodeKind(k: TNodeKind): TNodeKind =
case k
@@ -301,7 +305,7 @@ proc canonNodeKind(k: TNodeKind): TNodeKind =
of nkStrLit..nkTripleStrLit: result = nkStrLit
else: result = k
proc unpack(x: pointer, typ: PType, n: PNode): PNode =
proc unpack(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode =
template aw(k, v, field: untyped): untyped =
if n.isNil:
result = newNode(k)
@@ -313,7 +317,7 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
#echo "expected ", k, " but got ", result.kind
#debug result
return newNodeI(nkExceptBranch, n.info)
#globalError(n.info, "cannot map value from FFI")
#globalError(conf, n.info, "cannot map value from FFI")
result.field = v
template setNil() =
@@ -323,7 +327,7 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
else:
reset n[]
result = n
result.kind = nkNilLit
result[] = TNode(kind: nkNilLit)
result.typ = typ
template awi(kind, v: untyped): untyped = aw(kind, v, intVal)
@@ -344,13 +348,13 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
of tyUInt32: awi(nkUInt32Lit, rd(uint32, x).BiggestInt)
of tyUInt64: awi(nkUInt64Lit, rd(uint64, x).BiggestInt)
of tyEnum:
case typ.getSize
case getSize(conf, typ)
of 1: awi(nkIntLit, rd(uint8, x).BiggestInt)
of 2: awi(nkIntLit, rd(uint16, x).BiggestInt)
of 4: awi(nkIntLit, rd(int32, x).BiggestInt)
of 8: awi(nkIntLit, rd(int64, x).BiggestInt)
else:
globalError(n.info, "cannot map value from FFI (tyEnum, tySet)")
globalError(conf, n.info, "cannot map value from FFI (tyEnum, tySet)")
of tyFloat: awf(nkFloatLit, rd(float, x))
of tyFloat32: awf(nkFloat32Lit, rd(float32, x))
of tyFloat64: awf(nkFloat64Lit, rd(float64, x))
@@ -371,15 +375,15 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
elif n == nil or n.kind == nkPtrLit:
awi(nkPtrLit, cast[ByteAddress](p))
elif n != nil and n.len == 1:
internalAssert n.kind == nkRefTy
n.sons[0] = unpack(p, typ.lastSon, n.sons[0])
internalAssert(conf, n.kind == nkRefTy)
n[0] = unpack(conf, p, typ.lastSon, n[0])
result = n
else:
globalError(n.info, "cannot map value from FFI " & typeToString(typ))
globalError(conf, n.info, "cannot map value from FFI " & typeToString(typ))
of tyObject, tyTuple:
result = unpackObject(x, typ, n)
result = unpackObject(conf, x, typ, n)
of tyArray:
result = unpackArray(x, typ, n)
result = unpackArray(conf, x, typ, n)
of tyCString, tyString:
let p = rd(cstring, x)
if p.isNil:
@@ -389,12 +393,12 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
of tyNil:
setNil()
of tyDistinct, tyGenericInst, tyAlias, tySink:
result = unpack(x, typ.lastSon, n)
result = unpack(conf, x, typ.lastSon, n)
else:
# XXX what to do with 'array' here?
globalError(n.info, "cannot map value from FFI " & typeToString(typ))
globalError(conf, n.info, "cannot map value from FFI " & typeToString(typ))
proc fficast*(x: PNode, destTyp: PType): PNode =
proc fficast*(conf: ConfigRef, x: PNode, destTyp: PType): PNode =
if x.kind == nkPtrLit and x.typ.kind in {tyPtr, tyRef, tyVar, tyLent, tyPointer,
tyProc, tyCString, tyString,
tySequence}:
@@ -404,93 +408,93 @@ proc fficast*(x: PNode, destTyp: PType): PNode =
result = newNodeIT(x.kind, x.info, destTyp)
else:
# we play safe here and allocate the max possible size:
let size = max(packSize(x, x.typ), packSize(x, destTyp))
let size = max(packSize(conf, x, x.typ), packSize(conf, x, destTyp))
var a = alloc0(size)
pack(x, x.typ, a)
pack(conf, x, x.typ, a)
# cast through a pointer needs a new inner object:
let y = if x.kind == nkRefTy: newNodeI(nkRefTy, x.info, 1)
else: x.copyTree
y.typ = x.typ
result = unpack(a, destTyp, y)
result = unpack(conf, a, destTyp, y)
dealloc a
proc callForeignFunction*(call: PNode): PNode =
internalAssert call.sons[0].kind == nkPtrLit
proc callForeignFunction*(conf: ConfigRef, call: PNode): PNode =
internalAssert conf, call[0].kind == nkPtrLit
var cif: TCif
var sig: TParamList
var sig: ParamList
# use the arguments' types for varargs support:
for i in 1..call.len-1:
sig[i-1] = mapType(call.sons[i].typ)
for i in 1..<call.len:
sig[i-1] = mapType(conf, call[i].typ)
if sig[i-1].isNil:
globalError(call.info, "cannot map FFI type")
globalError(conf, call.info, "cannot map FFI type")
let typ = call.sons[0].typ
if prep_cif(cif, mapCallConv(typ.callConv, call.info), cuint(call.len-1),
mapType(typ.sons[0]), sig) != OK:
globalError(call.info, "error in FFI call")
let typ = call[0].typ
if prep_cif(cif, mapCallConv(conf, typ.callConv, call.info), cuint(call.len-1),
mapType(conf, typ[0]), sig) != OK:
globalError(conf, call.info, "error in FFI call")
var args: TArgList
let fn = cast[pointer](call.sons[0].intVal)
for i in 1 .. call.len-1:
var t = call.sons[i].typ
args[i-1] = alloc0(packSize(call.sons[i], t))
pack(call.sons[i], t, args[i-1])
let retVal = if isEmptyType(typ.sons[0]): pointer(nil)
else: alloc(typ.sons[0].getSize.int)
var args: ArgList
let fn = cast[pointer](call[0].intVal)
for i in 1..<call.len:
var t = call[i].typ
args[i-1] = alloc0(packSize(conf, call[i], t))
pack(conf, call[i], t, args[i-1])
let retVal = if isEmptyType(typ[0]): pointer(nil)
else: alloc(getSize(conf, typ[0]).int)
libffi.call(cif, fn, retVal, args)
if retVal.isNil:
result = newNode(nkEmpty)
else:
result = unpack(retVal, typ.sons[0], nil)
result = unpack(conf, retVal, typ[0], nil)
result.info = call.info
if retVal != nil: dealloc retVal
for i in 1 .. call.len-1:
call.sons[i] = unpack(args[i-1], typ.sons[i], call[i])
for i in 1..<call.len:
call[i] = unpack(conf, args[i-1], typ[i], call[i])
dealloc args[i-1]
proc callForeignFunction*(fn: PNode, fntyp: PType,
proc callForeignFunction*(conf: ConfigRef, fn: PNode, fntyp: PType,
args: var TNodeSeq, start, len: int,
info: TLineInfo): PNode =
internalAssert fn.kind == nkPtrLit
internalAssert conf, fn.kind == nkPtrLit
var cif: TCif
var sig: TParamList
var sig: ParamList
for i in 0..len-1:
var aTyp = args[i+start].typ
if aTyp.isNil:
internalAssert i+1 < fntyp.len
aTyp = fntyp.sons[i+1]
internalAssert conf, i+1 < fntyp.len
aTyp = fntyp[i+1]
args[i+start].typ = aTyp
sig[i] = mapType(aTyp)
if sig[i].isNil: globalError(info, "cannot map FFI type")
sig[i] = mapType(conf, aTyp)
if sig[i].isNil: globalError(conf, info, "cannot map FFI type")
if prep_cif(cif, mapCallConv(fntyp.callConv, info), cuint(len),
mapType(fntyp.sons[0]), sig) != OK:
globalError(info, "error in FFI call")
if prep_cif(cif, mapCallConv(conf, fntyp.callConv, info), cuint(len),
mapType(conf, fntyp[0]), sig) != OK:
globalError(conf, info, "error in FFI call")
var cargs: TArgList
var cargs: ArgList
let fn = cast[pointer](fn.intVal)
for i in 0 .. len-1:
for i in 0..len-1:
let t = args[i+start].typ
cargs[i] = alloc0(packSize(args[i+start], t))
pack(args[i+start], t, cargs[i])
let retVal = if isEmptyType(fntyp.sons[0]): pointer(nil)
else: alloc(fntyp.sons[0].getSize.int)
cargs[i] = alloc0(packSize(conf, args[i+start], t))
pack(conf, args[i+start], t, cargs[i])
let retVal = if isEmptyType(fntyp[0]): pointer(nil)
else: alloc(getSize(conf, fntyp[0]).int)
libffi.call(cif, fn, retVal, cargs)
if retVal.isNil:
result = newNode(nkEmpty)
else:
result = unpack(retVal, fntyp.sons[0], nil)
result = unpack(conf, retVal, fntyp[0], nil)
result.info = info
if retVal != nil: dealloc retVal
for i in 0 .. len-1:
for i in 0..len-1:
let t = args[i+start].typ
args[i+start] = unpack(cargs[i], t, args[i+start])
args[i+start] = unpack(conf, cargs[i], t, args[i+start])
dealloc cargs[i]

View File

@@ -10,16 +10,17 @@
## Template evaluation engine. Now hygienic.
import
strutils, options, ast, astalgo, msgs, os, idents, wordrecg, renderer,
lineinfos
strutils, options, ast, astalgo, msgs, renderer, lineinfos, idents
type
TemplCtx = object
owner, genSymOwner: PSym
instLines: bool # use the instantiation lines numbers
isDeclarative: bool
mapping: TIdTable # every gensym'ed symbol needs to be mapped to some
# new symbol
config: ConfigRef
ic: IdentCache
proc copyNode(ctx: TemplCtx, a, b: PNode): PNode =
result = copyNode(a)
@@ -36,29 +37,55 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) =
case templ.kind
of nkSym:
var s = templ.sym
if s.owner.id == c.owner.id:
if s.kind == skParam and sfGenSym notin s.flags:
handleParam actual.sons[s.position]
elif s.kind == skGenericParam or
s.kind == skType and s.typ != nil and s.typ.kind == tyGenericParam:
handleParam actual.sons[s.owner.typ.len + s.position - 1]
if (s.owner == nil and s.kind == skParam) or s.owner == c.owner:
if s.kind == skParam and {sfGenSym, sfTemplateParam} * s.flags == {sfTemplateParam}:
handleParam actual[s.position]
elif (s.owner != nil) and (s.kind == skGenericParam or
s.kind == skType and s.typ != nil and s.typ.kind == tyGenericParam):
handleParam actual[s.owner.typ.len + s.position - 1]
else:
internalAssert c.config, sfGenSym in s.flags or s.kind == skType
var x = PSym(idTableGet(c.mapping, s))
if x == nil:
x = copySym(s, false)
x.owner = c.genSymOwner
x = copySym(s)
# sem'check needs to set the owner properly later, see bug #9476
x.owner = nil # c.genSymOwner
#if x.kind == skParam and x.owner.kind == skModule:
# internalAssert c.config, false
idTablePut(c.mapping, s, x)
result.add newSymNode(x, if c.instLines: actual.info else: templ.info)
if sfGenSym in s.flags and optNimV019 notin c.config.globalOptions:
result.add newIdentNode(getIdent(c.ic, x.name.s & "`gensym" & $x.id),
if c.instLines: actual.info else: templ.info)
else:
result.add newSymNode(x, if c.instLines: actual.info else: templ.info)
else:
result.add copyNode(c, templ, actual)
of nkNone..nkIdent, nkType..nkNilLit: # atom
result.add copyNode(c, templ, actual)
of nkCommentStmt:
# for the documentation generator we don't keep documentation comments
# in the AST that would confuse it (bug #9432), but only if we are not in a
# "declarative" context (bug #9235).
if c.isDeclarative:
var res = copyNode(c, templ, actual)
for i in 0..<templ.len:
evalTemplateAux(templ[i], actual, c, res)
result.add res
else:
result.add newNodeI(nkEmpty, templ.info)
else:
var isDeclarative = false
if templ.kind in {nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef,
nkMacroDef, nkTemplateDef, nkConverterDef, nkTypeSection,
nkVarSection, nkLetSection, nkConstSection} and
not c.isDeclarative:
c.isDeclarative = true
isDeclarative = true
var res = copyNode(c, templ, actual)
for i in countup(0, sonsLen(templ) - 1):
evalTemplateAux(templ.sons[i], actual, c, res)
for i in 0..<templ.len:
evalTemplateAux(templ[i], actual, c, res)
result.add res
if isDeclarative: c.isDeclarative = false
const
errWrongNumberOfArguments = "wrong number of arguments"
@@ -81,7 +108,7 @@ proc evalTemplateArgs(n: PNode, s: PSym; conf: ConfigRef; fromHlo: bool): PNode
# their bodies. We could try to fix this, but it may be
# wiser to just deprecate immediate templates and macros
# now that we have working untyped parameters.
genericParams = if sfImmediate in s.flags or fromHlo: 0
genericParams = if fromHlo: 0
else: s.ast[genericParamsPos].len
expectedRegularParams = s.typ.len-1
givenRegularParams = totalParams - genericParams
@@ -95,22 +122,22 @@ proc evalTemplateArgs(n: PNode, s: PSym; conf: ConfigRef; fromHlo: bool): PNode
n.renderTree)
result = newNodeI(nkArgList, n.info)
for i in 1 .. givenRegularParams:
result.addSon n[i]
for i in 1..givenRegularParams:
result.add n[i]
# handle parameters with default values, which were
# not supplied by the user
for i in givenRegularParams+1 .. expectedRegularParams:
let default = s.typ.n.sons[i].sym.ast
for i in givenRegularParams+1..expectedRegularParams:
let default = s.typ.n[i].sym.ast
if default.isNil or default.kind == nkEmpty:
localError(conf, n.info, errWrongNumberOfArguments)
addSon(result, newNodeI(nkEmpty, n.info))
result.add newNodeI(nkEmpty, n.info)
else:
addSon(result, default.copyTree)
result.add default.copyTree
# add any generic paramaters
for i in 1 .. genericParams:
result.addSon n.sons[givenRegularParams + i]
# add any generic parameters
for i in 1..genericParams:
result.add n[givenRegularParams + i]
# to prevent endless recursion in template instantiation
const evalTemplateLimit* = 1000
@@ -128,7 +155,7 @@ proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
if x.kind in nkCallKinds:
for i in 1..<x.len:
if x[i].kind in nkCallKinds:
x.sons[i].info = info
x[i].info = info
else:
result = newNodeI(nkStmtListExpr, info)
var d = newNodeI(nkComesFrom, info)
@@ -138,7 +165,9 @@ proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
result.typ = res.typ
proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
conf: ConfigRef; fromHlo=false): PNode =
conf: ConfigRef;
ic: IdentCache;
fromHlo=false): PNode =
inc(conf.evalTemplateCounter)
if conf.evalTemplateCounter > evalTemplateLimit:
globalError(conf, n.info, errTemplateInstantiationTooNested)
@@ -150,24 +179,27 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
ctx.owner = tmpl
ctx.genSymOwner = genSymOwner
ctx.config = conf
ctx.ic = ic
initIdTable(ctx.mapping)
let body = tmpl.getBody
#echo "instantion of ", renderTree(body, {renderIds})
if isAtom(body):
result = newNodeI(nkPar, body.info)
evalTemplateAux(body, args, ctx, result)
if result.len == 1: result = result.sons[0]
if result.len == 1: result = result[0]
else:
localError(conf, result.info, "illformed AST: " &
renderTree(result, {renderNoComments}))
else:
result = copyNode(body)
#ctx.instLines = body.kind notin {nkStmtList, nkStmtListExpr,
# nkBlockStmt, nkBlockExpr}
#if ctx.instLines: result.info = n.info
for i in countup(0, safeLen(body) - 1):
evalTemplateAux(body.sons[i], args, ctx, result)
ctx.instLines = sfCallsite in tmpl.flags
if ctx.instLines:
result.info = n.info
for i in 0..<body.safeLen:
evalTemplateAux(body[i], args, ctx, result)
result.flags.incl nfFromTemplate
result = wrapInComesFrom(n.info, tmpl, result)
#if ctx.debugActive:
# echo "instantion of ", renderTree(result, {renderIds})
dec(conf.evalTemplateCounter)

File diff suppressed because it is too large Load Diff

View File

@@ -10,8 +10,8 @@
# This module implements Nim's standard template filter.
import
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
renderer, filters, lineinfos, pathutils
llstream, strutils, ast, msgs, options,
filters, lineinfos, pathutils
type
TParseState = enum
@@ -22,7 +22,7 @@ type
info: TLineInfo
indent, emitPar: int
x: string # the current input line
outp: PLLStream # the ouput will be parsed by pnimsyn
outp: PLLStream # the output will be parsed by pnimsyn
subsChar, nimDirective: char
emit, conc, toStr: string
curly, bracket, par: int
@@ -75,7 +75,7 @@ proc parseLine(p: var TTmplParser) =
let d = j
var keyw = ""
while j < len and p.x[j] in PatternChars:
add(keyw, p.x[j])
keyw.add(p.x[j])
inc(j)
scanPar(p, j)

View File

@@ -10,7 +10,7 @@
# This module implements Nim's simple filters and helpers for filters.
import
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
llstream, idents, strutils, ast, msgs, options,
renderer, pathutils
proc invalidPragma(conf: ConfigRef; n: PNode) =
@@ -20,13 +20,13 @@ proc invalidPragma(conf: ConfigRef; n: PNode) =
proc getArg(conf: ConfigRef; n: PNode, name: string, pos: int): PNode =
result = nil
if n.kind in {nkEmpty..nkNilLit}: return
for i in countup(1, sonsLen(n) - 1):
if n.sons[i].kind == nkExprEqExpr:
if n.sons[i].sons[0].kind != nkIdent: invalidPragma(conf, n)
if cmpIgnoreStyle(n.sons[i].sons[0].ident.s, name) == 0:
return n.sons[i].sons[1]
for i in 1..<n.len:
if n[i].kind == nkExprEqExpr:
if n[i][0].kind != nkIdent: invalidPragma(conf, n)
if cmpIgnoreStyle(n[i][0].ident.s, name) == 0:
return n[i][1]
elif i == pos:
return n.sons[i]
return n[i]
proc charArg*(conf: ConfigRef; n: PNode, name: string, pos: int, default: char): char =
var x = getArg(conf, n, name, pos)
@@ -55,7 +55,7 @@ proc filterStrip*(conf: ConfigRef; stdin: PLLStream, filename: AbsoluteFile, cal
var line = newStringOfCap(80)
while llStreamReadLine(stdin, line):
var stripped = strip(line, leading, trailing)
if len(pattern) == 0 or startsWith(stripped, pattern):
if pattern.len == 0 or startsWith(stripped, pattern):
llStreamWriteln(result, stripped)
else:
llStreamWriteln(result, line)
@@ -63,7 +63,7 @@ proc filterStrip*(conf: ConfigRef; stdin: PLLStream, filename: AbsoluteFile, cal
proc filterReplace*(conf: ConfigRef; stdin: PLLStream, filename: AbsoluteFile, call: PNode): PLLStream =
var sub = strArg(conf, call, "sub", 1, "")
if len(sub) == 0: invalidPragma(conf, call)
if sub.len == 0: invalidPragma(conf, call)
var by = strArg(conf, call, "by", 2, "")
result = llStreamOpen("")
var line = newStringOfCap(80)

View File

@@ -13,8 +13,8 @@ import ast, astalgo
const
someCmp = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
mEqUntracedRef, mLeI, mLeF64, mLeU, mLeU64, mLeEnum,
mLeCh, mLeB, mLePtr, mLtI, mLtF64, mLtU, mLtU64, mLtEnum,
mLeI, mLeF64, mLeU, mLeEnum,
mLeCh, mLeB, mLePtr, mLtI, mLtF64, mLtU, mLtEnum,
mLtCh, mLtB, mLtPtr}
proc isCounter(s: PSym): bool {.inline.} =
@@ -45,13 +45,13 @@ proc counterInTree(n, loop: PNode; counter: PSym): bool =
for it in n:
if counterInTree(it.lastSon): return true
else:
for i in 0 ..< safeLen(n):
for i in 0..<n.safeLen:
if counterInTree(n[i], loop, counter): return true
proc copyExcept(n: PNode, x, dest: PNode) =
if x == n: return
if n.kind in {nkStmtList, nkStmtListExpr}:
for i in 0 ..< n.len: copyExcept(n[i], x, dest)
for i in 0..<n.len: copyExcept(n[i], x, dest)
else:
dest.add n

View File

@@ -9,7 +9,7 @@
## Module that implements ``gorge`` for the compiler.
import msgs, std / sha1, os, osproc, streams, strutils, options,
import msgs, std / sha1, os, osproc, streams, options,
lineinfos, pathutils
proc readOutput(p: Process): (string, int) =
@@ -24,22 +24,23 @@ proc readOutput(p: Process): (string, int) =
proc opGorge*(cmd, input, cache: string, info: TLineInfo; conf: ConfigRef): (string, int) =
let workingDir = parentDir(toFullPath(conf, info))
if cache.len > 0:# and optForceFullMake notin gGlobalOptions:
if cache.len > 0:
let h = secureHash(cmd & "\t" & input & "\t" & cache)
let filename = toGeneratedFile(conf, AbsoluteFile("gorge_" & $h), "txt").string
var f: File
if open(f, filename):
if optForceFullMake notin conf.globalOptions and open(f, filename):
result = (f.readAll, 0)
f.close
return
var readSuccessful = false
try:
var p = startProcess(cmd, workingDir,
options={poEvalCommand, poStderrToStdout})
options={poEvalCommand, poStdErrToStdOut})
if input.len != 0:
p.inputStream.write(input)
p.inputStream.close()
result = p.readOutput
p.close()
readSuccessful = true
# only cache successful runs:
if result[1] == 0:
@@ -49,10 +50,11 @@ proc opGorge*(cmd, input, cache: string, info: TLineInfo; conf: ConfigRef): (str
else:
try:
var p = startProcess(cmd, workingDir,
options={poEvalCommand, poStderrToStdout})
options={poEvalCommand, poStdErrToStdOut})
if input.len != 0:
p.inputStream.write(input)
p.inputStream.close()
result = p.readOutput
p.close()
except IOError, OSError:
result = ("", -1)

View File

@@ -10,22 +10,21 @@
## This module implements the 'implies' relation for guards.
import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer, idents,
saturate, modulegraphs, options, lineinfos
saturate, modulegraphs, options, lineinfos, int128
const
someEq = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
mEqUntracedRef, mEqStr, mEqSet, mEqCString}
mEqStr, mEqSet, mEqCString}
# set excluded here as the semantics are vastly different:
someLe = {mLeI, mLeF64, mLeU, mLeU64, mLeEnum,
someLe = {mLeI, mLeF64, mLeU, mLeEnum,
mLeCh, mLeB, mLePtr, mLeStr}
someLt = {mLtI, mLtF64, mLtU, mLtU64, mLtEnum,
someLt = {mLtI, mLtF64, mLtU, mLtEnum,
mLtCh, mLtB, mLtPtr, mLtStr}
someLen = {mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq,
mXLenStr, mXLenSeq}
someLen = {mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq}
someIn = {mInRange, mInSet}
someIn = {mInSet}
someHigh = {mHigh}
# we don't list unsigned here because wrap around semantics suck for
@@ -35,8 +34,8 @@ const
someMul = {mMulI, mMulF64}
someDiv = {mDivI, mDivF64}
someMod = {mModI}
someMax = {mMaxI, mMaxF64}
someMin = {mMinI, mMinF64}
someMax = {mMaxI}
someMin = {mMinI}
someBinaryOp = someAdd+someSub+someMul+someMax+someMin
proc isValue(n: PNode): bool = n.kind in {nkCharLit..nkNilLit}
@@ -65,16 +64,16 @@ proc isLetLocation(m: PNode, isApprox: bool): bool =
while true:
case n.kind
of nkDotExpr, nkCheckedFieldExpr, nkObjUpConv, nkObjDownConv:
n = n.sons[0]
n = n[0]
of nkDerefExpr, nkHiddenDeref:
n = n.sons[0]
n = n[0]
inc derefs
of nkBracketExpr:
if isConstExpr(n.sons[1]) or isLet(n.sons[1]):
n = n.sons[0]
if isConstExpr(n[1]) or isLet(n[1]) or isConstExpr(n[1].skipConv):
n = n[0]
else: return
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
n = n.sons[1]
n = n[1]
else:
break
result = n.isLet and derefs <= ord(isApprox)
@@ -105,34 +104,34 @@ proc initOperators*(g: ModuleGraph): Operators =
proc swapArgs(fact: PNode, newOp: PSym): PNode =
result = newNodeI(nkCall, fact.info, 3)
result.sons[0] = newSymNode(newOp)
result.sons[1] = fact.sons[2]
result.sons[2] = fact.sons[1]
result[0] = newSymNode(newOp)
result[1] = fact[2]
result[2] = fact[1]
proc neg(n: PNode; o: Operators): PNode =
if n == nil: return nil
case n.getMagic
of mNot:
result = n.sons[1]
result = n[1]
of someLt:
# not (a < b) == a >= b == b <= a
result = swapArgs(n, o.opLe)
of someLe:
result = swapArgs(n, o.opLt)
of mInSet:
if n.sons[1].kind != nkCurly: return nil
let t = n.sons[2].typ.skipTypes(abstractInst)
if n[1].kind != nkCurly: return nil
let t = n[2].typ.skipTypes(abstractInst)
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = n.sons[0]
result.sons[2] = n.sons[2]
result[0] = n[0]
result[2] = n[2]
if t.kind == tyEnum:
var s = newNodeIT(nkCurly, n.info, n.sons[1].typ)
var s = newNodeIT(nkCurly, n.info, n[1].typ)
for e in t.n:
let eAsNode = newIntNode(nkIntLit, e.sym.position)
if not inSet(n.sons[1], eAsNode): s.add eAsNode
result.sons[1] = s
if not inSet(n[1], eAsNode): s.add eAsNode
result[1] = s
#elif t.kind notin {tyString, tySequence} and lengthOrd(t) < 1000:
# result.sons[1] = complement(n.sons[1])
# result[1] = complement(n[1])
else:
# not ({2, 3, 4}.contains(x)) x != 2 and x != 3 and x != 4
# XXX todo
@@ -140,13 +139,13 @@ proc neg(n: PNode; o: Operators): PNode =
of mOr:
# not (a or b) --> not a and not b
let
a = n.sons[1].neg(o)
b = n.sons[2].neg(o)
a = n[1].neg(o)
b = n[2].neg(o)
if a != nil and b != nil:
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(o.opAnd)
result.sons[1] = a
result.sons[2] = b
result[0] = newSymNode(o.opAnd)
result[1] = a
result[2] = b
elif a != nil:
result = a
elif b != nil:
@@ -154,19 +153,19 @@ proc neg(n: PNode; o: Operators): PNode =
else:
# leave not (a == 4) as it is
result = newNodeI(nkCall, n.info, 2)
result.sons[0] = newSymNode(o.opNot)
result.sons[1] = n
result[0] = newSymNode(o.opNot)
result[1] = n
proc buildCall(op: PSym; a: PNode): PNode =
result = newNodeI(nkCall, a.info, 2)
result.sons[0] = newSymNode(op)
result.sons[1] = a
result[0] = newSymNode(op)
result[1] = a
proc buildCall(op: PSym; a, b: PNode): PNode =
result = newNodeI(nkInfix, a.info, 3)
result.sons[0] = newSymNode(op)
result.sons[1] = a
result.sons[2] = b
result[0] = newSymNode(op)
result[1] = a
result[2] = b
proc `|+|`(a, b: PNode): PNode =
result = copyNode(a)
@@ -250,35 +249,35 @@ proc pred(n: PNode): PNode =
else:
result = n
proc buildLe*(o: Operators; a, b: PNode): PNode =
result = o.opLe.buildCall(a, b)
proc canon*(n: PNode; o: Operators): PNode =
# XXX for now only the new code in 'semparallel' uses this
if n.safeLen >= 1:
result = shallowCopy(n)
for i in 0 ..< n.len:
result.sons[i] = canon(n.sons[i], o)
for i in 0..<n.len:
result[i] = canon(n[i], o)
elif n.kind == nkSym and n.sym.kind == skLet and
n.sym.ast.getMagic in (someEq + someAdd + someMul + someMin +
someMax + someHigh + {mUnaryLt} + someSub + someLen + someDiv):
result = n.sym.ast.copyTree
n.sym.astdef.getMagic in (someEq + someAdd + someMul + someMin +
someMax + someHigh + someSub + someLen + someDiv):
result = n.sym.astdef.copyTree
else:
result = n
case result.getMagic
of someEq, someAdd, someMul, someMin, someMax:
# these are symmetric; put value as last:
if result.sons[1].isValue and not result.sons[2].isValue:
result = swapArgs(result, result.sons[0].sym)
if result[1].isValue and not result[2].isValue:
result = swapArgs(result, result[0].sym)
# (4 + foo) + 2 --> (foo + 4) + 2
of someHigh:
# high == len+(-1)
result = o.opAdd.buildCall(o.opLen.buildCall(result[1]), minusOne())
of mUnaryLt:
result = buildCall(o.opAdd, result[1], minusOne())
of someSub:
# x - 4 --> x + (-4)
result = negate(result[1], result[2], result, o)
of someLen:
result.sons[0] = o.opLen.newSymNode
of someLt:
result[0] = o.opLen.newSymNode
of someLt - {mLtF64}:
# x < y same as x <= y-1:
let y = n[2].canon(o)
let p = pred(y)
@@ -318,16 +317,16 @@ proc canon*(n: PNode; o: Operators): PNode =
if plus != nil and not isLetLocation(x, true):
result = buildCall(result[0].sym, plus, y[1])
else: discard
elif x.isValue and y.getMagic in someAdd and y[2].isValue:
elif x.isValue and y.getMagic in someAdd and y[2].kind == x.kind:
# 0 <= a.len + 3
# -3 <= a.len
result.sons[1] = x |-| y[2]
result.sons[2] = y[1]
elif x.isValue and y.getMagic in someSub and y[2].isValue:
result[1] = x |-| y[2]
result[2] = y[1]
elif x.isValue and y.getMagic in someSub and y[2].kind == x.kind:
# 0 <= a.len - 3
# 3 <= a.len
result.sons[1] = x |+| y[2]
result.sons[2] = y[1]
result[1] = x |+| y[2]
result[2] = y[1]
else: discard
proc buildAdd*(a: PNode; b: BiggestInt; o: Operators): PNode =
@@ -336,41 +335,43 @@ proc buildAdd*(a: PNode; b: BiggestInt; o: Operators): PNode =
proc usefulFact(n: PNode; o: Operators): PNode =
case n.getMagic
of someEq:
if skipConv(n.sons[2]).kind == nkNilLit and (
isLetLocation(n.sons[1], false) or isVar(n.sons[1])):
result = o.opIsNil.buildCall(n.sons[1])
if skipConv(n[2]).kind == nkNilLit and (
isLetLocation(n[1], false) or isVar(n[1])):
result = o.opIsNil.buildCall(n[1])
else:
if isLetLocation(n.sons[1], true) or isLetLocation(n.sons[2], true):
if isLetLocation(n[1], true) or isLetLocation(n[2], true):
# XXX algebraic simplifications! 'i-1 < a.len' --> 'i < a.len+1'
result = n
elif n[1].getMagic in someLen or n[2].getMagic in someLen:
result = n
of someLe+someLt:
if isLetLocation(n.sons[1], true) or isLetLocation(n.sons[2], true):
if isLetLocation(n[1], true) or isLetLocation(n[2], true):
# XXX algebraic simplifications! 'i-1 < a.len' --> 'i < a.len+1'
result = n
elif n[1].getMagic in someLen or n[2].getMagic in someLen:
# XXX Rethink this whole idea of 'usefulFact' for semparallel
result = n
of mIsNil:
if isLetLocation(n.sons[1], false) or isVar(n.sons[1]):
if isLetLocation(n[1], false) or isVar(n[1]):
result = n
of someIn:
if isLetLocation(n.sons[1], true):
if isLetLocation(n[1], true):
result = n
of mAnd:
let
a = usefulFact(n.sons[1], o)
b = usefulFact(n.sons[2], o)
a = usefulFact(n[1], o)
b = usefulFact(n[2], o)
if a != nil and b != nil:
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(o.opAnd)
result.sons[1] = a
result.sons[2] = b
result[0] = newSymNode(o.opAnd)
result[1] = a
result[2] = b
elif a != nil:
result = a
elif b != nil:
result = b
of mNot:
let a = usefulFact(n.sons[1], o)
let a = usefulFact(n[1], o)
if a != nil:
result = a.neg(o)
of mOr:
@@ -381,13 +382,13 @@ proc usefulFact(n: PNode; o: Operators): PNode =
# (x == 3) or (y == 2) ---> not ( not (x==3) and not (y == 2))
# not (x != 3 and y != 2)
let
a = usefulFact(n.sons[1], o).neg(o)
b = usefulFact(n.sons[2], o).neg(o)
a = usefulFact(n[1], o).neg(o)
b = usefulFact(n[2], o).neg(o)
if a != nil and b != nil:
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(o.opAnd)
result.sons[1] = a
result.sons[2] = b
result[0] = newSymNode(o.opAnd)
result[1] = a
result[2] = b
result = result.neg(o)
elif n.kind == nkSym and n.sym.kind == skLet:
# consider:
@@ -395,8 +396,8 @@ proc usefulFact(n: PNode; o: Operators): PNode =
# if a:
# ...
# We make can easily replace 'a' by '2 < x' here:
if n.sym.ast != nil:
result = usefulFact(n.sym.ast, o)
if n.sym.astdef != nil:
result = usefulFact(n.sym.astdef, o)
elif n.kind == nkStmtListExpr:
result = usefulFact(n.lastSon, o)
@@ -404,10 +405,20 @@ type
TModel* = object
s*: seq[PNode] # the "knowledge base"
o*: Operators
beSmart*: bool
proc addFact*(m: var TModel, nn: PNode) =
let n = usefulFact(nn, m.o)
if n != nil: m.s.add n
if n != nil:
if not m.beSmart:
m.s.add n
else:
let c = canon(n, m.o)
if c.getMagic == mAnd:
addFact(m, c[1])
addFact(m, c[2])
else:
m.s.add c
proc addFactNeg*(m: var TModel, n: PNode) =
let n = n.neg(m.o)
@@ -436,22 +447,22 @@ proc sameTree*(a, b: PNode): bool =
if not result and a.sym.magic != mNone:
result = a.sym.magic == b.sym.magic or sameOpr(a.sym, b.sym)
of nkIdent: result = a.ident.id == b.ident.id
of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
of nkCharLit..nkUInt64Lit: result = a.intVal == b.intVal
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
of nkType: result = a.typ == b.typ
of nkEmpty, nkNilLit: result = true
else:
if sonsLen(a) == sonsLen(b):
for i in countup(0, sonsLen(a) - 1):
if not sameTree(a.sons[i], b.sons[i]): return
if a.len == b.len:
for i in 0..<a.len:
if not sameTree(a[i], b[i]): return
result = true
proc hasSubTree(n, x: PNode): bool =
if n.sameTree(x): result = true
else:
for i in 0..safeLen(n)-1:
if hasSubTree(n.sons[i], x): return true
for i in 0..n.safeLen-1:
if hasSubTree(n[i], x): return true
proc invalidateFacts*(m: var TModel, n: PNode) =
# We are able to guard local vars (as opposed to 'let' variables)!
@@ -479,21 +490,21 @@ proc valuesUnequal(a, b: PNode): bool =
result = not sameValue(a, b)
proc impliesEq(fact, eq: PNode): TImplication =
let (loc, val) = if isLocation(eq.sons[1]): (1, 2) else: (2, 1)
let (loc, val) = if isLocation(eq[1]): (1, 2) else: (2, 1)
case fact.sons[0].sym.magic
case fact[0].sym.magic
of someEq:
if sameTree(fact.sons[1], eq.sons[loc]):
if sameTree(fact[1], eq[loc]):
# this is not correct; consider: a == b; a == 1 --> unknown!
if sameTree(fact.sons[2], eq.sons[val]): result = impYes
elif valuesUnequal(fact.sons[2], eq.sons[val]): result = impNo
elif sameTree(fact.sons[2], eq.sons[loc]):
if sameTree(fact.sons[1], eq.sons[val]): result = impYes
elif valuesUnequal(fact.sons[1], eq.sons[val]): result = impNo
if sameTree(fact[2], eq[val]): result = impYes
elif valuesUnequal(fact[2], eq[val]): result = impNo
elif sameTree(fact[2], eq[loc]):
if sameTree(fact[1], eq[val]): result = impYes
elif valuesUnequal(fact[1], eq[val]): result = impNo
of mInSet:
# remember: mInSet is 'contains' so the set comes first!
if sameTree(fact.sons[2], eq.sons[loc]) and isValue(eq.sons[val]):
if inSet(fact.sons[1], eq.sons[val]): result = impYes
if sameTree(fact[2], eq[loc]) and isValue(eq[val]):
if inSet(fact[1], eq[val]): result = impYes
else: result = impNo
of mNot, mOr, mAnd: assert(false, "impliesEq")
else: discard
@@ -522,7 +533,7 @@ proc geImpliesIn(x, c, aSet: PNode): TImplication =
var value = newIntNode(c.kind, c.intVal)
let max = lastOrd(nil, x.typ)
# don't iterate too often:
if max - value.intVal < 1000:
if max - getInt(value) < toInt128(1000):
var i, pos, neg: int
while value.intVal <= max:
if inSet(aSet, value): inc pos
@@ -536,28 +547,28 @@ proc compareSets(a, b: PNode): TImplication =
elif intersectSets(nil, a, b).len == 0: result = impNo
proc impliesIn(fact, loc, aSet: PNode): TImplication =
case fact.sons[0].sym.magic
case fact[0].sym.magic
of someEq:
if sameTree(fact.sons[1], loc):
if inSet(aSet, fact.sons[2]): result = impYes
if sameTree(fact[1], loc):
if inSet(aSet, fact[2]): result = impYes
else: result = impNo
elif sameTree(fact.sons[2], loc):
if inSet(aSet, fact.sons[1]): result = impYes
elif sameTree(fact[2], loc):
if inSet(aSet, fact[1]): result = impYes
else: result = impNo
of mInSet:
if sameTree(fact.sons[2], loc):
result = compareSets(fact.sons[1], aSet)
if sameTree(fact[2], loc):
result = compareSets(fact[1], aSet)
of someLe:
if sameTree(fact.sons[1], loc):
result = leImpliesIn(fact.sons[1], fact.sons[2], aSet)
elif sameTree(fact.sons[2], loc):
result = geImpliesIn(fact.sons[2], fact.sons[1], aSet)
if sameTree(fact[1], loc):
result = leImpliesIn(fact[1], fact[2], aSet)
elif sameTree(fact[2], loc):
result = geImpliesIn(fact[2], fact[1], aSet)
of someLt:
if sameTree(fact.sons[1], loc):
result = leImpliesIn(fact.sons[1], fact.sons[2].pred, aSet)
elif sameTree(fact.sons[2], loc):
if sameTree(fact[1], loc):
result = leImpliesIn(fact[1], fact[2].pred, aSet)
elif sameTree(fact[2], loc):
# 4 < x --> 3 <= x
result = geImpliesIn(fact.sons[2], fact.sons[1].pred, aSet)
result = geImpliesIn(fact[2], fact[1].pred, aSet)
of mNot, mOr, mAnd: assert(false, "impliesIn")
else: discard
@@ -567,90 +578,93 @@ proc valueIsNil(n: PNode): TImplication =
else: impUnknown
proc impliesIsNil(fact, eq: PNode): TImplication =
case fact.sons[0].sym.magic
case fact[0].sym.magic
of mIsNil:
if sameTree(fact.sons[1], eq.sons[1]):
if sameTree(fact[1], eq[1]):
result = impYes
of someEq:
if sameTree(fact.sons[1], eq.sons[1]):
result = valueIsNil(fact.sons[2].skipConv)
elif sameTree(fact.sons[2], eq.sons[1]):
result = valueIsNil(fact.sons[1].skipConv)
if sameTree(fact[1], eq[1]):
result = valueIsNil(fact[2].skipConv)
elif sameTree(fact[2], eq[1]):
result = valueIsNil(fact[1].skipConv)
of mNot, mOr, mAnd: assert(false, "impliesIsNil")
else: discard
proc impliesGe(fact, x, c: PNode): TImplication =
assert isLocation(x)
case fact.sons[0].sym.magic
case fact[0].sym.magic
of someEq:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x = 4; question x >= 56? --> true iff 4 >= 56
if leValue(c, fact.sons[2]): result = impYes
if leValue(c, fact[2]): result = impYes
else: result = impNo
elif sameTree(fact.sons[2], x):
if isValue(fact.sons[1]) and isValue(c):
if leValue(c, fact.sons[1]): result = impYes
elif sameTree(fact[2], x):
if isValue(fact[1]) and isValue(c):
if leValue(c, fact[1]): result = impYes
else: result = impNo
of someLt:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x < 4; question N <= x? --> false iff N <= 4
if leValue(fact.sons[2], c): result = impNo
if leValue(fact[2], c): result = impNo
# fact: x < 4; question 2 <= x? --> we don't know
elif sameTree(fact.sons[2], x):
elif sameTree(fact[2], x):
# fact: 3 < x; question: N-1 < x ? --> true iff N-1 <= 3
if isValue(fact.sons[1]) and isValue(c):
if leValue(c.pred, fact.sons[1]): result = impYes
if isValue(fact[1]) and isValue(c):
if leValue(c.pred, fact[1]): result = impYes
of someLe:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x <= 4; question x >= 56? --> false iff 4 <= 56
if leValue(fact.sons[2], c): result = impNo
if leValue(fact[2], c): result = impNo
# fact: x <= 4; question x >= 2? --> we don't know
elif sameTree(fact.sons[2], x):
elif sameTree(fact[2], x):
# fact: 3 <= x; question: x >= 2 ? --> true iff 2 <= 3
if isValue(fact.sons[1]) and isValue(c):
if leValue(c, fact.sons[1]): result = impYes
if isValue(fact[1]) and isValue(c):
if leValue(c, fact[1]): result = impYes
of mNot, mOr, mAnd: assert(false, "impliesGe")
else: discard
proc impliesLe(fact, x, c: PNode): TImplication =
if not isLocation(x):
if c.isValue:
if leValue(x, x): return impYes
else: return impNo
return impliesGe(fact, c, x)
case fact.sons[0].sym.magic
case fact[0].sym.magic
of someEq:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x = 4; question x <= 56? --> true iff 4 <= 56
if leValue(fact.sons[2], c): result = impYes
if leValue(fact[2], c): result = impYes
else: result = impNo
elif sameTree(fact.sons[2], x):
if isValue(fact.sons[1]) and isValue(c):
if leValue(fact.sons[1], c): result = impYes
elif sameTree(fact[2], x):
if isValue(fact[1]) and isValue(c):
if leValue(fact[1], c): result = impYes
else: result = impNo
of someLt:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x < 4; question x <= N? --> true iff N-1 <= 4
if leValue(fact.sons[2], c.pred): result = impYes
if leValue(fact[2], c.pred): result = impYes
# fact: x < 4; question x <= 2? --> we don't know
elif sameTree(fact.sons[2], x):
elif sameTree(fact[2], x):
# fact: 3 < x; question: x <= 1 ? --> false iff 1 <= 3
if isValue(fact.sons[1]) and isValue(c):
if leValue(c, fact.sons[1]): result = impNo
if isValue(fact[1]) and isValue(c):
if leValue(c, fact[1]): result = impNo
of someLe:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x <= 4; question x <= 56? --> true iff 4 <= 56
if leValue(fact.sons[2], c): result = impYes
if leValue(fact[2], c): result = impYes
# fact: x <= 4; question x <= 2? --> we don't know
elif sameTree(fact.sons[2], x):
elif sameTree(fact[2], x):
# fact: 3 <= x; question: x <= 2 ? --> false iff 2 < 3
if isValue(fact.sons[1]) and isValue(c):
if leValue(c, fact.sons[1].pred): result = impNo
if isValue(fact[1]) and isValue(c):
if leValue(c, fact[1].pred): result = impNo
of mNot, mOr, mAnd: assert(false, "impliesLe")
else: discard
@@ -686,32 +700,32 @@ proc factImplies(fact, prop: PNode): TImplication =
# (not a) -> b compute as not (a -> b) ???
# == not a or not b == not (a and b)
let arg = fact.sons[1]
let arg = fact[1]
case arg.getMagic
of mIsNil, mEqRef:
return ~factImplies(arg, prop)
of mAnd:
# not (a and b) means not a or not b:
# a or b --> both need to imply 'prop'
let a = factImplies(arg.sons[1], prop)
let b = factImplies(arg.sons[2], prop)
let a = factImplies(arg[1], prop)
let b = factImplies(arg[2], prop)
if a == b: return ~a
return impUnknown
else:
return impUnknown
of mAnd:
result = factImplies(fact.sons[1], prop)
result = factImplies(fact[1], prop)
if result != impUnknown: return result
return factImplies(fact.sons[2], prop)
return factImplies(fact[2], prop)
else: discard
case prop.sons[0].sym.magic
of mNot: result = ~fact.factImplies(prop.sons[1])
case prop[0].sym.magic
of mNot: result = ~fact.factImplies(prop[1])
of mIsNil: result = impliesIsNil(fact, prop)
of someEq: result = impliesEq(fact, prop)
of someLe: result = impliesLe(fact, prop.sons[1], prop.sons[2])
of someLt: result = impliesLt(fact, prop.sons[1], prop.sons[2])
of mInSet: result = impliesIn(fact, prop.sons[2], prop.sons[1])
of someLe: result = impliesLe(fact, prop[1], prop[2])
of someLt: result = impliesLt(fact, prop[1], prop[2])
of mInSet: result = impliesIn(fact, prop[2], prop[1])
else: result = impUnknown
proc doesImply*(facts: TModel, prop: PNode): TImplication =
@@ -802,7 +816,7 @@ proc ple(m: TModel; a, b: PNode): TImplication =
if lastOrd(nil, a.typ) <= b.intVal: return impYes
# 3 <= x iff low(x) <= 3
if a.isValue and b.typ != nil and b.typ.isOrdinalType:
if firstOrd(nil, b.typ) <= a.intVal: return impYes
if a.intVal <= firstOrd(nil, b.typ): return impYes
# x <= x
if sameTree(a, b): return impYes
@@ -813,7 +827,11 @@ proc ple(m: TModel; a, b: PNode): TImplication =
# x <= y+c if 0 <= c and x <= y
# x <= y+(-c) if c <= 0 and y >= x
if b.getMagic in someAdd and zero() <=? b[2] and a <=? b[1]: return impYes
if b.getMagic in someAdd:
if zero() <=? b[2] and a <=? b[1]: return impYes
# x <= y-c if x+c <= y
if b[2] <=? zero() and (canon(m.o.opSub.buildCall(a, b[2]), m.o) <=? b[1]):
return impYes
# x+c <= y if c <= 0 and x <= y
if a.getMagic in someAdd and a[2] <=? zero() and a[1] <=? b: return impYes
@@ -881,8 +899,8 @@ proc replaceSubTree(n, x, by: PNode): PNode =
result = by
elif hasSubTree(n, x):
result = shallowCopy(n)
for i in 0 .. safeLen(n)-1:
result.sons[i] = replaceSubTree(n.sons[i], x, by)
for i in 0..n.safeLen-1:
result[i] = replaceSubTree(n[i], x, by)
else:
result = n
@@ -902,10 +920,13 @@ proc pleViaModelRec(m: var TModel; a, b: PNode): TImplication =
# --> true if (len-100) <= (len-1)
let x = fact[1]
let y = fact[2]
if sameTree(x, a) and y.getMagic in someAdd and b.getMagic in someAdd and
sameTree(y[1], b[1]):
if ple(m, b[2], y[2]) == impYes:
return impYes
# x <= y.
# Question: x <= b? True iff y <= b.
if sameTree(x, a):
if ple(m, y, b) == impYes: return impYes
if y.getMagic in someAdd and b.getMagic in someAdd and sameTree(y[1], b[1]):
if ple(m, b[2], y[2]) == impYes:
return impYes
# x <= y implies a <= b if a <= x and y <= b
if ple(m, a, x) == impYes:
@@ -964,6 +985,10 @@ proc proveLe*(m: TModel; a, b: PNode): TImplication =
proc addFactLe*(m: var TModel; a, b: PNode) =
m.s.add canon(m.o.opLe.buildCall(a, b), m.o)
proc addFactLt*(m: var TModel; a, b: PNode) =
let bb = m.o.opAdd.buildCall(b, minusOne())
addFactLe(m, a, bb)
proc settype(n: PNode): PType =
result = newType(tySet, n.typ.owner)
addSonSkipIntLit(result, n.typ)
@@ -971,36 +996,37 @@ proc settype(n: PNode): PType =
proc buildOf(it, loc: PNode; o: Operators): PNode =
var s = newNodeI(nkCurly, it.info, it.len-1)
s.typ = settype(loc)
for i in 0..it.len-2: s.sons[i] = it.sons[i]
for i in 0..<it.len-1: s[i] = it[i]
result = newNodeI(nkCall, it.info, 3)
result.sons[0] = newSymNode(o.opContains)
result.sons[1] = s
result.sons[2] = loc
result[0] = newSymNode(o.opContains)
result[1] = s
result[2] = loc
proc buildElse(n: PNode; o: Operators): PNode =
var s = newNodeIT(nkCurly, n.info, settype(n.sons[0]))
for i in 1..n.len-2:
let branch = n.sons[i]
assert branch.kind == nkOfBranch
for j in 0..branch.len-2:
s.add(branch.sons[j])
var s = newNodeIT(nkCurly, n.info, settype(n[0]))
for i in 1..<n.len-1:
let branch = n[i]
assert branch.kind != nkElse
if branch.kind == nkOfBranch:
for j in 0..<branch.len-1:
s.add(branch[j])
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(o.opContains)
result.sons[1] = s
result.sons[2] = n.sons[0]
result[0] = newSymNode(o.opContains)
result[1] = s
result[2] = n[0]
proc addDiscriminantFact*(m: var TModel, n: PNode) =
var fact = newNodeI(nkCall, n.info, 3)
fact.sons[0] = newSymNode(m.o.opEq)
fact.sons[1] = n.sons[0]
fact.sons[2] = n.sons[1]
fact[0] = newSymNode(m.o.opEq)
fact[1] = n[0]
fact[2] = n[1]
m.s.add fact
proc addAsgnFact*(m: var TModel, key, value: PNode) =
var fact = newNodeI(nkCall, key.info, 3)
fact.sons[0] = newSymNode(m.o.opEq)
fact.sons[1] = key
fact.sons[2] = value
fact[0] = newSymNode(m.o.opEq)
fact[1] = key
fact[2] = value
m.s.add fact
proc sameSubexprs*(m: TModel; a, b: PNode): bool =
@@ -1014,34 +1040,34 @@ proc sameSubexprs*(m: TModel; a, b: PNode): bool =
# However, nil checking requires exactly the same mechanism! But for now
# we simply use sameTree and live with the unsoundness of the analysis.
var check = newNodeI(nkCall, a.info, 3)
check.sons[0] = newSymNode(m.o.opEq)
check.sons[1] = a
check.sons[2] = b
check[0] = newSymNode(m.o.opEq)
check[1] = a
check[2] = b
result = m.doesImply(check) == impYes
proc addCaseBranchFacts*(m: var TModel, n: PNode, i: int) =
let branch = n.sons[i]
let branch = n[i]
if branch.kind == nkOfBranch:
m.s.add buildOf(branch, n.sons[0], m.o)
m.s.add buildOf(branch, n[0], m.o)
else:
m.s.add n.buildElse(m.o).neg(m.o)
proc buildProperFieldCheck(access, check: PNode; o: Operators): PNode =
if check.sons[1].kind == nkCurly:
if check[1].kind == nkCurly:
result = copyTree(check)
if access.kind == nkDotExpr:
var a = copyTree(access)
a.sons[1] = check.sons[2]
result.sons[2] = a
a[1] = check[2]
result[2] = a
# 'access.kind != nkDotExpr' can happen for object constructors
# which we don't check yet
else:
# it is some 'not'
assert check.getMagic == mNot
result = buildProperFieldCheck(access, check.sons[1], o).neg(o)
result = buildProperFieldCheck(access, check[1], o).neg(o)
proc checkFieldAccess*(m: TModel, n: PNode; conf: ConfigRef) =
for i in 1..n.len-1:
let check = buildProperFieldCheck(n.sons[0], n.sons[i], m.o)
for i in 1..<n.len:
let check = buildProperFieldCheck(n[0], n[i], m.o)
if check != nil and m.doesImply(check) != impYes:
message(conf, n.info, warnProveField, renderTree(n.sons[0])); break
message(conf, n.info, warnProveField, renderTree(n[0])); break

View File

@@ -12,14 +12,14 @@
proc hlo(c: PContext, n: PNode): PNode
proc evalPattern(c: PContext, n, orig: PNode): PNode =
internalAssert c.config, n.kind == nkCall and n.sons[0].kind == nkSym
internalAssert c.config, n.kind == nkCall and n[0].kind == nkSym
# we need to ensure that the resulting AST is semchecked. However, it's
# aweful to semcheck before macro invocation, so we don't and treat
# awful to semcheck before macro invocation, so we don't and treat
# templates and macros as immediate in this context.
var rule: string
if optHints in c.config.options and hintPattern in c.config.notes:
if c.config.hasHint(hintPattern):
rule = renderTree(n, {renderNoComments})
let s = n.sons[0].sym
let s = n[0].sym
case s.kind
of skMacro:
result = semMacroExpr(c, n, orig, s)
@@ -27,7 +27,7 @@ proc evalPattern(c: PContext, n, orig: PNode): PNode =
result = semTemplateExpr(c, n, s, {efFromHlo})
else:
result = semDirectOp(c, n, {})
if optHints in c.config.options and hintPattern in c.config.notes:
if c.config.hasHint(hintPattern):
message(c.config, orig.info, hintPattern, rule & " --> '" &
renderTree(result, {renderNoComments}) & "'")
@@ -50,7 +50,7 @@ proc applyPatterns(c: PContext, n: PNode): PNode =
c.patterns[i] = nil
if x.kind == nkStmtList:
assert x.len == 3
x.sons[1] = evalPattern(c, x.sons[1], result)
x[1] = evalPattern(c, x[1], result)
result = flattenStmts(x)
else:
result = evalPattern(c, x, result)
@@ -68,17 +68,17 @@ proc hlo(c: PContext, n: PNode): PNode =
result = n
else:
if n.kind in {nkFastAsgn, nkAsgn, nkIdentDefs, nkVarTuple} and
n.sons[0].kind == nkSym and
{sfGlobal, sfPure} * n.sons[0].sym.flags == {sfGlobal, sfPure}:
n[0].kind == nkSym and
{sfGlobal, sfPure} * n[0].sym.flags == {sfGlobal, sfPure}:
# do not optimize 'var g {.global} = re(...)' again!
return n
result = applyPatterns(c, n)
if result == n:
# no optimization applied, try subtrees:
for i in 0 ..< safeLen(result):
let a = result.sons[i]
for i in 0..<result.safeLen:
let a = result[i]
let h = hlo(c, a)
if h != a: result.sons[i] = h
if h != a: result[i] = h
else:
# perform type checking, so that the replacement still fits:
if isEmptyType(n.typ) and isEmptyType(result.typ):
@@ -92,12 +92,12 @@ proc hlo(c: PContext, n: PNode): PNode =
proc hloBody(c: PContext, n: PNode): PNode =
# fast exit:
if c.patterns.len == 0 or optPatterns notin c.config.options: return n
if c.patterns.len == 0 or optTrMacros notin c.config.options: return n
c.hloLoopDetector = 0
result = hlo(c, n)
proc hloStmt(c: PContext, n: PNode): PNode =
# fast exit:
if c.patterns.len == 0 or optPatterns notin c.config.options: return n
if c.patterns.len == 0 or optTrMacros notin c.config.options: return n
c.hloLoopDetector = 0
result = hlo(c, n)

View File

@@ -12,7 +12,7 @@
# id. This module is essential for the compiler's performance.
import
hashes, strutils, wordrecg
hashes, wordrecg
type
TIdObj* = object of RootObj
@@ -87,7 +87,7 @@ proc getIdent*(ic: IdentCache; identifier: cstring, length: int, h: Hash): PIden
new(result)
result.h = h
result.s = newString(length)
for i in countup(0, length - 1): result.s[i] = identifier[i]
for i in 0..<length: result.s[i] = identifier[i]
result.next = ic.buckets[idx]
ic.buckets[idx] = result
if id == 0:
@@ -97,11 +97,11 @@ proc getIdent*(ic: IdentCache; identifier: cstring, length: int, h: Hash): PIden
result.id = id
proc getIdent*(ic: IdentCache; identifier: string): PIdent =
result = getIdent(ic, cstring(identifier), len(identifier),
result = getIdent(ic, cstring(identifier), identifier.len,
hashIgnoreStyle(identifier))
proc getIdent*(ic: IdentCache; identifier: string, h: Hash): PIdent =
result = getIdent(ic, cstring(identifier), len(identifier), h)
result = getIdent(ic, cstring(identifier), identifier.len, h)
proc newIdentCache*(): IdentCache =
result = IdentCache()
@@ -110,7 +110,7 @@ proc newIdentCache*(): IdentCache =
result.idDelegator = result.getIdent":delegator"
result.emptyIdent = result.getIdent("")
# initialize the keywords:
for s in countup(succ(low(specialWords)), high(specialWords)):
for s in succ(low(specialWords))..high(specialWords):
result.getIdent(specialWords[s], hashIgnoreStyle(specialWords[s])).id = ord(s)
proc whichKeyword*(id: PIdent): TSpecialWord =

View File

@@ -9,7 +9,7 @@
## This module contains a simple persistent id generator.
import idents, strutils, os, options, pathutils
import idents, strutils, options, pathutils
var gFrontEndId*: int

View File

@@ -10,13 +10,13 @@
## This module implements the symbol importing mechanism.
import
intsets, strutils, os, ast, astalgo, msgs, options, idents, lookups,
semdata, passes, renderer, modulepaths, sigmatch, lineinfos
intsets, ast, astalgo, msgs, options, idents, lookups,
semdata, modulepaths, sigmatch, lineinfos, sets
proc readExceptSet*(c: PContext, n: PNode): IntSet =
assert n.kind in {nkImportExceptStmt, nkExportExceptStmt}
result = initIntSet()
for i in 1 ..< n.len:
for i in 1..<n.len:
let ident = lookups.considerQuotedIdent(c, n[i])
result.incl(ident.id)
@@ -27,11 +27,11 @@ proc importPureEnumField*(c: PContext; s: PSym) =
if checkB == nil:
strTableAdd(c.pureEnumFields, s)
else:
# mark as ambigous:
# mark as ambiguous:
incl(c.ambiguousSymbols, checkB.id)
incl(c.ambiguousSymbols, s.id)
proc rawImportSymbol(c: PContext, s: PSym) =
proc rawImportSymbol(c: PContext, s, origin: PSym) =
# This does not handle stubs, because otherwise loading on demand would be
# pointless in practice. So importing stubs is fine here!
# check if we have already a symbol of the same name:
@@ -47,8 +47,8 @@ proc rawImportSymbol(c: PContext, s: PSym) =
if s.kind == skType:
var etyp = s.typ
if etyp.kind in {tyBool, tyEnum}:
for j in countup(0, sonsLen(etyp.n) - 1):
var e = etyp.n.sons[j].sym
for j in 0..<etyp.n.len:
var e = etyp.n[j].sym
if e.kind != skEnumField:
internalError(c.config, s.info, "rawImportSymbol")
# BUGFIX: because of aliases for enums the symbol may already
@@ -63,13 +63,14 @@ proc rawImportSymbol(c: PContext, s: PSym) =
check = nextIdentIter(it, c.importTable.symbols)
if e != nil:
if sfPure notin s.flags:
rawImportSymbol(c, e)
rawImportSymbol(c, e, origin)
else:
importPureEnumField(c, e)
else:
# rodgen assures that converters and patterns are no stubs
if s.kind == skConverter: addConverter(c, s)
if hasPattern(s): addPattern(c, s)
if s.owner != origin:
c.exportIndirections.incl((origin.id, s.id))
proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
let ident = lookups.considerQuotedIdent(c, n)
@@ -79,19 +80,20 @@ proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
else:
when false:
if s.kind == skStub: loadStub(s)
if s.kind notin ExportableSymKinds:
internalError(c.config, n.info, "importSymbol: 2")
let multiImport = s.kind notin ExportableSymKinds or s.kind in skProcKinds
# for an enumeration we have to add all identifiers
case s.kind
of skProcKinds:
if multiImport:
# for a overloadable syms add all overloaded routines
var it: TIdentIter
var e = initIdentIter(it, fromMod.tab, s.name)
while e != nil:
if e.name.id != s.name.id: internalError(c.config, n.info, "importSymbol: 3")
rawImportSymbol(c, e)
if s.kind in ExportableSymKinds:
rawImportSymbol(c, e, fromMod)
e = nextIdentIter(it, fromMod.tab)
else: rawImportSymbol(c, s)
else:
rawImportSymbol(c, s, fromMod)
suggestSym(c.config, n.info, s, c.graph.usageSym, false)
proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) =
var i: TTabIter
@@ -100,16 +102,16 @@ proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) =
if s.kind != skModule:
if s.kind != skEnumField:
if s.kind notin ExportableSymKinds:
internalError(c.config, s.info, "importAllSymbols: " & $s.kind)
internalError(c.config, s.info, "importAllSymbols: " & $s.kind & " " & s.name.s)
if exceptSet.isNil or s.name.id notin exceptSet:
rawImportSymbol(c, s)
rawImportSymbol(c, s, fromMod)
s = nextIter(i, fromMod.tab)
proc importAllSymbols*(c: PContext, fromMod: PSym) =
var exceptSet: IntSet
importAllSymbolsExcept(c, fromMod, exceptSet)
proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet) =
proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet; fromMod: PSym) =
if n.isNil: return
case n.kind
of nkExportStmt:
@@ -119,38 +121,43 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet) =
if s.kind == skModule:
importAllSymbolsExcept(c, s, exceptSet)
elif exceptSet.isNil or s.name.id notin exceptSet:
rawImportSymbol(c, s)
rawImportSymbol(c, s, fromMod)
of nkExportExceptStmt:
localError(c.config, n.info, "'export except' not implemented")
else:
for i in 0..safeLen(n)-1:
importForwarded(c, n.sons[i], exceptSet)
for i in 0..n.safeLen-1:
importForwarded(c, n[i], exceptSet, fromMod)
proc importModuleAs(c: PContext; n: PNode, realModule: PSym): PSym =
result = realModule
c.unusedImports.add((realModule, n.info))
if n.kind != nkImportAs: discard
elif n.len != 2 or n.sons[1].kind != nkIdent:
elif n.len != 2 or n[1].kind != nkIdent:
localError(c.config, n.info, "module alias must be an identifier")
elif n.sons[1].ident.id != realModule.name.id:
elif n[1].ident.id != realModule.name.id:
# some misguided guy will write 'import abc.foo as foo' ...
result = createModuleAlias(realModule, n.sons[1].ident, realModule.info,
result = createModuleAlias(realModule, n[1].ident, realModule.info,
c.config.options)
proc myImportModule(c: PContext, n: PNode; importStmtResult: PNode): PSym =
let f = checkModuleName(c.config, n)
if f != InvalidFileIDX:
if f != InvalidFileIdx:
let L = c.graph.importStack.len
let recursion = c.graph.importStack.find(f)
c.graph.importStack.add f
#echo "adding ", toFullPath(f), " at ", L+1
if recursion >= 0:
var err = ""
for i in countup(recursion, L-1):
for i in recursion..<L:
if i > recursion: err.add "\n"
err.add toFullPath(c.config, c.graph.importStack[i]) & " imports " &
toFullPath(c.config, c.graph.importStack[i+1])
c.recursiveDep = err
discard pushOptionEntry(c)
result = importModuleAs(c, n, c.graph.importModuleCallback(c.graph, c.module, f))
popOptionEntry(c)
#echo "set back to ", L
c.graph.importStack.setLen(L)
# we cannot perform this check reliably because of
@@ -161,9 +168,9 @@ proc myImportModule(c: PContext, n: PNode; importStmtResult: PNode): PSym =
localError(c.config, n.info, "A module cannot import itself")
if sfDeprecated in result.flags:
if result.constraint != nil:
message(c.config, n.info, warnDeprecated, result.constraint.strVal & "; " & result.name.s)
message(c.config, n.info, warnDeprecated, result.constraint.strVal & "; " & result.name.s & " is deprecated")
else:
message(c.config, n.info, warnDeprecated, result.name.s)
message(c.config, n.info, warnDeprecated, result.name.s & " is deprecated")
suggestSym(c.config, n.info, result, c.graph.usageSym, false)
importStmtResult.add newSymNode(result, n.info)
#newStrNode(toFullPath(c.config, f), n.info)
@@ -171,8 +178,8 @@ proc myImportModule(c: PContext, n: PNode; importStmtResult: PNode): PSym =
proc transformImportAs(c: PContext; n: PNode): PNode =
if n.kind == nkInfix and considerQuotedIdent(c, n[0]).s == "as":
result = newNodeI(nkImportAs, n.info)
result.add n.sons[1]
result.add n.sons[2]
result.add n[1]
result.add n[2]
else:
result = n
@@ -184,12 +191,12 @@ proc impMod(c: PContext; it: PNode; importStmtResult: PNode) =
# ``addDecl`` needs to be done before ``importAllSymbols``!
addDecl(c, m, it.info) # add symbol to symbol table of module
importAllSymbolsExcept(c, m, emptySet)
#importForwarded(c, m.ast, emptySet)
#importForwarded(c, m.ast, emptySet, m)
proc evalImport*(c: PContext, n: PNode): PNode =
result = newNodeI(nkImportStmt, n.info)
for i in countup(0, sonsLen(n) - 1):
let it = n.sons[i]
for i in 0..<n.len:
let it = n[i]
if it.kind == nkInfix and it.len == 3 and it[2].kind == nkBracket:
let sep = it[0]
let dir = it[1]
@@ -199,13 +206,13 @@ proc evalImport*(c: PContext, n: PNode): PNode =
imp.add sep # dummy entry, replaced in the loop
for x in it[2]:
# transform `a/b/[c as d]` to `/a/b/c as d`
if x.kind == nkInfix and x.sons[0].ident.s == "as":
if x.kind == nkInfix and x[0].ident.s == "as":
let impAs = copyTree(x)
imp.sons[2] = x.sons[1]
impAs.sons[1] = imp
imp[2] = x[1]
impAs[1] = imp
impMod(c, imp, result)
else:
imp.sons[2] = x
imp[2] = x
impMod(c, imp, result)
else:
impMod(c, it, result)
@@ -213,22 +220,22 @@ proc evalImport*(c: PContext, n: PNode): PNode =
proc evalFrom*(c: PContext, n: PNode): PNode =
result = newNodeI(nkImportStmt, n.info)
checkMinSonsLen(n, 2, c.config)
n.sons[0] = transformImportAs(c, n.sons[0])
var m = myImportModule(c, n.sons[0], result)
n[0] = transformImportAs(c, n[0])
var m = myImportModule(c, n[0], result)
if m != nil:
n.sons[0] = newSymNode(m)
n[0] = newSymNode(m)
addDecl(c, m, n.info) # add symbol to symbol table of module
for i in countup(1, sonsLen(n) - 1):
if n.sons[i].kind != nkNilLit:
importSymbol(c, n.sons[i], m)
for i in 1..<n.len:
if n[i].kind != nkNilLit:
importSymbol(c, n[i], m)
proc evalImportExcept*(c: PContext, n: PNode): PNode =
result = newNodeI(nkImportStmt, n.info)
checkMinSonsLen(n, 2, c.config)
n.sons[0] = transformImportAs(c, n.sons[0])
var m = myImportModule(c, n.sons[0], result)
n[0] = transformImportAs(c, n[0])
var m = myImportModule(c, n[0], result)
if m != nil:
n.sons[0] = newSymNode(m)
n[0] = newSymNode(m)
addDecl(c, m, n.info) # add symbol to symbol table of module
importAllSymbolsExcept(c, m, readExceptSet(c, n))
#importForwarded(c, m.ast, exceptSet)
#importForwarded(c, m.ast, exceptSet, m)

View File

@@ -12,11 +12,12 @@
const nimIncremental* = defined(nimIncremental)
import options, lineinfos, pathutils
import options, lineinfos
when nimIncremental:
import ast, msgs, intsets, btrees, db_sqlite, std / sha1
import ast, msgs, intsets, btrees, db_sqlite, std / sha1, pathutils
from strutils import parseInt
from os import isAbsolute
type
Writer* = object
@@ -47,7 +48,7 @@ when nimIncremental:
proc hashFileCached*(conf: ConfigRef; fileIdx: FileIndex; fullpath: AbsoluteFile): string =
result = msgs.getHash(conf, fileIdx)
if result.len == 0:
if result.len == 0 and isAbsolute(string fullpath):
result = $secureHashFile(string fullpath)
msgs.setHash(conf, fileIdx, result)
@@ -59,8 +60,8 @@ when nimIncremental:
let id = row[0]
let fullhash = hashFileCached(conf, fileIdx, AbsoluteFile fullpath)
if id.len == 0:
result = int incr.db.insertID(sql"insert into filenames(fullpath, fullhash) values (?, ?)",
fullpath, fullhash)
result = int incr.db.insertID(sql"insert into filenames(nimid, fullpath, fullhash) values (?, ?, ?)",
int(fileIdx), fullpath, fullhash)
else:
if row[1] != fullhash:
incr.db.exec(sql"update filenames set fullhash = ? where fullpath = ?", fullhash, fullpath)
@@ -102,6 +103,7 @@ when nimIncremental:
db.exec(sql"""
create table if not exists filenames(
id integer primary key,
nimid integer not null,
fullpath varchar(8000) not null,
fullHash varchar(256) not null
);

File diff suppressed because it is too large Load Diff

View File

@@ -6,10 +6,10 @@ Name: "Nim"
Version: "$version"
Platforms: """
windows: i386;amd64
linux: i386;amd64;powerpc64;arm;sparc;mips;mipsel;mips64;mips64el;powerpc;powerpc64el;arm64;riscv64
linux: i386;hppa;ia64;alpha;amd64;powerpc64;arm;sparc;sparc64;m68k;mips;mipsel;mips64;mips64el;powerpc;powerpc64el;arm64;riscv64
macosx: i386;amd64;powerpc64
solaris: i386;amd64;sparc;sparc64
freebsd: i386;amd64
freebsd: i386;amd64;powerpc64;arm;arm64
netbsd: i386;amd64
openbsd: i386;amd64
dragonfly: i386;amd64
@@ -49,11 +49,8 @@ Start: "doc/html/overview.html"
[Other]
Files: "readme.txt;copying.txt;install.txt"
Files: "makefile"
Files: "copying.txt"
Files: "koch.nim"
Files: "install_nimble.nims"
Files: "install_tools.nims"
Files: "icons/nim.ico"
Files: "icons/nim.rc"
@@ -68,17 +65,11 @@ Files: "compiler"
Files: "doc"
Files: "doc/html"
Files: "tools"
Files: "tools/nim-gdb.py"
Files: "nimpretty"
Files: "testament"
Files: "nimsuggest"
Files: "nimsuggest/tests/*.nim"
Files: "web/website.ini"
Files: "web/ticker.html"
Files: "web/*.nim"
Files: "web/*.rst"
Files: "web/*.csv"
Files: "web/news/*.rst"
Files: "bin/nimblepkg/*.nim"
Files: "bin/nimblepkg/*.cfg"
[Lib]
Files: "lib"
@@ -86,18 +77,18 @@ Files: "lib"
[Other]
Files: "examples"
Files: "dist/nimble"
Files: "dist/nimsuggest"
Files: "tests"
[Windows]
Files: "bin/nim.exe"
Files: "bin/c2nim.exe"
Files: "bin/nimgrep.exe"
Files: "bin/nimsuggest.exe"
Files: "bin/nimble.exe"
Files: "bin/vccexe.exe"
Files: "bin/nimgrab.exe"
Files: "bin/nimpretty.exe"
Files: "bin/testament.exe"
Files: "koch.exe"
Files: "finish.exe"
@@ -148,4 +139,4 @@ licenses: "bin/nim,MIT;lib/*,MIT;"
[nimble]
pkgName: "compiler"
pkgFiles: "compiler/*;doc/basicopt.txt;doc/advopt.txt"
pkgFiles: "compiler/*;doc/basicopt.txt;doc/advopt.txt;doc/nimdoc.css"

781
compiler/int128.nim Normal file
View File

@@ -0,0 +1,781 @@
## This module is for compiler internal use only. For reliable error
## messages and range checks, the compiler needs a data type that can
## hold all from ``low(BiggestInt)`` to ``high(BiggestUInt)``, This
## type is for that purpose.
from math import trunc
type
Int128* = object
udata: array[4,uint32]
template sdata(arg: Int128, idx: int): int32 =
# udata and sdata was supposed to be in a union, but unions are
# handled incorrectly in the VM.
cast[ptr int32](arg.udata[idx].unsafeAddr)[]
# encoding least significant int first (like LittleEndian)
const
Zero* = Int128(udata: [0'u32,0,0,0])
One* = Int128(udata: [1'u32,0,0,0])
Ten* = Int128(udata: [10'u32,0,0,0])
Min = Int128(udata: [0'u32,0,0,0x80000000'u32])
Max = Int128(udata: [high(uint32),high(uint32),high(uint32),uint32(high(int32))])
NegOne* = Int128(udata: [0xffffffff'u32,0xffffffff'u32,0xffffffff'u32,0xffffffff'u32])
template low*(t: typedesc[Int128]): Int128 = Min
template high*(t: typedesc[Int128]): Int128 = Max
proc `$`*(a: Int128): string
proc toInt128*[T: SomeInteger | bool](arg: T): Int128 =
when T is bool: result.sdata(0) = int32(arg)
elif T is SomeUnsignedInt:
when sizeof(arg) <= 4:
result.udata[0] = uint32(arg)
else:
result.udata[0] = uint32(arg and T(0xffffffff))
result.udata[1] = uint32(arg shr 32)
elif sizeof(arg) <= 4:
result.sdata(0) = int32(arg)
if arg < 0: # sign extend
result.sdata(1) = -1
result.sdata(2) = -1
result.sdata(3) = -1
else:
let tmp = int64(arg)
result.udata[0] = uint32(tmp and 0xffffffff)
result.sdata(1) = int32(tmp shr 32)
if arg < 0: # sign extend
result.sdata(2) = -1
result.sdata(3) = -1
template isNegative(arg: Int128): bool =
arg.sdata(3) < 0
template isNegative(arg: int32): bool =
arg < 0
proc bitconcat(a,b: uint32): uint64 =
(uint64(a) shl 32) or uint64(b)
proc bitsplit(a: uint64): (uint32,uint32) =
(cast[uint32](a shr 32), cast[uint32](a))
proc toInt64*(arg: Int128): int64 =
if isNegative(arg):
assert(arg.sdata(3) == -1, "out of range")
assert(arg.sdata(2) == -1, "out of range")
else:
assert(arg.sdata(3) == 0, "out of range")
assert(arg.sdata(2) == 0, "out of range")
cast[int64](bitconcat(arg.udata[1], arg.udata[0]))
proc toInt64Checked*(arg: Int128; onError: int64): int64 =
if isNegative(arg):
if arg.sdata(3) != -1 or arg.sdata(2) != -1:
return onError
else:
if arg.sdata(3) != 0 or arg.sdata(2) != 0:
return onError
return cast[int64](bitconcat(arg.udata[1], arg.udata[0]))
proc toInt32*(arg: Int128): int32 =
if isNegative(arg):
assert(arg.sdata(3) == -1, "out of range")
assert(arg.sdata(2) == -1, "out of range")
assert(arg.sdata(1) == -1, "out of range")
else:
assert(arg.sdata(3) == 0, "out of range")
assert(arg.sdata(2) == 0, "out of range")
assert(arg.sdata(1) == 0, "out of range")
arg.sdata(0)
proc toInt16*(arg: Int128): int16 =
if isNegative(arg):
assert(arg.sdata(3) == -1, "out of range")
assert(arg.sdata(2) == -1, "out of range")
assert(arg.sdata(1) == -1, "out of range")
else:
assert(arg.sdata(3) == 0, "out of range")
assert(arg.sdata(2) == 0, "out of range")
assert(arg.sdata(1) == 0, "out of range")
int16(arg.sdata(0))
proc toInt8*(arg: Int128): int8 =
if isNegative(arg):
assert(arg.sdata(3) == -1, "out of range")
assert(arg.sdata(2) == -1, "out of range")
assert(arg.sdata(1) == -1, "out of range")
else:
assert(arg.sdata(3) == 0, "out of range")
assert(arg.sdata(2) == 0, "out of range")
assert(arg.sdata(1) == 0, "out of range")
int8(arg.sdata(0))
proc toInt*(arg: Int128): int =
when sizeof(int) == 4:
cast[int](toInt32(arg))
else:
cast[int](toInt64(arg))
proc toUInt64*(arg: Int128): uint64 =
assert(arg.udata[3] == 0)
assert(arg.udata[2] == 0)
bitconcat(arg.udata[1], arg.udata[0])
proc toUInt32*(arg: Int128): uint32 =
assert(arg.udata[3] == 0)
assert(arg.udata[2] == 0)
assert(arg.udata[1] == 0)
arg.udata[0]
proc toUInt16*(arg: Int128): uint16 =
assert(arg.udata[3] == 0)
assert(arg.udata[2] == 0)
assert(arg.udata[1] == 0)
uint16(arg.udata[0])
proc toUInt8*(arg: Int128): uint8 =
assert(arg.udata[3] == 0)
assert(arg.udata[2] == 0)
assert(arg.udata[1] == 0)
uint8(arg.udata[0])
proc toUInt*(arg: Int128): uint =
when sizeof(int) == 4:
cast[uint](toInt32(arg))
else:
cast[uint](toInt64(arg))
proc castToInt64*(arg: Int128): int64 =
## Conversion to int64 without range check.
cast[int64](bitconcat(arg.udata[1], arg.udata[0]))
proc castToUInt64*(arg: Int128): uint64 =
## Conversion to uint64 without range check.
cast[uint64](bitconcat(arg.udata[1], arg.udata[0]))
proc addToHex(result: var string; arg: uint32) =
for i in 0..<8:
let idx = (arg shr ((7-i) * 4)) and 0xf
result.add "0123456789abcdef"[idx]
proc addToHex*(result: var string; arg: Int128) =
var i = 3
while i >= 0:
result.addToHex(arg.udata[i])
i -= 1
proc toHex*(arg: Int128): string =
result.addToHex(arg)
proc inc*(a: var Int128, y: uint32 = 1) =
let input = a
a.udata[0] += y
if unlikely(a.udata[0] < y):
a.udata[1].inc
if unlikely(a.udata[1] == 0):
a.udata[2].inc
if unlikely(a.udata[2] == 0):
a.udata[3].inc
doAssert(a.sdata(3) != low(int32), "overflow")
proc cmp*(a,b: Int128): int =
let tmp1 = cmp(a.sdata(3), b.sdata(3))
if tmp1 != 0: return tmp1
let tmp2 = cmp(a.udata[2], b.udata[2])
if tmp2 != 0: return tmp2
let tmp3 = cmp(a.udata[1], b.udata[1])
if tmp3 != 0: return tmp3
let tmp4 = cmp(a.udata[0], b.udata[0])
return tmp4
proc `<`*(a,b: Int128): bool =
cmp(a,b) < 0
proc `<=`*(a,b: Int128): bool =
cmp(a,b) <= 0
proc `==`*(a,b: Int128): bool =
if a.udata[0] != b.udata[0]: return false
if a.udata[1] != b.udata[1]: return false
if a.udata[2] != b.udata[2]: return false
if a.udata[3] != b.udata[3]: return false
return true
proc inplaceBitnot(a: var Int128) =
a.udata[0] = not a.udata[0]
a.udata[1] = not a.udata[1]
a.udata[2] = not a.udata[2]
a.udata[3] = not a.udata[3]
proc bitnot*(a: Int128): Int128 =
result.udata[0] = not a.udata[0]
result.udata[1] = not a.udata[1]
result.udata[2] = not a.udata[2]
result.udata[3] = not a.udata[3]
proc bitand*(a,b: Int128): Int128 =
result.udata[0] = a.udata[0] and b.udata[0]
result.udata[1] = a.udata[1] and b.udata[1]
result.udata[2] = a.udata[2] and b.udata[2]
result.udata[3] = a.udata[3] and b.udata[3]
proc bitor*(a,b: Int128): Int128 =
result.udata[0] = a.udata[0] or b.udata[0]
result.udata[1] = a.udata[1] or b.udata[1]
result.udata[2] = a.udata[2] or b.udata[2]
result.udata[3] = a.udata[3] or b.udata[3]
proc bitxor*(a,b: Int128): Int128 =
result.udata[0] = a.udata[0] xor b.udata[0]
result.udata[1] = a.udata[1] xor b.udata[1]
result.udata[2] = a.udata[2] xor b.udata[2]
result.udata[3] = a.udata[3] xor b.udata[3]
proc `shr`*(a: Int128, b: int): Int128 =
let b = b and 127
if b < 32:
result.sdata(3) = a.sdata(3) shr b
result.udata[2] = cast[uint32](bitconcat(a.udata[3], a.udata[2]) shr b)
result.udata[1] = cast[uint32](bitconcat(a.udata[2], a.udata[1]) shr b)
result.udata[0] = cast[uint32](bitconcat(a.udata[1], a.udata[0]) shr b)
elif b < 64:
if isNegative(a):
result.sdata(3) = -1
result.sdata(2) = a.sdata(3) shr (b and 31)
result.udata[1] = cast[uint32](bitconcat(a.udata[3], a.udata[2]) shr (b and 31))
result.udata[0] = cast[uint32](bitconcat(a.udata[2], a.udata[1]) shr (b and 31))
elif b < 96:
if isNegative(a):
result.sdata(3) = -1
result.sdata(2) = -1
result.sdata(1) = a.sdata(3) shr (b and 31)
result.udata[0] = cast[uint32](bitconcat(a.udata[3], a.udata[2]) shr (b and 31))
else: # b < 128
if isNegative(a):
result.sdata(3) = -1
result.sdata(2) = -1
result.sdata(1) = -1
result.sdata(0) = a.sdata(3) shr (b and 31)
proc `shl`*(a: Int128, b: int): Int128 =
let b = b and 127
if b < 32:
result.udata[0] = a.udata[0] shl b
result.udata[1] = cast[uint32]((bitconcat(a.udata[1], a.udata[0]) shl b) shr 32)
result.udata[2] = cast[uint32]((bitconcat(a.udata[2], a.udata[1]) shl b) shr 32)
result.udata[3] = cast[uint32]((bitconcat(a.udata[3], a.udata[2]) shl b) shr 32)
elif b < 64:
result.udata[0] = 0
result.udata[1] = a.udata[0] shl (b and 31)
result.udata[2] = cast[uint32]((bitconcat(a.udata[1], a.udata[0]) shl (b and 31)) shr 32)
result.udata[3] = cast[uint32]((bitconcat(a.udata[2], a.udata[1]) shl (b and 31)) shr 32)
elif b < 96:
result.udata[0] = 0
result.udata[1] = 0
result.udata[2] = a.udata[0] shl (b and 31)
result.udata[3] = cast[uint32]((bitconcat(a.udata[1], a.udata[0]) shl (b and 31)) shr 32)
else:
result.udata[0] = 0
result.udata[1] = 0
result.udata[2] = 0
result.udata[3] = a.udata[0] shl (b and 31)
proc `+`*(a,b: Int128): Int128 =
let tmp0 = uint64(a.udata[0]) + uint64(b.udata[0])
result.udata[0] = cast[uint32](tmp0)
let tmp1 = uint64(a.udata[1]) + uint64(b.udata[1]) + (tmp0 shr 32)
result.udata[1] = cast[uint32](tmp1)
let tmp2 = uint64(a.udata[2]) + uint64(b.udata[2]) + (tmp1 shr 32)
result.udata[2] = cast[uint32](tmp2)
let tmp3 = uint64(a.udata[3]) + uint64(b.udata[3]) + (tmp2 shr 32)
result.udata[3] = cast[uint32](tmp3)
proc `+=`*(a: var Int128, b: Int128) =
a = a + b
proc `-`*(a: Int128): Int128 =
result = bitnot(a)
result.inc
proc `-`*(a,b: Int128): Int128 =
a + (-b)
proc `-=`*(a: var Int128, b: Int128) =
a = a - b
proc abs*(a: Int128): Int128 =
if isNegative(a):
-a
else:
a
proc abs(a: int32): int =
if a < 0: -a else: a
proc `*`(a: Int128, b: uint32): Int128 =
let tmp0 = uint64(a.udata[0]) * uint64(b)
let tmp1 = uint64(a.udata[1]) * uint64(b)
let tmp2 = uint64(a.udata[2]) * uint64(b)
let tmp3 = uint64(a.udata[3]) * uint64(b)
if unlikely(tmp3 > uint64(high(int32))):
assert(false, "overflow")
result.udata[0] = cast[uint32](tmp0)
result.udata[1] = cast[uint32](tmp1) + cast[uint32](tmp0 shr 32)
result.udata[2] = cast[uint32](tmp2) + cast[uint32](tmp1 shr 32)
result.udata[3] = cast[uint32](tmp3) + cast[uint32](tmp2 shr 32)
proc `*`*(a: Int128, b: int32): Int128 =
result = a * cast[uint32](abs(b))
if b < 0:
result = -result
proc `*=`*(a: var Int128, b: int32): Int128 =
result = result * b
proc makeInt128(high,low: uint64): Int128 =
result.udata[0] = cast[uint32](low)
result.udata[1] = cast[uint32](low shr 32)
result.udata[2] = cast[uint32](high)
result.udata[3] = cast[uint32](high shr 32)
proc high64(a: Int128): uint64 =
bitconcat(a.udata[3], a.udata[2])
proc low64(a: Int128): uint64 =
bitconcat(a.udata[1], a.udata[0])
proc `*`*(lhs,rhs: Int128): Int128 =
let
a = cast[uint64](lhs.udata[0])
b = cast[uint64](lhs.udata[1])
c = cast[uint64](lhs.udata[2])
d = cast[uint64](lhs.udata[3])
e = cast[uint64](rhs.udata[0])
f = cast[uint64](rhs.udata[1])
g = cast[uint64](rhs.udata[2])
h = cast[uint64](rhs.udata[3])
let a32 = cast[uint64](lhs.udata[1])
let a00 = cast[uint64](lhs.udata[0])
let b32 = cast[uint64](rhs.udata[1])
let b00 = cast[uint64](rhs.udata[0])
result = makeInt128(high64(lhs) * low64(rhs) + low64(lhs) * high64(rhs) + a32 * b32, a00 * b00)
result = result + toInt128(a32 * b00) shl 32
result = result + toInt128(a00 * b32) shl 32
proc `*=`*(a: var Int128, b: Int128) =
a = a * b
import bitops
proc fastLog2*(a: Int128): int =
if a.udata[3] != 0:
return 96 + fastLog2(a.udata[3])
if a.udata[2] != 0:
return 64 + fastLog2(a.udata[2])
if a.udata[1] != 0:
return 32 + fastLog2(a.udata[1])
if a.udata[0] != 0:
return fastLog2(a.udata[0])
proc divMod*(dividend, divisor: Int128): tuple[quotient, remainder: Int128] =
assert(divisor != Zero)
let isNegativeA = isNegative(dividend)
let isNegativeB = isNegative(divisor)
var dividend = abs(dividend)
let divisor = abs(divisor)
if divisor > dividend:
result.quotient = Zero
if isNegativeA:
result.remainder = -dividend
else:
result.remainder = dividend
return
if divisor == dividend:
if isNegativeA xor isNegativeB:
result.quotient = NegOne
else:
result.quotient = One
result.remainder = Zero
return
var denominator = divisor
var quotient = Zero
# Left aligns the MSB of the denominator and the dividend.
let shift = fastLog2(dividend) - fastLog2(denominator)
denominator = denominator shl shift
# Uses shift-subtract algorithm to divide dividend by denominator. The
# remainder will be left in dividend.
for i in 0..shift:
quotient = quotient shl 1
if dividend >= denominator:
dividend = dividend - denominator
quotient = bitor(quotient, One)
denominator = denominator shr 1
if isNegativeA xor isNegativeB:
result.quotient = -quotient
else:
result.quotient = quotient
if isNegativeA:
result.remainder = -dividend
else:
result.remainder = dividend
proc `div`*(a,b: Int128): Int128 =
let (a,b) = divMod(a,b)
return a
proc `mod`*(a,b: Int128): Int128 =
let (a,b) = divMod(a,b)
return b
proc addInt128*(result: var string; value: Int128) =
let initialSize = result.len
if value == Zero:
result.add "0"
elif value == low(Int128):
result.add "-170141183460469231731687303715884105728"
else:
let isNegative = isNegative(value)
var value = abs(value)
while value > Zero:
let (quot, rem) = divMod(value, Ten)
result.add "0123456789"[rem.toInt64]
value = quot
if isNegative:
result.add '-'
var i = initialSize
var j = high(result)
while i < j:
swap(result[i], result[j])
i += 1
j -= 1
proc `$`*(a: Int128): string =
result.addInt128(a)
proc parseDecimalInt128*(arg: string, pos: int = 0): Int128 =
assert(pos < arg.len)
assert(arg[pos] in {'-','0'..'9'})
var isNegative = false
var pos = pos
if arg[pos] == '-':
isNegative = true
pos += 1
result = Zero
while pos < arg.len and arg[pos] in '0'..'9':
result = result * Ten
result.inc(uint32(arg[pos]) - uint32('0'))
pos += 1
if isNegative:
result = -result
# fluff
proc `<`*(a: Int128, b: BiggestInt): bool =
cmp(a,toInt128(b)) < 0
proc `<`*(a: BiggestInt, b: Int128): bool =
cmp(toInt128(a), b) < 0
proc `<=`*(a: Int128, b: BiggestInt): bool =
cmp(a,toInt128(b)) <= 0
proc `<=`*(a: BiggestInt, b: Int128): bool =
cmp(toInt128(a), b) <= 0
proc `==`*(a: Int128, b: BiggestInt): bool =
a == toInt128(b)
proc `==`*(a: BiggestInt, b: Int128): bool =
toInt128(a) == b
proc `-`*(a: BiggestInt, b: Int128): Int128 =
toInt128(a) - b
proc `-`*(a: Int128, b: BiggestInt): Int128 =
a - toInt128(b)
proc `+`*(a: BiggestInt, b: Int128): Int128 =
toInt128(a) + b
proc `+`*(a: Int128, b: BiggestInt): Int128 =
a + toInt128(b)
proc toFloat64*(arg: Int128): float64 =
let isNegative = isNegative(arg)
let arg = abs(arg)
let a = float64(bitconcat(arg.udata[1], arg.udata[0]))
let b = float64(bitconcat(arg.udata[3], arg.udata[2]))
result = a + 18446744073709551616'f64 * b # a + 2^64 * b
if isNegative:
result = -result
proc ldexp(x: float64, exp: cint): float64 {.importc: "ldexp", header: "<math.h>".}
template bitor(a,b,c: Int128): Int128 = bitor(bitor(a,b), c)
proc toInt128*(arg: float64): Int128 =
let isNegative = arg < 0
let v0 = ldexp(abs(arg), -100)
let w0 = uint64(trunc(v0))
let v1 = ldexp(v0 - float64(w0), 50)
let w1 = uint64(trunc(v1))
let v2 = ldexp(v1 - float64(w1), 50)
let w2 = uint64(trunc(v2))
let res = bitor(toInt128(w0) shl 100, toInt128(w1) shl 50, toInt128(w2))
if isNegative:
return -res
else:
return res
proc maskUInt64*(arg: Int128): Int128 {.noinit, inline.} =
result.udata[0] = arg.udata[0]
result.udata[1] = arg.udata[1]
result.udata[2] = 0
result.udata[3] = 0
proc maskUInt32*(arg: Int128): Int128 {.noinit, inline.} =
result.udata[0] = arg.udata[0]
result.udata[1] = 0
result.udata[2] = 0
result.udata[3] = 0
proc maskUInt16*(arg: Int128): Int128 {.noinit, inline.} =
result.udata[0] = arg.udata[0] and 0xffff
result.udata[1] = 0
result.udata[2] = 0
result.udata[3] = 0
proc maskUInt8*(arg: Int128): Int128 {.noinit, inline.} =
result.udata[0] = arg.udata[0] and 0xff
result.udata[1] = 0
result.udata[2] = 0
result.udata[3] = 0
proc maskBytes*(arg: Int128, numbytes: int): Int128 {.noinit.} =
case numbytes
of 1:
return maskUInt8(arg)
of 2:
return maskUInt16(arg)
of 4:
return maskUInt32(arg)
of 8:
return maskUInt64(arg)
else:
assert(false, "masking only implemented for 1, 2, 4 and 8 bytes")
when isMainModule:
let (a,b) = divMod(Ten,Ten)
doAssert $One == "1"
doAssert $Ten == "10"
doAssert $Zero == "0"
let c = parseDecimalInt128("12345678989876543210123456789")
doAssert $c == "12345678989876543210123456789"
var d : array[39, Int128]
d[0] = parseDecimalInt128("1")
d[1] = parseDecimalInt128("10")
d[2] = parseDecimalInt128("100")
d[3] = parseDecimalInt128("1000")
d[4] = parseDecimalInt128("10000")
d[5] = parseDecimalInt128("100000")
d[6] = parseDecimalInt128("1000000")
d[7] = parseDecimalInt128("10000000")
d[8] = parseDecimalInt128("100000000")
d[9] = parseDecimalInt128("1000000000")
d[10] = parseDecimalInt128("10000000000")
d[11] = parseDecimalInt128("100000000000")
d[12] = parseDecimalInt128("1000000000000")
d[13] = parseDecimalInt128("10000000000000")
d[14] = parseDecimalInt128("100000000000000")
d[15] = parseDecimalInt128("1000000000000000")
d[16] = parseDecimalInt128("10000000000000000")
d[17] = parseDecimalInt128("100000000000000000")
d[18] = parseDecimalInt128("1000000000000000000")
d[19] = parseDecimalInt128("10000000000000000000")
d[20] = parseDecimalInt128("100000000000000000000")
d[21] = parseDecimalInt128("1000000000000000000000")
d[22] = parseDecimalInt128("10000000000000000000000")
d[23] = parseDecimalInt128("100000000000000000000000")
d[24] = parseDecimalInt128("1000000000000000000000000")
d[25] = parseDecimalInt128("10000000000000000000000000")
d[26] = parseDecimalInt128("100000000000000000000000000")
d[27] = parseDecimalInt128("1000000000000000000000000000")
d[28] = parseDecimalInt128("10000000000000000000000000000")
d[29] = parseDecimalInt128("100000000000000000000000000000")
d[30] = parseDecimalInt128("1000000000000000000000000000000")
d[31] = parseDecimalInt128("10000000000000000000000000000000")
d[32] = parseDecimalInt128("100000000000000000000000000000000")
d[33] = parseDecimalInt128("1000000000000000000000000000000000")
d[34] = parseDecimalInt128("10000000000000000000000000000000000")
d[35] = parseDecimalInt128("100000000000000000000000000000000000")
d[36] = parseDecimalInt128("1000000000000000000000000000000000000")
d[37] = parseDecimalInt128("10000000000000000000000000000000000000")
d[38] = parseDecimalInt128("100000000000000000000000000000000000000")
for i in 0..<d.len:
for j in 0..<d.len:
doAssert(cmp(d[i], d[j]) == cmp(i,j))
if i + j < d.len:
doAssert d[i] * d[j] == d[i+j]
if i - j >= 0:
doAssert d[i] div d[j] == d[i-j]
var sum: Int128
for it in d:
sum += it
doAssert $sum == "111111111111111111111111111111111111111"
for it in d.mitems:
it = -it
for i in 0..<d.len:
for j in 0..<d.len:
doAssert(cmp(d[i], d[j]) == -cmp(i,j))
if i + j < d.len:
doAssert d[i] * d[j] == -d[i+j]
if i - j >= 0:
doAssert d[i] div d[j] == -d[i-j]
doAssert $high(Int128) == "170141183460469231731687303715884105727"
doAssert $low(Int128) == "-170141183460469231731687303715884105728"
var ma = 100'i64
var mb = 13
doAssert toInt128(ma) * toInt128(0) == toInt128(0)
doAssert toInt128(-ma) * toInt128(0) == toInt128(0)
# sign correctness
doAssert divMod(toInt128( ma),toInt128( mb)) == (toInt128( ma div mb), toInt128( ma mod mb))
doAssert divMod(toInt128(-ma),toInt128( mb)) == (toInt128(-ma div mb), toInt128(-ma mod mb))
doAssert divMod(toInt128( ma),toInt128(-mb)) == (toInt128( ma div -mb), toInt128( ma mod -mb))
doAssert divMod(toInt128(-ma),toInt128(-mb)) == (toInt128(-ma div -mb), toInt128(-ma mod -mb))
doAssert divMod(toInt128( mb),toInt128( mb)) == (toInt128( mb div mb), toInt128( mb mod mb))
doAssert divMod(toInt128(-mb),toInt128( mb)) == (toInt128(-mb div mb), toInt128(-mb mod mb))
doAssert divMod(toInt128( mb),toInt128(-mb)) == (toInt128( mb div -mb), toInt128( mb mod -mb))
doAssert divMod(toInt128(-mb),toInt128(-mb)) == (toInt128(-mb div -mb), toInt128(-mb mod -mb))
doAssert divMod(toInt128( mb),toInt128( ma)) == (toInt128( mb div ma), toInt128( mb mod ma))
doAssert divMod(toInt128(-mb),toInt128( ma)) == (toInt128(-mb div ma), toInt128(-mb mod ma))
doAssert divMod(toInt128( mb),toInt128(-ma)) == (toInt128( mb div -ma), toInt128( mb mod -ma))
doAssert divMod(toInt128(-mb),toInt128(-ma)) == (toInt128(-mb div -ma), toInt128(-mb mod -ma))
let e = parseDecimalInt128("70997106675279150998592376708984375")
let strArray = [
# toHex(e shr 0), toHex(e shr 1), toHex(e shr 2), toHex(e shr 3)
"000dac6d782d266a37300c32591eee37", "0006d636bc1693351b9806192c8f771b", "00036b1b5e0b499a8dcc030c9647bb8d", "0001b58daf05a4cd46e601864b23ddc6",
"0000dac6d782d266a37300c32591eee3", "00006d636bc1693351b9806192c8f771", "000036b1b5e0b499a8dcc030c9647bb8", "00001b58daf05a4cd46e601864b23ddc",
"00000dac6d782d266a37300c32591eee", "000006d636bc1693351b9806192c8f77", "0000036b1b5e0b499a8dcc030c9647bb", "000001b58daf05a4cd46e601864b23dd",
"000000dac6d782d266a37300c32591ee", "0000006d636bc1693351b9806192c8f7", "00000036b1b5e0b499a8dcc030c9647b", "0000001b58daf05a4cd46e601864b23d",
"0000000dac6d782d266a37300c32591e", "00000006d636bc1693351b9806192c8f", "000000036b1b5e0b499a8dcc030c9647", "00000001b58daf05a4cd46e601864b23",
"00000000dac6d782d266a37300c32591", "000000006d636bc1693351b9806192c8", "0000000036b1b5e0b499a8dcc030c964", "000000001b58daf05a4cd46e601864b2",
"000000000dac6d782d266a37300c3259", "0000000006d636bc1693351b9806192c", "00000000036b1b5e0b499a8dcc030c96", "0000000001b58daf05a4cd46e601864b",
"0000000000dac6d782d266a37300c325", "00000000006d636bc1693351b9806192", "000000000036b1b5e0b499a8dcc030c9", "00000000001b58daf05a4cd46e601864",
"00000000000dac6d782d266a37300c32", "000000000006d636bc1693351b980619", "0000000000036b1b5e0b499a8dcc030c", "000000000001b58daf05a4cd46e60186",
"000000000000dac6d782d266a37300c3", "0000000000006d636bc1693351b98061", "00000000000036b1b5e0b499a8dcc030", "0000000000001b58daf05a4cd46e6018",
"0000000000000dac6d782d266a37300c", "00000000000006d636bc1693351b9806", "000000000000036b1b5e0b499a8dcc03", "00000000000001b58daf05a4cd46e601",
"00000000000000dac6d782d266a37300", "000000000000006d636bc1693351b980", "0000000000000036b1b5e0b499a8dcc0", "000000000000001b58daf05a4cd46e60",
"000000000000000dac6d782d266a3730", "0000000000000006d636bc1693351b98", "00000000000000036b1b5e0b499a8dcc", "0000000000000001b58daf05a4cd46e6",
"0000000000000000dac6d782d266a373", "00000000000000006d636bc1693351b9", "000000000000000036b1b5e0b499a8dc", "00000000000000001b58daf05a4cd46e",
"00000000000000000dac6d782d266a37", "000000000000000006d636bc1693351b", "0000000000000000036b1b5e0b499a8d", "000000000000000001b58daf05a4cd46",
"000000000000000000dac6d782d266a3", "0000000000000000006d636bc1693351", "00000000000000000036b1b5e0b499a8", "0000000000000000001b58daf05a4cd4",
"0000000000000000000dac6d782d266a", "00000000000000000006d636bc169335", "000000000000000000036b1b5e0b499a", "00000000000000000001b58daf05a4cd",
"00000000000000000000dac6d782d266", "000000000000000000006d636bc16933", "0000000000000000000036b1b5e0b499", "000000000000000000001b58daf05a4c",
"000000000000000000000dac6d782d26", "0000000000000000000006d636bc1693", "00000000000000000000036b1b5e0b49", "0000000000000000000001b58daf05a4",
"0000000000000000000000dac6d782d2", "00000000000000000000006d636bc169", "000000000000000000000036b1b5e0b4", "00000000000000000000001b58daf05a",
"00000000000000000000000dac6d782d", "000000000000000000000006d636bc16", "0000000000000000000000036b1b5e0b", "000000000000000000000001b58daf05",
"000000000000000000000000dac6d782", "0000000000000000000000006d636bc1", "00000000000000000000000036b1b5e0", "0000000000000000000000001b58daf0",
"0000000000000000000000000dac6d78", "00000000000000000000000006d636bc", "000000000000000000000000036b1b5e", "00000000000000000000000001b58daf",
"00000000000000000000000000dac6d7", "000000000000000000000000006d636b", "0000000000000000000000000036b1b5", "000000000000000000000000001b58da",
"000000000000000000000000000dac6d", "0000000000000000000000000006d636", "00000000000000000000000000036b1b", "0000000000000000000000000001b58d",
"0000000000000000000000000000dac6", "00000000000000000000000000006d63", "000000000000000000000000000036b1", "00000000000000000000000000001b58",
"00000000000000000000000000000dac", "000000000000000000000000000006d6", "0000000000000000000000000000036b", "000000000000000000000000000001b5",
"000000000000000000000000000000da", "0000000000000000000000000000006d", "00000000000000000000000000000036", "0000000000000000000000000000001b",
"0000000000000000000000000000000d", "00000000000000000000000000000006", "00000000000000000000000000000003", "00000000000000000000000000000001",
"00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000",
"00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000",
"00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000",
]
for i in 0 ..< 128:
let str1 = toHex(e shr i)
let str2 = strArray[i]
doAssert str1 == str2
let strArray2 = [
"000dac6d782d266a37300c32591eee37", "001b58daf05a4cd46e601864b23ddc6e", "0036b1b5e0b499a8dcc030c9647bb8dc", "006d636bc1693351b9806192c8f771b8",
"00dac6d782d266a37300c32591eee370", "01b58daf05a4cd46e601864b23ddc6e0", "036b1b5e0b499a8dcc030c9647bb8dc0", "06d636bc1693351b9806192c8f771b80",
"0dac6d782d266a37300c32591eee3700", "1b58daf05a4cd46e601864b23ddc6e00", "36b1b5e0b499a8dcc030c9647bb8dc00", "6d636bc1693351b9806192c8f771b800",
"dac6d782d266a37300c32591eee37000", "b58daf05a4cd46e601864b23ddc6e000", "6b1b5e0b499a8dcc030c9647bb8dc000", "d636bc1693351b9806192c8f771b8000",
"ac6d782d266a37300c32591eee370000", "58daf05a4cd46e601864b23ddc6e0000", "b1b5e0b499a8dcc030c9647bb8dc0000", "636bc1693351b9806192c8f771b80000",
"c6d782d266a37300c32591eee3700000", "8daf05a4cd46e601864b23ddc6e00000", "1b5e0b499a8dcc030c9647bb8dc00000", "36bc1693351b9806192c8f771b800000",
"6d782d266a37300c32591eee37000000", "daf05a4cd46e601864b23ddc6e000000", "b5e0b499a8dcc030c9647bb8dc000000", "6bc1693351b9806192c8f771b8000000",
"d782d266a37300c32591eee370000000", "af05a4cd46e601864b23ddc6e0000000", "5e0b499a8dcc030c9647bb8dc0000000", "bc1693351b9806192c8f771b80000000",
"782d266a37300c32591eee3700000000", "f05a4cd46e601864b23ddc6e00000000", "e0b499a8dcc030c9647bb8dc00000000", "c1693351b9806192c8f771b800000000",
"82d266a37300c32591eee37000000000", "05a4cd46e601864b23ddc6e000000000", "0b499a8dcc030c9647bb8dc000000000", "1693351b9806192c8f771b8000000000",
"2d266a37300c32591eee370000000000", "5a4cd46e601864b23ddc6e0000000000", "b499a8dcc030c9647bb8dc0000000000", "693351b9806192c8f771b80000000000",
"d266a37300c32591eee3700000000000", "a4cd46e601864b23ddc6e00000000000", "499a8dcc030c9647bb8dc00000000000", "93351b9806192c8f771b800000000000",
"266a37300c32591eee37000000000000", "4cd46e601864b23ddc6e000000000000", "99a8dcc030c9647bb8dc000000000000", "3351b9806192c8f771b8000000000000",
"66a37300c32591eee370000000000000", "cd46e601864b23ddc6e0000000000000", "9a8dcc030c9647bb8dc0000000000000", "351b9806192c8f771b80000000000000",
"6a37300c32591eee3700000000000000", "d46e601864b23ddc6e00000000000000", "a8dcc030c9647bb8dc00000000000000", "51b9806192c8f771b800000000000000",
"a37300c32591eee37000000000000000", "46e601864b23ddc6e000000000000000", "8dcc030c9647bb8dc000000000000000", "1b9806192c8f771b8000000000000000",
"37300c32591eee370000000000000000", "6e601864b23ddc6e0000000000000000", "dcc030c9647bb8dc0000000000000000", "b9806192c8f771b80000000000000000",
"7300c32591eee3700000000000000000", "e601864b23ddc6e00000000000000000", "cc030c9647bb8dc00000000000000000", "9806192c8f771b800000000000000000",
"300c32591eee37000000000000000000", "601864b23ddc6e000000000000000000", "c030c9647bb8dc000000000000000000", "806192c8f771b8000000000000000000",
"00c32591eee370000000000000000000", "01864b23ddc6e0000000000000000000", "030c9647bb8dc0000000000000000000", "06192c8f771b80000000000000000000",
"0c32591eee3700000000000000000000", "1864b23ddc6e00000000000000000000", "30c9647bb8dc00000000000000000000", "6192c8f771b800000000000000000000",
"c32591eee37000000000000000000000", "864b23ddc6e000000000000000000000", "0c9647bb8dc000000000000000000000", "192c8f771b8000000000000000000000",
"32591eee370000000000000000000000", "64b23ddc6e0000000000000000000000", "c9647bb8dc0000000000000000000000", "92c8f771b80000000000000000000000",
"2591eee3700000000000000000000000", "4b23ddc6e00000000000000000000000", "9647bb8dc00000000000000000000000", "2c8f771b800000000000000000000000",
"591eee37000000000000000000000000", "b23ddc6e000000000000000000000000", "647bb8dc000000000000000000000000", "c8f771b8000000000000000000000000",
"91eee370000000000000000000000000", "23ddc6e0000000000000000000000000", "47bb8dc0000000000000000000000000", "8f771b80000000000000000000000000",
"1eee3700000000000000000000000000", "3ddc6e00000000000000000000000000", "7bb8dc00000000000000000000000000", "f771b800000000000000000000000000",
"eee37000000000000000000000000000", "ddc6e000000000000000000000000000", "bb8dc000000000000000000000000000", "771b8000000000000000000000000000",
"ee370000000000000000000000000000", "dc6e0000000000000000000000000000", "b8dc0000000000000000000000000000", "71b80000000000000000000000000000",
"e3700000000000000000000000000000", "c6e00000000000000000000000000000", "8dc00000000000000000000000000000", "1b800000000000000000000000000000",
"37000000000000000000000000000000", "6e000000000000000000000000000000", "dc000000000000000000000000000000", "b8000000000000000000000000000000",
"70000000000000000000000000000000", "e0000000000000000000000000000000", "c0000000000000000000000000000000", "80000000000000000000000000000000",
]
for i in 0 ..< 128:
let str1 = toHex(e shl i)
let str2 = strArray2[i]
doAssert str1 == str2

File diff suppressed because it is too large Load Diff

View File

@@ -7,28 +7,30 @@
# distribution, for details about the copyright.
#
# included from jsgen.nim
## Type info generation for the JS backend.
proc rope(arg: Int128): Rope = rope($arg)
proc genTypeInfo(p: PProc, typ: PType): Rope
proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope =
var
s, u: Rope
length: int
field: PSym
b: PNode
result = nil
case n.kind
of nkRecList:
length = sonsLen(n)
if length == 1:
result = genObjectFields(p, typ, n.sons[0])
if n.len == 1:
result = genObjectFields(p, typ, n[0])
else:
s = nil
for i in countup(0, length - 1):
if i > 0: add(s, ", \L")
add(s, genObjectFields(p, typ, n.sons[i]))
for i in 0..<n.len:
if i > 0: s.add(", \L")
s.add(genObjectFields(p, typ, n[i]))
result = ("{kind: 2, len: $1, offset: 0, " &
"typ: null, name: null, sons: [$2]}") % [rope(length), s]
"typ: null, name: null, sons: [$2]}") % [rope(n.len), s]
of nkSym:
field = n.sym
s = genTypeInfo(p, field.typ)
@@ -37,29 +39,28 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope =
[mangleName(p.module, field), s,
makeJSString(field.name.s)]
of nkRecCase:
length = sonsLen(n)
if (n.sons[0].kind != nkSym): internalError(p.config, n.info, "genObjectFields")
field = n.sons[0].sym
if (n[0].kind != nkSym): internalError(p.config, n.info, "genObjectFields")
field = n[0].sym
s = genTypeInfo(p, field.typ)
for i in countup(1, length - 1):
b = n.sons[i] # branch
for i in 1..<n.len:
b = n[i] # branch
u = nil
case b.kind
of nkOfBranch:
if sonsLen(b) < 2:
if b.len < 2:
internalError(p.config, b.info, "genObjectFields; nkOfBranch broken")
for j in countup(0, sonsLen(b) - 2):
if u != nil: add(u, ", ")
if b.sons[j].kind == nkRange:
addf(u, "[$1, $2]", [rope(getOrdValue(b.sons[j].sons[0])),
rope(getOrdValue(b.sons[j].sons[1]))])
for j in 0..<b.len - 1:
if u != nil: u.add(", ")
if b[j].kind == nkRange:
u.addf("[$1, $2]", [rope(getOrdValue(b[j][0])),
rope(getOrdValue(b[j][1]))])
else:
add(u, rope(getOrdValue(b.sons[j])))
u.add(rope(getOrdValue(b[j])))
of nkElse:
u = rope(lengthOrd(p.config, field.typ))
else: internalError(p.config, n.info, "genObjectFields(nkRecCase)")
if result != nil: add(result, ", \L")
addf(result, "[setConstr($1), $2]",
if result != nil: result.add(", \L")
result.addf("[setConstr($1), $2]",
[u, genObjectFields(p, typ, lastSon(b))])
result = ("{kind: 3, offset: \"$1\", len: $3, " &
"typ: $2, name: $4, sons: [$5]}") % [
@@ -68,27 +69,27 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope =
else: internalError(p.config, n.info, "genObjectFields")
proc objHasTypeField(t: PType): bool {.inline.} =
tfInheritable in t.flags or t.sons[0] != nil
tfInheritable in t.flags or t[0] != nil
proc genObjectInfo(p: PProc, typ: PType, name: Rope) =
let kind = if objHasTypeField(typ): tyObject else: tyTuple
var s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n") % [name, rope(ord(kind))]
prepend(p.g.typeInfo, s)
addf(p.g.typeInfo, "var NNI$1 = $2;$n",
p.g.typeInfo.addf("var NNI$1 = $2;$n",
[rope(typ.id), genObjectFields(p, typ, typ.n)])
addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)])
if (typ.kind == tyObject) and (typ.sons[0] != nil):
addf(p.g.typeInfo, "$1.base = $2;$n",
[name, genTypeInfo(p, typ.sons[0].skipTypes(skipPtrs))])
p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)])
if (typ.kind == tyObject) and (typ[0] != nil):
p.g.typeInfo.addf("$1.base = $2;$n",
[name, genTypeInfo(p, typ[0].skipTypes(skipPtrs))])
proc genTupleFields(p: PProc, typ: PType): Rope =
var s: Rope = nil
for i in 0 ..< typ.len:
if i > 0: add(s, ", \L")
for i in 0..<typ.len:
if i > 0: s.add(", \L")
s.addf("{kind: 1, offset: \"Field$1\", len: 0, " &
"typ: $2, name: \"Field$1\", sons: null}",
[i.rope, genTypeInfo(p, typ.sons[i])])
[i.rope, genTypeInfo(p, typ[i])])
result = ("{kind: 2, len: $1, offset: 0, " &
"typ: null, name: null, sons: [$2]}") % [rope(typ.len), s]
@@ -96,38 +97,37 @@ proc genTupleInfo(p: PProc, typ: PType, name: Rope) =
var s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n") % [name, rope(ord(typ.kind))]
prepend(p.g.typeInfo, s)
addf(p.g.typeInfo, "var NNI$1 = $2;$n",
p.g.typeInfo.addf("var NNI$1 = $2;$n",
[rope(typ.id), genTupleFields(p, typ)])
addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)])
p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)])
proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
let length = sonsLen(typ.n)
var s: Rope = nil
for i in countup(0, length - 1):
if (typ.n.sons[i].kind != nkSym): internalError(p.config, typ.n.info, "genEnumInfo")
let field = typ.n.sons[i].sym
if i > 0: add(s, ", \L")
for i in 0..<typ.n.len:
if (typ.n[i].kind != nkSym): internalError(p.config, typ.n.info, "genEnumInfo")
let field = typ.n[i].sym
if i > 0: s.add(", \L")
let extName = if field.ast == nil: field.name.s else: field.ast.strVal
addf(s, "\"$1\": {kind: 1, offset: $1, typ: $2, name: $3, len: 0, sons: null}",
s.addf("\"$1\": {kind: 1, offset: $1, typ: $2, name: $3, len: 0, sons: null}",
[rope(field.position), name, makeJSString(extName)])
var n = ("var NNI$1 = {kind: 2, offset: 0, typ: null, " &
"name: null, len: $2, sons: {$3}};$n") % [rope(typ.id), rope(length), s]
"name: null, len: $2, sons: {$3}};$n") % [rope(typ.id), rope(typ.n.len), s]
s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n") % [name, rope(ord(typ.kind))]
prepend(p.g.typeInfo, s)
add(p.g.typeInfo, n)
addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)])
if typ.sons[0] != nil:
addf(p.g.typeInfo, "$1.base = $2;$n",
[name, genTypeInfo(p, typ.sons[0])])
p.g.typeInfo.add(n)
p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)])
if typ[0] != nil:
p.g.typeInfo.addf("$1.base = $2;$n",
[name, genTypeInfo(p, typ[0])])
proc genTypeInfo(p: PProc, typ: PType): Rope =
let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink})
let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink, tyOwned})
result = "NTI$1" % [rope(t.id)]
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
case t.kind
of tyDistinct:
result = genTypeInfo(p, t.sons[0])
result = genTypeInfo(p, t[0])
of tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64:
var s =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
@@ -138,15 +138,15 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
[result, rope(ord(t.kind))]
prepend(p.g.typeInfo, s)
addf(p.g.typeInfo, "$1.base = $2;$n",
p.g.typeInfo.addf("$1.base = $2;$n",
[result, genTypeInfo(p, t.lastSon)])
of tyArray:
var s =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
[result, rope(ord(t.kind))]
prepend(p.g.typeInfo, s)
addf(p.g.typeInfo, "$1.base = $2;$n",
[result, genTypeInfo(p, t.sons[1])])
p.g.typeInfo.addf("$1.base = $2;$n",
[result, genTypeInfo(p, t[1])])
of tyEnum: genEnumInfo(p, t, result)
of tyObject: genObjectInfo(p, t, result)
of tyTuple: genTupleInfo(p, t, result)

View File

@@ -10,8 +10,9 @@
# This file implements lambda lifting for the transformator.
import
intsets, strutils, options, ast, astalgo, trees, treetab, msgs,
idents, renderer, types, magicsys, lowerings, tables, modulegraphs, lineinfos
intsets, strutils, options, ast, astalgo, msgs,
idents, renderer, types, magicsys, lowerings, tables, modulegraphs, lineinfos,
transf, liftdestructors
discard """
The basic approach is that captured vars need to be put on the heap and
@@ -127,8 +128,8 @@ proc newCall(a: PSym, b: PNode): PNode =
proc createClosureIterStateType*(g: ModuleGraph; iter: PSym): PType =
var n = newNodeI(nkRange, iter.info)
addSon(n, newIntNode(nkIntLit, -1))
addSon(n, newIntNode(nkIntLit, 0))
n.add newIntNode(nkIntLit, -1)
n.add newIntNode(nkIntLit, 0)
result = newType(tyRange, iter)
result.n = n
var intType = nilOrSysInt(g)
@@ -147,27 +148,27 @@ proc createEnvObj(g: ModuleGraph; owner: PSym; info: TLineInfo): PType =
proc getClosureIterResult*(g: ModuleGraph; iter: PSym): PSym =
if resultPos < iter.ast.len:
result = iter.ast.sons[resultPos].sym
result = iter.ast[resultPos].sym
else:
# XXX a bit hacky:
result = newSym(skResult, getIdent(g.cache, ":result"), iter, iter.info, {})
result.typ = iter.typ.sons[0]
result.typ = iter.typ[0]
incl(result.flags, sfUsed)
iter.ast.add newSymNode(result)
proc addHiddenParam(routine: PSym, param: PSym) =
assert param.kind == skParam
var params = routine.ast.sons[paramsPos]
var params = routine.ast[paramsPos]
# -1 is correct here as param.position is 0 based but we have at position 0
# some nkEffect node:
param.position = routine.typ.n.len-1
addSon(params, newSymNode(param))
params.add newSymNode(param)
#incl(routine.typ.flags, tfCapturesEnv)
assert sfFromGeneric in param.flags
#echo "produced environment: ", param.id, " for ", routine.id
proc getHiddenParam(g: ModuleGraph; routine: PSym): PSym =
let params = routine.ast.sons[paramsPos]
let params = routine.ast[paramsPos]
let hidden = lastSon(params)
if hidden.kind == nkSym and hidden.sym.kind == skParam and hidden.sym.name.s == paramName:
result = hidden.sym
@@ -178,7 +179,7 @@ proc getHiddenParam(g: ModuleGraph; routine: PSym): PSym =
result = routine
proc getEnvParam*(routine: PSym): PSym =
let params = routine.ast.sons[paramsPos]
let params = routine.ast[paramsPos]
let hidden = lastSon(params)
if hidden.kind == nkSym and hidden.sym.name.s == paramName:
result = hidden.sym
@@ -205,8 +206,8 @@ proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode =
# which is however the only case when we generate an assignment in the first
# place.
result = newNodeI(nkAsgn, info, 2)
result.sons[0] = le
result.sons[1] = ri
result[0] = le
result[1] = ri
proc makeClosure*(g: ModuleGraph; prc: PSym; env: PNode; info: TLineInfo): PNode =
result = newNodeIT(nkClosure, info, prc.typ)
@@ -217,6 +218,10 @@ proc makeClosure*(g: ModuleGraph; prc: PSym; env: PNode; info: TLineInfo): PNode
if env.skipConv.kind == nkClosure:
localError(g.config, info, "internal error: taking closure of closure")
result.add(env)
#if isClosureIterator(result.typ):
createTypeBoundOps(g, nil, result.typ, info)
if tfHasAsgn in result.typ.flags or optSeqDestructors in g.config.globalOptions:
prc.flags.incl sfInjectDestructors
proc interestingIterVar(s: PSym): bool {.inline.} =
# XXX optimization: Only lift the variable if it lives across
@@ -232,6 +237,12 @@ proc liftingHarmful(conf: ConfigRef; owner: PSym): bool {.inline.} =
let isCompileTime = sfCompileTime in owner.flags or owner.kind == skMacro
result = conf.cmd == cmdCompileToJS and not isCompileTime
proc createTypeBoundOpsLL(g: ModuleGraph; refType: PType; info: TLineInfo; owner: PSym) =
createTypeBoundOps(g, nil, refType.lastSon, info)
createTypeBoundOps(g, nil, refType, info)
if tfHasAsgn in refType.flags or optSeqDestructors in g.config.globalOptions:
owner.flags.incl sfInjectDestructors
proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
if liftingHarmful(g.config, owner): return n
@@ -244,7 +255,7 @@ proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
var env: PNode
if owner.isIterator:
let it = getHiddenParam(g, owner)
addUniqueField(it.typ.sons[0], hp, g.cache)
addUniqueField(it.typ.skipTypes({tyOwned})[0], hp, g.cache)
env = indirectAccess(newSymNode(it), hp, hp.info)
else:
let e = newSym(skLet, iter.name, owner, n.info)
@@ -256,11 +267,12 @@ proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
result.add(v)
# add 'new' statement:
result.add newCall(getSysSym(g, n.info, "internalNew"), env)
createTypeBoundOpsLL(g, env.typ, n.info, owner)
result.add makeClosure(g, iter, env, n.info)
proc freshVarForClosureIter*(g: ModuleGraph; s, owner: PSym): PNode =
let envParam = getHiddenParam(g, owner)
let obj = envParam.typ.lastSon
let obj = envParam.typ.skipTypes({tyOwned, tyRef, tyPtr})
addField(obj, s, g.cache)
var access = newSymNode(envParam)
@@ -277,8 +289,9 @@ proc freshVarForClosureIter*(g: ModuleGraph; s, owner: PSym): PNode =
proc markAsClosure(g: ModuleGraph; owner: PSym; n: PNode) =
let s = n.sym
if illegalCapture(s):
localError(g.config, n.info, "illegal capture '$1' of type <$2> which is declared here: $3" %
[s.name.s, typeToString(s.typ), g.config$s.info])
localError(g.config, n.info,
("'$1' is of type <$2> which cannot be captured as it would violate memory" &
" safety, declared here: $3") % [s.name.s, typeToString(s.typ), g.config$s.info])
elif owner.typ.callConv notin {ccClosure, ccDefault}:
localError(g.config, n.info, "illegal capture '$1' because '$2' has the calling convention: <$3>" %
[s.name.s, owner.name.s, CallingConvToStr[owner.typ.callConv]])
@@ -318,21 +331,51 @@ proc getEnvTypeForOwner(c: var DetectionPass; owner: PSym;
rawAddSon(result, obj)
c.ownerToType[owner.id] = result
proc asOwnedRef(c: DetectionPass; t: PType): PType =
if optOwnedRefs in c.graph.config.globalOptions:
assert t.kind == tyRef
result = newType(tyOwned, t.owner)
result.flags.incl tfHasOwned
result.rawAddSon t
else:
result = t
proc getEnvTypeForOwnerUp(c: var DetectionPass; owner: PSym;
info: TLineInfo): PType =
var r = c.getEnvTypeForOwner(owner, info)
result = newType(tyPtr, owner)
rawAddSon(result, r.skipTypes({tyOwned, tyRef, tyPtr}))
proc createUpField(c: var DetectionPass; dest, dep: PSym; info: TLineInfo) =
let refObj = c.getEnvTypeForOwner(dest, info) # getHiddenParam(dest).typ
let obj = refObj.lastSon
let fieldType = c.getEnvTypeForOwner(dep, info) #getHiddenParam(dep).typ
let obj = refObj.skipTypes({tyOwned, tyRef, tyPtr})
# The assumption here is that gcDestructors means we cannot deal
# with cycles properly, so it's better to produce a weak ref (=ptr) here.
# This seems to be generally correct but since it's a bit risky it's disabled
# for now.
# XXX This is wrong for the 'hamming' test, so remove this logic again.
let fieldType = if isDefined(c.graph.config, "nimCycleBreaker"):
c.getEnvTypeForOwnerUp(dep, info) #getHiddenParam(dep).typ
else:
c.getEnvTypeForOwner(dep, info)
if refObj == fieldType:
localError(c.graph.config, dep.info, "internal error: invalid up reference computed")
let upIdent = getIdent(c.graph.cache, upName)
let upField = lookupInRecord(obj.n, upIdent)
if upField != nil:
if upField.typ != fieldType:
if upField.typ.skipTypes({tyOwned, tyRef, tyPtr}) != fieldType.skipTypes({tyOwned, tyRef, tyPtr}):
localError(c.graph.config, dep.info, "internal error: up references do not agree")
when false:
if c.graph.config.selectedGC == gcDestructors and sfCursor notin upField.flags:
localError(c.graph.config, dep.info, "internal error: up reference is not a .cursor")
else:
let result = newSym(skField, upIdent, obj.owner, obj.owner.info)
result.typ = fieldType
when false:
if c.graph.config.selectedGC == gcDestructors:
result.flags.incl sfCursor
rawAddField(obj, result)
discard """
@@ -389,7 +432,8 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
if innerProc:
if s.isIterator: c.somethingToDo = true
if not c.processed.containsOrIncl(s.id):
detectCapturedVars(s.getBody, s, c)
let body = transformBody(c.graph, s, cache = true)
detectCapturedVars(body, s, c)
let ow = s.skipGenericOwner
if ow == owner:
if owner.isIterator:
@@ -397,18 +441,15 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
addClosureParam(c, owner, n.info)
if interestingIterVar(s):
if not c.capturedVars.containsOrIncl(s.id):
let obj = getHiddenParam(c.graph, owner).typ.lastSon
#let obj = c.getEnvTypeForOwner(s.owner).lastSon
let obj = getHiddenParam(c.graph, owner).typ.skipTypes({tyOwned, tyRef, tyPtr})
#let obj = c.getEnvTypeForOwner(s.owner).skipTypes({tyOwned, tyRef, tyPtr})
if s.name.id == getIdent(c.graph.cache, ":state").id:
obj.n[0].sym.id = -s.id
else:
addField(obj, s, c.graph.cache)
# but always return because the rest of the proc is only relevant when
# ow != owner:
return
# direct or indirect dependency:
if (innerProc and s.typ.callConv == ccClosure) or interestingVar(s):
elif (innerProc and s.typ.callConv == ccClosure) or interestingVar(s):
discard """
proc outer() =
var x: int
@@ -426,8 +467,8 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
#echo "capturing ", n.info
# variable 's' is actually captured:
if interestingVar(s) and not c.capturedVars.containsOrIncl(s.id):
let obj = c.getEnvTypeForOwner(ow, n.info).lastSon
#getHiddenParam(owner).typ.lastSon
let obj = c.getEnvTypeForOwner(ow, n.info).skipTypes({tyOwned, tyRef, tyPtr})
#getHiddenParam(owner).typ.skipTypes({tyOwned, tyRef, tyPtr})
addField(obj, s, c.graph.cache)
# create required upFields:
var w = owner.skipGenericOwner
@@ -451,17 +492,14 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
createUpField(c, w, up, n.info)
w = up
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit,
nkTemplateDef, nkTypeSection:
nkTemplateDef, nkTypeSection, nkProcDef, nkMethodDef,
nkConverterDef, nkMacroDef, nkFuncDef, nkCommentStmt, nkTypeOfExpr:
discard
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef:
discard
of nkLambdaKinds, nkIteratorDef, nkFuncDef:
of nkLambdaKinds, nkIteratorDef:
if n.typ != nil:
detectCapturedVars(n[namePos], owner, c)
of nkReturnStmt:
if n[0].kind in {nkAsgn, nkFastAsgn}:
detectCapturedVars(n[0].sons[1], owner, c)
else: assert n[0].kind == nkEmpty
detectCapturedVars(n[0], owner, c)
else:
for i in 0..<n.len:
detectCapturedVars(n[i], owner, c)
@@ -471,6 +509,7 @@ type
processed: IntSet
envVars: Table[int, PNode]
inContainer: int
unownedEnvVars: Table[int, PNode] # only required for --newruntime
proc initLiftingPass(fn: PSym): LiftingPass =
result.processed = initIntSet()
@@ -484,7 +523,7 @@ proc accessViaEnvParam(g: ModuleGraph; n: PNode; owner: PSym): PNode =
if not envParam.isNil:
var access = newSymNode(envParam)
while true:
let obj = access.typ.sons[0]
let obj = access.typ[0]
assert obj.kind == tyObject
let field = getFieldFromObj(obj, s)
if field != nil:
@@ -495,56 +534,75 @@ proc accessViaEnvParam(g: ModuleGraph; n: PNode; owner: PSym): PNode =
localError(g.config, n.info, "internal error: environment misses: " & s.name.s)
result = n
proc newEnvVar(cache: IdentCache; owner: PSym; typ: PType): PNode =
var v = newSym(skVar, getIdent(cache, envName), owner, owner.info)
incl(v.flags, sfShadowed)
proc newEnvVar(cache: IdentCache; owner: PSym; typ: PType; info: TLineInfo): PNode =
var v = newSym(skVar, getIdent(cache, envName), owner, info)
v.flags = {sfShadowed, sfGeneratedOp}
v.typ = typ
result = newSymNode(v)
when false:
if owner.kind == skIterator and owner.typ.callConv == ccClosure:
let it = getHiddenParam(owner)
addUniqueField(it.typ.sons[0], v)
addUniqueField(it.typ[0], v)
result = indirectAccess(newSymNode(it), v, v.info)
else:
result = newSymNode(v)
proc setupEnvVar(owner: PSym; d: DetectionPass;
c: var LiftingPass): PNode =
c: var LiftingPass; info: TLineInfo): PNode =
if owner.isIterator:
return getHiddenParam(d.graph, owner).newSymNode
result = c.envvars.getOrDefault(owner.id)
result = c.envVars.getOrDefault(owner.id)
if result.isNil:
let envVarType = d.ownerToType.getOrDefault(owner.id)
if envVarType.isNil:
localError d.graph.config, owner.info, "internal error: could not determine closure type"
result = newEnvVar(d.graph.cache, owner, envVarType)
result = newEnvVar(d.graph.cache, owner, asOwnedRef(d, envVarType), info)
c.envVars[owner.id] = result
if optOwnedRefs in d.graph.config.globalOptions:
var v = newSym(skVar, getIdent(d.graph.cache, envName & "Alt"), owner, info)
v.flags = {sfShadowed, sfGeneratedOp}
v.typ = envVarType
c.unownedEnvVars[owner.id] = newSymNode(v)
proc getUpViaParam(g: ModuleGraph; owner: PSym): PNode =
let p = getHiddenParam(g, owner)
result = p.newSymNode
if owner.isIterator:
let upField = lookupInRecord(p.typ.lastSon.n, getIdent(g.cache, upName))
let upField = lookupInRecord(p.typ.skipTypes({tyOwned, tyRef, tyPtr}).n, getIdent(g.cache, upName))
if upField == nil:
localError(g.config, owner.info, "could not find up reference for closure iter")
else:
result = rawIndirectAccess(result, upField, p.info)
proc rawClosureCreation(owner: PSym;
d: DetectionPass; c: var LiftingPass): PNode =
d: DetectionPass; c: var LiftingPass;
info: TLineInfo): PNode =
result = newNodeI(nkStmtList, owner.info)
var env: PNode
if owner.isIterator:
env = getHiddenParam(d.graph, owner).newSymNode
else:
env = setupEnvVar(owner, d, c)
env = setupEnvVar(owner, d, c, info)
if env.kind == nkSym:
var v = newNodeI(nkVarSection, env.info)
addVar(v, env)
result.add(v)
if optOwnedRefs in d.graph.config.globalOptions:
let unowned = c.unownedEnvVars[owner.id]
assert unowned != nil
addVar(v, unowned)
# add 'new' statement:
result.add(newCall(getSysSym(d.graph, env.info, "internalNew"), env))
if optOwnedRefs in d.graph.config.globalOptions:
let unowned = c.unownedEnvVars[owner.id]
assert unowned != nil
let env2 = copyTree(env)
env2.typ = unowned.typ
result.add newAsgnStmt(unowned, env2, env.info)
createTypeBoundOpsLL(d.graph, unowned.typ, env.info, owner)
# add assignment statements for captured parameters:
for i in 1..<owner.typ.n.len:
let local = owner.typ.n[i].sym
@@ -552,11 +610,14 @@ proc rawClosureCreation(owner: PSym;
let fieldAccess = indirectAccess(env, local, env.info)
# add ``env.param = param``
result.add(newAsgnStmt(fieldAccess, newSymNode(local), env.info))
createTypeBoundOps(d.graph, nil, fieldAccess.typ, env.info)
if tfHasAsgn in fieldAccess.typ.flags or optSeqDestructors in d.graph.config.globalOptions:
owner.flags.incl sfInjectDestructors
let upField = lookupInRecord(env.typ.lastSon.n, getIdent(d.graph.cache, upName))
let upField = lookupInRecord(env.typ.skipTypes({tyOwned, tyRef, tyPtr}).n, getIdent(d.graph.cache, upName))
if upField != nil:
let up = getUpViaParam(d.graph, owner)
if up != nil and upField.typ == up.typ:
if up != nil and upField.typ.skipTypes({tyOwned, tyRef, tyPtr}) == up.typ.skipTypes({tyOwned, tyRef, tyPtr}):
result.add(newAsgnStmt(rawIndirectAccess(env, upField, env.info),
up, env.info))
#elif oldenv != nil and oldenv.typ == upField.typ:
@@ -564,6 +625,18 @@ proc rawClosureCreation(owner: PSym;
# oldenv, env.info))
else:
localError(d.graph.config, env.info, "internal error: cannot create up reference")
# we are not in the sem'check phase anymore! so pass 'nil' for the PContext
# and hope for the best:
createTypeBoundOpsLL(d.graph, env.typ, owner.info, owner)
proc finishClosureCreation(owner: PSym; d: DetectionPass; c: LiftingPass;
info: TLineInfo; res: PNode) =
if optOwnedRefs in d.graph.config.globalOptions:
let unowned = c.unownedEnvVars[owner.id]
assert unowned != nil
let nilLit = newNodeIT(nkNilLit, info, unowned.typ)
res.add newAsgnStmt(unowned, nilLit, info)
createTypeBoundOpsLL(d.graph, unowned.typ, info, owner)
proc closureCreationForIter(iter: PNode;
d: DetectionPass; c: var LiftingPass): PNode =
@@ -571,11 +644,11 @@ proc closureCreationForIter(iter: PNode;
let owner = iter.sym.skipGenericOwner
var v = newSym(skVar, getIdent(d.graph.cache, envName), owner, iter.info)
incl(v.flags, sfShadowed)
v.typ = getHiddenParam(d.graph, iter.sym).typ
v.typ = asOwnedRef(d, getHiddenParam(d.graph, iter.sym).typ)
var vnode: PNode
if owner.isIterator:
let it = getHiddenParam(d.graph, owner)
addUniqueField(it.typ.sons[0], v, d.graph.cache)
addUniqueField(it.typ.skipTypes({tyOwned, tyRef, tyPtr}), v, d.graph.cache)
vnode = indirectAccess(newSymNode(it), v, v.info)
else:
vnode = v.newSymNode
@@ -583,11 +656,12 @@ proc closureCreationForIter(iter: PNode;
addVar(vs, vnode)
result.add(vs)
result.add(newCall(getSysSym(d.graph, iter.info, "internalNew"), vnode))
createTypeBoundOpsLL(d.graph, vnode.typ, iter.info, owner)
let upField = lookupInRecord(v.typ.lastSon.n, getIdent(d.graph.cache, upName))
let upField = lookupInRecord(v.typ.skipTypes({tyOwned, tyRef, tyPtr}).n, getIdent(d.graph.cache, upName))
if upField != nil:
let u = setupEnvVar(owner, d, c)
if u.typ == upField.typ:
let u = setupEnvVar(owner, d, c, iter.info)
if u.typ.skipTypes({tyOwned, tyRef, tyPtr}) == upField.typ.skipTypes({tyOwned, tyRef, tyPtr}):
result.add(newAsgnStmt(rawIndirectAccess(vnode, upField, iter.info),
u, iter.info))
else:
@@ -596,8 +670,10 @@ proc closureCreationForIter(iter: PNode;
proc accessViaEnvVar(n: PNode; owner: PSym; d: DetectionPass;
c: var LiftingPass): PNode =
let access = setupEnvVar(owner, d, c)
let obj = access.typ.sons[0]
var access = setupEnvVar(owner, d, c, n.info)
if optOwnedRefs in d.graph.config.globalOptions:
access = c.unownedEnvVars[owner.id]
let obj = access.typ.skipTypes({tyOwned, tyRef, tyPtr})
let field = getFieldFromObj(obj, n.sym)
if field != nil:
result = rawIndirectAccess(access, field, n.info)
@@ -606,7 +682,7 @@ proc accessViaEnvVar(n: PNode; owner: PSym; d: DetectionPass;
result = n
proc getStateField*(g: ModuleGraph; owner: PSym): PSym =
getHiddenParam(g, owner).typ.sons[0].n.sons[0].sym
getHiddenParam(g, owner).typ.skipTypes({tyOwned, tyRef, tyPtr}).n[0].sym
proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
c: var LiftingPass): PNode
@@ -622,7 +698,7 @@ proc symToClosure(n: PNode; owner: PSym; d: DetectionPass;
result = closureCreationForIter(n, d, c)
elif s.skipGenericOwner == owner:
# direct dependency, so use the outer's env variable:
result = makeClosure(d.graph, s, setupEnvVar(owner, d, c), n.info)
result = makeClosure(d.graph, s, setupEnvVar(owner, d, c, n.info), n.info)
else:
let available = getHiddenParam(d.graph, owner)
let wanted = getHiddenParam(d.graph, s).typ
@@ -631,7 +707,7 @@ proc symToClosure(n: PNode; owner: PSym; d: DetectionPass;
while true:
if access.typ == wanted:
return makeClosure(d.graph, s, access, n.info)
let obj = access.typ.sons[0]
let obj = access.typ.skipTypes({tyOwned, tyRef, tyPtr})
let upField = lookupInRecord(obj.n, getIdent(d.graph.cache, upName))
if upField == nil:
localError(d.graph.config, n.info, "internal error: no environment found")
@@ -650,14 +726,18 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
# echo renderTree(s.getBody, {renderIds})
let oldInContainer = c.inContainer
c.inContainer = 0
var body = liftCapturedVars(s.getBody, s, d, c)
if c.envvars.getOrDefault(s.id).isNil:
s.ast.sons[bodyPos] = body
var body = transformBody(d.graph, s, cache = false)
body = liftCapturedVars(body, s, d, c)
if c.envVars.getOrDefault(s.id).isNil:
s.transformedBody = body
else:
s.ast.sons[bodyPos] = newTree(nkStmtList, rawClosureCreation(s, d, c), body)
s.transformedBody = newTree(nkStmtList, rawClosureCreation(s, d, c, n.info), body)
finishClosureCreation(s, d, c, n.info, s.transformedBody)
c.inContainer = oldInContainer
if s.typ.callConv == ccClosure:
result = symToClosure(n, owner, d, c)
elif s.id in d.capturedVars:
if s.owner != owner:
result = accessViaEnvParam(d.graph, n, owner)
@@ -666,20 +746,19 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
else:
result = accessViaEnvVar(n, owner, d, c)
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, nkComesFrom,
nkTemplateDef, nkTypeSection:
discard
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef:
nkTemplateDef, nkTypeSection, nkProcDef, nkMethodDef, nkConverterDef,
nkMacroDef, nkFuncDef:
discard
of nkClosure:
if n[1].kind == nkNilLit:
n.sons[0] = liftCapturedVars(n[0], owner, d, c)
let x = n.sons[0].skipConv
n[0] = liftCapturedVars(n[0], owner, d, c)
let x = n[0].skipConv
if x.kind == nkClosure:
#localError(n.info, "internal error: closure to closure created")
# now we know better, so patch it:
n.sons[0] = x.sons[0]
n.sons[1] = x.sons[1]
of nkLambdaKinds, nkIteratorDef, nkFuncDef:
n[0] = x[0]
n[1] = x[1]
of nkLambdaKinds, nkIteratorDef:
if n.typ != nil and n[namePos].kind == nkSym:
let oldInContainer = c.inContainer
c.inContainer = 0
@@ -689,44 +768,65 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
c.inContainer = oldInContainer
of nkHiddenStdConv:
if n.len == 2:
n.sons[1] = liftCapturedVars(n[1], owner, d, c)
n[1] = liftCapturedVars(n[1], owner, d, c)
if n[1].kind == nkClosure: result = n[1]
of nkReturnStmt:
if n[0].kind in {nkAsgn, nkFastAsgn}:
# we have a `result = result` expression produced by the closure
# transform, let's not touch the LHS in order to make the lifting pass
# correct when `result` is lifted
n[0].sons[1] = liftCapturedVars(n[0].sons[1], owner, d, c)
else: assert n[0].kind == nkEmpty
n[0][1] = liftCapturedVars(n[0][1], owner, d, c)
else:
n[0] = liftCapturedVars(n[0], owner, d, c)
of nkTypeOfExpr:
result = n
else:
if owner.isIterator:
if nfLL in n.flags:
# special case 'when nimVm' due to bug #3636:
n.sons[1] = liftCapturedVars(n[1], owner, d, c)
n[1] = liftCapturedVars(n[1], owner, d, c)
return
let inContainer = n.kind in {nkObjConstr, nkBracket}
if inContainer: inc c.inContainer
for i in 0..<n.len:
n.sons[i] = liftCapturedVars(n[i], owner, d, c)
n[i] = liftCapturedVars(n[i], owner, d, c)
if inContainer: dec c.inContainer
# ------------------ old stuff -------------------------------------------
proc semCaptureSym*(s, owner: PSym) =
discard """
proc outer() =
var x: int
proc inner() =
proc innerInner() =
echo x
innerInner()
inner()
# inner() takes a closure too!
"""
proc propagateClosure(start, last: PSym) =
var o = start
while o != nil and o.kind != skModule:
if o == last: break
o.typ.callConv = ccClosure
o = o.skipGenericOwner
if interestingVar(s) and s.kind != skResult:
if owner.typ != nil and not isGenericRoutine(owner):
# XXX: is this really safe?
# if we capture a var from another generic routine,
# it won't be consider captured.
var o = owner.skipGenericOwner
while o.kind != skModule and o != nil:
while o != nil and o.kind != skModule:
if s.owner == o:
if owner.typ.callConv in {ccClosure, ccDefault} or owner.kind == skIterator:
owner.typ.callConv = ccClosure
propagateClosure(owner.skipGenericOwner, s.owner)
else:
discard "do not produce an error here, but later"
#echo "computing .closure for ", owner.name.s, " ", owner.info, " because of ", s.name.s
#echo "computing .closure for ", owner.name.s, " because of ", s.name.s
o = o.skipGenericOwner
# since the analysis is not entirely correct, we don't set 'tfCapturesEnv'
# here
@@ -737,12 +837,12 @@ proc liftIterToProc*(g: ModuleGraph; fn: PSym; body: PNode; ptrType: PType): PNo
# pretend 'fn' is a closure iterator for the analysis:
let oldKind = fn.kind
let oldCC = fn.typ.callConv
fn.kind = skIterator
fn.transitionRoutineSymKind(skIterator)
fn.typ.callConv = ccClosure
d.ownerToType[fn.id] = ptrType
detectCapturedVars(body, fn, d)
result = liftCapturedVars(body, fn, d, c)
fn.kind = oldKind
fn.transitionRoutineSymKind(oldKind)
fn.typ.callConv = oldCC
proc liftLambdas*(g: ModuleGraph; fn: PSym, body: PNode; tooEarly: var bool): PNode =
@@ -769,8 +869,9 @@ proc liftLambdas*(g: ModuleGraph; fn: PSym, body: PNode; tooEarly: var bool): PN
var c = initLiftingPass(fn)
result = liftCapturedVars(body, fn, d, c)
# echo renderTree(result, {renderIds})
if c.envvars.getOrDefault(fn.id) != nil:
result = newTree(nkStmtList, rawClosureCreation(fn, d, c), result)
if c.envVars.getOrDefault(fn.id) != nil:
result = newTree(nkStmtList, rawClosureCreation(fn, d, c, body.info), result)
finishClosureCreation(fn, d, c, body.info, result)
else:
result = body
#if fn.name.s == "get2":
@@ -813,11 +914,10 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
...
"""
if liftingHarmful(g.config, owner): return body
var L = body.len
if not (body.kind == nkForStmt and body[L-2].kind in nkCallKinds):
if not (body.kind == nkForStmt and body[^2].kind in nkCallKinds):
localError(g.config, body.info, "ignored invalid for loop")
return body
var call = body[L-2]
var call = body[^2]
result = newNodeI(nkStmtList, body.info)
@@ -838,37 +938,39 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
result.add(v)
# add 'new' statement:
result.add(newCall(getSysSym(g, env.info, "internalNew"), env.newSymNode))
createTypeBoundOpsLL(g, env.typ, body.info, owner)
elif op.kind == nkStmtListExpr:
let closure = op.lastSon
if closure.kind == nkClosure:
call.sons[0] = closure
for i in 0 .. op.len-2:
call[0] = closure
for i in 0..<op.len-1:
result.add op[i]
var loopBody = newNodeI(nkStmtList, body.info, 3)
var whileLoop = newNodeI(nkWhileStmt, body.info, 2)
whileLoop.sons[0] = newIntTypeNode(nkIntLit, 1, getSysType(g, body.info, tyBool))
whileLoop.sons[1] = loopBody
whileLoop[0] = newIntTypeNode(1, getSysType(g, body.info, tyBool))
whileLoop[1] = loopBody
result.add whileLoop
# setup loopBody:
# gather vars in a tuple:
var v2 = newNodeI(nkLetSection, body.info)
var vpart = newNodeI(if L == 3: nkIdentDefs else: nkVarTuple, body.info)
for i in 0 .. L-3:
var vpart = newNodeI(if body.len == 3: nkIdentDefs else: nkVarTuple, body.info)
for i in 0..<body.len-2:
if body[i].kind == nkSym:
body[i].sym.kind = skLet
addSon(vpart, body[i])
body[i].sym.transitionToLet()
vpart.add body[i]
addSon(vpart, newNodeI(nkEmpty, body.info)) # no explicit type
vpart.add newNodeI(nkEmpty, body.info) # no explicit type
if not env.isNil:
call.sons[0] = makeClosure(g, call.sons[0].sym, env.newSymNode, body.info)
addSon(vpart, call)
addSon(v2, vpart)
call[0] = makeClosure(g, call[0].sym, env.newSymNode, body.info)
vpart.add call
v2.add vpart
loopBody.sons[0] = v2
loopBody[0] = v2
var bs = newNodeI(nkBreakState, body.info)
bs.addSon(call.sons[0])
bs.add call[0]
let ibs = newNodeI(nkIfStmt, body.info)
let elifBranch = newNodeI(nkElifBranch, body.info)
@@ -880,5 +982,5 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
elifBranch.add(br)
ibs.add(elifBranch)
loopBody.sons[1] = ibs
loopBody.sons[2] = body[L-1]
loopBody[1] = ibs
loopBody[2] = body[^1]

View File

@@ -9,13 +9,10 @@
## Layouter for nimpretty.
import idents, lexer, lineinfos, llstream, options, msgs, strutils,
pathutils
from os import changeFileExt
import idents, lexer, lineinfos, llstream, options, msgs, strutils, pathutils
const
MaxLineLen = 80
LineCommentColumn = 30
MinLineLen = 15
type
SplitKind = enum
@@ -24,41 +21,86 @@ type
SemicolonKind = enum
detectSemicolonKind, useSemicolon, dontTouch
LayoutToken* = enum
ltSpaces,
ltCrucialNewline, ## a semantically crucial newline (indentation!)
ltSplittingNewline, ## newline used for splitting up long
## expressions (like after a comma or a binary operator)
ltTab,
ltOptionalNewline, ## optional newline introduced by nimpretty
ltComment, ltLit, ltKeyword, ltExportMarker, ltIdent,
ltOther, ltOpr, ltSomeParLe, ltSomeParRi,
ltBeginSection, ltEndSection
Emitter* = object
config: ConfigRef
fid: FileIndex
lastTok: TTokType
inquote: bool
inquote, lastTokWasTerse: bool
semicolons: SemicolonKind
col, lastLineNumber, lineSpan, indentLevel, indWidth: int
nested: int
col, lastLineNumber, lineSpan, indentLevel, indWidth*, inSection: int
keepIndents*: int
doIndentMore*: int
content: string
kinds*: seq[LayoutToken]
tokens*: seq[string]
indentStack: seq[int]
fixedUntil: int # marks where we must not go in the content
altSplitPos: array[SplitKind, int] # alternative split positions
maxLineLen*: int
proc openEmitter*(em: var Emitter, cache: IdentCache;
config: ConfigRef, fileIdx: FileIndex) =
let fullPath = Absolutefile config.toFullPath(fileIdx)
em.indWidth = getIndentWidth(fileIdx, llStreamOpen(fullPath, fmRead),
cache, config)
if em.indWidth == 0: em.indWidth = 2
let fullPath = AbsoluteFile config.toFullPath(fileIdx)
if em.indWidth == 0:
em.indWidth = getIndentWidth(fileIdx, llStreamOpen(fullPath, fmRead),
cache, config)
if em.indWidth == 0: em.indWidth = 2
em.config = config
em.fid = fileIdx
em.lastTok = tkInvalid
em.inquote = false
em.col = 0
em.content = newStringOfCap(16_000)
em.indentStack = newSeqOfCap[int](30)
em.indentStack.add 0
em.lastLineNumber = 1
proc closeEmitter*(em: var Emitter) =
var f = llStreamOpen(em.config.outFile, fmWrite)
if f == nil:
rawMessage(em.config, errGenerated, "cannot open file: " & em.config.outFile.string)
f.llStreamWrite em.content
llStreamClose(f)
proc computeMax(em: Emitter; pos: int): int =
var p = pos
var extraSpace = 0
result = 0
while p < em.tokens.len and em.kinds[p] != ltEndSection:
var lhs = 0
var lineLen = 0
var foundTab = false
while p < em.tokens.len and em.kinds[p] != ltEndSection:
if em.kinds[p] in {ltCrucialNewline, ltSplittingNewline}:
if foundTab and lineLen <= em.maxLineLen:
result = max(result, lhs + extraSpace)
inc p
break
if em.kinds[p] == ltTab:
extraSpace = if em.kinds[p-1] == ltSpaces: 0 else: 1
foundTab = true
else:
if not foundTab:
inc lhs, em.tokens[p].len
inc lineLen, em.tokens[p].len
inc p
proc computeRhs(em: Emitter; pos: int): int =
var p = pos
result = 0
while p < em.tokens.len and em.kinds[p] notin {ltCrucialNewline, ltSplittingNewline}:
inc result, em.tokens[p].len
inc p
proc isLongEnough(lineLen, startPos, endPos: int): bool =
result = lineLen > MinLineLen and endPos > startPos + 4
proc findNewline(em: Emitter; p, lineLen: var int) =
while p < em.tokens.len and em.kinds[p] notin {ltCrucialNewline, ltSplittingNewline}:
inc lineLen, em.tokens[p].len
inc p
proc countNewlines(s: string): int =
result = 0
@@ -72,78 +114,348 @@ proc calcCol(em: var Emitter; s: string) =
dec i
inc em.col
template wr(x) =
em.content.add x
inc em.col, x.len
proc optionalIsGood(em: var Emitter; pos, currentLen: int): bool =
let ourIndent = em.tokens[pos].len
var p = pos+1
var lineLen = 0
em.findNewline(p, lineLen)
if p == pos+1: # optionalNewline followed by another newline
result = false
elif em.kinds[p-1] == ltComment and currentLen+lineLen < em.maxLineLen+MinLineLen:
result = false
elif p+1 < em.tokens.len and em.kinds[p+1] == ltSpaces and
em.kinds[p-1] == ltOptionalNewline:
if em.tokens[p+1].len == ourIndent:
# concatenate lines with the same indententation
var nlPos = p
var lineLenTotal = lineLen
inc p
em.findNewline(p, lineLenTotal)
if isLongEnough(lineLenTotal, nlPos, p):
em.kinds[nlPos] = ltOptionalNewline
if em.kinds[nlPos+1] == ltSpaces:
# inhibit extra spaces when concatenating two lines
em.tokens[nlPos+1] = if em.tokens[nlPos-2] == ",": " " else: ""
result = true
elif em.tokens[p+1].len < ourIndent:
result = isLongEnough(lineLen, pos, p)
elif em.kinds[pos+1] in {ltOther, ltSomeParLe, ltSomeParRi}: # note: pos+1, not p+1
result = false
else:
result = isLongEnough(lineLen, pos, p)
proc lenOfNextTokens(em: Emitter; pos: int): int =
result = 0
for i in 1..<em.tokens.len-pos:
if em.kinds[pos+i] in {ltCrucialNewline, ltSplittingNewline, ltOptionalNewline}: break
inc result, em.tokens[pos+i].len
proc guidingInd(em: Emitter; pos: int): int =
var i = pos - 1
while i >= 0 and em.kinds[i] != ltSomeParLe:
dec i
while i+1 <= em.kinds.high and em.kinds[i] != ltSomeParRi:
if em.kinds[i] == ltSplittingNewline and em.kinds[i+1] == ltSpaces:
return em.tokens[i+1].len
inc i
result = -1
proc renderTokens*(em: var Emitter): string =
## Render Emitter tokens to a string of code
template defaultCase() =
content.add em.tokens[i]
inc lineLen, em.tokens[i].len
var content = newStringOfCap(16_000)
var maxLhs = 0
var lineLen = 0
var lineBegin = 0
var openPars = 0
var i = 0
while i <= em.tokens.high:
when defined(debug):
echo (token: em.tokens[i], kind: em.kinds[i])
case em.kinds[i]
of ltBeginSection:
maxLhs = computeMax(em, lineBegin)
of ltEndSection:
maxLhs = 0
lineBegin = i+1
of ltTab:
if i >= 2 and em.kinds[i-2] in {ltCrucialNewline, ltSplittingNewline} and
em.kinds[i-1] in {ltCrucialNewline, ltSplittingNewline, ltSpaces}:
# a previous section has ended
maxLhs = 0
if maxLhs == 0:
if em.kinds[i-1] != ltSpaces:
content.add em.tokens[i]
inc lineLen, em.tokens[i].len
else:
# pick the shorter indentation token:
var spaces = maxLhs - lineLen
if spaces < em.tokens[i].len or computeRhs(em, i+1)+maxLhs <= em.maxLineLen+MinLineLen:
if spaces <= 0 and content[^1] notin {' ', '\L'}: spaces = 1
for j in 1..spaces: content.add ' '
inc lineLen, spaces
else:
content.add em.tokens[i]
inc lineLen, em.tokens[i].len
of ltCrucialNewline, ltSplittingNewline:
content.add em.tokens[i]
lineLen = 0
lineBegin = i+1
of ltOptionalNewline:
let totalLineLen = lineLen + lenOfNextTokens(em, i)
if totalLineLen > em.maxLineLen and optionalIsGood(em, i, lineLen):
if i-1 >= 0 and em.kinds[i-1] == ltSpaces:
let spaces = em.tokens[i-1].len
content.setLen(content.len - spaces)
content.add "\L"
let guide = if openPars > 0: guidingInd(em, i) else: -1
if guide >= 0:
content.add repeat(' ', guide)
lineLen = guide
else:
content.add em.tokens[i]
lineLen = em.tokens[i].len
lineBegin = i+1
if i+1 < em.kinds.len and em.kinds[i+1] == ltSpaces:
# inhibit extra spaces at the start of a new line
inc i
of ltLit:
let lineSpan = countNewlines(em.tokens[i])
if lineSpan > 0:
em.calcCol(em.tokens[i])
lineLen = em.col
else:
inc lineLen, em.tokens[i].len
content.add em.tokens[i]
of ltSomeParLe:
inc openPars
defaultCase()
of ltSomeParRi:
doAssert openPars > 0
dec openPars
defaultCase()
else:
defaultCase()
inc i
return content
proc writeOut*(em: Emitter, content: string) =
## Write to disk
let outFile = em.config.absOutFile
if fileExists(outFile) and readFile(outFile.string) == content:
discard "do nothing, see #9499"
return
var f = llStreamOpen(outFile, fmWrite)
if f == nil:
rawMessage(em.config, errGenerated, "cannot open file: " & outFile.string)
return
f.llStreamWrite content
llStreamClose(f)
proc closeEmitter*(em: var Emitter) =
## Renders emitter tokens and write to a file
let content = renderTokens(em)
em.writeOut(content)
proc wr(em: var Emitter; x: string; lt: LayoutToken) =
em.tokens.add x
em.kinds.add lt
inc em.col, x.len
assert em.tokens.len == em.kinds.len
proc wrNewline(em: var Emitter; kind = ltCrucialNewline) =
em.tokens.add "\L"
em.kinds.add kind
em.col = 0
proc newlineWasSplitting*(em: var Emitter) =
if em.kinds.len >= 3 and em.kinds[^3] == ltCrucialNewline:
em.kinds[^3] = ltSplittingNewline
#[
Splitting newlines can occur:
- after commas, semicolon, '[', '('.
- after binary operators, '='.
- after ':' type
We only need parser support for the "after type" case.
]#
proc wrSpaces(em: var Emitter; spaces: int) =
if spaces > 0:
wr(em, strutils.repeat(' ', spaces), ltSpaces)
proc wrSpace(em: var Emitter) =
wr(em, " ", ltSpaces)
proc wrTab(em: var Emitter) =
wr(em, " ", ltTab)
proc beginSection*(em: var Emitter) =
let pos = max(0, em.tokens.len-2)
em.tokens.insert "", pos
em.kinds.insert ltBeginSection, pos
inc em.inSection
#wr(em, "", ltBeginSection)
proc endSection*(em: var Emitter) =
em.tokens.insert "", em.tokens.len-2
em.kinds.insert ltEndSection, em.kinds.len-2
dec em.inSection
#wr(em, "", ltEndSection)
proc removeSpaces(em: var Emitter) =
while em.kinds.len > 0 and em.kinds[^1] == ltSpaces:
let tokenLen = em.tokens[^1].len
setLen(em.tokens, em.tokens.len-1)
setLen(em.kinds, em.kinds.len-1)
dec em.col, tokenLen
template goodCol(col): bool = col in 40..MaxLineLen
const
openPars = {tkParLe, tkParDotLe,
tkBracketLe, tkBracketLeColon, tkCurlyDotLe,
tkCurlyLe}
splitters = openPars + {tkComma, tkSemicolon}
tkBracketLe, tkBracketDotLe, tkBracketLeColon,
tkCurlyDotLe, tkCurlyLe}
closedPars = {tkParRi, tkParDotRi,
tkBracketRi, tkBracketDotRi,
tkCurlyDotRi, tkCurlyRi}
splitters = openPars + {tkComma, tkSemiColon} # do not add 'tkColon' here!
oprSet = {tkOpr, tkDiv, tkMod, tkShl, tkShr, tkIn, tkNotin, tkIs,
tkIsnot, tkNot, tkOf, tkAs, tkDotDot, tkAnd, tkOr, tkXor}
template rememberSplit(kind) =
if goodCol(em.col):
em.altSplitPos[kind] = em.content.len
template goodCol(col): bool = col >= em.maxLineLen div 2
template moreIndent(em): int =
(if em.doIndentMore > 0: em.indWidth*2 else: em.indWidth)
if em.doIndentMore > 0: em.indWidth*2 else: em.indWidth
proc softLinebreak(em: var Emitter, lit: string) =
# XXX Use an algorithm that is outlined here:
# https://llvm.org/devmtg/2013-04/jasper-slides.pdf
# +2 because we blindly assume a comma or ' &' might follow
if not em.inquote and em.col+lit.len+2 >= MaxLineLen:
if em.lastTok in splitters:
while em.content.len > 0 and em.content[em.content.high] == ' ':
setLen(em.content, em.content.len-1)
wr("\L")
em.col = 0
for i in 1..em.indentLevel+moreIndent(em): wr(" ")
template rememberSplit(kind) =
if goodCol(em.col) and not em.inquote:
let spaces = em.indentLevel+moreIndent(em)
if spaces < em.col and spaces > 0:
wr(em, strutils.repeat(' ', spaces), ltOptionalNewline)
#em.altSplitPos[kind] = em.tokens.len
proc emitMultilineComment(em: var Emitter, lit: string, col: int; dontIndent: bool) =
# re-align every line in the multi-line comment:
var i = 0
var lastIndent = if em.keepIndents > 0: em.indentLevel else: em.indentStack[^1]
var b = 0
var dontIndent = dontIndent
var hasEmptyLine = false
for commentLine in splitLines(lit):
if i == 0 and (commentLine.endsWith("\\") or commentLine.endsWith("[")):
dontIndent = true
wr em, commentLine, ltComment
elif dontIndent:
if i > 0: wrNewline em
wr em, commentLine, ltComment
else:
# search backwards for a good split position:
for a in em.altSplitPos:
if a > em.fixedUntil:
var spaces = 0
while a+spaces < em.content.len and em.content[a+spaces] == ' ':
inc spaces
if spaces > 0: delete(em.content, a, a+spaces-1)
let ws = "\L" & repeat(' ',em.indentLevel+moreIndent(em))
em.col = em.content.len - a
em.content.insert(ws, a)
break
let stripped = commentLine.strip()
if i == 0:
if em.kinds.len > 0 and em.kinds[^1] != ltTab:
wr(em, "", ltTab)
elif stripped.len == 0:
wrNewline em
hasEmptyLine = true
else:
var a = 0
while a < commentLine.len and commentLine[a] == ' ': inc a
if a > lastIndent:
b += em.indWidth
lastIndent = a
elif a < lastIndent:
b -= em.indWidth
lastIndent = a
wrNewline em
if not hasEmptyLine or col + b < 15:
if col + b > 0:
wr(em, repeat(' ', col+b), ltTab)
else:
wr(em, "", ltTab)
else:
wr(em, repeat(' ', a), ltSpaces)
wr em, stripped, ltComment
inc i
proc lastChar(s: string): char =
result = if s.len > 0: s[s.high] else: '\0'
proc endsInWhite(em: Emitter): bool =
var i = em.tokens.len-1
while i >= 0 and em.kinds[i] in {ltBeginSection, ltEndSection}: dec(i)
result = if i >= 0: em.kinds[i] in {ltSpaces, ltCrucialNewline, ltSplittingNewline, ltTab} else: true
proc endsInNewline(em: Emitter): bool =
var i = em.tokens.len-1
while i >= 0 and em.kinds[i] in {ltBeginSection, ltEndSection, ltSpaces}: dec(i)
result = if i >= 0: em.kinds[i] in {ltCrucialNewline, ltSplittingNewline, ltTab} else: true
proc endsInAlpha(em: Emitter): bool =
var i = em.tokens.len-1
while i >= 0 and em.kinds[i] in {ltBeginSection, ltEndSection}: dec(i)
result = if i >= 0: em.tokens[i].lastChar in SymChars+{'_'} else: false
proc emitComment(em: var Emitter; tok: TToken; dontIndent: bool) =
var col = em.col
let lit = strip fileSection(em.config, em.fid, tok.commentOffsetA, tok.commentOffsetB)
em.lineSpan = countNewlines(lit)
if em.lineSpan > 0: calcCol(em, lit)
if em.lineSpan == 0:
if not endsInNewline(em):
wrTab em
wr em, lit, ltComment
else:
if not endsInWhite(em):
wrTab em
inc col
emitMultilineComment(em, lit, col, dontIndent)
proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
template wasExportMarker(em): bool =
em.kinds.len > 0 and em.kinds[^1] == ltExportMarker
template endsInWhite(em): bool =
em.content.len == 0 or em.content[em.content.high] in {' ', '\L'}
template endsInAlpha(em): bool =
em.content.len > 0 and em.content[em.content.high] in SymChars+{'_'}
proc emitComment(em: var Emitter; tok: TToken) =
let lit = strip fileSection(em.config, em.fid, tok.commentOffsetA, tok.commentOffsetB)
em.lineSpan = countNewlines(lit)
if em.lineSpan > 0: calcCol(em, lit)
if not endsInWhite(em):
wr(" ")
if em.lineSpan == 0 and max(em.col, LineCommentColumn) + lit.len <= MaxLineLen:
for i in 1 .. LineCommentColumn - em.col: wr(" ")
wr lit
if tok.tokType == tkComment and tok.literal.startsWith("#!nimpretty"):
case tok.literal
of "#!nimpretty off":
inc em.keepIndents
wrNewline em
em.lastLineNumber = tok.line + 1
of "#!nimpretty on":
dec em.keepIndents
em.lastLineNumber = tok.line
wrNewline em
wr em, tok.literal, ltComment
em.col = 0
em.lineSpan = 0
return
var preventComment = false
if tok.tokType == tkComment and tok.line == em.lastLineNumber and tok.indent >= 0:
if tok.tokType == tkComment and tok.line == em.lastLineNumber:
# we have an inline comment so handle it before the indentation token:
emitComment(em, tok)
emitComment(em, tok, dontIndent = (em.inSection == 0))
preventComment = true
em.fixedUntil = em.content.high
em.fixedUntil = em.tokens.high
elif tok.indent >= 0:
if em.lastTok in (splitters + oprSet):
var newlineKind = ltCrucialNewline
if em.keepIndents > 0:
em.indentLevel = tok.indent
elif (em.lastTok in (splitters + oprSet) and
tok.tokType notin (closedPars - {tkBracketDotRi})):
if tok.tokType in openPars and tok.indent > em.indentStack[^1]:
while em.indentStack[^1] < tok.indent:
em.indentStack.add(em.indentStack[^1] + em.indWidth)
# aka: we are in an expression context:
let alignment = max(tok.indent - em.indentStack[^1], 0)
em.indentLevel = alignment + em.indentStack.high * em.indWidth
newlineKind = ltSplittingNewline
else:
if tok.indent > em.indentStack[^1]:
em.indentStack.add tok.indent
@@ -162,114 +474,123 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
is not touched.
]#
# remove trailing whitespace:
while em.content.len > 0 and em.content[em.content.high] == ' ':
setLen(em.content, em.content.len-1)
wr("\L")
for i in 2..tok.line - em.lastLineNumber: wr("\L")
em.col = 0
for i in 1..em.indentLevel:
wr(" ")
em.fixedUntil = em.content.high
removeSpaces em
wrNewline em, newlineKind
for i in 2..tok.line - em.lastLineNumber: wrNewline(em)
wrSpaces em, em.indentLevel
em.fixedUntil = em.tokens.high
var lastTokWasTerse = false
case tok.tokType
of tokKeywordLow..tokKeywordHigh:
if endsInAlpha(em):
wr(" ")
wrSpace em
elif not em.inquote and not endsInWhite(em) and
em.lastTok notin openPars:
em.lastTok notin (openPars+{tkOpr, tkDotDot}) and not em.lastTokWasTerse:
#and tok.tokType in oprSet
wr(" ")
wrSpace em
if not em.inquote:
wr(TokTypeToStr[tok.tokType])
case tok.tokType
of tkAnd: rememberSplit(splitAnd)
of tkOr: rememberSplit(splitOr)
of tkIn, tkNotin:
wr(em, TokTypeToStr[tok.tokType], ltKeyword)
if tok.tokType in {tkAnd, tkOr, tkIn, tkNotin}:
rememberSplit(splitIn)
wr(" ")
else: discard
wrSpace em
else:
# keywords in backticks are not normalized:
wr(tok.ident.s)
wr(em, tok.ident.s, ltIdent)
of tkColon:
wr(TokTypeToStr[tok.tokType])
wr(" ")
of tkSemicolon, tkComma:
wr(TokTypeToStr[tok.tokType])
wr(em, TokTypeToStr[tok.tokType], ltOther)
wrSpace em
of tkSemiColon, tkComma:
wr(em, TokTypeToStr[tok.tokType], ltOther)
rememberSplit(splitComma)
wr(" ")
of tkParDotLe, tkParLe, tkBracketDotLe, tkBracketLe,
tkCurlyLe, tkCurlyDotLe, tkBracketLeColon:
if tok.strongSpaceA > 0 and not em.endsInWhite:
wr(" ")
wr(TokTypeToStr[tok.tokType])
wrSpace em
of openPars:
if tok.strongSpaceA > 0 and not em.endsInWhite and
(not em.wasExportMarker or tok.tokType == tkCurlyDotLe):
wrSpace em
wr(em, TokTypeToStr[tok.tokType], ltSomeParLe)
rememberSplit(splitParLe)
of tkParRi,
tkBracketRi, tkCurlyRi,
tkBracketDotRi,
tkCurlyDotRi,
tkParDotRi,
tkColonColon, tkDot:
wr(TokTypeToStr[tok.tokType])
of closedPars:
wr(em, TokTypeToStr[tok.tokType], ltSomeParRi)
of tkColonColon:
wr(em, TokTypeToStr[tok.tokType], ltOther)
of tkDot:
lastTokWasTerse = true
wr(em, TokTypeToStr[tok.tokType], ltOther)
of tkEquals:
if not em.inquote and not em.endsInWhite: wr(" ")
wr(TokTypeToStr[tok.tokType])
if not em.inquote: wr(" ")
if not em.inquote and not em.endsInWhite: wrSpace(em)
wr(em, TokTypeToStr[tok.tokType], ltOther)
if not em.inquote: wrSpace(em)
of tkOpr, tkDotDot:
if tok.strongSpaceA == 0 and tok.strongSpaceB == 0:
if em.inquote or ((tok.strongSpaceA == 0 and tok.strongSpaceB == 0) and
tok.ident.s notin ["<", ">", "<=", ">=", "==", "!="]):
# bug #9504: remember to not spacify a keyword:
lastTokWasTerse = true
# if not surrounded by whitespace, don't produce any whitespace either:
wr(tok.ident.s)
wr(em, tok.ident.s, ltOpr)
else:
if not em.endsInWhite: wr(" ")
wr(tok.ident.s)
if not em.endsInWhite: wrSpace(em)
wr(em, tok.ident.s, ltOpr)
template isUnary(tok): bool =
tok.strongSpaceB == 0 and tok.strongSpaceA > 0
if not isUnary(tok):
wr(" ")
rememberSplit(splitBinary)
wrSpace(em)
of tkAccent:
if not em.inquote and endsInAlpha(em): wr(" ")
wr(TokTypeToStr[tok.tokType])
if not em.inquote and endsInAlpha(em): wrSpace(em)
wr(em, TokTypeToStr[tok.tokType], ltOther)
em.inquote = not em.inquote
of tkComment:
if not preventComment:
emitComment(em, tok)
emitComment(em, tok, dontIndent = false)
of tkIntLit..tkStrLit, tkRStrLit, tkTripleStrLit, tkGStrLit, tkGTripleStrLit, tkCharLit:
let lit = fileSection(em.config, em.fid, tok.offsetA, tok.offsetB)
softLinebreak(em, lit)
if endsInAlpha(em) and tok.tokType notin {tkGStrLit, tkGTripleStrLit}: wr(" ")
if endsInAlpha(em) and tok.tokType notin {tkGStrLit, tkGTripleStrLit}: wrSpace(em)
em.lineSpan = countNewlines(lit)
if em.lineSpan > 0: calcCol(em, lit)
wr lit
wr em, lit, ltLit
of tkEof: discard
else:
let lit = if tok.ident != nil: tok.ident.s else: tok.literal
softLinebreak(em, lit)
if endsInAlpha(em): wr(" ")
wr lit
if endsInAlpha(em): wrSpace(em)
wr em, lit, ltIdent
em.lastTok = tok.tokType
em.lastTokWasTerse = lastTokWasTerse
em.lastLineNumber = tok.line + em.lineSpan
em.lineSpan = 0
proc endsWith(em: Emitter; k: varargs[string]): bool =
if em.tokens.len < k.len: return false
for i in 0..high(k):
if em.tokens[em.tokens.len - k.len + i] != k[i]: return false
return true
proc rfind(em: Emitter, t: string): int =
for i in 1..5:
if em.tokens[^i] == t:
return i
proc starWasExportMarker*(em: var Emitter) =
if em.content.endsWith(" * "):
setLen(em.content, em.content.len-3)
em.content.add("*")
if em.endsWith(" ", "*", " "):
setLen(em.tokens, em.tokens.len-3)
setLen(em.kinds, em.kinds.len-3)
em.tokens.add("*")
em.kinds.add ltExportMarker
dec em.col, 2
proc commaWasSemicolon*(em: var Emitter) =
if em.semicolons == detectSemicolonKind:
em.semicolons = if em.content.endsWith(", "): dontTouch else: useSemicolon
if em.semicolons == useSemicolon and em.content.endsWith(", "):
setLen(em.content, em.content.len-2)
em.content.add("; ")
em.semicolons = if em.rfind(";") > 0: useSemicolon else: dontTouch
if em.semicolons == useSemicolon:
let commaPos = em.rfind(",")
if commaPos > 0:
em.tokens[^commaPos] = ";"
proc curlyRiWasPragma*(em: var Emitter) =
if em.content.endsWith("}"):
setLen(em.content, em.content.len-1)
em.content.add(".}")
if em.endsWith("}"):
em.tokens[^1] = ".}"
inc em.col

View File

@@ -17,7 +17,7 @@
import
hashes, options, msgs, strutils, platform, idents, nimlexbase, llstream,
wordrecg, lineinfos, pathutils
wordrecg, lineinfos, pathutils, parseutils
const
MaxLineLength* = 80 # lines longer than this lead to a warning
@@ -134,7 +134,7 @@ type
TErrorHandler* = proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string)
TLexer* = object of TBaseLexer
fileIdx*: FileIndex
indentAhead*: int # if > 0 an indendation has already been read
indentAhead*: int # if > 0 an indentation has already been read
# this is needed because scanning comments
# needs so much look-ahead
currLineIndent*: int
@@ -146,10 +146,6 @@ type
previousToken: TLineInfo
config*: ConfigRef
when defined(nimpretty):
var
gIndentationWidth*: int
proc getLineInfo*(L: TLexer, tok: TToken): TLineInfo {.inline.} =
result = newLineInfo(L.fileIdx, tok.line, tok.col)
when defined(nimpretty):
@@ -173,7 +169,7 @@ proc isNimIdentifier*(s: string): bool =
inc(i)
result = true
proc tokToStr*(tok: TToken): string =
proc `$`*(tok: TToken): string =
case tok.tokType
of tkIntLit..tkInt64Lit: result = $tok.iNumber
of tkFloatLit..tkFloat64Lit: result = $tok.fNumber
@@ -188,11 +184,11 @@ proc tokToStr*(tok: TToken): string =
proc prettyTok*(tok: TToken): string =
if isKeyword(tok.tokType): result = "keyword " & tok.ident.s
else: result = tokToStr(tok)
else: result = $tok
proc printTok*(conf: ConfigRef; tok: TToken) =
msgWriteln(conf, $tok.line & ":" & $tok.col & "\t" &
TokTypeToStr[tok.tokType] & " " & tokToStr(tok))
TokTypeToStr[tok.tokType] & " " & $tok)
proc initToken*(L: var TToken) =
L.tokType = tkInvalid
@@ -223,8 +219,8 @@ proc fillToken(L: var TToken) =
proc openLexer*(lex: var TLexer, fileIdx: FileIndex, inputstream: PLLStream;
cache: IdentCache; config: ConfigRef) =
openBaseLexer(lex, inputstream)
lex.fileIdx = fileidx
lex.indentAhead = - 1
lex.fileIdx = fileIdx
lex.indentAhead = -1
lex.currLineIndent = 0
inc(lex.lineNumber, inputstream.lineOffset)
lex.cache = cache
@@ -307,55 +303,39 @@ template tokenEndPrevious(tok, pos) =
when defined(nimpretty):
tok.offsetB = L.offsetBase + pos
{.push overflowChecks: off.}
# We need to parse the largest uint literal without overflow checks
proc unsafeParseUInt(s: string, b: var BiggestInt, start = 0): int =
var i = start
if i < s.len and s[i] in {'0'..'9'}:
b = 0
while i < s.len and s[i] in {'0'..'9'}:
b = b * 10 + (ord(s[i]) - ord('0'))
inc(i)
while i < s.len and s[i] == '_': inc(i) # underscores are allowed and ignored
result = i - start
{.pop.} # overflowChecks
template eatChar(L: var TLexer, t: var TToken, replacementChar: char) =
add(t.literal, replacementChar)
t.literal.add(replacementChar)
inc(L.bufpos)
template eatChar(L: var TLexer, t: var TToken) =
add(t.literal, L.buf[L.bufpos])
t.literal.add(L.buf[L.bufpos])
inc(L.bufpos)
proc getNumber(L: var TLexer, result: var TToken) =
proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: set[char]): Natural =
var pos = L.bufpos # use registers for pos, buf
var buf = L.buf
result = 0
while true:
if buf[pos] in chars:
add(tok.literal, buf[pos])
if L.buf[pos] in chars:
tok.literal.add(L.buf[pos])
inc(pos)
inc(result)
else:
break
if buf[pos] == '_':
if buf[pos+1] notin chars:
if L.buf[pos] == '_':
if L.buf[pos+1] notin chars:
lexMessage(L, errGenerated,
"only single underscores may occur in a token and token may not " &
"end with an underscore: e.g. '1__1' and '1_' are invalid")
break
add(tok.literal, '_')
tok.literal.add('_')
inc(pos)
L.bufpos = pos
proc matchChars(L: var TLexer, tok: var TToken, chars: set[char]) =
var pos = L.bufpos # use registers for pos, buf
var buf = L.buf
while buf[pos] in chars:
add(tok.literal, buf[pos])
while L.buf[pos] in chars:
tok.literal.add(L.buf[pos])
inc(pos)
L.bufpos = pos
@@ -371,12 +351,12 @@ proc getNumber(L: var TLexer, result: var TToken) =
# We must verify +/- specifically so that we're not past the literal
if L.buf[L.bufpos] in {'+', '-'} and
L.buf[L.bufpos - 1] in {'e', 'E'}:
add(t.literal, L.buf[L.bufpos])
t.literal.add(L.buf[L.bufpos])
inc(L.bufpos)
matchChars(L, t, literalishChars)
if L.buf[L.bufpos] in {'\'', 'f', 'F', 'd', 'D', 'i', 'I', 'u', 'U'}:
inc(L.bufpos)
add(t.literal, L.buf[L.bufpos])
t.literal.add(L.buf[L.bufpos])
matchChars(L, t, {'0'..'9'})
L.bufpos = msgPos
lexMessage(L, msgKind, msg % t.literal)
@@ -395,7 +375,7 @@ proc getNumber(L: var TLexer, result: var TToken) =
result.literal = ""
result.base = base10
startpos = L.bufpos
tokenBegin(result, startPos)
tokenBegin(result, startpos)
# First stage: find out base, make verifications, build token literal string
# {'c', 'C'} is added for deprecation reasons to provide a clear error message
@@ -550,13 +530,13 @@ proc getNumber(L: var TLexer, result: var TToken) =
case result.tokType
of tkIntLit, tkInt64Lit: result.iNumber = xi
of tkInt8Lit: result.iNumber = BiggestInt(int8(toU8(int(xi))))
of tkInt16Lit: result.iNumber = BiggestInt(int16(toU16(int(xi))))
of tkInt32Lit: result.iNumber = BiggestInt(int32(toU32(int64(xi))))
of tkInt8Lit: result.iNumber = ashr(xi shl 56, 56)
of tkInt16Lit: result.iNumber = ashr(xi shl 48, 48)
of tkInt32Lit: result.iNumber = ashr(xi shl 32, 32)
of tkUIntLit, tkUInt64Lit: result.iNumber = xi
of tkUInt8Lit: result.iNumber = BiggestInt(uint8(toU8(int(xi))))
of tkUInt16Lit: result.iNumber = BiggestInt(uint16(toU16(int(xi))))
of tkUInt32Lit: result.iNumber = BiggestInt(uint32(toU32(int64(xi))))
of tkUInt8Lit: result.iNumber = xi and 0xff
of tkUInt16Lit: result.iNumber = xi and 0xffff
of tkUInt32Lit: result.iNumber = xi and 0xffffffff
of tkFloat32Lit:
result.fNumber = (cast[PFloat32](addr(xi)))[]
# note: this code is endian neutral!
@@ -585,34 +565,44 @@ proc getNumber(L: var TLexer, result: var TToken) =
case result.tokType
of floatTypes:
result.fNumber = parseFloat(result.literal)
of tkUint64Lit:
xi = 0
let len = unsafeParseUInt(result.literal, xi)
if len != result.literal.len or len == 0:
raise newException(ValueError, "invalid integer: " & $xi)
result.iNumber = xi
of tkUInt64Lit, tkUIntLit:
var iNumber: uint64
var len: int
try:
len = parseBiggestUInt(result.literal, iNumber)
except ValueError:
raise newException(OverflowError, "number out of range: " & $result.literal)
if len != result.literal.len:
raise newException(ValueError, "invalid integer: " & $result.literal)
result.iNumber = cast[int64](iNumber)
else:
result.iNumber = parseBiggestInt(result.literal)
var iNumber: int64
var len: int
try:
len = parseBiggestInt(result.literal, iNumber)
except ValueError:
raise newException(OverflowError, "number out of range: " & $result.literal)
if len != result.literal.len:
raise newException(ValueError, "invalid integer: " & $result.literal)
result.iNumber = iNumber
# Explicit bounds checks
# Explicit bounds checks. Only T.high needs to be considered
# since result.iNumber can't be negative.
let outOfRange =
case result.tokType
of tkInt8Lit: (result.iNumber < int8.low or result.iNumber > int8.high)
of tkUInt8Lit: (result.iNumber < BiggestInt(uint8.low) or
result.iNumber > BiggestInt(uint8.high))
of tkInt16Lit: (result.iNumber < int16.low or result.iNumber > int16.high)
of tkUInt16Lit: (result.iNumber < BiggestInt(uint16.low) or
result.iNumber > BiggestInt(uint16.high))
of tkInt32Lit: (result.iNumber < int32.low or result.iNumber > int32.high)
of tkUInt32Lit: (result.iNumber < BiggestInt(uint32.low) or
result.iNumber > BiggestInt(uint32.high))
of tkInt8Lit: result.iNumber > int8.high
of tkUInt8Lit: result.iNumber > BiggestInt(uint8.high)
of tkInt16Lit: result.iNumber > int16.high
of tkUInt16Lit: result.iNumber > BiggestInt(uint16.high)
of tkInt32Lit: result.iNumber > int32.high
of tkUInt32Lit: result.iNumber > BiggestInt(uint32.high)
else: false
if outOfRange: lexMessageLitNum(L, "number out of range: '$1'", startpos)
# Promote int literal to int64? Not always necessary, but more consistent
if result.tokType == tkIntLit:
if (result.iNumber < low(int32)) or (result.iNumber > high(int32)):
if result.iNumber > high(int32):
result.tokType = tkInt64Lit
except ValueError:
@@ -622,7 +612,12 @@ proc getNumber(L: var TLexer, result: var TToken) =
tokenEnd(result, postPos-1)
L.bufpos = postPos
proc handleHexChar(L: var TLexer, xi: var int) =
proc handleHexChar(L: var TLexer, xi: var int; position: range[0..4]) =
template invalid() =
lexMessage(L, errGenerated,
"expected a hex digit, but found: " & L.buf[L.bufpos] &
"; maybe prepend with 0")
case L.buf[L.bufpos]
of '0'..'9':
xi = (xi shl 4) or (ord(L.buf[L.bufpos]) - ord('0'))
@@ -633,13 +628,58 @@ proc handleHexChar(L: var TLexer, xi: var int) =
of 'A'..'F':
xi = (xi shl 4) or (ord(L.buf[L.bufpos]) - ord('A') + 10)
inc(L.bufpos)
else: discard
of '"', '\'':
if position <= 1: invalid()
# do not progress the bufpos here.
if position == 0: inc(L.bufpos)
else:
invalid()
# Need to progress for `nim check`
inc(L.bufpos)
proc handleDecChars(L: var TLexer, xi: var int) =
while L.buf[L.bufpos] in {'0'..'9'}:
xi = (xi * 10) + (ord(L.buf[L.bufpos]) - ord('0'))
inc(L.bufpos)
proc addUnicodeCodePoint(s: var string, i: int) =
let i = cast[uint](i)
# inlined toUTF-8 to avoid unicode and strutils dependencies.
let pos = s.len
if i <= 127:
s.setLen(pos+1)
s[pos+0] = chr(i)
elif i <= 0x07FF:
s.setLen(pos+2)
s[pos+0] = chr((i shr 6) or 0b110_00000)
s[pos+1] = chr((i and ones(6)) or 0b10_0000_00)
elif i <= 0xFFFF:
s.setLen(pos+3)
s[pos+0] = chr(i shr 12 or 0b1110_0000)
s[pos+1] = chr(i shr 6 and ones(6) or 0b10_0000_00)
s[pos+2] = chr(i and ones(6) or 0b10_0000_00)
elif i <= 0x001FFFFF:
s.setLen(pos+4)
s[pos+0] = chr(i shr 18 or 0b1111_0000)
s[pos+1] = chr(i shr 12 and ones(6) or 0b10_0000_00)
s[pos+2] = chr(i shr 6 and ones(6) or 0b10_0000_00)
s[pos+3] = chr(i and ones(6) or 0b10_0000_00)
elif i <= 0x03FFFFFF:
s.setLen(pos+5)
s[pos+0] = chr(i shr 24 or 0b111110_00)
s[pos+1] = chr(i shr 18 and ones(6) or 0b10_0000_00)
s[pos+2] = chr(i shr 12 and ones(6) or 0b10_0000_00)
s[pos+3] = chr(i shr 6 and ones(6) or 0b10_0000_00)
s[pos+4] = chr(i and ones(6) or 0b10_0000_00)
elif i <= 0x7FFFFFFF:
s.setLen(pos+6)
s[pos+0] = chr(i shr 30 or 0b1111110_0)
s[pos+1] = chr(i shr 24 and ones(6) or 0b10_0000_00)
s[pos+2] = chr(i shr 18 and ones(6) or 0b10_0000_00)
s[pos+3] = chr(i shr 12 and ones(6) or 0b10_0000_00)
s[pos+4] = chr(i shr 6 and ones(6) or 0b10_0000_00)
s[pos+5] = chr(i and ones(6) or 0b10_0000_00)
proc getEscapedChar(L: var TLexer, tok: var TToken) =
inc(L.bufpos) # skip '\'
case L.buf[L.bufpos]
@@ -647,81 +687,88 @@ proc getEscapedChar(L: var TLexer, tok: var TToken) =
if L.config.oldNewlines:
if tok.tokType == tkCharLit:
lexMessage(L, errGenerated, "\\n not allowed in character literal")
add(tok.literal, L.config.target.tnl)
tok.literal.add(L.config.target.tnl)
else:
add(tok.literal, '\L')
tok.literal.add('\L')
inc(L.bufpos)
of 'p', 'P':
if tok.tokType == tkCharLit:
lexMessage(L, errGenerated, "\\p not allowed in character literal")
add(tok.literal, L.config.target.tnl)
tok.literal.add(L.config.target.tnl)
inc(L.bufpos)
of 'r', 'R', 'c', 'C':
add(tok.literal, CR)
tok.literal.add(CR)
inc(L.bufpos)
of 'l', 'L':
add(tok.literal, LF)
tok.literal.add(LF)
inc(L.bufpos)
of 'f', 'F':
add(tok.literal, FF)
tok.literal.add(FF)
inc(L.bufpos)
of 'e', 'E':
add(tok.literal, ESC)
tok.literal.add(ESC)
inc(L.bufpos)
of 'a', 'A':
add(tok.literal, BEL)
tok.literal.add(BEL)
inc(L.bufpos)
of 'b', 'B':
add(tok.literal, BACKSPACE)
tok.literal.add(BACKSPACE)
inc(L.bufpos)
of 'v', 'V':
add(tok.literal, VT)
tok.literal.add(VT)
inc(L.bufpos)
of 't', 'T':
add(tok.literal, '\t')
tok.literal.add('\t')
inc(L.bufpos)
of '\'', '\"':
add(tok.literal, L.buf[L.bufpos])
tok.literal.add(L.buf[L.bufpos])
inc(L.bufpos)
of '\\':
add(tok.literal, '\\')
tok.literal.add('\\')
inc(L.bufpos)
of 'x', 'X', 'u', 'U':
var tp = L.buf[L.bufpos]
of 'x', 'X':
inc(L.bufpos)
var xi = 0
handleHexChar(L, xi)
handleHexChar(L, xi)
if tp in {'u', 'U'}:
handleHexChar(L, xi)
handleHexChar(L, xi)
# inlined toUTF-8 to avoid unicode and strutils dependencies.
if xi <=% 127:
add(tok.literal, xi.char )
elif xi <=% 0x07FF:
add(tok.literal, ((xi shr 6) or 0b110_00000).char )
add(tok.literal, ((xi and ones(6)) or 0b10_0000_00).char )
elif xi <=% 0xFFFF:
add(tok.literal, (xi shr 12 or 0b1110_0000).char )
add(tok.literal, (xi shr 6 and ones(6) or 0b10_0000_00).char )
add(tok.literal, (xi and ones(6) or 0b10_0000_00).char )
else: # value is 0xFFFF
add(tok.literal, "\xef\xbf\xbf" )
handleHexChar(L, xi, 1)
handleHexChar(L, xi, 2)
tok.literal.add(chr(xi))
of 'u', 'U':
if tok.tokType == tkCharLit:
lexMessage(L, errGenerated, "\\u not allowed in character literal")
inc(L.bufpos)
var xi = 0
if L.buf[L.bufpos] == '{':
inc(L.bufpos)
var start = L.bufpos
while L.buf[L.bufpos] != '}':
handleHexChar(L, xi, 0)
if start == L.bufpos:
lexMessage(L, errGenerated,
"Unicode codepoint cannot be empty")
inc(L.bufpos)
if xi > 0x10FFFF:
let hex = ($L.buf)[start..L.bufpos-2]
lexMessage(L, errGenerated,
"Unicode codepoint must be lower than 0x10FFFF, but was: " & hex)
else:
add(tok.literal, chr(xi))
handleHexChar(L, xi, 1)
handleHexChar(L, xi, 2)
handleHexChar(L, xi, 3)
handleHexChar(L, xi, 4)
addUnicodeCodePoint(tok.literal, xi)
of '0'..'9':
if matchTwoChars(L, '0', {'0'..'9'}):
lexMessage(L, warnOctalEscape)
var xi = 0
handleDecChars(L, xi)
if (xi <= 255): add(tok.literal, chr(xi))
if (xi <= 255): tok.literal.add(chr(xi))
else: lexMessage(L, errGenerated, "invalid character constant")
else: lexMessage(L, errGenerated, "invalid character constant")
proc newString(s: cstring, len: int): string =
## XXX, how come there is no support for this?
result = newString(len)
for i in 0 ..< len:
for i in 0..<len:
result[i] = s[i]
proc handleCRLF(L: var TLexer, pos: int): int =
@@ -740,37 +787,40 @@ proc handleCRLF(L: var TLexer, pos: int): int =
result = nimlexbase.handleLF(L, pos)
else: result = pos
proc getString(L: var TLexer, tok: var TToken, rawMode: bool) =
type
StringMode = enum
normal,
raw,
generalized
proc getString(L: var TLexer, tok: var TToken, mode: StringMode) =
var pos = L.bufpos
var buf = L.buf # put `buf` in a register
var line = L.lineNumber # save linenumber for better error message
tokenBegin(tok, pos)
tokenBegin(tok, pos - ord(mode == raw))
inc pos # skip "
if buf[pos] == '\"' and buf[pos+1] == '\"':
if L.buf[pos] == '\"' and L.buf[pos+1] == '\"':
tok.tokType = tkTripleStrLit # long string literal:
inc(pos, 2) # skip ""
# skip leading newline:
if buf[pos] in {' ', '\t'}:
if L.buf[pos] in {' ', '\t'}:
var newpos = pos+1
while buf[newpos] in {' ', '\t'}: inc newpos
if buf[newpos] in {CR, LF}: pos = newpos
while L.buf[newpos] in {' ', '\t'}: inc newpos
if L.buf[newpos] in {CR, LF}: pos = newpos
pos = handleCRLF(L, pos)
buf = L.buf
while true:
case buf[pos]
case L.buf[pos]
of '\"':
if buf[pos+1] == '\"' and buf[pos+2] == '\"' and
buf[pos+3] != '\"':
if L.buf[pos+1] == '\"' and L.buf[pos+2] == '\"' and
L.buf[pos+3] != '\"':
tokenEndIgnore(tok, pos+2)
L.bufpos = pos + 3 # skip the three """
break
add(tok.literal, '\"')
tok.literal.add('\"')
inc(pos)
of CR, LF:
tokenEndIgnore(tok, pos)
pos = handleCRLF(L, pos)
buf = L.buf
add(tok.literal, "\n")
tok.literal.add("\n")
of nimlexbase.EndOfFile:
tokenEndIgnore(tok, pos)
var line2 = L.lineNumber
@@ -780,18 +830,18 @@ proc getString(L: var TLexer, tok: var TToken, rawMode: bool) =
L.bufpos = pos
break
else:
add(tok.literal, buf[pos])
tok.literal.add(L.buf[pos])
inc(pos)
else:
# ordinary string literal
if rawMode: tok.tokType = tkRStrLit
if mode != normal: tok.tokType = tkRStrLit
else: tok.tokType = tkStrLit
while true:
var c = buf[pos]
var c = L.buf[pos]
if c == '\"':
if rawMode and buf[pos+1] == '\"':
if mode != normal and L.buf[pos+1] == '\"':
inc(pos, 2)
add(tok.literal, '"')
tok.literal.add('"')
else:
tokenEndIgnore(tok, pos)
inc(pos) # skip '"'
@@ -800,12 +850,12 @@ proc getString(L: var TLexer, tok: var TToken, rawMode: bool) =
tokenEndIgnore(tok, pos)
lexMessage(L, errGenerated, "closing \" expected")
break
elif (c == '\\') and not rawMode:
elif (c == '\\') and mode == normal:
L.bufpos = pos
getEscapedChar(L, tok)
pos = L.bufpos
else:
add(tok.literal, c)
tok.literal.add(c)
inc(pos)
L.bufpos = pos
@@ -814,7 +864,9 @@ proc getCharacter(L: var TLexer, tok: var TToken) =
inc(L.bufpos) # skip '
var c = L.buf[L.bufpos]
case c
of '\0'..pred(' '), '\'': lexMessage(L, errGenerated, "invalid character literal")
of '\0'..pred(' '), '\'':
lexMessage(L, errGenerated, "invalid character literal")
tok.literal = $c
of '\\': getEscapedChar(L, tok)
else:
tok.literal = $c
@@ -827,10 +879,10 @@ proc getCharacter(L: var TLexer, tok: var TToken) =
proc getSymbol(L: var TLexer, tok: var TToken) =
var h: Hash = 0
var pos = L.bufpos
var buf = L.buf
tokenBegin(tok, pos)
var suspicious = false
while true:
var c = buf[pos]
var c = L.buf[pos]
case c
of 'a'..'z', '0'..'9', '\x80'..'\xFF':
h = h !& ord(c)
@@ -839,21 +891,26 @@ proc getSymbol(L: var TLexer, tok: var TToken) =
c = chr(ord(c) + (ord('a') - ord('A'))) # toLower()
h = h !& ord(c)
inc(pos)
suspicious = true
of '_':
if buf[pos+1] notin SymChars:
if L.buf[pos+1] notin SymChars:
lexMessage(L, errGenerated, "invalid token: trailing underscore")
break
inc(pos)
suspicious = true
else: break
tokenEnd(tok, pos-1)
h = !$h
tok.ident = L.cache.getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h)
L.bufpos = pos
if (tok.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or
(tok.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)):
tok.tokType = tkSymbol
else:
tok.tokType = TTokType(tok.ident.id + ord(tkSymbol))
if suspicious and {optStyleHint, optStyleError} * L.config.globalOptions != {}:
lintReport(L.config, getLineInfo(L), tok.ident.s.normalize, tok.ident.s)
L.bufpos = pos
proc endOperator(L: var TLexer, tok: var TToken, pos: int,
hash: Hash) {.inline.} =
@@ -865,11 +922,10 @@ proc endOperator(L: var TLexer, tok: var TToken, pos: int,
proc getOperator(L: var TLexer, tok: var TToken) =
var pos = L.bufpos
var buf = L.buf
tokenBegin(tok, pos)
var h: Hash = 0
while true:
var c = buf[pos]
var c = L.buf[pos]
if c notin OpChars: break
h = h !& ord(c)
inc(pos)
@@ -878,10 +934,10 @@ proc getOperator(L: var TLexer, tok: var TToken) =
# advance pos but don't store it in L.bufpos so the next token (which might
# be an operator too) gets the preceding spaces:
tok.strongSpaceB = 0
while buf[pos] == ' ':
while L.buf[pos] == ' ':
inc pos
inc tok.strongSpaceB
if buf[pos] in {CR, LF, nimlexbase.EndOfFile}:
if L.buf[pos] in {CR, LF, nimlexbase.EndOfFile}:
tok.strongSpaceB = -1
proc getPrecedence*(tok: TToken, strongSpaces: bool): int =
@@ -891,15 +947,14 @@ proc getPrecedence*(tok: TToken, strongSpaces: bool): int =
case tok.tokType
of tkOpr:
let L = tok.ident.s.len
let relevantChar = tok.ident.s[0]
# arrow like?
if L > 1 and tok.ident.s[L-1] == '>' and
tok.ident.s[L-2] in {'-', '~', '='}: return considerStrongSpaces(1)
if tok.ident.s.len > 1 and tok.ident.s[^1] == '>' and
tok.ident.s[^2] in {'-', '~', '='}: return considerStrongSpaces(1)
template considerAsgn(value: untyped) =
result = if tok.ident.s[L-1] == '=': 1 else: value
result = if tok.ident.s[^1] == '=': 1 else: value
case relevantChar
of '$', '^': considerAsgn(10)
@@ -912,7 +967,7 @@ proc getPrecedence*(tok: TToken, strongSpaces: bool): int =
of '?': result = 2
else: considerAsgn(2)
of tkDiv, tkMod, tkShl, tkShr: result = 9
of tkIn, tkNotin, tkIs, tkIsnot, tkNot, tkOf, tkAs: result = 5
of tkIn, tkNotin, tkIs, tkIsnot, tkOf, tkAs: result = 5
of tkDotDot: result = 6
of tkAnd: result = 4
of tkOr, tkXor, tkPtr, tkRef: result = 3
@@ -922,9 +977,8 @@ proc getPrecedence*(tok: TToken, strongSpaces: bool): int =
proc newlineFollows*(L: TLexer): bool =
var pos = L.bufpos
var buf = L.buf
while true:
case buf[pos]
case L.buf[pos]
of ' ', '\t':
inc(pos)
of CR, LF:
@@ -932,49 +986,47 @@ proc newlineFollows*(L: TLexer): bool =
break
of '#':
inc(pos)
if buf[pos] == '#': inc(pos)
if buf[pos] != '[': return true
if L.buf[pos] == '#': inc(pos)
if L.buf[pos] != '[': return true
else:
break
proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int;
isDoc: bool) =
var pos = start
var buf = L.buf
var toStrip = 0
tokenBegin(tok, pos)
# detect the amount of indentation:
if isDoc:
toStrip = getColNumber(L, pos)
while buf[pos] == ' ': inc pos
if buf[pos] in {CR, LF}:
while L.buf[pos] == ' ': inc pos
if L.buf[pos] in {CR, LF}:
pos = handleCRLF(L, pos)
buf = L.buf
toStrip = 0
while buf[pos] == ' ':
while L.buf[pos] == ' ':
inc pos
inc toStrip
var nesting = 0
while true:
case buf[pos]
case L.buf[pos]
of '#':
if isDoc:
if buf[pos+1] == '#' and buf[pos+2] == '[':
if L.buf[pos+1] == '#' and L.buf[pos+2] == '[':
inc nesting
tok.literal.add '#'
elif buf[pos+1] == '[':
elif L.buf[pos+1] == '[':
inc nesting
inc pos
of ']':
if isDoc:
if buf[pos+1] == '#' and buf[pos+2] == '#':
if L.buf[pos+1] == '#' and L.buf[pos+2] == '#':
if nesting == 0:
tokenEndIgnore(tok, pos+2)
inc(pos, 3)
break
dec nesting
tok.literal.add ']'
elif buf[pos+1] == '#':
elif L.buf[pos+1] == '#':
if nesting == 0:
tokenEndIgnore(tok, pos+1)
inc(pos, 2)
@@ -984,14 +1036,13 @@ proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int;
of CR, LF:
tokenEndIgnore(tok, pos)
pos = handleCRLF(L, pos)
buf = L.buf
# strip leading whitespace:
when defined(nimpretty): tok.literal.add "\L"
if isDoc:
when not defined(nimpretty): tok.literal.add "\n"
inc tok.iNumber
var c = toStrip
while buf[pos] == ' ' and c > 0:
while L.buf[pos] == ' ' and c > 0:
inc pos
dec c
of nimlexbase.EndOfFile:
@@ -999,7 +1050,7 @@ proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int;
lexMessagePos(L, errGenerated, pos, "end of multiline comment expected")
break
else:
if isDoc or defined(nimpretty): tok.literal.add buf[pos]
if isDoc or defined(nimpretty): tok.literal.add L.buf[pos]
inc(pos)
L.bufpos = pos
when defined(nimpretty):
@@ -1007,49 +1058,47 @@ proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int;
proc scanComment(L: var TLexer, tok: var TToken) =
var pos = L.bufpos
var buf = L.buf
tok.tokType = tkComment
# iNumber contains the number of '\n' in the token
tok.iNumber = 0
assert buf[pos+1] == '#'
assert L.buf[pos+1] == '#'
when defined(nimpretty):
tok.commentOffsetA = L.offsetBase + pos - 1
if buf[pos+2] == '[':
if L.buf[pos+2] == '[':
skipMultiLineComment(L, tok, pos+3, true)
return
tokenBegin(tok, pos)
inc(pos, 2)
var toStrip = 0
while buf[pos] == ' ':
while L.buf[pos] == ' ':
inc pos
inc toStrip
while true:
var lastBackslash = -1
while buf[pos] notin {CR, LF, nimlexbase.EndOfFile}:
if buf[pos] == '\\': lastBackslash = pos+1
add(tok.literal, buf[pos])
while L.buf[pos] notin {CR, LF, nimlexbase.EndOfFile}:
if L.buf[pos] == '\\': lastBackslash = pos+1
tok.literal.add(L.buf[pos])
inc(pos)
tokenEndIgnore(tok, pos)
pos = handleCRLF(L, pos)
buf = L.buf
var indent = 0
while buf[pos] == ' ':
while L.buf[pos] == ' ':
inc(pos)
inc(indent)
if buf[pos] == '#' and buf[pos+1] == '#':
if L.buf[pos] == '#' and L.buf[pos+1] == '#':
tok.literal.add "\n"
inc(pos, 2)
var c = toStrip
while buf[pos] == ' ' and c > 0:
while L.buf[pos] == ' ' and c > 0:
inc pos
dec c
inc tok.iNumber
else:
if buf[pos] > ' ':
if L.buf[pos] > ' ':
L.indentAhead = indent
tokenEndIgnore(tok, pos)
break
@@ -1059,56 +1108,63 @@ proc scanComment(L: var TLexer, tok: var TToken) =
proc skip(L: var TLexer, tok: var TToken) =
var pos = L.bufpos
var buf = L.buf
tokenBegin(tok, pos)
tok.strongSpaceA = 0
when defined(nimpretty):
var hasComment = false
var commentIndent = L.currLineIndent
tok.commentOffsetA = L.offsetBase + pos
tok.commentOffsetB = tok.commentOffsetA
tok.line = -1
while true:
case buf[pos]
case L.buf[pos]
of ' ':
inc(pos)
inc(tok.strongSpaceA)
of '\t':
if not L.allowTabs: lexMessagePos(L, errGenerated, pos, "tabulators are not allowed")
if not L.allowTabs: lexMessagePos(L, errGenerated, pos, "tabs are not allowed, use spaces instead")
inc(pos)
of CR, LF:
tokenEndPrevious(tok, pos)
when defined(nimpretty):
# we are not yet in a comment, so update the comment token's line information:
if not hasComment: inc tok.line
pos = handleCRLF(L, pos)
buf = L.buf
var indent = 0
while true:
if buf[pos] == ' ':
if L.buf[pos] == ' ':
inc(pos)
inc(indent)
elif buf[pos] == '#' and buf[pos+1] == '[':
when defined(nimpretty): hasComment = true
elif L.buf[pos] == '#' and L.buf[pos+1] == '[':
when defined(nimpretty):
hasComment = true
if tok.line < 0:
tok.line = L.lineNumber
commentIndent = indent
skipMultiLineComment(L, tok, pos+2, false)
pos = L.bufpos
buf = L.buf
else:
break
tok.strongSpaceA = 0
if buf[pos] > ' ' and (buf[pos] != '#' or buf[pos+1] == '#'):
when defined(nimpretty):
if L.buf[pos] == '#' and tok.line < 0: commentIndent = indent
if L.buf[pos] > ' ' and (L.buf[pos] != '#' or L.buf[pos+1] == '#'):
tok.indent = indent
L.currLineIndent = indent
break
of '#':
# do not skip documentation comment:
if buf[pos+1] == '#': break
when defined(nimpretty): hasComment = true
if buf[pos+1] == '[':
if L.buf[pos+1] == '#': break
when defined(nimpretty):
hasComment = true
if tok.line < 0:
tok.line = L.lineNumber
if L.buf[pos+1] == '[':
skipMultiLineComment(L, tok, pos+2, false)
pos = L.bufpos
buf = L.buf
else:
tokenBegin(tok, pos)
while buf[pos] notin {CR, LF, nimlexbase.EndOfFile}: inc(pos)
while L.buf[pos] notin {CR, LF, nimlexbase.EndOfFile}:
when defined(nimpretty): tok.literal.add L.buf[pos]
inc(pos)
tokenEndIgnore(tok, pos+1)
when defined(nimpretty):
tok.commentOffsetB = L.offsetBase + pos + 1
@@ -1120,8 +1176,7 @@ proc skip(L: var TLexer, tok: var TToken) =
if hasComment:
tok.commentOffsetB = L.offsetBase + pos - 1
tok.tokType = tkComment
if gIndentationWidth <= 0:
gIndentationWidth = tok.indent
tok.indent = commentIndent
proc rawGetTok*(L: var TLexer, tok: var TToken) =
template atTokenEnd() {.dirty.} =
@@ -1168,7 +1223,7 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
of 'r', 'R':
if L.buf[L.bufpos + 1] == '\"':
inc(L.bufpos)
getString(L, tok, true)
getString(L, tok, raw)
else:
getSymbol(L, tok)
of '(':
@@ -1246,9 +1301,9 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
lexMessage(L, errGenerated, "invalid token: " & c & " (\\" & $(ord(c)) & ')')
of '\"':
# check for generalized raw string literal:
var rawMode = L.bufpos > 0 and L.buf[L.bufpos-1] in SymChars
getString(L, tok, rawMode)
if rawMode:
let mode = if L.bufpos > 0 and L.buf[L.bufpos-1] in SymChars: generalized else: normal
getString(L, tok, mode)
if mode == generalized:
# tkRStrLit -> tkGStrLit
# tkTripleStrLit -> tkGTripleStrLit
inc(tok.tokType, 2)
@@ -1280,10 +1335,13 @@ proc getIndentWidth*(fileIdx: FileIndex, inputstream: PLLStream;
var tok: TToken
initToken(tok)
openLexer(lex, fileIdx, inputstream, cache, config)
while true:
var prevToken = tkEof
while tok.tokType != tkEof:
rawGetTok(lex, tok)
result = tok.indent
if result > 0 or tok.tokType == tkEof: break
if tok.indent > 0 and prevToken in {tkColon, tkEquals, tkType, tkConst, tkLet, tkVar, tkUsing}:
result = tok.indent
if result > 0: break
prevToken = tok.tokType
closeLexer(lex)
proc getPrecedence*(ident: PIdent): int =
@@ -1292,7 +1350,7 @@ proc getPrecedence*(ident: PIdent): int =
initToken(tok)
tok.ident = ident
tok.tokType =
if tok.ident.id in ord(tokKeywordLow) - ord(tkSymbol) .. ord(tokKeywordHigh) - ord(tkSymbol):
if tok.ident.id in ord(tokKeywordLow) - ord(tkSymbol)..ord(tokKeywordHigh) - ord(tkSymbol):
TTokType(tok.ident.id + ord(tkSymbol))
else: tkOpr
getPrecedence(tok, false)

View File

@@ -0,0 +1,891 @@
#
#
# The Nim Compiler
# (c) Copyright 2015 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## This module implements lifting for type-bound operations
## (``=sink``, ``=``, ``=destroy``, ``=deepCopy``).
# Todo:
# - use openArray instead of array to avoid over-specializations
import modulegraphs, lineinfos, idents, ast, renderer, semdata,
sighashes, lowerings, options, types, msgs, magicsys, tables
from trees import isCaseObj
type
TLiftCtx = object
g: ModuleGraph
info: TLineInfo # for construction
kind: TTypeAttachedOp
fn: PSym
asgnForType: PType
recurse: bool
c: PContext # c can be nil, then we are called from lambdalifting!
proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode)
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
info: TLineInfo): PSym
proc createTypeBoundOps*(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo)
proc at(a, i: PNode, elemType: PType): PNode =
result = newNodeI(nkBracketExpr, a.info, 2)
result[0] = a
result[1] = i
result.typ = elemType
proc fillBodyTup(c: var TLiftCtx; t: PType; body, x, y: PNode) =
for i in 0..<t.len:
let lit = lowerings.newIntLit(c.g, x.info, i)
let b = if c.kind == attachedTrace: y else: y.at(lit, t[i])
fillBody(c, t[i], body, x.at(lit, t[i]), b)
proc dotField(x: PNode, f: PSym): PNode =
result = newNodeI(nkDotExpr, x.info, 2)
if x.typ.skipTypes(abstractInst).kind == tyVar:
result[0] = x.newDeref
else:
result[0] = x
result[1] = newSymNode(f, x.info)
result.typ = f.typ
proc newAsgnStmt(le, ri: PNode): PNode =
result = newNodeI(nkAsgn, le.info, 2)
result[0] = le
result[1] = ri
proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
if c.kind in {attachedAsgn, attachedDeepCopy, attachedSink}:
body.add newAsgnStmt(x, y)
proc genAddr(g: ModuleGraph; x: PNode): PNode =
if x.kind == nkHiddenDeref:
checkSonsLen(x, 1, g.config)
result = x[0]
else:
result = newNodeIT(nkHiddenAddr, x.info, makeVarType(x.typ.owner, x.typ))
result.add x
proc destructorCall(g: ModuleGraph; op: PSym; x: PNode): PNode =
result = newNodeIT(nkCall, x.info, op.typ[0])
result.add(newSymNode(op))
result.add genAddr(g, x)
proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode; enforceDefaultOp: bool) =
case n.kind
of nkSym:
let f = n.sym
let b = if c.kind == attachedTrace: y else: y.dotField(f)
if (sfCursor in f.flags and f.typ.skipTypes(abstractInst).kind in {tyRef, tyProc} and
c.g.config.selectedGC in {gcArc, gcOrc, gcHooks}) or
enforceDefaultOp:
defaultOp(c, f.typ, body, x.dotField(f), b)
else:
fillBody(c, f.typ, body, x.dotField(f), b)
of nkNilLit: discard
of nkRecCase:
# XXX This is only correct for 'attachedSink'!
var localEnforceDefaultOp = enforceDefaultOp
if c.kind == attachedSink:
# the value needs to be destroyed before we assign the selector
# or the value is lost
let prevKind = c.kind
c.kind = attachedDestructor
fillBodyObj(c, n, body, x, y, enforceDefaultOp = false)
c.kind = prevKind
localEnforceDefaultOp = true
# copy the selector:
fillBodyObj(c, n[0], body, x, y, enforceDefaultOp = false)
# we need to generate a case statement:
var caseStmt = newNodeI(nkCaseStmt, c.info)
# XXX generate 'if' that checks same branches
# generate selector:
var access = dotField(x, n[0].sym)
caseStmt.add(access)
var emptyBranches = 0
# copy the branches over, but replace the fields with the for loop body:
for i in 1..<n.len:
var branch = copyTree(n[i])
branch[^1] = newNodeI(nkStmtList, c.info)
fillBodyObj(c, n[i].lastSon, branch[^1], x, y,
enforceDefaultOp = localEnforceDefaultOp)
if branch[^1].len == 0: inc emptyBranches
caseStmt.add(branch)
if emptyBranches != n.len-1:
body.add(caseStmt)
of nkRecList:
for t in items(n): fillBodyObj(c, t, body, x, y, enforceDefaultOp)
else:
illFormedAstLocal(n, c.g.config)
proc fillBodyObjTImpl(c: var TLiftCtx; t: PType, body, x, y: PNode) =
if t.len > 0 and t[0] != nil:
fillBody(c, skipTypes(t[0], abstractPtrs), body, x, y)
fillBodyObj(c, t.n, body, x, y, enforceDefaultOp = false)
proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
var hasCase = isCaseObj(t.n)
var obj = t
while obj.len > 0 and obj[0] != nil:
obj = skipTypes(obj[0], abstractPtrs)
hasCase = hasCase or isCaseObj(obj.n)
if hasCase and c.kind in {attachedAsgn, attachedDeepCopy}:
# assignment for case objects is complex, we do:
# =destroy(dest)
# wasMoved(dest)
# for every field:
# `=` dest.field, src.field
# ^ this is what we used to do, but for 'result = result.sons[0]' it
# destroys 'result' too early.
# So this is what we really need to do:
# let blob {.cursor.} = dest # remembers the old dest.kind
# wasMoved(dest)
# dest.kind = src.kind
# for every field (dependent on dest.kind):
# `=` dest.field, src.field
# =destroy(blob)
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), c.fn, c.info)
temp.typ = x.typ
incl(temp.flags, sfFromGeneric)
var v = newNodeI(nkVarSection, c.info)
let blob = newSymNode(temp)
v.addVar(blob, x)
body.add v
#body.add newAsgnStmt(blob, x)
var wasMovedCall = newNodeI(nkCall, c.info)
wasMovedCall.add(newSymNode(createMagic(c.g, "wasMoved", mWasMoved)))
wasMovedCall.add x # mWasMoved does not take the address
body.add wasMovedCall
fillBodyObjTImpl(c, t, body, x, y)
when false:
# does not work yet due to phase-ordering problems:
assert t.destructor != nil
body.add destructorCall(c.g, t.destructor, blob)
let prevKind = c.kind
c.kind = attachedDestructor
fillBodyObjTImpl(c, t, body, blob, y)
c.kind = prevKind
else:
fillBodyObjTImpl(c, t, body, x, y)
proc newHookCall(g: ModuleGraph; op: PSym; x, y: PNode): PNode =
#if sfError in op.flags:
# localError(c.config, x.info, "usage of '$1' is a user-defined error" % op.name.s)
result = newNodeI(nkCall, x.info)
result.add newSymNode(op)
if op.typ.sons[1].kind == tyVar:
result.add genAddr(g, x)
else:
result.add x
if y != nil:
result.add y
proc newOpCall(op: PSym; x: PNode): PNode =
result = newNodeIT(nkCall, x.info, op.typ[0])
result.add(newSymNode(op))
result.add x
proc newDeepCopyCall(op: PSym; x, y: PNode): PNode =
result = newAsgnStmt(x, newOpCall(op, y))
proc useNoGc(c: TLiftCtx; t: PType): bool {.inline.} =
result = optSeqDestructors in c.g.config.globalOptions and
({tfHasGCedMem, tfHasOwned} * t.flags != {} or t.isGCedMem)
proc requiresDestructor(c: TLiftCtx; t: PType): bool {.inline.} =
result = optSeqDestructors in c.g.config.globalOptions and
containsGarbageCollectedRef(t)
proc instantiateGeneric(c: var TLiftCtx; op: PSym; t, typeInst: PType): PSym =
if c.c != nil and typeInst != nil:
result = c.c.instTypeBoundOp(c.c, op, typeInst, c.info, attachedAsgn, 1)
else:
localError(c.g.config, c.info,
"cannot generate destructor for generic type: " & typeToString(t))
result = nil
proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode;
field: var PSym): bool =
if optSeqDestructors in c.g.config.globalOptions:
let op = field
if field != nil and sfOverriden in field.flags:
if sfError in op.flags:
incl c.fn.flags, sfError
#else:
# markUsed(c.g.config, c.info, op, c.g.usageSym)
onUse(c.info, op)
body.add newHookCall(c.g, op, x, y)
result = true
elif tfHasAsgn in t.flags:
var op: PSym
if sameType(t, c.asgnForType):
# generate recursive call:
if c.recurse:
op = c.fn
else:
c.recurse = true
return false
else:
op = field
if op == nil:
op = produceSym(c.g, c.c, t, c.kind, c.info)
if sfError in op.flags:
incl c.fn.flags, sfError
#else:
# markUsed(c.g.config, c.info, op, c.g.usageSym)
onUse(c.info, op)
# We also now do generic instantiations in the destructor lifting pass:
if op.ast[genericParamsPos].kind != nkEmpty:
op = instantiateGeneric(c, op, t, t.typeInst)
field = op
#echo "trying to use ", op.ast
#echo "for ", op.name.s, " "
#debug(t)
#return false
assert op.ast[genericParamsPos].kind == nkEmpty
body.add newHookCall(c.g, op, x, y)
result = true
proc addDestructorCall(c: var TLiftCtx; orig: PType; body, x: PNode) =
let t = orig.skipTypes(abstractInst)
var op = t.destructor
if op != nil and sfOverriden in op.flags:
if op.ast[genericParamsPos].kind != nkEmpty:
# patch generic destructor:
op = instantiateGeneric(c, op, t, t.typeInst)
t.attachedOps[attachedDestructor] = op
if op == nil and (useNoGc(c, t) or requiresDestructor(c, t)):
op = produceSym(c.g, c.c, t, attachedDestructor, c.info)
doAssert op != nil
doAssert op == t.destructor
if op != nil:
#markUsed(c.g.config, c.info, op, c.g.usageSym)
onUse(c.info, op)
body.add destructorCall(c.g, op, x)
elif useNoGc(c, t):
internalError(c.g.config, c.info,
"type-bound operator could not be resolved")
proc considerUserDefinedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
case c.kind
of attachedDestructor:
var op = t.destructor
if op != nil and sfOverriden in op.flags:
if op.ast[genericParamsPos].kind != nkEmpty:
# patch generic destructor:
op = instantiateGeneric(c, op, t, t.typeInst)
t.attachedOps[attachedDestructor] = op
#markUsed(c.g.config, c.info, op, c.g.usageSym)
onUse(c.info, op)
body.add destructorCall(c.g, op, x)
result = true
#result = addDestructorCall(c, t, body, x)
of attachedAsgn, attachedSink, attachedTrace:
result = considerAsgnOrSink(c, t, body, x, y, t.attachedOps[c.kind])
of attachedDispose:
result = considerAsgnOrSink(c, t, body, x, nil, t.attachedOps[c.kind])
of attachedDeepCopy:
let op = t.attachedOps[attachedDeepCopy]
if op != nil:
#markUsed(c.g.config, c.info, op, c.g.usageSym)
onUse(c.info, op)
body.add newDeepCopyCall(op, x, y)
result = true
proc declareCounter(c: var TLiftCtx; body: PNode; first: BiggestInt): PNode =
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), c.fn, c.info)
temp.typ = getSysType(c.g, body.info, tyInt)
incl(temp.flags, sfFromGeneric)
var v = newNodeI(nkVarSection, c.info)
result = newSymNode(temp)
v.addVar(result, lowerings.newIntLit(c.g, body.info, first))
body.add v
proc genBuiltin(g: ModuleGraph; magic: TMagic; name: string; i: PNode): PNode =
result = newNodeI(nkCall, i.info)
result.add createMagic(g, name, magic).newSymNode
result.add i
proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =
result = newNodeI(nkWhileStmt, c.info, 2)
let cmp = genBuiltin(c.g, mLtI, "<", i)
cmp.add genLen(c.g, dest)
cmp.typ = getSysType(c.g, c.info, tyBool)
result[0] = cmp
result[1] = newNodeI(nkStmtList, c.info)
proc genIf(c: var TLiftCtx; cond, action: PNode): PNode =
result = newTree(nkIfStmt, newTree(nkElifBranch, cond, action))
proc addIncStmt(c: var TLiftCtx; body, i: PNode) =
let incCall = genBuiltin(c.g, mInc, "inc", i)
incCall.add lowerings.newIntLit(c.g, c.info, 1)
body.add incCall
proc newSeqCall(g: ModuleGraph; x, y: PNode): PNode =
# don't call genAddr(c, x) here:
result = genBuiltin(g, mNewSeq, "newSeq", x)
let lenCall = genBuiltin(g, mLengthSeq, "len", y)
lenCall.typ = getSysType(g, x.info, tyInt)
result.add lenCall
proc setLenStrCall(g: ModuleGraph; x, y: PNode): PNode =
let lenCall = genBuiltin(g, mLengthStr, "len", y)
lenCall.typ = getSysType(g, x.info, tyInt)
result = genBuiltin(g, mSetLengthStr, "setLen", x) # genAddr(g, x))
result.add lenCall
proc setLenSeqCall(c: var TLiftCtx; t: PType; x, y: PNode): PNode =
let lenCall = genBuiltin(c.g, mLengthSeq, "len", y)
lenCall.typ = getSysType(c.g, x.info, tyInt)
var op = getSysMagic(c.g, x.info, "setLen", mSetLengthSeq)
op = instantiateGeneric(c, op, t, t)
result = newTree(nkCall, newSymNode(op, x.info), x, lenCall)
proc forallElements(c: var TLiftCtx; t: PType; body, x, y: PNode) =
let i = declareCounter(c, body, toInt64(firstOrd(c.g.config, t)))
let whileLoop = genWhileLoop(c, i, x)
let elemType = t.lastSon
let b = if c.kind == attachedTrace: y else: y.at(i, elemType)
fillBody(c, elemType, whileLoop[1], x.at(i, elemType), b)
addIncStmt(c, whileLoop[1], i)
body.add whileLoop
proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
case c.kind
of attachedAsgn, attachedDeepCopy:
# we generate:
# setLen(dest, y.len)
# var i = 0
# while i < y.len: dest[i] = y[i]; inc(i)
# This is usually more efficient than a destroy/create pair.
body.add setLenSeqCall(c, t, x, y)
forallElements(c, t, body, x, y)
of attachedSink:
let moveCall = genBuiltin(c.g, mMove, "move", x)
moveCall.add y
doAssert t.destructor != nil
moveCall.add destructorCall(c.g, t.destructor, x)
body.add moveCall
of attachedDestructor:
# destroy all elements:
forallElements(c, t, body, x, y)
body.add genBuiltin(c.g, mDestroy, "destroy", x)
of attachedTrace:
# follow all elements:
forallElements(c, t, body, x, y)
of attachedDispose:
body.add genBuiltin(c.g, mDestroy, "destroy", x)
proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
createTypeBoundOps(c.g, c.c, t, body.info)
# recursions are tricky, so we might need to forward the generated
# operation here:
var t = t
if t.assignment == nil or t.destructor == nil:
let h = sighashes.hashType(t, {CoType, CoConsiderOwned, CoDistinct})
let canon = c.g.canonTypes.getOrDefault(h)
if canon != nil: t = canon
case c.kind
of attachedAsgn, attachedDeepCopy:
doAssert t.assignment != nil
body.add newHookCall(c.g, t.assignment, x, y)
of attachedSink:
# we always inline the move for better performance:
let moveCall = genBuiltin(c.g, mMove, "move", x)
moveCall.add y
doAssert t.destructor != nil
moveCall.add destructorCall(c.g, t.destructor, x)
body.add moveCall
# alternatively we could do this:
when false:
doAssert t.asink != nil
body.add newHookCall(c.g, t.asink, x, y)
of attachedDestructor:
doAssert t.destructor != nil
body.add destructorCall(c.g, t.destructor, x)
of attachedTrace:
body.add newHookCall(c.g, t.attachedOps[c.kind], x, y)
of attachedDispose:
body.add newHookCall(c.g, t.attachedOps[c.kind], x, nil)
proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
case c.kind
of attachedAsgn, attachedDeepCopy:
body.add callCodegenProc(c.g, "nimAsgnStrV2", c.info, genAddr(c.g, x), y)
of attachedSink:
let moveCall = genBuiltin(c.g, mMove, "move", x)
moveCall.add y
doAssert t.destructor != nil
moveCall.add destructorCall(c.g, t.destructor, x)
body.add moveCall
of attachedDestructor, attachedDispose:
body.add genBuiltin(c.g, mDestroy, "destroy", x)
of attachedTrace:
discard "strings are atomic and have no inner elements that are to trace"
proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
var actions = newNodeI(nkStmtList, c.info)
let elemType = t.lastSon
if isFinal(elemType):
addDestructorCall(c, elemType, actions, genDeref(x, nkDerefExpr))
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, x)
else:
addDestructorCall(c, elemType, newNodeI(nkStmtList, c.info), genDeref(x, nkDerefExpr))
actions.add callCodegenProc(c.g, "nimDestroyAndDispose", c.info, x)
let isCyclic = c.g.config.selectedGC == gcOrc and types.canFormAcycle(t)
var cond: PNode
if isCyclic:
if isFinal(elemType):
let typInfo = genBuiltin(c.g, mGetTypeInfo, "getTypeInfo", newNodeIT(nkType, x.info, elemType))
typInfo.typ = getSysType(c.g, c.info, tyPointer)
cond = callCodegenProc(c.g, "nimDecRefIsLastCyclicStatic", c.info, x, typInfo)
else:
cond = callCodegenProc(c.g, "nimDecRefIsLastCyclicDyn", c.info, x)
else:
cond = callCodegenProc(c.g, "nimDecRefIsLast", c.info, x)
cond.typ = getSysType(c.g, x.info, tyBool)
case c.kind
of attachedSink:
body.add genIf(c, cond, actions)
body.add newAsgnStmt(x, y)
of attachedAsgn:
body.add genIf(c, y, callCodegenProc(c.g,
if isCyclic: "nimIncRefCyclic" else: "nimIncRef", c.info, y))
body.add genIf(c, cond, actions)
body.add newAsgnStmt(x, y)
of attachedDestructor:
actions.add newAsgnStmt(x, newNodeIT(nkNilLit, body.info, t))
body.add genIf(c, cond, actions)
of attachedDeepCopy: assert(false, "cannot happen")
of attachedTrace:
if isFinal(elemType):
let typInfo = genBuiltin(c.g, mGetTypeInfo, "getTypeInfo", newNodeIT(nkType, x.info, elemType))
typInfo.typ = getSysType(c.g, c.info, tyPointer)
body.add callCodegenProc(c.g, "nimTraceRef", c.info, genAddrOf(x), typInfo, y)
else:
# If the ref is polymorphic we have to account for this
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(x), y)
of attachedDispose:
# this is crucial! dispose is like =destroy but we don't follow refs
# as that is dealt within the cycle collector.
when false:
let cond = copyTree(x)
cond.typ = getSysType(c.g, x.info, tyBool)
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, x)
body.add genIf(c, cond, actions)
proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
## Closures are really like refs except they always use a virtual destructor
## and we need to do the refcounting only on the ref field which we call 'xenv':
let xenv = genBuiltin(c.g, mAccessEnv, "accessEnv", x)
xenv.typ = getSysType(c.g, c.info, tyPointer)
var actions = newNodeI(nkStmtList, c.info)
actions.add callCodegenProc(c.g, "nimDestroyAndDispose", c.info, xenv)
let decRefProc =
if c.g.config.selectedGC == gcOrc: "nimDecRefIsLastCyclicDyn"
else: "nimDecRefIsLast"
let cond = callCodegenProc(c.g, decRefProc, c.info, xenv)
cond.typ = getSysType(c.g, x.info, tyBool)
case c.kind
of attachedSink:
body.add genIf(c, cond, actions)
body.add newAsgnStmt(x, y)
of attachedAsgn:
let yenv = genBuiltin(c.g, mAccessEnv, "accessEnv", y)
yenv.typ = getSysType(c.g, c.info, tyPointer)
let incRefProc =
if c.g.config.selectedGC == gcOrc: "nimIncRefCyclic"
else: "nimIncRef"
body.add genIf(c, yenv, callCodegenProc(c.g, incRefProc, c.info, yenv))
body.add genIf(c, cond, actions)
body.add newAsgnStmt(x, y)
of attachedDestructor:
actions.add newAsgnStmt(xenv, newNodeIT(nkNilLit, body.info, xenv.typ))
body.add genIf(c, cond, actions)
of attachedDeepCopy: assert(false, "cannot happen")
of attachedTrace:
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(xenv), y)
of attachedDispose:
# this is crucial! dispose is like =destroy but we don't follow refs
# as that is dealt within the cycle collector.
when false:
let cond = copyTree(xenv)
cond.typ = getSysType(c.g, xenv.info, tyBool)
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, xenv)
body.add genIf(c, cond, actions)
proc weakrefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
case c.kind
of attachedSink:
# we 'nil' y out afterwards so we *need* to take over its reference
# count value:
body.add genIf(c, x, callCodegenProc(c.g, "nimDecWeakRef", c.info, x))
body.add newAsgnStmt(x, y)
of attachedAsgn:
body.add genIf(c, y, callCodegenProc(c.g, "nimIncRef", c.info, y))
body.add genIf(c, x, callCodegenProc(c.g, "nimDecWeakRef", c.info, x))
body.add newAsgnStmt(x, y)
of attachedDestructor:
# it's better to prepend the destruction of weak refs in order to
# prevent wrong "dangling refs exist" problems:
var actions = newNodeI(nkStmtList, c.info)
actions.add callCodegenProc(c.g, "nimDecWeakRef", c.info, x)
actions.add newAsgnStmt(x, newNodeIT(nkNilLit, body.info, t))
let des = genIf(c, x, actions)
if body.len == 0:
body.add des
else:
body.sons.insert(des, 0)
of attachedDeepCopy: assert(false, "cannot happen")
of attachedTrace, attachedDispose: discard
proc ownedRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
var actions = newNodeI(nkStmtList, c.info)
let elemType = t.lastSon
#fillBody(c, elemType, actions, genDeref(x), genDeref(y))
#var disposeCall = genBuiltin(c.g, mDispose, "dispose", x)
if isFinal(elemType):
addDestructorCall(c, elemType, actions, genDeref(x, nkDerefExpr))
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, x)
else:
addDestructorCall(c, elemType, newNodeI(nkStmtList, c.info), genDeref(x, nkDerefExpr))
actions.add callCodegenProc(c.g, "nimDestroyAndDispose", c.info, x)
case c.kind
of attachedSink, attachedAsgn:
body.add genIf(c, x, actions)
body.add newAsgnStmt(x, y)
of attachedDestructor:
actions.add newAsgnStmt(x, newNodeIT(nkNilLit, body.info, t))
body.add genIf(c, x, actions)
of attachedDeepCopy: assert(false, "cannot happen")
of attachedTrace, attachedDispose: discard
proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
if c.kind == attachedDeepCopy:
# a big problem is that we don't know the environment's type here, so we
# have to go through some indirection; we delegate this to the codegen:
let call = newNodeI(nkCall, c.info, 2)
call.typ = t
call[0] = newSymNode(createMagic(c.g, "deepCopy", mDeepCopy))
call[1] = y
body.add newAsgnStmt(x, call)
elif (optOwnedRefs in c.g.config.globalOptions and
optRefCheck in c.g.config.options) or c.g.config.selectedGC in {gcArc, gcOrc}:
let xx = genBuiltin(c.g, mAccessEnv, "accessEnv", x)
xx.typ = getSysType(c.g, c.info, tyPointer)
case c.kind
of attachedSink:
# we 'nil' y out afterwards so we *need* to take over its reference
# count value:
body.add genIf(c, xx, callCodegenProc(c.g, "nimDecWeakRef", c.info, xx))
body.add newAsgnStmt(x, y)
of attachedAsgn:
let yy = genBuiltin(c.g, mAccessEnv, "accessEnv", y)
yy.typ = getSysType(c.g, c.info, tyPointer)
body.add genIf(c, yy, callCodegenProc(c.g, "nimIncRef", c.info, yy))
body.add genIf(c, xx, callCodegenProc(c.g, "nimDecWeakRef", c.info, xx))
body.add newAsgnStmt(x, y)
of attachedDestructor:
var actions = newNodeI(nkStmtList, c.info)
actions.add callCodegenProc(c.g, "nimDecWeakRef", c.info, xx)
actions.add newAsgnStmt(xx, newNodeIT(nkNilLit, body.info, xx.typ))
let des = genIf(c, xx, actions)
if body.len == 0:
body.add des
else:
body.sons.insert(des, 0)
of attachedDeepCopy: assert(false, "cannot happen")
of attachedTrace, attachedDispose: discard
proc ownedClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
let xx = genBuiltin(c.g, mAccessEnv, "accessEnv", x)
xx.typ = getSysType(c.g, c.info, tyPointer)
var actions = newNodeI(nkStmtList, c.info)
#discard addDestructorCall(c, elemType, newNodeI(nkStmtList, c.info), genDeref(xx))
actions.add callCodegenProc(c.g, "nimDestroyAndDispose", c.info, xx)
case c.kind
of attachedSink, attachedAsgn:
body.add genIf(c, xx, actions)
body.add newAsgnStmt(x, y)
of attachedDestructor:
actions.add newAsgnStmt(xx, newNodeIT(nkNilLit, body.info, xx.typ))
body.add genIf(c, xx, actions)
of attachedDeepCopy: assert(false, "cannot happen")
of attachedTrace, attachedDispose: discard
proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
case t.kind
of tyNone, tyEmpty, tyVoid: discard
of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString,
tyPtr, tyOpt, tyUncheckedArray, tyVar, tyLent:
defaultOp(c, t, body, x, y)
of tyRef:
if c.g.config.selectedGC in {gcArc, gcOrc}:
atomicRefOp(c, t, body, x, y)
elif (optOwnedRefs in c.g.config.globalOptions and
optRefCheck in c.g.config.options):
weakrefOp(c, t, body, x, y)
else:
defaultOp(c, t, body, x, y)
of tyProc:
if t.callConv == ccClosure:
if c.g.config.selectedGC in {gcArc, gcOrc}:
atomicClosureOp(c, t, body, x, y)
else:
closureOp(c, t, body, x, y)
else:
defaultOp(c, t, body, x, y)
of tyOwned:
let base = t.skipTypes(abstractInstOwned)
if optOwnedRefs in c.g.config.globalOptions:
case base.kind
of tyRef:
ownedRefOp(c, base, body, x, y)
return
of tyProc:
if base.callConv == ccClosure:
ownedClosureOp(c, base, body, x, y)
return
else: discard
defaultOp(c, base, body, x, y)
of tyArray:
if tfHasAsgn in t.flags or useNoGc(c, t):
forallElements(c, t, body, x, y)
else:
defaultOp(c, t, body, x, y)
of tySequence:
if useNoGc(c, t):
useSeqOrStrOp(c, t, body, x, y)
elif optSeqDestructors in c.g.config.globalOptions:
# note that tfHasAsgn is propagated so we need the check on
# 'selectedGC' here to determine if we have the new runtime.
discard considerUserDefinedOp(c, t, body, x, y)
elif tfHasAsgn in t.flags:
if c.kind in {attachedAsgn, attachedSink, attachedDeepCopy}:
body.add newSeqCall(c.g, x, y)
forallElements(c, t, body, x, y)
else:
defaultOp(c, t, body, x, y)
of tyString:
if useNoGc(c, t):
useSeqOrStrOp(c, t, body, x, y)
elif tfHasAsgn in t.flags:
discard considerUserDefinedOp(c, t, body, x, y)
else:
defaultOp(c, t, body, x, y)
of tyObject:
if not considerUserDefinedOp(c, t, body, x, y):
if c.kind in {attachedAsgn, attachedSink} and t.sym != nil and sfImportc in t.sym.flags:
body.add newAsgnStmt(x, y)
else:
fillBodyObjT(c, t, body, x, y)
of tyDistinct:
if not considerUserDefinedOp(c, t, body, x, y):
fillBody(c, t[0], body, x, y)
of tyTuple:
fillBodyTup(c, t, body, x, y)
of tyVarargs, tyOpenArray:
if c.kind == attachedDestructor and (tfHasAsgn in t.flags or useNoGc(c, t)):
forallElements(c, t, body, x, y)
else:
discard "cannot copy openArray"
of tyFromExpr, tyProxy, tyBuiltInTypeClass, tyUserTypeClass,
tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot, tyAnything,
tyGenericParam, tyGenericBody, tyNil, tyUntyped, tyTyped,
tyTypeDesc, tyGenericInvocation, tyForward:
#internalError(c.g.config, c.info, "assignment requested for type: " & typeToString(t))
discard
of tyOrdinal, tyRange, tyInferred,
tyGenericInst, tyStatic, tyAlias, tySink:
fillBody(c, lastSon(t), body, x, y)
proc produceSymDistinctType(g: ModuleGraph; c: PContext; typ: PType;
kind: TTypeAttachedOp; info: TLineInfo): PSym =
assert typ.kind == tyDistinct
let baseType = typ[0]
if baseType.attachedOps[kind] == nil:
discard produceSym(g, c, baseType, kind, info)
typ.attachedOps[kind] = baseType.attachedOps[kind]
result = typ.attachedOps[kind]
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
info: TLineInfo): PSym =
if typ.kind == tyDistinct:
return produceSymDistinctType(g, c, typ, kind, info)
var a: TLiftCtx
a.info = info
a.g = g
a.kind = kind
a.c = c
let body = newNodeI(nkStmtList, info)
let procname = getIdent(g.cache, AttachedOpToStr[kind])
result = newSym(skProc, procname, typ.owner, info)
a.fn = result
a.asgnForType = typ
let dest = newSym(skParam, getIdent(g.cache, "dest"), result, info)
let src = newSym(skParam, getIdent(g.cache, if kind == attachedTrace: "env" else: "src"), result, info)
var d: PNode
#if kind notin {attachedTrace, attachedDispose}:
dest.typ = makeVarType(typ.owner, typ)
d = newDeref(newSymNode(dest))
#else:
# dest.typ = typ
# d = newSymNode(dest)
if kind == attachedTrace:
src.typ = getSysType(g, info, tyPointer)
else:
src.typ = typ
result.typ = newProcType(info, typ.owner)
result.typ.addParam dest
if kind notin {attachedDestructor, attachedDispose}:
result.typ.addParam src
# register this operation already:
typ.attachedOps[kind] = result
if kind == attachedSink and typ.attachedOps[attachedDestructor] != nil and
sfOverriden in typ.attachedOps[attachedDestructor].flags:
## compiler can use a combination of `=destroy` and memCopy for sink op
dest.flags.incl sfCursor
body.add newOpCall(typ.attachedOps[attachedDestructor], d[0])
body.add newAsgnStmt(d, newSymNode(src))
else:
var tk: TTypeKind
if g.config.selectedGC in {gcArc, gcOrc, gcHooks}:
tk = skipTypes(typ, {tyOrdinal, tyRange, tyInferred, tyGenericInst, tyStatic, tyAlias, tySink}).kind
else:
tk = tyNone # no special casing for strings and seqs
case tk
of tySequence:
fillSeqOp(a, typ, body, d, newSymNode(src))
of tyString:
fillStrOp(a, typ, body, d, newSymNode(src))
else:
fillBody(a, typ, body, d, newSymNode(src))
var n = newNodeI(nkProcDef, info, bodyPos+1)
for i in 0..<n.len: n[i] = newNodeI(nkEmpty, info)
n[namePos] = newSymNode(result)
n[paramsPos] = result.typ.n
n[bodyPos] = body
result.ast = n
incl result.flags, sfFromGeneric
incl result.flags, sfGeneratedOp
template liftTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) =
discard "now a nop"
proc patchBody(g: ModuleGraph; c: PContext; n: PNode; info: TLineInfo) =
if n.kind in nkCallKinds:
if n[0].kind == nkSym and n[0].sym.magic == mDestroy:
let t = n[1].typ.skipTypes(abstractVar)
if t.destructor == nil:
discard produceSym(g, c, t, attachedDestructor, info)
if t.destructor != nil:
if t.destructor.ast[genericParamsPos].kind != nkEmpty:
internalError(g.config, info, "resolved destructor is generic")
if t.destructor.magic == mDestroy:
internalError(g.config, info, "patching mDestroy with mDestroy?")
n[0] = newSymNode(t.destructor)
for x in n: patchBody(g, c, x, info)
template inst(field, t) =
if field.ast != nil and field.ast[genericParamsPos].kind != nkEmpty:
if t.typeInst != nil:
var a: TLiftCtx
a.info = info
a.g = g
a.kind = k
a.c = c
field = instantiateGeneric(a, field, t, t.typeInst)
if field.ast != nil:
patchBody(g, c, field.ast, info)
else:
localError(g.config, info, "unresolved generic parameter")
proc isTrival(s: PSym): bool {.inline.} =
s == nil or (s.ast != nil and s.ast[bodyPos].len == 0)
proc isEmptyContainer(g: ModuleGraph, t: PType): bool =
(t.kind == tyArray and lengthOrd(g.config, t[0]) == 0) or
(t.kind == tySequence and t[0].kind == tyError)
proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo) =
## In the semantic pass this is called in strategic places
## to ensure we lift assignment, destructors and moves properly.
## The later 'injectdestructors' pass depends on it.
if orig == nil or {tfCheckedForDestructor, tfHasMeta} * orig.flags != {}: return
incl orig.flags, tfCheckedForDestructor
let skipped = orig.skipTypes({tyGenericInst, tyAlias, tySink})
if isEmptyContainer(skipped): return
let h = sighashes.hashType(skipped, {CoType, CoConsiderOwned, CoDistinct})
var canon = g.canonTypes.getOrDefault(h)
if canon == nil:
g.canonTypes[h] = skipped
canon = skipped
# multiple cases are to distinguish here:
# 1. we don't know yet if 'typ' has a nontrival destructor.
# 2. we have a nop destructor. --> mDestroy
# 3. we have a lifted destructor.
# 4. We have a custom destructor.
# 5. We have a (custom) generic destructor.
# we do not generate '=trace' nor '=dispose' procs if we
# have the cycle detection disabled, saves code size.
let lastAttached = if g.config.selectedGC == gcOrc: attachedDispose
else: attachedSink
# we generate the destructor first so that other operators can depend on it:
for k in attachedDestructor..lastAttached:
if canon.attachedOps[k] == nil:
discard produceSym(g, c, canon, k, info)
else:
inst(canon.attachedOps[k], canon)
if canon != orig:
orig.attachedOps[k] = canon.attachedOps[k]
if not isTrival(orig.destructor):
#or not isTrival(orig.assignment) or
# not isTrival(orig.sink):
orig.flags.incl tfHasAsgn

View File

@@ -10,7 +10,7 @@
## This module implements the '.liftLocals' pragma.
import
intsets, strutils, options, ast, astalgo, msgs,
strutils, options, ast, msgs,
idents, renderer, types, lowerings, lineinfos
from pragmas import getPragmaVal
@@ -30,10 +30,10 @@ proc lookupOrAdd(c: var Ctx; s: PSym; info: TLineInfo): PNode =
let field = addUniqueField(c.objType, s, c.cache)
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = c.objType
add(deref, newSymNode(c.partialParam, info))
deref.add(newSymNode(c.partialParam, info))
result = newNodeI(nkDotExpr, info)
add(result, deref)
add(result, newSymNode(field))
result.add(deref)
result.add(newSymNode(field))
result.typ = field.typ
proc liftLocals(n: PNode; i: int; c: var Ctx) =
@@ -44,12 +44,12 @@ proc liftLocals(n: PNode; i: int; c: var Ctx) =
n[i] = lookupOrAdd(c, it.sym, it.info)
of procDefs, nkTypeSection: discard
else:
for i in 0 ..< it.safeLen:
for i in 0..<it.safeLen:
liftLocals(it, i, c)
proc lookupParam(params, dest: PNode): PSym =
if dest.kind != nkIdent: return nil
for i in 1 ..< params.len:
for i in 1..<params.len:
if params[i].kind == nkSym and params[i].sym.name.id == dest.ident.id:
return params[i].sym

View File

@@ -13,7 +13,7 @@
import ropes, tables, pathutils
const
explanationsBaseUrl* = "https://nim-lang.org/docs/manual"
explanationsBaseUrl* = "https://nim-lang.org/docs"
type
TMsgKind* = enum
@@ -23,6 +23,7 @@ type
errGeneralParseError,
errNewSectionExpected,
errInvalidDirectiveX,
errProveInit,
errGenerated,
errUser,
warnCannotOpenFile,
@@ -33,18 +34,24 @@ type
warnFieldXNotSupported, warnCommentXIgnored,
warnTypelessParam,
warnUseBase, warnWriteToForeignHeap, warnUnsafeCode,
warnEachIdentIsTuple, warnShadowIdent,
warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
warnUnusedImportX,
warnInheritFromException,
warnEachIdentIsTuple,
warnUnsafeSetLen,
warnUnsafeDefault,
warnProveInit, warnProveField, warnProveIndex,
warnStaticIndexCheck, warnGcUnsafe, warnGcUnsafe2,
warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed,
warnInconsistentSpacing, warnUser,
warnInconsistentSpacing, warnCaseTransition, warnCycleCreated, warnUser,
hintSuccess, hintSuccessX, hintCC,
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
hintLineTooLong, hintXDeclaredButNotUsed,
hintConvToBaseNotNeeded,
hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath,
hintConditionAlwaysTrue, hintName, hintPattern,
hintConditionAlwaysTrue, hintConditionAlwaysFalse, hintName, hintPattern,
hintExecuting, hintLinking, hintDependency,
hintSource, hintPerformance, hintStackTrace, hintGCStats,
hintGlobalVar,
hintGlobalVar, hintExpandMacro,
hintUser, hintUserRaw,
hintExtendedContext
@@ -59,13 +66,14 @@ const
errGeneralParseError: "general parse error",
errNewSectionExpected: "new section expected",
errInvalidDirectiveX: "invalid directive: '$1'",
errProveInit: "Cannot prove that '$1' is initialized.",
errGenerated: "$1",
errUser: "$1",
warnCannotOpenFile: "cannot open '$1'",
warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored",
warnXIsNeverRead: "'$1' is never read",
warnXmightNotBeenInit: "'$1' might not have been initialized",
warnDeprecated: "$1 is deprecated",
warnDeprecated: "$1",
warnConfigDeprecated: "config file '$1' is deprecated",
warnSmallLshouldNotBeUsed: "'l' should not be used as an identifier; may look like '1' (one)",
warnUnknownMagic: "unknown magic '$1' might crash the compiler",
@@ -78,11 +86,16 @@ const
warnUseBase: "use {.base.} for base methods; baseless methods are deprecated",
warnWriteToForeignHeap: "write to foreign heap",
warnUnsafeCode: "unsafe code: '$1'",
warnUnusedImportX: "imported and not used: '$1'",
warnInheritFromException: "inherit from a more precise exception type like ValueError, IOError or OSError",
warnEachIdentIsTuple: "each identifier is a tuple",
warnShadowIdent: "shadowed identifier: '$1'",
warnUnsafeSetLen: "setLen can potentially expand the sequence, " &
"but the element type '$1' doesn't have a valid default value",
warnUnsafeDefault: "The '$1' type doesn't have a valid default value",
warnProveInit: "Cannot prove that '$1' is initialized. This will become a compile time error in the future.",
warnProveField: "cannot prove that field '$1' is accessible",
warnProveIndex: "cannot prove index '$1' is valid",
warnStaticIndexCheck: "$1",
warnGcUnsafe: "not GC-safe: '$1'",
warnGcUnsafe2: "$1",
warnUninit: "'$1' might not have been initialized",
@@ -91,10 +104,13 @@ const
warnLockLevel: "$1",
warnResultShadowed: "Special variable 'result' is shadowed.",
warnInconsistentSpacing: "Number of spaces around '$#' is not consistent",
warnCaseTransition: "Potential object case transition, instantiate new object instead",
warnCycleCreated: "$1",
warnUser: "$1",
hintSuccess: "operation successful: $#",
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)",
hintCC: "CC: \'$1\'", # unused
# keep in sync with `testament.isSuccess`
hintSuccessX: "$loc LOC; $sec sec; $mem; $build build; proj: $project; out: $output",
hintCC: "CC: $1",
hintLineTooLong: "line too long",
hintXDeclaredButNotUsed: "'$1' is declared but not used",
hintConvToBaseNotNeeded: "conversion to base object is not needed",
@@ -107,16 +123,18 @@ const
hintConf: "used config file '$1'",
hintPath: "added path: '$1'",
hintConditionAlwaysTrue: "condition is always true: '$1'",
hintName: "name should be: '$1'",
hintConditionAlwaysFalse: "condition is always false: '$1'",
hintName: "$1",
hintPattern: "$1",
hintExecuting: "$1",
hintLinking: "",
hintLinking: "$1",
hintDependency: "$1",
hintSource: "$1",
hintPerformance: "$1",
hintStackTrace: "$1",
hintGCStats: "$1",
hintGlobalVar: "global variable declared here",
hintExpandMacro: "expanded macro: $1",
hintUser: "$1",
hintUserRaw: "$1",
hintExtendedContext: "$1",
@@ -131,17 +149,21 @@ const
"LanguageXNotSupported", "FieldXNotSupported",
"CommentXIgnored",
"TypelessParam", "UseBase", "WriteToForeignHeap",
"UnsafeCode", "EachIdentIsTuple", "ShadowIdent",
"ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
"UnsafeCode", "UnusedImport", "InheritFromException",
"EachIdentIsTuple",
"UnsafeSetLen", "UnsafeDefault",
"ProveInit", "ProveField", "ProveIndex",
"IndexCheck", "GcUnsafe", "GcUnsafe2", "Uninit",
"GcMem", "Destructor", "LockLevel", "ResultShadowed",
"Spacing", "User"]
"Spacing", "CaseTransition", "CycleCreated", "User"]
HintsToStr* = [
"Success", "SuccessX", "CC", "LineTooLong",
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
"XDeclaredButNotUsed",
"ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
"ExprAlwaysX", "QuitCalled", "Processing", "CodeBegin", "CodeEnd", "Conf",
"Path", "CondTrue", "Name", "Pattern", "Exec", "Link", "Dependency",
"Source", "Performance", "StackTrace", "GCStats", "GlobalVar",
"Path", "CondTrue", "CondFalse", "Name", "Pattern", "Exec", "Link", "Dependency",
"Source", "Performance", "StackTrace", "GCStats", "GlobalVar", "ExpandMacro",
"User", "UserRaw", "ExtendedContext",
]
@@ -166,11 +188,11 @@ type
proc computeNotesVerbosity(): array[0..3, TNoteKinds] =
result[3] = {low(TNoteKind)..high(TNoteKind)} - {}
result[2] = result[3] - {hintStackTrace, warnUninit, hintExtendedContext}
result[1] = result[2] - {warnShadowIdent, warnProveField, warnProveIndex,
result[1] = result[2] - {warnProveField, warnProveIndex,
warnGcUnsafe, hintPath, hintDependency, hintCodeBegin, hintCodeEnd,
hintSource, hintGlobalVar, hintGCStats}
result[0] = result[1] - {hintSuccessX, hintSuccess, hintConf,
hintProcessing, hintPattern, hintExecuting, hintLinking}
hintProcessing, hintPattern, hintExecuting, hintLinking, hintCC}
const
NotesVerbosity* = computeNotesVerbosity()
@@ -191,7 +213,7 @@ type
# used for better error messages and
# embedding the original source in the
# generated code
dirtyfile*: AbsoluteFile # the file that is actually read into memory
dirtyFile*: AbsoluteFile # the file that is actually read into memory
# and parsed; usually "" but is used
# for 'nimsuggest'
hash*: string # the checksum of the file
@@ -219,27 +241,25 @@ type
TErrorOutputs* = set[TErrorOutput]
ERecoverableError* = object of ValueError
ESuggestDone* = object of Exception
ESuggestDone* = object of ValueError
proc `==`*(a, b: FileIndex): bool {.borrow.}
proc raiseRecoverableError*(msg: string) {.noinline, noreturn.} =
proc raiseRecoverableError*(msg: string) {.noinline.} =
raise newException(ERecoverableError, msg)
const
InvalidFileIDX* = FileIndex(-1)
proc unknownLineInfo*(): TLineInfo =
result.line = uint16(0)
result.col = int16(-1)
result.fileIndex = InvalidFileIDX
InvalidFileIdx* = FileIndex(-1)
unknownLineInfo* = TLineInfo(line: 0, col: -1, fileIndex: InvalidFileIdx)
type
Severity* {.pure.} = enum ## VS Code only supports these three
Hint, Warning, Error
const trackPosInvalidFileIdx* = FileIndex(-2) # special marker so that no suggestions
# are produced within comments and string literals
const
trackPosInvalidFileIdx* = FileIndex(-2) # special marker so that no suggestions
# are produced within comments and string literals
commandLineIdx* = FileIndex(-3)
type
MsgConfig* = object ## does not need to be stored in the incremental cache
@@ -248,7 +268,7 @@ type
## some close token.
errorOutputs*: TErrorOutputs
msgContext*: seq[TLineInfo]
msgContext*: seq[tuple[info: TLineInfo, detail: string]]
lastError*: TLineInfo
filenameToIndexTbl*: Table[string, FileIndex]
fileInfos*: seq[TFileInfo]
@@ -257,7 +277,7 @@ type
proc initMsgConfig*(): MsgConfig =
result.msgContext = @[]
result.lastError = unknownLineInfo()
result.lastError = unknownLineInfo
result.filenameToIndexTbl = initTable[string, FileIndex]()
result.fileInfos = @[]
result.errorOutputs = {eStdOut, eStdErr}

View File

@@ -7,14 +7,11 @@
# distribution, for details about the copyright.
#
## This module implements the code "prettifier". This is part of the toolchain
## to convert Nim code into a consistent style.
## This module implements the style checker.
import
strutils, os, intsets, strtabs
import strutils
import options, ast, astalgo, msgs, semdata, ropes, idents,
lineinfos, pathutils
import options, ast, msgs, idents, lineinfos, wordrecg
const
Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'}
@@ -23,36 +20,6 @@ proc identLen*(line: string, start: int): int =
while start+result < line.len and line[start+result] in Letters:
inc result
when false:
import prettybase
type
StyleCheck* {.pure.} = enum None, Warn, Auto
var
gOverWrite* = true
gStyleCheck*: StyleCheck
gCheckExtern*, gOnlyMainfile*: bool
proc overwriteFiles*(conf: ConfigRef) =
let doStrip = options.getConfigVar(conf, "pretty.strip").normalize == "on"
for i in 0 .. high(conf.m.fileInfos):
if conf.m.fileInfos[i].dirty and
(not gOnlyMainfile or FileIndex(i) == conf.projectMainIdx):
let newFile = if gOverWrite: conf.m.fileInfos[i].fullpath
else: conf.m.fileInfos[i].fullpath.changeFileExt(".pretty.nim")
try:
var f = open(newFile.string, fmWrite)
for line in conf.m.fileInfos[i].lines:
if doStrip:
f.write line.strip(leading = false, trailing = true)
else:
f.write line
f.write(conf.m.fileInfos[i], "\L")
f.close
except IOError:
rawMessage(conf, errGenerated, "cannot open file: " & newFile.string)
proc `=~`(s: string, a: openArray[string]): bool =
for x in a:
if s.startsWith(x): return true
@@ -70,10 +37,10 @@ proc beautifyName(s: string, k: TSymKind): string =
# Types should start with a capital unless builtins like 'int' etc.:
if s =~ ["int", "uint", "cint", "cuint", "clong", "cstring", "string",
"char", "byte", "bool", "openArray", "seq", "array", "void",
"pointer", "float", "csize", "cdouble", "cchar", "cschar",
"cshort", "cu", "nil", "expr", "stmt", "typedesc", "auto", "any",
"range", "openarray", "varargs", "set", "cfloat"
]:
"pointer", "float", "csize", "csize_t", "cdouble", "cchar", "cschar",
"cshort", "cu", "nil", "typedesc", "auto", "any",
"range", "openarray", "varargs", "set", "cfloat", "ref", "ptr",
"untyped", "typed", "static", "sink", "lent", "type", "owned"]:
result.add s[i]
else:
result.add toUpperAscii(s[i])
@@ -102,75 +69,73 @@ proc beautifyName(s: string, k: TSymKind): string =
result.add s[i]
inc i
proc differ*(line: string, a, b: int, x: string): bool =
let y = line[a..b]
result = cmpIgnoreStyle(y, x) == 0 and y != x
proc differ*(line: string, a, b: int, x: string): string =
proc substrEq(s: string, pos, last: int, substr: string): bool =
var i = 0
while i < substr.len and pos+i <= last and s[pos+i] == substr[i]:
inc i
return i == substr.len
proc replaceInFile(conf: ConfigRef; info: TLineInfo; newName: string) =
let line = conf.m.fileInfos[info.fileIndex.int].lines[info.line.int-1]
var first = min(info.col.int, line.len)
if first < 0: return
#inc first, skipIgnoreCase(line, "proc ", first)
while first > 0 and line[first-1] in Letters: dec first
if first < 0: return
if line[first] == '`': inc first
let last = min(b, line.len)
let last = first+identLen(line, first)-1
if differ(line, first, last, newName):
# last-first+1 != newName.len or
var x = line.substr(0, first-1) & newName & line.substr(last+1)
system.shallowCopy(conf.m.fileInfos[info.fileIndex.int].lines[info.line.int-1], x)
conf.m.fileInfos[info.fileIndex.int].dirty = true
result = ""
if not substrEq(line, a, b, x):
let y = line[a..b]
if cmpIgnoreStyle(y, x) == 0:
result = y
proc checkStyle(conf: ConfigRef; cache: IdentCache; info: TLineInfo, s: string, k: TSymKind; sym: PSym) =
let beau = beautifyName(s, k)
if s != beau:
if gStyleCheck == StyleCheck.Auto:
sym.name = getIdent(cache, beau)
replaceInFile(conf, info, beau)
else:
message(conf, info, hintName, beau)
proc styleCheckDefImpl(conf: ConfigRef; cache: IdentCache; info: TLineInfo; s: PSym; k: TSymKind) =
# operators stay as they are:
if k in {skResult, skTemp} or s.name.s[0] notin Letters: return
if k in {skType, skGenericParam} and sfAnon in s.flags: return
if {sfImportc, sfExportc} * s.flags == {} or gCheckExtern:
checkStyle(conf, cache, info, s.name.s, k, s)
lintReport(conf, info, beau, s)
proc nep1CheckDefImpl(conf: ConfigRef; info: TLineInfo; s: PSym; k: TSymKind) =
# operators stay as they are:
if k in {skResult, skTemp} or s.name.s[0] notin Letters: return
if k in {skType, skGenericParam} and sfAnon in s.flags: return
if s.typ != nil and s.typ.kind == tyTypeDesc: return
if {sfImportc, sfExportc} * s.flags != {}: return
if optStyleCheck notin s.options: return
let beau = beautifyName(s.name.s, k)
if s.name.s != beau:
message(conf, info, hintName, beau)
lintReport(conf, info, beau, s.name.s)
template styleCheckDef*(conf: ConfigRef; info: TLineInfo; s: PSym; k: TSymKind) =
if optCheckNep1 in conf.globalOptions:
if {optStyleHint, optStyleError} * conf.globalOptions != {}:
nep1CheckDefImpl(conf, info, s, k)
when defined(nimfix):
if gStyleCheck != StyleCheck.None: styleCheckDefImpl(conf, cache, info, s, k)
template styleCheckDef*(conf: ConfigRef; info: TLineInfo; s: PSym) =
styleCheckDef(conf, info, s, s.kind)
template styleCheckDef*(conf: ConfigRef; s: PSym) =
styleCheckDef(conf, s.info, s, s.kind)
proc styleCheckUseImpl(conf: ConfigRef; info: TLineInfo; s: PSym) =
proc differs(conf: ConfigRef; info: TLineInfo; newName: string): string =
let line = sourceLine(conf, info)
var first = min(info.col.int, line.len)
if first < 0: return
#inc first, skipIgnoreCase(line, "proc ", first)
while first > 0 and line[first-1] in Letters: dec first
if first < 0: return
if first+1 < line.len and line[first] == '`': inc first
let last = first+identLen(line, first)-1
result = differ(line, first, last, newName)
proc styleCheckUse*(conf: ConfigRef; info: TLineInfo; s: PSym) =
if info.fileIndex.int < 0: return
# we simply convert it to what it looks like in the definition
# for consistency
# operators stay as they are:
if s.kind in {skResult, skTemp} or s.name.s[0] notin Letters:
if s.kind == skTemp or s.name.s[0] notin Letters or sfAnon in s.flags:
return
if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return
let newName = s.name.s
let oldName = differs(conf, info, newName)
if oldName.len > 0:
lintReport(conf, info, newName, oldName)
replaceInFile(conf, info, newName)
#if newName == "File": writeStackTrace()
template styleCheckUse*(info: TLineInfo; s: PSym) =
when defined(nimfix):
if gStyleCheck != StyleCheck.None: styleCheckUseImpl(conf, info, s)
proc checkPragmaUse*(conf: ConfigRef; info: TLineInfo; w: TSpecialWord; pragmaName: string) =
let wanted = canonPragmaSpelling(w)
if pragmaName != wanted:
lintReport(conf, info, wanted, pragmaName)

View File

@@ -1,28 +0,0 @@
#
#
# The Nim Compiler
# (c) Copyright 2012 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
# This module is deprecated, don't use it.
# TODO Remove this
import os
static:
echo "WARNING: imported deprecated module compiler/lists.nim, use seq ore lists from the standard library"
proc appendStr*(list: var seq[string]; data: string) {.deprecated.} =
# just use system.add
list.add(data)
proc includeStr(list: var seq[string]; data: string): bool {.deprecated.} =
if list.contains(data):
result = true
else:
result = false
list.add data

View File

@@ -10,13 +10,16 @@
## Low-level streams for high performance.
import
strutils, pathutils
pathutils
# support '-d:useGnuReadline' for backwards compatibility:
when not defined(windows) and (defined(useGnuReadline) or defined(useLinenoise)):
import rdstdin
# support `useGnuReadline`, `useLinenoise` for backwards compatibility
const hasRstdin = (defined(nimUseLinenoise) or defined(useLinenoise) or defined(useGnuReadline)) and
not defined(windows)
when hasRstdin: import rdstdin
type
TLLRepl* = proc (s: PLLStream, buf: pointer, bufLen: int): int
TLLStreamKind* = enum # enum of different stream implementations
llsNone, # null stream: reading and writing has no effect
llsString, # stream encapsulates a string
@@ -28,6 +31,7 @@ type
s*: string
rd*, wr*: int # for string streams
lineOffset*: int # for fake stdin line numbers
repl*: TLLRepl # gives stdin control to clients
PLLStream* = ref TLLStream
@@ -50,11 +54,13 @@ proc llStreamOpen*(): PLLStream =
new(result)
result.kind = llsNone
proc llStreamOpenStdIn*(): PLLStream =
proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int
proc llStreamOpenStdIn*(r: TLLRepl = llReadFromStdin): PLLStream =
new(result)
result.kind = llsStdIn
result.s = ""
result.lineOffset = -1
result.repl = r
proc llStreamClose*(s: PLLStream) =
case s.kind
@@ -66,10 +72,10 @@ proc llStreamClose*(s: PLLStream) =
when not declared(readLineFromStdin):
# fallback implementation:
proc readLineFromStdin(prompt: string, line: var string): bool =
stdout.write(prompt)
stderr.write(prompt)
result = readLine(stdin, line)
if not result:
stdout.write("\n")
stderr.write("\n")
quit(0)
proc endsWith*(x: string, s: set[char]): bool =
@@ -93,7 +99,7 @@ proc continueLine(line: string, inTripleString: bool): bool {.inline.} =
proc countTriples(s: string): int =
var i = 0
while i < s.len:
while i+2 < s.len:
if s[i] == '"' and s[i+1] == '"' and s[i+2] == '"':
inc result
inc i, 2
@@ -105,12 +111,12 @@ proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
var line = newStringOfCap(120)
var triples = 0
while readLineFromStdin(if s.s.len == 0: ">>> " else: "... ", line):
add(s.s, line)
add(s.s, "\n")
s.s.add(line)
s.s.add("\n")
inc triples, countTriples(line)
if not continueLine(line, (triples and 1) == 1): break
inc(s.lineOffset)
result = min(bufLen, len(s.s) - s.rd)
result = min(bufLen, s.s.len - s.rd)
if result > 0:
copyMem(buf, addr(s.s[s.rd]), result)
inc(s.rd, result)
@@ -120,14 +126,14 @@ proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int =
of llsNone:
result = 0
of llsString:
result = min(bufLen, len(s.s) - s.rd)
result = min(bufLen, s.s.len - s.rd)
if result > 0:
copyMem(buf, addr(s.s[0 + s.rd]), result)
inc(s.rd, result)
of llsFile:
result = readBuffer(s.f, buf, bufLen)
of llsStdIn:
result = llReadFromStdin(s, buf, bufLen)
result = s.repl(s, buf, bufLen)
proc llStreamReadLine*(s: PLLStream, line: var string): bool =
setLen(line, 0)
@@ -135,7 +141,7 @@ proc llStreamReadLine*(s: PLLStream, line: var string): bool =
of llsNone:
result = true
of llsString:
while s.rd < len(s.s):
while s.rd < s.s.len:
case s.s[s.rd]
of '\x0D':
inc(s.rd)
@@ -145,9 +151,9 @@ proc llStreamReadLine*(s: PLLStream, line: var string): bool =
inc(s.rd)
break
else:
add(line, s.s[s.rd])
line.add(s.s[s.rd])
inc(s.rd)
result = line.len > 0 or s.rd < len(s.s)
result = line.len > 0 or s.rd < s.s.len
of llsFile:
result = readLine(s.f, line)
of llsStdIn:
@@ -158,8 +164,8 @@ proc llStreamWrite*(s: PLLStream, data: string) =
of llsNone, llsStdIn:
discard
of llsString:
add(s.s, data)
inc(s.wr, len(data))
s.s.add(data)
inc(s.wr, data.len)
of llsFile:
write(s.f, data)
@@ -173,7 +179,7 @@ proc llStreamWrite*(s: PLLStream, data: char) =
of llsNone, llsStdIn:
discard
of llsString:
add(s.s, data)
s.s.add(data)
inc(s.wr)
of llsFile:
c = data
@@ -185,7 +191,7 @@ proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int) =
discard
of llsString:
if buflen > 0:
setLen(s.s, len(s.s) + buflen)
setLen(s.s, s.s.len + buflen)
copyMem(addr(s.s[0 + s.wr]), buf, buflen)
inc(s.wr, buflen)
of llsFile:
@@ -200,7 +206,7 @@ proc llStreamReadAll*(s: PLLStream): string =
of llsString:
if s.rd == 0: result = s.s
else: result = substr(s.s, s.rd)
s.rd = len(s.s)
s.rd = s.s.len
of llsFile:
result = newString(bufSize)
var bytes = readBuffer(s.f, addr(result[0]), bufSize)

View File

@@ -11,7 +11,7 @@
import
intsets, ast, astalgo, idents, semdata, types, msgs, options,
renderer, wordrecg, idgen, nimfix/prettybase, lineinfos, strutils
renderer, nimfix/prettybase, lineinfos, strutils
proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope)
@@ -36,11 +36,11 @@ proc considerQuotedIdent*(c: PContext; n: PNode, origin: PNode = nil): PIdent =
of nkAccQuoted:
case n.len
of 0: handleError(n, origin)
of 1: result = considerQuotedIdent(c, n.sons[0], origin)
of 1: result = considerQuotedIdent(c, n[0], origin)
else:
var id = ""
for i in 0..<n.len:
let x = n.sons[i]
let x = n[i]
case x.kind
of nkIdent: id.add(x.ident.s)
of nkSym: id.add(x.sym.name.s)
@@ -49,7 +49,7 @@ proc considerQuotedIdent*(c: PContext; n: PNode, origin: PNode = nil): PIdent =
result = getIdent(c.cache, id)
of nkOpenSymChoice, nkClosedSymChoice:
if n[0].kind == nkSym:
result = n.sons[0].sym.name
result = n[0].sym.name
else:
handleError(n, origin)
else:
@@ -89,7 +89,7 @@ proc skipAlias*(s: PSym; n: PNode; conf: ConfigRef): PSym =
prettybase.replaceDeprecated(conf, n.info, s, result)
else:
message(conf, n.info, warnDeprecated, "use " & result.name.s & " instead; " &
s.name.s)
s.name.s & " is deprecated")
proc localSearchInScope*(c: PContext, s: PIdent): PSym =
result = strTableGet(c.currentScope.symbols, s)
@@ -100,16 +100,15 @@ proc searchInScopes*(c: PContext, s: PIdent): PSym =
if result != nil: return
result = nil
when declared(echo):
proc debugScopes*(c: PContext; limit=0) {.deprecated.} =
var i = 0
for scope in walkScopes(c.currentScope):
echo "scope ", i
for h in 0 .. high(scope.symbols.data):
if scope.symbols.data[h] != nil:
echo scope.symbols.data[h].name.s
if i == limit: break
inc i
proc debugScopes*(c: PContext; limit=0) {.deprecated.} =
var i = 0
for scope in walkScopes(c.currentScope):
echo "scope ", i
for h in 0..high(scope.symbols.data):
if scope.symbols.data[h] != nil:
echo scope.symbols.data[h].name.s
if i == limit: break
inc i
proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym =
for scope in walkScopes(c.currentScope):
@@ -124,7 +123,7 @@ proc errorSym*(c: PContext, n: PNode): PSym =
## creates an error symbol to avoid cascading errors (for IDE support)
var m = n
# ensure that 'considerQuotedIdent' can't fail:
if m.kind == nkDotExpr: m = m.sons[1]
if m.kind == nkDotExpr: m = m[1]
let ident = if m.kind in {nkIdent, nkSym, nkAccQuoted}:
considerQuotedIdent(c, m)
else:
@@ -150,7 +149,7 @@ type
proc getSymRepr*(conf: ConfigRef; s: PSym): string =
case s.kind
of skProc, skFunc, skMethod, skConverter, skIterator:
of routineKinds, skType:
result = getProcHeader(conf, s)
else:
result = s.name.s
@@ -168,13 +167,13 @@ proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) =
localError(c.config, s.info, "implementation of '$1' expected" %
getSymRepr(c.config, s))
inc missingImpls
elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options:
if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}:
elif {sfUsed, sfExported} * s.flags == {}:
if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam, skEnumField}:
# XXX: implicit type params are currently skTypes
# maybe they can be made skGenericParam as well.
if s.typ != nil and tfImplicitTypeParam notin s.typ.flags and
s.typ.kind != tyGenericParam:
message(c.config, s.info, hintXDeclaredButNotUsed, getSymRepr(c.config, s))
message(c.config, s.info, hintXDeclaredButNotUsed, s.name.s)
s = nextIter(it, scope.symbols)
proc wrongRedefinition*(c: PContext; info: TLineInfo, s: string;
@@ -190,7 +189,7 @@ proc addDecl*(c: PContext, sym: PSym, info: TLineInfo) =
wrongRedefinition(c, info, sym.name.s, conflict.info)
proc addDecl*(c: PContext, sym: PSym) =
let conflict = c.currentScope.addUniqueSym(sym)
let conflict = strTableInclReportConflict(c.currentScope.symbols, sym, true)
if conflict != nil:
wrongRedefinition(c, sym.info, sym.name.s, conflict.info)
@@ -233,7 +232,7 @@ proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) =
addInterfaceDeclAux(c, sym)
when defined(nimfix):
# when we cannot find the identifier, retry with a changed identifer:
# when we cannot find the identifier, retry with a changed identifier:
proc altSpelling(x: PIdent): PIdent =
case x.s[0]
of 'A'..'Z': result = getIdent(toLowerAscii(x.s[0]) & x.s.substr(1))
@@ -255,9 +254,10 @@ proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) =
var candidate = initIdentIter(ti, c.importTable.symbols, s.name)
var i = 0
while candidate != nil:
if i == 0: err.add " --use "
else: err.add " or "
err.add candidate.owner.name.s & "." & candidate.name.s
if i == 0: err.add " -- use one of the following:\n"
else: err.add "\n"
err.add " " & candidate.owner.name.s & "." & candidate.name.s
err.add ": " & typeToString(candidate.typ)
candidate = nextIdentIter(ti, c.importTable.symbols)
inc i
localError(c.config, info, errGenerated, err)
@@ -325,29 +325,29 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
errorUseQualifier(c, n.info, n.sym)
of nkDotExpr:
result = nil
var m = qualifiedLookUp(c, n.sons[0], (flags*{checkUndeclared})+{checkModule})
var m = qualifiedLookUp(c, n[0], (flags*{checkUndeclared})+{checkModule})
if m != nil and m.kind == skModule:
var ident: PIdent = nil
if n.sons[1].kind == nkIdent:
ident = n.sons[1].ident
elif n.sons[1].kind == nkAccQuoted:
ident = considerQuotedIdent(c, n.sons[1])
if n[1].kind == nkIdent:
ident = n[1].ident
elif n[1].kind == nkAccQuoted:
ident = considerQuotedIdent(c, n[1])
if ident != nil:
if m == c.module:
result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n, c.config)
else:
result = strTableGet(m.tab, ident).skipAlias(n, c.config)
if result == nil and checkUndeclared in flags:
fixSpelling(n.sons[1], ident, searchInScopes)
errorUndeclaredIdentifier(c, n.sons[1].info, ident.s)
result = errorSym(c, n.sons[1])
elif n.sons[1].kind == nkSym:
result = n.sons[1].sym
fixSpelling(n[1], ident, searchInScopes)
errorUndeclaredIdentifier(c, n[1].info, ident.s)
result = errorSym(c, n[1])
elif n[1].kind == nkSym:
result = n[1].sym
elif checkUndeclared in flags and
n.sons[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}:
localError(c.config, n.sons[1].info, "identifier expected, but got: " &
renderTree(n.sons[1]))
result = errorSym(c, n.sons[1])
n[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}:
localError(c.config, n[1].info, "identifier expected, but got: " &
renderTree(n[1]))
result = errorSym(c, n[1])
else:
result = nil
when false:
@@ -371,13 +371,13 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
o.mode = oimDone
of nkDotExpr:
o.mode = oimOtherModule
o.m = qualifiedLookUp(c, n.sons[0], {checkUndeclared, checkModule})
o.m = qualifiedLookUp(c, n[0], {checkUndeclared, checkModule})
if o.m != nil and o.m.kind == skModule:
var ident: PIdent = nil
if n.sons[1].kind == nkIdent:
ident = n.sons[1].ident
elif n.sons[1].kind == nkAccQuoted:
ident = considerQuotedIdent(c, n.sons[1], n)
if n[1].kind == nkIdent:
ident = n[1].ident
elif n[1].kind == nkAccQuoted:
ident = considerQuotedIdent(c, n[1], n)
if ident != nil:
if o.m == c.module:
# a module may access its private members:
@@ -387,12 +387,12 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
else:
result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n, c.config)
else:
noidentError(c.config, n.sons[1], n)
result = errorSym(c, n.sons[1])
noidentError(c.config, n[1], n)
result = errorSym(c, n[1])
of nkClosedSymChoice, nkOpenSymChoice:
o.mode = oimSymChoice
if n[0].kind == nkSym:
result = n.sons[0].sym
result = n[0].sym
else:
o.mode = oimDone
return nil
@@ -429,8 +429,8 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
of oimOtherModule:
result = nextIdentIter(o.it, o.m.tab).skipAlias(n, c.config)
of oimSymChoice:
if o.symChoiceIndex < sonsLen(n):
result = n.sons[o.symChoiceIndex].sym
if o.symChoiceIndex < n.len:
result = n[o.symChoiceIndex].sym
incl(o.inSymChoice, result.id)
inc o.symChoiceIndex
elif n.kind == nkOpenSymChoice:
@@ -438,19 +438,19 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
o.mode = oimSymChoiceLocalLookup
o.scope = c.currentScope
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
n[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
while result == nil:
o.scope = o.scope.parent
if o.scope == nil: break
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
n[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
of oimSymChoiceLocalLookup:
result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice).skipAlias(n, c.config)
while result == nil:
o.scope = o.scope.parent
if o.scope == nil: break
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
n[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
when false:
if result != nil and result.kind == skStub: loadStub(result)

View File

@@ -14,36 +14,50 @@ const
import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs,
lineinfos
from trees import getMagic
proc newDeref*(n: PNode): PNode {.inline.} =
result = newNodeIT(nkHiddenDeref, n.info, n.typ.sons[0])
addSon(result, n)
result = newNodeIT(nkHiddenDeref, n.info, n.typ[0])
result.add n
proc newTupleAccess*(g: ModuleGraph; tup: PNode, i: int): PNode =
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
abstractInst).sons[i])
addSon(result, copyTree(tup))
var lit = newNodeIT(nkIntLit, tup.info, getSysType(g, tup.info, tyInt))
lit.intVal = i
addSon(result, lit)
if tup.kind == nkHiddenAddr:
result = newNodeIT(nkHiddenAddr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent}))
result.add newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent})[i])
result[0].add tup[0]
var lit = newNodeIT(nkIntLit, tup.info, getSysType(g, tup.info, tyInt))
lit.intVal = i
result[0].add lit
else:
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
abstractInst)[i])
result.add copyTree(tup)
var lit = newNodeIT(nkIntLit, tup.info, getSysType(g, tup.info, tyInt))
lit.intVal = i
result.add lit
proc addVar*(father, v: PNode) =
var vpart = newNodeI(nkIdentDefs, v.info, 3)
vpart.sons[0] = v
vpart.sons[1] = newNodeI(nkEmpty, v.info)
vpart.sons[2] = vpart[1]
addSon(father, vpart)
vpart[0] = v
vpart[1] = newNodeI(nkEmpty, v.info)
vpart[2] = vpart[1]
father.add vpart
proc newAsgnStmt(le, ri: PNode): PNode =
proc addVar*(father, v, value: PNode) =
var vpart = newNodeI(nkIdentDefs, v.info, 3)
vpart[0] = v
vpart[1] = newNodeI(nkEmpty, v.info)
vpart[2] = value
father.add vpart
proc newAsgnStmt*(le, ri: PNode): PNode =
result = newNodeI(nkAsgn, le.info, 2)
result.sons[0] = le
result.sons[1] = ri
result[0] = le
result[1] = ri
proc newFastAsgnStmt(le, ri: PNode): PNode =
proc newFastAsgnStmt*(le, ri: PNode): PNode =
result = newNodeI(nkFastAsgn, le.info, 2)
result.sons[0] = le
result.sons[1] = ri
result[0] = le
result[1] = ri
proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
assert n.kind == nkVarTuple
@@ -56,58 +70,74 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
var v = newNodeI(nkVarSection, value.info)
let tempAsNode = newSymNode(temp)
v.addVar(tempAsNode)
v.addVar(tempAsNode, value)
result.add(v)
for i in 0..<n.len-2:
let val = newTupleAccess(g, tempAsNode, i)
if n[i].kind == nkSym: v.addVar(n[i], val)
else: result.add newAsgnStmt(n[i], val)
proc evalOnce*(g: ModuleGraph; value: PNode; owner: PSym): PNode =
## Turns (value) into (let tmp = value; tmp) so that 'value' can be re-used
## freely, multiple times. This is frequently required and such a builtin would also be
## handy to have in macros.nim. The value that can be reused is 'result.lastSon'!
result = newNodeIT(nkStmtListExpr, value.info, value.typ)
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), owner, value.info, g.config.options)
temp.typ = skipTypes(value.typ, abstractInst)
incl(temp.flags, sfFromGeneric)
var v = newNodeI(nkLetSection, value.info)
let tempAsNode = newSymNode(temp)
v.addVar(tempAsNode)
result.add(v)
result.add newAsgnStmt(tempAsNode, value)
for i in 0 .. n.len-3:
if n.sons[i].kind == nkSym: v.addVar(n.sons[i])
result.add newAsgnStmt(n.sons[i], newTupleAccess(g, tempAsNode, i))
result.add tempAsNode
proc newTupleAccessRaw*(tup: PNode, i: int): PNode =
result = newNodeI(nkBracketExpr, tup.info)
addSon(result, copyTree(tup))
result.add copyTree(tup)
var lit = newNodeI(nkIntLit, tup.info)
lit.intVal = i
addSon(result, lit)
result.add lit
proc newTryFinally*(body, final: PNode): PNode =
result = newTree(nkTryStmt, body, newTree(nkFinally, final))
result = newTree(nkHiddenTryStmt, body, newTree(nkFinally, final))
proc lowerTupleUnpackingForAsgn*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
let value = n.lastSon
result = newNodeI(nkStmtList, n.info)
var temp = newSym(skLet, getIdent(g.cache, "_"), owner, value.info, owner.options)
var temp = newSym(skTemp, getIdent(g.cache, "_"), owner, value.info, owner.options)
var v = newNodeI(nkLetSection, value.info)
let tempAsNode = newSymNode(temp) #newIdentNode(getIdent(genPrefix & $temp.id), value.info)
var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3)
vpart.sons[0] = tempAsNode
vpart.sons[1] = newNodeI(nkEmpty, value.info)
vpart.sons[2] = value
addSon(v, vpart)
vpart[0] = tempAsNode
vpart[1] = newNodeI(nkEmpty, value.info)
vpart[2] = value
v.add vpart
result.add(v)
let lhs = n.sons[0]
for i in 0 .. lhs.len-1:
result.add newAsgnStmt(lhs.sons[i], newTupleAccessRaw(tempAsNode, i))
let lhs = n[0]
for i in 0..<lhs.len:
result.add newAsgnStmt(lhs[i], newTupleAccessRaw(tempAsNode, i))
proc lowerSwap*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
result = newNodeI(nkStmtList, n.info)
# note: cannot use 'skTemp' here cause we really need the copy for the VM :-(
var temp = newSym(skVar, getIdent(g.cache, genPrefix), owner, n.info, owner.options)
temp.typ = n.sons[1].typ
temp.typ = n[1].typ
incl(temp.flags, sfFromGeneric)
var v = newNodeI(nkVarSection, n.info)
let tempAsNode = newSymNode(temp)
var vpart = newNodeI(nkIdentDefs, v.info, 3)
vpart.sons[0] = tempAsNode
vpart.sons[1] = newNodeI(nkEmpty, v.info)
vpart.sons[2] = n[1]
addSon(v, vpart)
vpart[0] = tempAsNode
vpart[1] = newNodeI(nkEmpty, v.info)
vpart[2] = n[1]
v.add vpart
result.add(v)
result.add newFastAsgnStmt(n[1], n[2])
@@ -127,45 +157,53 @@ proc createObj*(g: ModuleGraph; owner: PSym, info: TLineInfo; final=true): PType
s.typ = result
result.sym = s
template fieldCheck {.dirty.} =
when false:
if tfCheckedForDestructor in obj.flags:
echo "missed field ", field.name.s
writeStackTrace()
proc rawAddField*(obj: PType; field: PSym) =
assert field.kind == skField
field.position = sonsLen(obj.n)
addSon(obj.n, newSymNode(field))
field.position = obj.n.len
obj.n.add newSymNode(field)
propagateToOwner(obj, field.typ)
fieldCheck()
proc rawIndirectAccess*(a: PNode; field: PSym; info: TLineInfo): PNode =
# returns a[].field as a node
assert field.kind == skField
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = a.typ.skipTypes(abstractInst).sons[0]
addSon(deref, a)
deref.typ = a.typ.skipTypes(abstractInst)[0]
deref.add a
result = newNodeI(nkDotExpr, info)
addSon(result, deref)
addSon(result, newSymNode(field))
result.add deref
result.add newSymNode(field)
result.typ = field.typ
proc rawDirectAccess*(obj, field: PSym): PNode =
# returns a.field as a node
assert field.kind == skField
result = newNodeI(nkDotExpr, field.info)
addSon(result, newSymNode obj)
addSon(result, newSymNode field)
result.add newSymNode(obj)
result.add newSymNode(field)
result.typ = field.typ
proc lookupInRecord(n: PNode, id: int): PSym =
result = nil
case n.kind
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
result = lookupInRecord(n.sons[i], id)
for i in 0..<n.len:
result = lookupInRecord(n[i], id)
if result != nil: return
of nkRecCase:
if n.sons[0].kind != nkSym: return
result = lookupInRecord(n.sons[0], id)
if n[0].kind != nkSym: return
result = lookupInRecord(n[0], id)
if result != nil: return
for i in countup(1, sonsLen(n) - 1):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
result = lookupInRecord(lastSon(n.sons[i]), id)
result = lookupInRecord(lastSon(n[i]), id)
if result != nil: return
else: discard
of nkSym:
@@ -180,9 +218,12 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache) =
field.id = -s.id
let t = skipIntLit(s.typ)
field.typ = t
assert t.kind != tyStmt
field.position = sonsLen(obj.n)
addSon(obj.n, newSymNode(field))
assert t.kind != tyTyped
propagateToOwner(obj, t)
field.position = obj.n.len
field.flags = s.flags * {sfCursor}
obj.n.add newSymNode(field)
fieldCheck()
proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable.} =
result = lookupInRecord(obj.n, s.id)
@@ -192,46 +233,47 @@ proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable
field.id = -s.id
let t = skipIntLit(s.typ)
field.typ = t
assert t.kind != tyStmt
field.position = sonsLen(obj.n)
addSon(obj.n, newSymNode(field))
assert t.kind != tyTyped
propagateToOwner(obj, t)
field.position = obj.n.len
obj.n.add newSymNode(field)
result = field
proc newDotExpr(obj, b: PSym): PNode =
proc newDotExpr*(obj, b: PSym): PNode =
result = newNodeI(nkDotExpr, obj.info)
let field = lookupInRecord(obj.typ.n, b.id)
assert field != nil, b.name.s
addSon(result, newSymNode(obj))
addSon(result, newSymNode(field))
result.add newSymNode(obj)
result.add newSymNode(field)
result.typ = field.typ
proc indirectAccess*(a: PNode, b: int, info: TLineInfo): PNode =
# returns a[].b as a node
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = a.typ.skipTypes(abstractInst).sons[0]
deref.typ = a.typ.skipTypes(abstractInst)[0]
var t = deref.typ.skipTypes(abstractInst)
var field: PSym
while true:
assert t.kind == tyObject
field = lookupInRecord(t.n, b)
if field != nil: break
t = t.sons[0]
t = t[0]
if t == nil: break
t = t.skipTypes(skipPtrs)
#if field == nil:
# echo "FIELD ", b
# debug deref.typ
assert field != nil
addSon(deref, a)
deref.add a
result = newNodeI(nkDotExpr, info)
addSon(result, deref)
addSon(result, newSymNode(field))
result.add deref
result.add newSymNode(field)
result.typ = field.typ
proc indirectAccess(a: PNode, b: string, info: TLineInfo; cache: IdentCache): PNode =
proc indirectAccess*(a: PNode, b: string, info: TLineInfo; cache: IdentCache): PNode =
# returns a[].b as a node
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = a.typ.skipTypes(abstractInst).sons[0]
deref.typ = a.typ.skipTypes(abstractInst)[0]
var t = deref.typ.skipTypes(abstractInst)
var field: PSym
let bb = getIdent(cache, b)
@@ -239,17 +281,17 @@ proc indirectAccess(a: PNode, b: string, info: TLineInfo; cache: IdentCache): PN
assert t.kind == tyObject
field = getSymFromList(t.n, bb)
if field != nil: break
t = t.sons[0]
t = t[0]
if t == nil: break
t = t.skipTypes(skipPtrs)
#if field == nil:
# echo "FIELD ", b
# debug deref.typ
assert field != nil
addSon(deref, a)
deref.add a
result = newNodeI(nkDotExpr, info)
addSon(result, deref)
addSon(result, newSymNode(field))
result.add deref
result.add newSymNode(field)
result.typ = field.typ
proc getFieldFromObj*(t: PType; v: PSym): PSym =
@@ -259,7 +301,7 @@ proc getFieldFromObj*(t: PType; v: PSym): PSym =
assert t.kind == tyObject
result = lookupInRecord(t.n, v.id)
if result != nil: break
t = t.sons[0]
t = t[0]
if t == nil: break
t = t.skipTypes(skipPtrs)
@@ -270,257 +312,33 @@ proc indirectAccess*(a: PNode, b: PSym, info: TLineInfo): PNode =
proc indirectAccess*(a, b: PSym, info: TLineInfo): PNode =
result = indirectAccess(newSymNode(a), b, info)
proc genAddrOf*(n: PNode): PNode =
proc genAddrOf*(n: PNode, typeKind = tyPtr): PNode =
result = newNodeI(nkAddr, n.info, 1)
result.sons[0] = n
result.typ = newType(tyPtr, n.typ.owner)
result[0] = n
result.typ = newType(typeKind, n.typ.owner)
result.typ.rawAddSon(n.typ)
proc genDeref*(n: PNode): PNode =
result = newNodeIT(nkHiddenDeref, n.info,
n.typ.skipTypes(abstractInst).sons[0])
proc genDeref*(n: PNode; k = nkHiddenDeref): PNode =
result = newNodeIT(k, n.info,
n.typ.skipTypes(abstractInst)[0])
result.add n
proc callCodegenProc*(g: ModuleGraph; name: string, arg1: PNode;
arg2, arg3, optionalArgs: PNode = nil): PNode =
result = newNodeI(nkCall, arg1.info)
proc callCodegenProc*(g: ModuleGraph; name: string;
info: TLineInfo = unknownLineInfo;
arg1, arg2, arg3, optionalArgs: PNode = nil): PNode =
result = newNodeI(nkCall, info)
let sym = magicsys.getCompilerProc(g, name)
if sym == nil:
localError(g.config, arg1.info, "system module needs: " & name)
localError(g.config, info, "system module needs: " & name)
else:
result.add newSymNode(sym)
result.add arg1
if arg1 != nil: result.add arg1
if arg2 != nil: result.add arg2
if arg3 != nil: result.add arg3
if optionalArgs != nil:
for i in 1..optionalArgs.len-3:
for i in 1..<optionalArgs.len-2:
result.add optionalArgs[i]
result.typ = sym.typ.sons[0]
proc callProc(a: PNode): PNode =
result = newNodeI(nkCall, a.info)
result.add a
result.typ = a.typ.sons[0]
# we have 4 cases to consider:
# - a void proc --> nothing to do
# - a proc returning GC'ed memory --> requires a flowVar
# - a proc returning non GC'ed memory --> pass as hidden 'var' parameter
# - not in a parallel environment --> requires a flowVar for memory safety
type
TSpawnResult* = enum
srVoid, srFlowVar, srByVar
TFlowVarKind = enum
fvInvalid # invalid type T for 'FlowVar[T]'
fvGC # FlowVar of a GC'ed type
fvBlob # FlowVar of a blob type
proc spawnResult*(t: PType; inParallel: bool): TSpawnResult =
if t.isEmptyType: srVoid
elif inParallel and not containsGarbageCollectedRef(t): srByVar
else: srFlowVar
proc flowVarKind(t: PType): TFlowVarKind =
if t.skipTypes(abstractInst).kind in {tyRef, tyString, tySequence}: fvGC
elif containsGarbageCollectedRef(t): fvInvalid
else: fvBlob
proc typeNeedsNoDeepCopy(t: PType): bool =
var t = t.skipTypes(abstractInst)
# for the tconvexhull example (and others) we're a bit lax here and pretend
# seqs and strings are *by value* only and 'shallow' doesn't exist!
if t.kind == tyString: return true
# note that seq[T] is fine, but 'var seq[T]' is not, so we need to skip 'var'
# for the stricter check and likewise we can skip 'seq' for a less
# strict check:
if t.kind in {tyVar, tyLent, tySequence}: t = t.lastSon
result = not containsGarbageCollectedRef(t)
proc hoistExpr*(varSection, expr: PNode, name: PIdent, owner: PSym): PSym =
result = newSym(skLet, name, owner, varSection.info, owner.options)
result.flags.incl sfHoisted
result.typ = expr.typ
var varDef = newNodeI(nkIdentDefs, varSection.info, 3)
varDef.sons[0] = newSymNode(result)
varDef.sons[1] = newNodeI(nkEmpty, varSection.info)
varDef.sons[2] = expr
varSection.add varDef
proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; owner: PSym; typ: PType;
v: PNode; useShallowCopy=false): PSym =
result = newSym(skTemp, getIdent(g.cache, genPrefix), owner, varSection.info,
owner.options)
result.typ = typ
incl(result.flags, sfFromGeneric)
var vpart = newNodeI(nkIdentDefs, varSection.info, 3)
vpart.sons[0] = newSymNode(result)
vpart.sons[1] = newNodeI(nkEmpty, varSection.info)
vpart.sons[2] = if varInit.isNil: v else: vpart[1]
varSection.add vpart
if varInit != nil:
if useShallowCopy and typeNeedsNoDeepCopy(typ):
varInit.add newFastAsgnStmt(newSymNode(result), v)
else:
let deepCopyCall = newNodeI(nkCall, varInit.info, 3)
deepCopyCall.sons[0] = newSymNode(getSysMagic(g, varSection.info, "deepCopy", mDeepCopy))
deepCopyCall.sons[1] = newSymNode(result)
deepCopyCall.sons[2] = v
varInit.add deepCopyCall
discard """
We generate roughly this:
proc f_wrapper(thread, args) =
barrierEnter(args.barrier) # for parallel statement
var a = args.a # thread transfer; deepCopy or shallowCopy or no copy
# depending on whether we're in a 'parallel' statement
var b = args.b
var fv = args.fv
fv.owner = thread # optional
nimArgsPassingDone() # signal parent that the work is done
#
args.fv.blob = f(a, b, ...)
nimFlowVarSignal(args.fv)
# - or -
f(a, b, ...)
barrierLeave(args.barrier) # for parallel statement
stmtList:
var scratchObj
scratchObj.a = a
scratchObj.b = b
nimSpawn(f_wrapper, addr scratchObj)
scratchObj.fv # optional
"""
proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym;
varSection, varInit, call, barrier, fv: PNode;
spawnKind: TSpawnResult): PSym =
var body = newNodeI(nkStmtList, f.info)
var threadLocalBarrier: PSym
if barrier != nil:
var varSection2 = newNodeI(nkVarSection, barrier.info)
threadLocalBarrier = addLocalVar(g, varSection2, nil, argsParam.owner,
barrier.typ, barrier)
body.add varSection2
body.add callCodegenProc(g, "barrierEnter", threadLocalBarrier.newSymNode)
var threadLocalProm: PSym
if spawnKind == srByVar:
threadLocalProm = addLocalVar(g, varSection, nil, argsParam.owner, fv.typ, fv)
elif fv != nil:
internalAssert g.config, fv.typ.kind == tyGenericInst
threadLocalProm = addLocalVar(g, varSection, nil, argsParam.owner, fv.typ, fv)
body.add varSection
body.add varInit
if fv != nil and spawnKind != srByVar:
# generate:
# fv.owner = threadParam
body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode,
"owner", fv.info, g.cache), threadParam.newSymNode)
body.add callCodegenProc(g, "nimArgsPassingDone", threadParam.newSymNode)
if spawnKind == srByVar:
body.add newAsgnStmt(genDeref(threadLocalProm.newSymNode), call)
elif fv != nil:
let fk = fv.typ.sons[1].flowVarKind
if fk == fvInvalid:
localError(g.config, f.info, "cannot create a flowVar of type: " &
typeToString(fv.typ.sons[1]))
body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode,
if fk == fvGC: "data" else: "blob", fv.info, g.cache), call)
if fk == fvGC:
let incRefCall = newNodeI(nkCall, fv.info, 2)
incRefCall.sons[0] = newSymNode(getSysMagic(g, fv.info, "GCref", mGCref))
incRefCall.sons[1] = indirectAccess(threadLocalProm.newSymNode,
"data", fv.info, g.cache)
body.add incRefCall
if barrier == nil:
# by now 'fv' is shared and thus might have beeen overwritten! we need
# to use the thread-local view instead:
body.add callCodegenProc(g, "nimFlowVarSignal", threadLocalProm.newSymNode)
else:
body.add call
if barrier != nil:
body.add callCodegenProc(g, "barrierLeave", threadLocalBarrier.newSymNode)
var params = newNodeI(nkFormalParams, f.info)
params.add newNodeI(nkEmpty, f.info)
params.add threadParam.newSymNode
params.add argsParam.newSymNode
var t = newType(tyProc, threadParam.owner)
t.rawAddSon nil
t.rawAddSon threadParam.typ
t.rawAddSon argsParam.typ
t.n = newNodeI(nkFormalParams, f.info)
t.n.add newNodeI(nkEffectList, f.info)
t.n.add threadParam.newSymNode
t.n.add argsParam.newSymNode
let name = (if f.kind == nkSym: f.sym.name.s else: genPrefix) & "Wrapper"
result = newSym(skProc, getIdent(g.cache, name), argsParam.owner, f.info,
argsParam.options)
let emptyNode = newNodeI(nkEmpty, f.info)
result.ast = newProcNode(nkProcDef, f.info, body = body,
params = params, name = newSymNode(result), pattern = emptyNode,
genericParams = emptyNode, pragmas = emptyNode,
exceptions = emptyNode)
result.typ = t
proc createCastExpr(argsParam: PSym; objType: PType): PNode =
result = newNodeI(nkCast, argsParam.info)
result.add newNodeI(nkEmpty, argsParam.info)
result.add newSymNode(argsParam)
result.typ = newType(tyPtr, objType.owner)
result.typ.rawAddSon(objType)
proc setupArgsForConcurrency(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym,
castExpr, call,
varSection, varInit, result: PNode) =
let formals = n[0].typ.n
let tmpName = getIdent(g.cache, genPrefix)
for i in 1 ..< n.len:
# we pick n's type here, which hopefully is 'tyArray' and not
# 'tyOpenArray':
var argType = n[i].typ.skipTypes(abstractInst)
if i < formals.len and formals[i].typ.kind in {tyVar, tyLent}:
localError(g.config, n[i].info, "'spawn'ed function cannot have a 'var' parameter")
#elif containsTyRef(argType):
# localError(n[i].info, "'spawn'ed function cannot refer to 'ref'/closure")
let fieldname = if i < formals.len: formals[i].sym.name else: tmpName
var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options)
field.typ = argType
objType.addField(field, g.cache)
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[i])
let temp = addLocalVar(g, varSection, varInit, objType.owner, argType,
indirectAccess(castExpr, field, n.info))
call.add(newSymNode(temp))
proc getRoot*(n: PNode): PSym =
## ``getRoot`` takes a *path* ``n``. A path is an lvalue expression
## like ``obj.x[i].y``. The *root* of a path is the symbol that can be
## determined as the owner; ``obj`` in the example.
case n.kind
of nkSym:
if n.sym.kind in {skVar, skResult, skTemp, skLet, skForVar}:
result = n.sym
of nkDotExpr, nkBracketExpr, nkHiddenDeref, nkDerefExpr,
nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
result = getRoot(n.sons[0])
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = getRoot(n.sons[1])
of nkCallKinds:
if getMagic(n) == mSlice: result = getRoot(n.sons[1])
else: discard
result.typ = sym.typ[0]
proc newIntLit*(g: ModuleGraph; info: TLineInfo; value: BiggestInt): PNode =
result = nkIntLit.newIntNode(value)
@@ -528,202 +346,30 @@ proc newIntLit*(g: ModuleGraph; info: TLineInfo; value: BiggestInt): PNode =
proc genHigh*(g: ModuleGraph; n: PNode): PNode =
if skipTypes(n.typ, abstractVar).kind == tyArray:
result = newIntLit(g, n.info, lastOrd(g.config, skipTypes(n.typ, abstractVar)))
result = newIntLit(g, n.info, toInt64(lastOrd(g.config, skipTypes(n.typ, abstractVar))))
else:
result = newNodeI(nkCall, n.info, 2)
result.typ = getSysType(g, n.info, tyInt)
result.sons[0] = newSymNode(getSysMagic(g, n.info, "high", mHigh))
result.sons[1] = n
result[0] = newSymNode(getSysMagic(g, n.info, "high", mHigh))
result[1] = n
proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym;
castExpr, call,
varSection, varInit, result: PNode) =
let formals = n[0].typ.n
let tmpName = getIdent(g.cache, genPrefix)
# we need to copy the foreign scratch object fields into local variables
# for correctness: These are called 'threadLocal' here.
for i in 1 ..< n.len:
let n = n[i]
let argType = skipTypes(if i < formals.len: formals[i].typ else: n.typ,
abstractInst)
#if containsTyRef(argType):
# localError(n.info, "'spawn'ed function cannot refer to 'ref'/closure")
let fieldname = if i < formals.len: formals[i].sym.name else: tmpName
var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options)
if argType.kind in {tyVarargs, tyOpenArray}:
# important special case: we always create a zero-copy slice:
let slice = newNodeI(nkCall, n.info, 4)
slice.typ = n.typ
slice.sons[0] = newSymNode(createMagic(g, "slice", mSlice))
slice.sons[0].typ = getSysType(g, n.info, tyInt) # fake type
var fieldB = newSym(skField, tmpName, objType.owner, n.info, g.config.options)
fieldB.typ = getSysType(g, n.info, tyInt)
objType.addField(fieldB, g.cache)
if getMagic(n) == mSlice:
let a = genAddrOf(n[1])
field.typ = a.typ
objType.addField(field, g.cache)
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
var fieldA = newSym(skField, tmpName, objType.owner, n.info, g.config.options)
fieldA.typ = getSysType(g, n.info, tyInt)
objType.addField(fieldA, g.cache)
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldA), n[2])
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), n[3])
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldA.typ,
indirectAccess(castExpr, fieldA, n.info),
useShallowCopy=true)
slice.sons[2] = threadLocal.newSymNode
else:
let a = genAddrOf(n)
field.typ = a.typ
objType.addField(field, g.cache)
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), genHigh(g, n))
slice.sons[2] = newIntLit(g, n.info, 0)
# the array itself does not need to go through a thread local variable:
slice.sons[1] = genDeref(indirectAccess(castExpr, field, n.info))
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldB.typ,
indirectAccess(castExpr, fieldB, n.info),
useShallowCopy=true)
slice.sons[3] = threadLocal.newSymNode
call.add slice
elif (let size = computeSize(g.config, argType); size < 0 or size > 16) and
n.getRoot != nil:
# it is more efficient to pass a pointer instead:
let a = genAddrOf(n)
field.typ = a.typ
objType.addField(field, g.cache)
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, field.typ,
indirectAccess(castExpr, field, n.info),
useShallowCopy=true)
call.add(genDeref(threadLocal.newSymNode))
else:
# boring case
field.typ = argType
objType.addField(field, g.cache)
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n)
let threadLocal = addLocalVar(g, varSection, varInit,
objType.owner, field.typ,
indirectAccess(castExpr, field, n.info),
useShallowCopy=true)
call.add(threadLocal.newSymNode)
proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: PType;
barrier, dest: PNode = nil): PNode =
# if 'barrier' != nil, then it is in a 'parallel' section and we
# generate quite different code
let n = spawnExpr[^2]
let spawnKind = spawnResult(retType, barrier!=nil)
case spawnKind
of srVoid:
internalAssert g.config, dest == nil
result = newNodeI(nkStmtList, n.info)
of srFlowVar:
internalAssert g.config, dest == nil
result = newNodeIT(nkStmtListExpr, n.info, retType)
of srByVar:
if dest == nil: localError(g.config, n.info, "'spawn' must not be discarded")
result = newNodeI(nkStmtList, n.info)
if n.kind notin nkCallKinds:
localError(g.config, n.info, "'spawn' takes a call expression")
return
if optThreadAnalysis in g.config.globalOptions:
if {tfThread, tfNoSideEffect} * n[0].typ.flags == {}:
localError(g.config, n.info, "'spawn' takes a GC safe call expression")
var
threadParam = newSym(skParam, getIdent(g.cache, "thread"), owner, n.info, g.config.options)
argsParam = newSym(skParam, getIdent(g.cache, "args"), owner, n.info, g.config.options)
block:
let ptrType = getSysType(g, n.info, tyPointer)
threadParam.typ = ptrType
argsParam.typ = ptrType
argsParam.position = 1
var objType = createObj(g, owner, n.info)
incl(objType.flags, tfFinal)
let castExpr = createCastExpr(argsParam, objType)
var scratchObj = newSym(skVar, getIdent(g.cache, "scratch"), owner, n.info, g.config.options)
block:
scratchObj.typ = objType
incl(scratchObj.flags, sfFromGeneric)
var varSectionB = newNodeI(nkVarSection, n.info)
varSectionB.addVar(scratchObj.newSymNode)
result.add varSectionB
var call = newNodeIT(nkCall, n.info, n.typ)
var fn = n.sons[0]
# templates and macros are in fact valid here due to the nature of
# the transformation:
if fn.kind == nkClosure:
localError(g.config, n.info, "closure in spawn environment is not allowed")
if not (fn.kind == nkSym and fn.sym.kind in {skProc, skTemplate, skMacro,
skFunc, skMethod, skConverter}):
# for indirect calls we pass the function pointer in the scratchObj
var argType = n[0].typ.skipTypes(abstractInst)
var field = newSym(skField, getIdent(g.cache, "fn"), owner, n.info, g.config.options)
field.typ = argType
objType.addField(field, g.cache)
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[0])
fn = indirectAccess(castExpr, field, n.info)
elif fn.kind == nkSym and fn.sym.kind == skIterator:
localError(g.config, n.info, "iterator in spawn environment is not allowed")
elif fn.typ.callConv == ccClosure:
localError(g.config, n.info, "closure in spawn environment is not allowed")
call.add(fn)
var varSection = newNodeI(nkVarSection, n.info)
var varInit = newNodeI(nkStmtList, n.info)
if barrier.isNil:
setupArgsForConcurrency(g, n, objType, scratchObj, castExpr, call,
varSection, varInit, result)
proc genLen*(g: ModuleGraph; n: PNode): PNode =
if skipTypes(n.typ, abstractVar).kind == tyArray:
result = newIntLit(g, n.info, toInt64(lastOrd(g.config, skipTypes(n.typ, abstractVar)) + 1))
else:
setupArgsForParallelism(g, n, objType, scratchObj, castExpr, call,
varSection, varInit, result)
result = newNodeI(nkCall, n.info, 2)
result.typ = getSysType(g, n.info, tyInt)
result[0] = newSymNode(getSysMagic(g, n.info, "len", mLengthSeq))
result[1] = n
var barrierAsExpr: PNode = nil
if barrier != nil:
let typ = newType(tyPtr, owner)
typ.rawAddSon(magicsys.getCompilerProc(g, "Barrier").typ)
var field = newSym(skField, getIdent(g.cache, "barrier"), owner, n.info, g.config.options)
field.typ = typ
objType.addField(field, g.cache)
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), barrier)
barrierAsExpr = indirectAccess(castExpr, field, n.info)
proc hoistExpr*(varSection, expr: PNode, name: PIdent, owner: PSym): PSym =
result = newSym(skLet, name, owner, varSection.info, owner.options)
result.flags.incl sfHoisted
result.typ = expr.typ
var fvField, fvAsExpr: PNode = nil
if spawnKind == srFlowVar:
var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options)
field.typ = retType
objType.addField(field, g.cache)
fvField = newDotExpr(scratchObj, field)
fvAsExpr = indirectAccess(castExpr, field, n.info)
# create flowVar:
result.add newFastAsgnStmt(fvField, callProc(spawnExpr[^1]))
if barrier == nil:
result.add callCodegenProc(g, "nimFlowVarCreateSemaphore", fvField)
var varDef = newNodeI(nkIdentDefs, varSection.info, 3)
varDef[0] = newSymNode(result)
varDef[1] = newNodeI(nkEmpty, varSection.info)
varDef[2] = expr
elif spawnKind == srByVar:
var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options)
field.typ = newType(tyPtr, objType.owner)
field.typ.rawAddSon(retType)
objType.addField(field, g.cache)
fvAsExpr = indirectAccess(castExpr, field, n.info)
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), genAddrOf(dest))
let wrapper = createWrapperProc(g, fn, threadParam, argsParam,
varSection, varInit, call,
barrierAsExpr, fvAsExpr, spawnKind)
result.add callCodegenProc(g, "nimSpawn" & $spawnExpr.len, wrapper.newSymNode,
genAddrOf(scratchObj.newSymNode), nil, spawnExpr)
if spawnKind == srFlowVar: result.add fvField
varSection.add varDef

View File

@@ -9,7 +9,7 @@
## This module implements helpers for the macro cache.
import lineinfos, ast, modulegraphs, vmdef, magicsys
import lineinfos, ast, modulegraphs, vmdef
proc recordInc*(c: PCtx; info: TLineInfo; key: string; by: BiggestInt) =
var recorded = newNodeI(nkCommentStmt, info)

View File

@@ -10,7 +10,7 @@
# Built-in types and compilerprocs are registered here.
import
ast, astalgo, hashes, msgs, platform, nversion, times, idents,
ast, astalgo, msgs, platform, idents,
modulegraphs, lineinfos
export createMagic
@@ -40,7 +40,7 @@ proc getSysMagic*(g: ModuleGraph; info: TLineInfo; name: string, m: TMagic): PSy
while r != nil:
if r.magic == m:
# prefer the tyInt variant:
if r.typ.sons[0] != nil and r.typ.sons[0].kind == tyInt: return r
if r.typ[0] != nil and r.typ[0].kind == tyInt: return r
result = r
r = nextIdentIter(ti, g.systemModule.tab)
if result != nil: return result
@@ -68,7 +68,7 @@ proc getSysType*(g: ModuleGraph; info: TLineInfo; kind: TTypeKind): PType =
of tyUInt64: result = sysTypeFromName("uint64")
of tyFloat: result = sysTypeFromName("float")
of tyFloat32: result = sysTypeFromName("float32")
of tyFloat64: return sysTypeFromName("float64")
of tyFloat64: result = sysTypeFromName("float64")
of tyFloat128: result = sysTypeFromName("float128")
of tyBool: result = sysTypeFromName("bool")
of tyChar: result = sysTypeFromName("char")
@@ -79,7 +79,9 @@ proc getSysType*(g: ModuleGraph; info: TLineInfo; kind: TTypeKind): PType =
else: internalError(g.config, "request for typekind: " & $kind)
g.sysTypes[kind] = result
if result.kind != kind:
internalError(g.config, "wanted: " & $kind & " got: " & $result.kind)
if kind == tyFloat64 and result.kind == tyFloat: discard # because of aliasing
else:
internalError(g.config, "wanted: " & $kind & " got: " & $result.kind)
if result == nil: internalError(g.config, "type not found: " & $kind)
proc resetSysTypes*(g: ModuleGraph) =
@@ -123,7 +125,7 @@ proc addSonSkipIntLit*(father, son: PType) =
when not defined(nimNoNilSeqs):
if isNil(father.sons): father.sons = @[]
let s = son.skipIntLit
add(father.sons, s)
father.sons.add(s)
propagateToOwner(father, s)
proc setIntLitType*(g: ModuleGraph; result: PNode) =

View File

@@ -13,25 +13,24 @@ when not defined(nimcore):
{.error: "nimcore MUST be defined for Nim's core tooling".}
import
llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
os, condsyms, times,
wordrecg, sem, semdata, idents, passes, docgen, extccomp,
cgen, jsgen, json, nversion,
platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen,
docgen2, parser, modules, ccgutils, sigmatch, ropes,
llstream, strutils, ast, lexer, syntaxes, options, msgs,
condsyms, times,
sem, idents, passes, extccomp,
cgen, json, nversion,
platform, nimconf, passaux, depends, vm, idgen,
modules,
modulegraphs, tables, rod, lineinfos, pathutils
from magicsys import resetSysTypes
proc codegenPass(g: ModuleGraph) =
registerPass g, cgenPass
when not defined(leanCompiler):
import jsgen, docgen, docgen2
proc semanticPasses(g: ModuleGraph) =
registerPass g, verbosePass
registerPass g, semPass
proc writeDepsFile(g: ModuleGraph; project: AbsoluteFile) =
let f = open(changeFileExt(project, "deps").string, fmWrite)
proc writeDepsFile(g: ModuleGraph) =
let fname = g.config.nimcacheDir / RelativeFile(g.config.projectName & ".deps")
let f = open(fname.string, fmWrite)
for m in g.modules:
if m != nil:
f.writeLine(toFullPath(g.config, m.position.FileIndex))
@@ -45,7 +44,7 @@ proc commandGenDepend(graph: ModuleGraph) =
registerPass(graph, gendependPass)
compileProject(graph)
let project = graph.config.projectFull
writeDepsFile(graph, project)
writeDepsFile(graph)
generateDot(graph, project)
execExternalProgram(graph.config, "dot -Tpng -o" &
changeFileExt(project, "png").string &
@@ -57,46 +56,80 @@ proc commandCheck(graph: ModuleGraph) =
semanticPasses(graph) # use an empty backend for semantic checking only
compileProject(graph)
proc commandDoc2(graph: ModuleGraph; json: bool) =
graph.config.errorMax = high(int) # do not stop after first error
semanticPasses(graph)
if json: registerPass(graph, docgen2JsonPass)
else: registerPass(graph, docgen2Pass)
compileProject(graph)
finishDoc2Pass(graph.config.projectName)
when not defined(leanCompiler):
proc commandDoc2(graph: ModuleGraph; json: bool) =
handleDocOutputOptions graph.config
graph.config.errorMax = high(int) # do not stop after first error
semanticPasses(graph)
if json: registerPass(graph, docgen2JsonPass)
else: registerPass(graph, docgen2Pass)
compileProject(graph)
finishDoc2Pass(graph.config.projectName)
proc commandCompileToC(graph: ModuleGraph) =
let conf = graph.config
if conf.outDir.isEmpty:
conf.outDir = conf.projectPath
if conf.outFile.isEmpty:
let targetName = if optGenDynLib in conf.globalOptions:
platform.OS[conf.target.targetOS].dllFrmt % conf.projectName
else:
conf.projectName & platform.OS[conf.target.targetOS].exeExt
conf.outFile = RelativeFile targetName
extccomp.initVars(conf)
semanticPasses(graph)
registerPass(graph, cgenPass)
if {optRun, optForceFullMake} * conf.globalOptions == {optRun} or isDefined(conf, "nimBetterRun"):
let proj = changeFileExt(conf.projectFull, "")
if not changeDetectedViaJsonBuildInstructions(conf, proj):
# nothing changed
graph.config.notes = graph.config.mainPackageNotes
return
compileProject(graph)
if graph.config.errorCounter > 0:
return # issue #9933
cgenWriteModules(graph.backend, conf)
if conf.cmd != cmdRun:
let proj = changeFileExt(conf.projectFull, "")
extccomp.callCCompiler(conf, proj)
extccomp.writeJsonBuildInstructions(conf, proj)
extccomp.callCCompiler(conf)
# for now we do not support writing out a .json file with the build instructions when HCR is on
if not conf.hcrOn:
extccomp.writeJsonBuildInstructions(conf)
if optGenScript in graph.config.globalOptions:
writeDepsFile(graph, toGeneratedFile(conf, proj, ""))
writeDepsFile(graph)
proc commandJsonScript(graph: ModuleGraph) =
let proj = changeFileExt(graph.config.projectFull, "")
extccomp.runJsonBuildInstructions(graph.config, proj)
proc commandCompileToJS(graph: ModuleGraph) =
#incl(gGlobalOptions, optSafeCode)
setTarget(graph.config.target, osJS, cpuJS)
#initDefines()
defineSymbol(graph.config.symbols, "ecmascript") # For backward compatibility
defineSymbol(graph.config.symbols, "js")
semanticPasses(graph)
registerPass(graph, JSgenPass)
compileProject(graph)
when not defined(leanCompiler):
proc commandCompileToJS(graph: ModuleGraph) =
let conf = graph.config
conf.exc = excCpp
if conf.outDir.isEmpty:
conf.outDir = conf.projectPath
if conf.outFile.isEmpty:
conf.outFile = RelativeFile(conf.projectName & ".js")
#incl(gGlobalOptions, optSafeCode)
setTarget(graph.config.target, osJS, cpuJS)
#initDefines()
defineSymbol(graph.config.symbols, "ecmascript") # For backward compatibility
defineSymbol(graph.config.symbols, "js")
semanticPasses(graph)
registerPass(graph, JSgenPass)
compileProject(graph)
if optGenScript in graph.config.globalOptions:
writeDepsFile(graph)
proc interactivePasses(graph: ModuleGraph) =
initDefines(graph.config.symbols)
defineSymbol(graph.config.symbols, "nimscript")
# note: seems redundant with -d:nimHasLibFFI
when hasFFI: defineSymbol(graph.config.symbols, "nimffi")
registerPass(graph, verbosePass)
registerPass(graph, semPass)
@@ -118,14 +151,6 @@ const evalPasses = [verbosePass, semPass, evalPass]
proc evalNim(graph: ModuleGraph; nodes: PNode, module: PSym) =
carryPasses(graph, nodes, module, evalPasses)
proc commandEval(graph: ModuleGraph; exp: string) =
if graph.systemModule == nil:
interactivePasses(graph)
compileSystemModule(graph)
let echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")"
evalNim(graph, echoExp.parseString(graph.cache, graph.config),
makeStdinModule(graph))
proc commandScan(cache: IdentCache, config: ConfigRef) =
var f = addFileExt(AbsoluteFile mainCommandArg(config), NimExt)
var stream = llStreamOpen(f, fmRead)
@@ -160,9 +185,12 @@ proc mainCommand*(graph: ModuleGraph) =
of "c", "cc", "compile", "compiletoc":
# compile means compileToC currently
conf.cmd = cmdCompileToC
if conf.exc == excNone: conf.exc = excSetjmp
defineSymbol(graph.config.symbols, "c")
commandCompileToC(graph)
of "cpp", "compiletocpp":
conf.cmd = cmdCompileToCpp
if conf.exc == excNone: conf.exc = excCpp
defineSymbol(graph.config.symbols, "cpp")
commandCompileToC(graph)
of "objc", "compiletooc":
@@ -172,54 +200,94 @@ proc mainCommand*(graph: ModuleGraph) =
of "run":
conf.cmd = cmdRun
when hasTinyCBackend:
extccomp.setCC("tcc")
extccomp.setCC(conf, "tcc", unknownLineInfo)
commandCompileToC(graph)
else:
rawMessage(conf, errGenerated, "'run' command not available; rebuild with -d:tinyc")
of "js", "compiletojs":
conf.cmd = cmdCompileToJS
commandCompileToJS(graph)
when defined(leanCompiler):
quit "compiler wasn't built with JS code generator"
else:
conf.cmd = cmdCompileToJS
if conf.hcrOn:
# XXX: At the moment, system.nim cannot be compiled in JS mode
# with "-d:useNimRtl". The HCR option has been processed earlier
# and it has added this define implictly, so we must undo that here.
# A better solution might be to fix system.nim
undefSymbol(conf.symbols, "useNimRtl")
commandCompileToJS(graph)
of "doc0":
wantMainModule(conf)
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
commandDoc(cache, conf)
when defined(leanCompiler):
quit "compiler wasn't built with documentation generator"
else:
wantMainModule(conf)
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
commandDoc(cache, conf)
of "doc2", "doc":
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
defineSymbol(conf.symbols, "nimdoc")
commandDoc2(graph, false)
conf.setNoteDefaults(warnLockLevel, false) # issue #13218
conf.setNoteDefaults(warnRedefinitionOfLabel, false) # issue #13218
# because currently generates lots of false positives due to conflation
# of labels links in doc comments, eg for random.rand:
# ## * `rand proc<#rand,Rand,Natural>`_ that returns an integer
# ## * `rand proc<#rand,Rand,range[]>`_ that returns a float
when defined(leanCompiler):
quit "compiler wasn't built with documentation generator"
else:
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
defineSymbol(conf.symbols, "nimdoc")
commandDoc2(graph, false)
of "rst2html":
conf.cmd = cmdRst2html
loadConfigs(DocConfig, cache, conf)
commandRst2Html(cache, conf)
conf.setNoteDefaults(warnRedefinitionOfLabel, false) # similar to issue #13218
when defined(leanCompiler):
quit "compiler wasn't built with documentation generator"
else:
conf.cmd = cmdRst2html
loadConfigs(DocConfig, cache, conf)
commandRst2Html(cache, conf)
of "rst2tex":
conf.cmd = cmdRst2tex
loadConfigs(DocTexConfig, cache, conf)
commandRst2TeX(cache, conf)
when defined(leanCompiler):
quit "compiler wasn't built with documentation generator"
else:
conf.cmd = cmdRst2tex
loadConfigs(DocTexConfig, cache, conf)
commandRst2TeX(cache, conf)
of "jsondoc0":
wantMainModule(conf)
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
wantMainModule(conf)
defineSymbol(conf.symbols, "nimdoc")
commandJson(cache, conf)
when defined(leanCompiler):
quit "compiler wasn't built with documentation generator"
else:
wantMainModule(conf)
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
wantMainModule(conf)
defineSymbol(conf.symbols, "nimdoc")
commandJson(cache, conf)
of "jsondoc2", "jsondoc":
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
wantMainModule(conf)
defineSymbol(conf.symbols, "nimdoc")
commandDoc2(graph, true)
when defined(leanCompiler):
quit "compiler wasn't built with documentation generator"
else:
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
wantMainModule(conf)
defineSymbol(conf.symbols, "nimdoc")
commandDoc2(graph, true)
of "ctags":
wantMainModule(conf)
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
defineSymbol(conf.symbols, "nimdoc")
commandTags(cache, conf)
when defined(leanCompiler):
quit "compiler wasn't built with documentation generator"
else:
wantMainModule(conf)
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
defineSymbol(conf.symbols, "nimdoc")
commandTags(cache, conf)
of "buildindex":
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
commandBuildIndex(cache, conf)
when defined(leanCompiler):
quit "compiler wasn't built with documentation generator"
else:
conf.cmd = cmdDoc
loadConfigs(DocConfig, cache, conf)
commandBuildIndex(cache, conf)
of "gendepend":
conf.cmd = cmdGenDepend
commandGenDepend(graph)
@@ -232,13 +300,32 @@ proc mainCommand*(graph: ModuleGraph) =
for s in definedSymbolNames(conf.symbols): definedSymbols.elems.add(%s)
var libpaths = newJArray()
var lazyPaths = newJArray()
for dir in conf.searchPaths: libpaths.elems.add(%dir.string)
for dir in conf.lazyPaths: lazyPaths.elems.add(%dir.string)
var dumpdata = % [
var hints = newJObject() # consider factoring with `listHints`
for a in hintMin..hintMax:
let key = lineinfos.HintsToStr[ord(a) - ord(hintMin)]
hints[key] = %(a in conf.notes)
var warnings = newJObject()
for a in warnMin..warnMax:
let key = lineinfos.WarningsToStr[ord(a) - ord(warnMin)]
warnings[key] = %(a in conf.notes)
var dumpdata = %[
(key: "version", val: %VersionAsString),
(key: "prefixdir", val: %conf.getPrefixDir().string),
(key: "libpath", val: %conf.libpath.string),
(key: "project_path", val: %conf.projectFull.string),
(key: "defined_symbols", val: definedSymbols),
(key: "lib_paths", val: libpaths)
(key: "lib_paths", val: %libpaths),
(key: "lazyPaths", val: %lazyPaths),
(key: "outdir", val: %conf.outDir.string),
(key: "out", val: %conf.outFile.string),
(key: "nimcache", val: %getNimcacheDir(conf).string),
(key: "hints", val: hints),
(key: "warnings", val: warnings),
]
msgWriteln(conf, $dumpdata, {msgStdout, msgSkipHook})
@@ -265,7 +352,11 @@ proc mainCommand*(graph: ModuleGraph) =
conf.cmd = cmdInteractive
commandInteractive(graph)
of "e":
commandEval(graph, mainCommandArg(conf))
if not fileExists(conf.projectFull):
rawMessage(conf, errGenerated, "NimScript file does not exist: " & conf.projectFull.string)
elif not conf.projectFull.string.endsWith(".nims"):
rawMessage(conf, errGenerated, "not a NimScript file: " & conf.projectFull.string)
# main NimScript logic handled in cmdlinehelper.nim.
of "nop", "help":
# prevent the "success" message:
conf.cmd = cmdDump
@@ -277,15 +368,25 @@ proc mainCommand*(graph: ModuleGraph) =
if conf.errorCounter == 0 and
conf.cmd notin {cmdInterpret, cmdRun, cmdDump}:
when declared(system.getMaxMem):
let usedMem = formatSize(getMaxMem()) & " peakmem"
else:
let usedMem = formatSize(getTotalMem())
rawMessage(conf, hintSuccessX, [$conf.linesCompiled,
formatFloat(epochTime() - conf.lastCmdTime, ffDecimal, 3),
usedMem,
if isDefined(conf, "release"): "Release Build"
else: "Debug Build"])
let mem =
when declared(system.getMaxMem): formatSize(getMaxMem()) & " peakmem"
else: formatSize(getTotalMem()) & " totmem"
let loc = $conf.linesCompiled
let build = if isDefined(conf, "danger"): "Dangerous Release"
elif isDefined(conf, "release"): "Release"
else: "Debug"
let sec = formatFloat(epochTime() - conf.lastCmdTime, ffDecimal, 3)
let project = if optListFullPaths in conf.globalOptions: $conf.projectFull else: $conf.projectName
var output = $conf.absOutFile
if optListFullPaths notin conf.globalOptions: output = output.AbsoluteFile.extractFilename
rawMessage(conf, hintSuccessX, [
"loc", loc,
"sec", sec,
"mem", mem,
"build", build,
"project", project,
"output", output,
])
when PrintRopeCacheStats:
echo "rope cache stats: "

View File

@@ -26,13 +26,16 @@
##
import ast, intsets, tables, options, lineinfos, hashes, idents,
incremental, btrees
incremental, btrees, md5
type
SigHash* = distinct MD5Digest
ModuleGraph* = ref object
modules*: seq[PSym] ## indexed by int32 fileIdx
packageSyms*: TStrTable
deps*: IntSet # the dependency graph or potentially its transitive closure.
importDeps*: Table[FileIndex, seq[FileIndex]] # explicit import module dependencies
suggestMode*: bool # whether we are in nimsuggest mode or not.
invalidTransitiveClosure: bool
inclToMod*: Table[FileIndex, FileIndex] # mapping of include file to the
@@ -47,7 +50,7 @@ type
doStopCompile*: proc(): bool {.closure.}
usageSym*: PSym # for nimsuggest
owners*: seq[PSym]
methods*: seq[tuple[methods: TSymSeq, dispatcher: PSym]] # needs serialization!
methods*: seq[tuple[methods: seq[PSym], dispatcher: PSym]] # needs serialization!
systemModule*: PSym
sysTypes*: array[TTypeKind, PType]
compilerprocs*: TStrTable
@@ -56,26 +59,123 @@ type
opContains*, opNot*: PSym
emptyNode*: PNode
incr*: IncrementalCtx
canonTypes*: Table[SigHash, PType]
symBodyHashes*: Table[int, SigHash] # symId to digest mapping
importModuleCallback*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex): PSym {.nimcall.}
includeFileCallback*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex): PNode {.nimcall.}
recordStmt*: proc (graph: ModuleGraph; m: PSym; n: PNode) {.nimcall.}
cacheSeqs*: Table[string, PNode] # state that is shared to suppor the 'macrocache' API
cacheSeqs*: Table[string, PNode] # state that is shared to support the 'macrocache' API
cacheCounters*: Table[string, BiggestInt]
cacheTables*: Table[string, BTree[string, PNode]]
passes*: seq[TPass]
onDefinition*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
onDefinitionResolveForward*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
onUsage*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
globalDestructors*: seq[PNode]
proofEngine*: proc (graph: ModuleGraph; assumptions: seq[PNode]; toProve: PNode): (bool, string) {.nimcall.}
requirementsCheck*: proc (graph: ModuleGraph; assumptions: seq[PNode];
call, requirement: PNode): (bool, string) {.nimcall.}
compatibleProps*: proc (graph: ModuleGraph; formal, actual: PType): bool {.nimcall.}
TPassContext* = object of RootObj # the pass's context
PPassContext* = ref TPassContext
TPassOpen* = proc (graph: ModuleGraph; module: PSym): PPassContext {.nimcall.}
TPassClose* = proc (graph: ModuleGraph; p: PPassContext, n: PNode): PNode {.nimcall.}
TPassProcess* = proc (p: PPassContext, topLevelStmt: PNode): PNode {.nimcall.}
TPass* = tuple[open: TPassOpen,
process: TPassProcess,
close: TPassClose,
isFrontend: bool]
const
cb64 = [
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
"o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9a",
"9b", "9c"]
proc toBase64a(s: cstring, len: int): string =
## encodes `s` into base64 representation.
result = newStringOfCap(((len + 2) div 3) * 4)
result.add "__"
var i = 0
while i < len - 2:
let a = ord(s[i])
let b = ord(s[i+1])
let c = ord(s[i+2])
result.add cb64[a shr 2]
result.add cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)]
result.add cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)]
result.add cb64[c and 0x3F]
inc(i, 3)
if i < len-1:
let a = ord(s[i])
let b = ord(s[i+1])
result.add cb64[a shr 2]
result.add cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)]
result.add cb64[((b and 0x0F) shl 2)]
elif i < len:
let a = ord(s[i])
result.add cb64[a shr 2]
result.add cb64[(a and 3) shl 4]
proc `$`*(u: SigHash): string =
toBase64a(cast[cstring](unsafeAddr u), sizeof(u))
proc `==`*(a, b: SigHash): bool =
result = equalMem(unsafeAddr a, unsafeAddr b, sizeof(a))
proc hash*(u: SigHash): Hash =
result = 0
for x in 0..3:
result = (result shl 8) or u.MD5Digest[x].int
proc hash*(x: FileIndex): Hash {.borrow.}
when defined(nimfind):
template onUse*(info: TLineInfo; s: PSym) =
when compiles(c.c.graph):
if c.c.graph.onUsage != nil: c.c.graph.onUsage(c.c.graph, s, info)
else:
if c.graph.onUsage != nil: c.graph.onUsage(c.graph, s, info)
template onDef*(info: TLineInfo; s: PSym) =
when compiles(c.c.graph):
if c.c.graph.onDefinition != nil: c.c.graph.onDefinition(c.c.graph, s, info)
else:
if c.graph.onDefinition != nil: c.graph.onDefinition(c.graph, s, info)
template onDefResolveForward*(info: TLineInfo; s: PSym) =
when compiles(c.c.graph):
if c.c.graph.onDefinitionResolveForward != nil:
c.c.graph.onDefinitionResolveForward(c.c.graph, s, info)
else:
if c.graph.onDefinitionResolveForward != nil:
c.graph.onDefinitionResolveForward(c.graph, s, info)
else:
template onUse*(info: TLineInfo; s: PSym) = discard
template onDef*(info: TLineInfo; s: PSym) = discard
template onDefResolveForward*(info: TLineInfo; s: PSym) = discard
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
result = g.doStopCompile != nil and g.doStopCompile()
proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym =
result = newSym(skProc, getIdent(g.cache, name), nil, unknownLineInfo(), {})
result = newSym(skProc, getIdent(g.cache, name), nil, unknownLineInfo, {})
result.magic = m
result.flags = {sfNeverRaises}
proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
result = ModuleGraph()
initStrTable(result.packageSyms)
result.deps = initIntSet()
result.importDeps = initTable[FileIndex, seq[FileIndex]]()
result.modules = @[]
result.importStack = @[]
result.inclToMod = initTable[FileIndex, FileIndex]()
@@ -94,6 +194,8 @@ proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
result.cacheSeqs = initTable[string, PNode]()
result.cacheCounters = initTable[string, BiggestInt]()
result.cacheTables = initTable[string, BTree[string, PNode]]()
result.canonTypes = initTable[SigHash, PType]()
result.symBodyHashes = initTable[int, SigHash]()
proc resetAllModules*(g: ModuleGraph) =
initStrTable(g.packageSyms)
@@ -118,7 +220,7 @@ proc addDep*(g: ModuleGraph; m: PSym, dep: FileIndex) =
addModuleDep(g.incr, g.config, m.info.fileIndex, dep, isIncludeFile = false)
if g.suggestMode:
g.deps.incl m.position.dependsOn(dep.int)
# we compute the transitive closure later when quering the graph lazily.
# we compute the transitive closure later when querying the graph lazily.
# this improves efficiency quite a lot:
#invalidTransitiveClosure = true

View File

@@ -8,7 +8,7 @@
#
import ast, renderer, strutils, msgs, options, idents, os, lineinfos,
pathutils, nimblecmd
pathutils
when false:
const
@@ -114,7 +114,6 @@ proc getModuleName*(conf: ConfigRef; n: PNode): string =
try:
result =
pathSubs(conf, n.strVal, toFullPath(conf, n.info).splitFile().dir)
.replace(" ")
except ValueError:
localError(conf, n.info, "invalid path: " & n.strVal)
result = n.strVal
@@ -140,17 +139,17 @@ proc getModuleName*(conf: ConfigRef; n: PNode): string =
result.add modname
of nkPrefix:
when false:
if n.sons[0].kind == nkIdent and n.sons[0].ident.s == "$":
if n[0].kind == nkIdent and n[0].ident.s == "$":
result = lookupPackage(n[1], nil)
else:
discard
# hacky way to implement 'x / y /../ z':
result = renderTree(n, {renderNoComments}).replace(" ")
of nkDotExpr:
localError(conf, n.info, warnDeprecated, "using '.' instead of '/' in import paths")
localError(conf, n.info, warnDeprecated, "using '.' instead of '/' in import paths is deprecated")
result = renderTree(n, {renderNoComments}).replace(".", "/")
of nkImportAs:
result = getModuleName(conf, n.sons[0])
result = getModuleName(conf, n[0])
else:
localError(conf, n.info, "invalid module name: '$1'" % n.renderTree)
result = ""
@@ -163,6 +162,6 @@ proc checkModuleName*(conf: ConfigRef; n: PNode; doLocalError=true): FileIndex =
if doLocalError:
let m = if modulename.len > 0: modulename else: $n
localError(conf, n.info, "cannot open file: " & m)
result = InvalidFileIDX
result = InvalidFileIdx
else:
result = fileInfoIdx(conf, fullPath)

View File

@@ -10,27 +10,16 @@
## Implements the module handling, including the caching of modules.
import
ast, astalgo, magicsys, std / sha1, msgs, cgendata, sigmatch, options,
idents, os, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod,
lineinfos, pathutils
ast, astalgo, magicsys, msgs, options,
idents, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod,
lineinfos, pathutils, tables
proc resetSystemArtifacts*(g: ModuleGraph) =
magicsys.resetSysTypes(g)
proc newModule(graph: ModuleGraph; fileIdx: FileIndex): PSym =
# We cannot call ``newSym`` here, because we have to circumvent the ID
# mechanism, which we do in order to assign each module a persistent ID.
new(result)
result.id = -1 # for better error checking
result.kind = skModule
let filename = toFullPath(graph.config, fileIdx)
result.name = getIdent(graph.cache, splitFile(filename).name)
if not isNimIdentifier(result.name.s):
rawMessage(graph.config, errGenerated, "invalid module name: " & result.name.s)
result.info = newLineInfo(fileIdx, 1, 1)
proc partialInitModule(result: PSym; graph: ModuleGraph; fileIdx: FileIndex; filename: AbsoluteFile) =
let
pck = getPackageName(graph.config, filename)
pck = getPackageName(graph.config, filename.string)
pck2 = if pck.len > 0: pck else: "unknown"
pack = getIdent(graph.cache, pck2)
var packSym = graph.packageSyms.strTableGet(pack)
@@ -38,35 +27,60 @@ proc newModule(graph: ModuleGraph; fileIdx: FileIndex): PSym =
packSym = newSym(skPackage, getIdent(graph.cache, pck2), nil, result.info)
initStrTable(packSym.tab)
graph.packageSyms.strTableAdd(packSym)
else:
let existing = strTableGet(packSym.tab, result.name)
if existing != nil and existing.info.fileIndex != result.info.fileIndex:
when false:
# we used to produce an error:
localError(graph.config, result.info,
"module names need to be unique per Nimble package; module clashes with " &
toFullPath(graph.config, existing.info.fileIndex))
else:
# but starting with version 0.20 we now produce a fake Nimble package instead
# to resolve the conflicts:
let pck3 = fakePackageName(graph.config, filename)
# this makes the new `packSym`'s owner be the original `packSym`
packSym = newSym(skPackage, getIdent(graph.cache, pck3), packSym, result.info)
initStrTable(packSym.tab)
graph.packageSyms.strTableAdd(packSym)
result.owner = packSym
result.position = int fileIdx
if int(fileIdx) >= graph.modules.len:
setLen(graph.modules, int(fileIdx) + 1)
#growCache graph.modules, int fileIdx
graph.modules[result.position] = result
incl(result.flags, sfUsed)
initStrTable(result.tab)
strTableAdd(result.tab, result) # a module knows itself
let existing = strTableGet(packSym.tab, result.name)
if existing != nil and existing.info.fileIndex != result.info.fileIndex:
localError(graph.config, result.info,
"module names need to be unique per Nimble package; module clashes with " &
toFullPath(graph.config, existing.info.fileIndex))
# strTableIncl() for error corrections:
discard strTableIncl(packSym.tab, result)
strTableAdd(packSym.tab, result)
proc newModule(graph: ModuleGraph; fileIdx: FileIndex): PSym =
let filename = AbsoluteFile toFullPath(graph.config, fileIdx)
# We cannot call ``newSym`` here, because we have to circumvent the ID
# mechanism, which we do in order to assign each module a persistent ID.
result = PSym(kind: skModule, id: -1, # for better error checking
name: getIdent(graph.cache, splitFile(filename).name),
info: newLineInfo(fileIdx, 1, 1))
if not isNimIdentifier(result.name.s):
rawMessage(graph.config, errGenerated, "invalid module name: " & result.name.s)
partialInitModule(result, graph, fileIdx, filename)
proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymFlags): PSym =
result = graph.getModule(fileIdx)
if result == nil:
result = newModule(graph, fileIdx)
result.flags = result.flags + flags
if sfMainModule in result.flags:
graph.config.mainPackageId = result.owner.id
result.id = getModuleId(graph, fileIdx, AbsoluteFile toFullPath(graph.config, fileIdx))
let filename = AbsoluteFile toFullPath(graph.config, fileIdx)
let (r, id) = loadModuleSym(graph, fileIdx, filename)
result = r
if result == nil:
result = newModule(graph, fileIdx)
result.flags = result.flags + flags
result.id = id
registerModule(graph, result)
else:
partialInitModule(result, graph, fileIdx, filename)
result.id = id
assert result.id < 0
discard processModule(graph, result,
if sfMainModule in flags and graph.config.projectIsStdin: stdin.llStreamOpen else: nil)
elif graph.isDirty(result):
@@ -78,19 +92,22 @@ proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymFlags): P
if sfMainModule in flags and graph.config.projectIsStdin: stdin.llStreamOpen else: nil)
graph.markClientsDirty(fileIdx)
proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PSym {.procvar.} =
proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PSym =
# this is called by the semantic checking phase
assert graph.config != nil
result = compileModule(graph, fileIdx, {})
graph.addDep(s, fileIdx)
# keep track of import relationships
if graph.config.hcrOn:
graph.importDeps.mgetOrPut(FileIndex(s.position), @[]).add(fileIdx)
#if sfSystemModule in result.flags:
# localError(result.info, errAttemptToRedefine, result.name.s)
# restore the notes for outer module:
graph.config.notes =
if s.owner.id == graph.config.mainPackageId: graph.config.mainPackageNotes
if s.owner.id == graph.config.mainPackageId or isDefined(graph.config, "booting"): graph.config.mainPackageNotes
else: graph.config.foreignPackageNotes
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PNode {.procvar.} =
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PNode =
result = syntaxes.parseFile(fileIdx, graph.cache, graph.config)
graph.addDep(s, fileIdx)
graph.addIncludeDep(s.position.FileIndex, fileIdx)
@@ -112,12 +129,12 @@ proc wantMainModule*(conf: ConfigRef) =
"command expects a filename")
conf.projectMainIdx = fileInfoIdx(conf, addFileExt(conf.projectFull, NimExt))
proc compileProject*(graph: ModuleGraph; projectFileIdx = InvalidFileIDX) =
proc compileProject*(graph: ModuleGraph; projectFileIdx = InvalidFileIdx) =
connectCallbacks(graph)
let conf = graph.config
wantMainModule(conf)
let systemFileIdx = fileInfoIdx(conf, conf.libpath / RelativeFile"system.nim")
let projectFile = if projectFileIdx == InvalidFileIDX: conf.projectMainIdx else: projectFileIdx
let projectFile = if projectFileIdx == InvalidFileIdx: conf.projectMainIdx else: projectFileIdx
graph.importStack.add projectFile
if projectFile == systemFileIdx:
discard graph.compileModule(projectFile, {sfMainModule, sfSystemModule})
@@ -128,6 +145,7 @@ proc compileProject*(graph: ModuleGraph; projectFileIdx = InvalidFileIDX) =
proc makeModule*(graph: ModuleGraph; filename: AbsoluteFile): PSym =
result = graph.newModule(fileInfoIdx(graph.config, filename))
result.id = getID()
registerModule(graph, result)
proc makeModule*(graph: ModuleGraph; filename: string): PSym =
result = makeModule(graph, AbsoluteFile filename)

View File

@@ -8,7 +8,7 @@
#
import
options, strutils, os, tables, ropes, platform, terminal, macros,
options, strutils, os, tables, ropes, terminal, macros,
lineinfos, pathutils
proc toCChar*(c: char; result: var string) =
@@ -26,13 +26,13 @@ proc makeCString*(s: string): Rope =
const MaxLineLength = 64
result = nil
var res = newStringOfCap(int(s.len.toFloat * 1.1) + 1)
add(res, "\"")
for i in countup(0, len(s) - 1):
res.add("\"")
for i in 0..<s.len:
if (i + 1) mod MaxLineLength == 0:
add(res, "\"\L\"")
res.add("\"\L\"")
toCChar(s[i], res)
add(res, '\"')
add(result, rope(res))
res.add('\"')
result.add(rope(res))
proc newFileInfo(fullPath: AbsoluteFile, projPath: RelativeFile): TFileInfo =
@@ -40,9 +40,8 @@ proc newFileInfo(fullPath: AbsoluteFile, projPath: RelativeFile): TFileInfo =
#shallow(result.fullPath)
result.projPath = projPath
#shallow(result.projPath)
let fileName = fullPath.extractFilename
result.shortName = fileName.changeFileExt("")
result.quotedName = fileName.makeCString
result.shortName = fullPath.extractFilename
result.quotedName = result.shortName.makeCString
result.quotedFullName = fullPath.string.makeCString
result.lines = @[]
when defined(nimpretty):
@@ -82,6 +81,7 @@ proc fileInfoIdx*(conf: ConfigRef; filename: AbsoluteFile; isKnownFile: var bool
pseudoPath = true
if conf.m.filenameToIndexTbl.hasKey(canon.string):
isKnownFile = true
result = conf.m.filenameToIndexTbl[canon.string]
else:
isKnownFile = false
@@ -96,14 +96,20 @@ proc fileInfoIdx*(conf: ConfigRef; filename: AbsoluteFile): FileIndex =
proc newLineInfo*(fileInfoIdx: FileIndex, line, col: int): TLineInfo =
result.fileIndex = fileInfoIdx
result.line = uint16(line)
result.col = int16(col)
if line < int high(uint16):
result.line = uint16(line)
else:
result.line = high(uint16)
if col < int high(int16):
result.col = int16(col)
else:
result.col = -1
proc newLineInfo*(conf: ConfigRef; filename: AbsoluteFile, line, col: int): TLineInfo {.inline.} =
result = newLineInfo(fileInfoIdx(conf, filename), line, col)
proc concat(strings: openarray[string]): string =
proc concat(strings: openArray[string]): string =
var totalLen = 0
for s in strings: totalLen += s.len
result = newStringOfCap totalLen
@@ -135,35 +141,49 @@ const
WarningColor = fgYellow
HintTitle = "Hint: "
HintColor = fgGreen
# NOTE: currently line info line numbers start with 1,
# but column numbers start with 0, however most editors expect
# first column to be 1, so we need to +1 here
ColOffset* = 1
proc getInfoContextLen*(conf: ConfigRef): int = return conf.m.msgContext.len
proc setInfoContextLen*(conf: ConfigRef; L: int) = setLen(conf.m.msgContext, L)
proc pushInfoContext*(conf: ConfigRef; info: TLineInfo) =
conf.m.msgContext.add(info)
proc pushInfoContext*(conf: ConfigRef; info: TLineInfo; detail: string = "") =
conf.m.msgContext.add((info, detail))
proc popInfoContext*(conf: ConfigRef) =
setLen(conf.m.msgContext, len(conf.m.msgContext) - 1)
setLen(conf.m.msgContext, conf.m.msgContext.len - 1)
proc getInfoContext*(conf: ConfigRef; index: int): TLineInfo =
let L = conf.m.msgContext.len
let i = if index < 0: L + index else: index
if i >=% L: result = unknownLineInfo()
else: result = conf.m.msgContext[i]
let i = if index < 0: conf.m.msgContext.len + index else: index
if i >=% conf.m.msgContext.len: result = unknownLineInfo
else: result = conf.m.msgContext[i].info
const
commandLineDesc = "command line"
template toFilename*(conf: ConfigRef; fileIdx: FileIndex): string =
if fileIdx.int32 < 0 or conf == nil:
"???"
(if fileIdx == commandLineIdx: commandLineDesc else: "???")
else:
conf.m.fileInfos[fileIdx.int32].projPath.string
conf.m.fileInfos[fileIdx.int32].shortName
proc toProjPath*(conf: ConfigRef; fileIdx: FileIndex): string =
if fileIdx.int32 < 0 or conf == nil:
(if fileIdx == commandLineIdx: commandLineDesc else: "???")
else: conf.m.fileInfos[fileIdx.int32].projPath.string
proc toFullPath*(conf: ConfigRef; fileIdx: FileIndex): string =
if fileIdx.int32 < 0 or conf == nil: result = "???"
else: result = conf.m.fileInfos[fileIdx.int32].fullPath.string
if fileIdx.int32 < 0 or conf == nil:
result = (if fileIdx == commandLineIdx: commandLineDesc else: "???")
else:
result = conf.m.fileInfos[fileIdx.int32].fullPath.string
proc setDirtyFile*(conf: ConfigRef; fileIdx: FileIndex; filename: AbsoluteFile) =
assert fileIdx.int32 >= 0
conf.m.fileInfos[fileIdx.int32].dirtyFile = filename
setLen conf.m.fileInfos[fileIdx.int32].lines, 0
proc setHash*(conf: ConfigRef; fileIdx: FileIndex; hash: string) =
assert fileIdx.int32 >= 0
@@ -175,7 +195,7 @@ proc getHash*(conf: ConfigRef; fileIdx: FileIndex): string =
proc toFullPathConsiderDirty*(conf: ConfigRef; fileIdx: FileIndex): AbsoluteFile =
if fileIdx.int32 < 0:
result = AbsoluteFile"???"
result = AbsoluteFile(if fileIdx == commandLineIdx: commandLineDesc else: "???")
elif not conf.m.fileInfos[fileIdx.int32].dirtyFile.isEmpty:
result = conf.m.fileInfos[fileIdx.int32].dirtyFile
else:
@@ -184,16 +204,28 @@ proc toFullPathConsiderDirty*(conf: ConfigRef; fileIdx: FileIndex): AbsoluteFile
template toFilename*(conf: ConfigRef; info: TLineInfo): string =
toFilename(conf, info.fileIndex)
template toProjPath*(conf: ConfigRef; info: TLineInfo): string =
toProjPath(conf, info.fileIndex)
template toFullPath*(conf: ConfigRef; info: TLineInfo): string =
toFullPath(conf, info.fileIndex)
proc toMsgFilename*(conf: ConfigRef; info: TLineInfo): string =
if info.fileIndex.int32 < 0:
result = "???"
elif optListFullPaths in conf.globalOptions:
result = conf.m.fileInfos[info.fileIndex.int32].fullPath.string
else:
result = conf.m.fileInfos[info.fileIndex.int32].projPath.string
template toFullPathConsiderDirty*(conf: ConfigRef; info: TLineInfo): string =
string toFullPathConsiderDirty(conf, info.fileIndex)
proc toMsgFilename*(conf: ConfigRef; info: FileIndex): string =
let
absPath = toFullPath(conf, info)
relPath = toProjPath(conf, info)
result = if (optListFullPaths in conf.globalOptions) or
(relPath.len > absPath.len) or
(relPath.count("..") > 2):
absPath
else:
relPath
template toMsgFilename*(conf: ConfigRef; info: TLineInfo): string =
toMsgFilename(conf, info.fileIndex)
proc toLinenumber*(info: TLineInfo): int {.inline.} =
result = int info.line
@@ -201,11 +233,10 @@ proc toLinenumber*(info: TLineInfo): int {.inline.} =
proc toColumn*(info: TLineInfo): int {.inline.} =
result = info.col
proc toFileLine*(conf: ConfigRef; info: TLineInfo): string {.inline.} =
result = toFilename(conf, info) & ":" & $info.line
proc toFileLineCol*(conf: ConfigRef; info: TLineInfo): string {.inline.} =
result = toFilename(conf, info) & "(" & $info.line & ", " & $info.col & ")"
# consider calling `helpers.lineInfoToString` instead
result = toMsgFilename(conf, info) & "(" & $info.line & ", " &
$(info.col + ColOffset) & ")"
proc `$`*(conf: ConfigRef; info: TLineInfo): string = toFileLineCol(conf, info)
@@ -302,20 +333,21 @@ proc getMessageStr(msg: TMsgKind, arg: string): string =
type
TErrorHandling = enum doNothing, doAbort, doRaise
proc log*(s: string) {.procvar.} =
proc log*(s: string) =
var f: File
if open(f, getHomeDir() / "nimsuggest.log", fmAppend):
f.writeLine(s)
close(f)
proc quit(conf: ConfigRef; msg: TMsgKind) =
if defined(debug) or msg == errInternal or hintStackTrace in conf.notes:
if stackTraceAvailable() and isNil(conf.writelnHook):
writeStackTrace()
else:
styledMsgWriteln(fgRed, "No stack traceback available\n" &
"To create a stacktrace, rerun compilation with ./koch temp " &
conf.command & " <file>")
proc quit(conf: ConfigRef; msg: TMsgKind) {.gcsafe.} =
if defined(debug) or msg == errInternal or conf.hasHint(hintStackTrace):
{.gcsafe.}:
if stackTraceAvailable() and isNil(conf.writelnHook):
writeStackTrace()
else:
styledMsgWriteln(fgRed, "No stack traceback available\n" &
"To create a stacktrace, rerun compilation with ./koch temp " &
conf.command & " <file>")
quit 1
proc handleError(conf: ConfigRef; msg: TMsgKind, eh: TErrorHandling, s: string) =
@@ -340,20 +372,26 @@ proc exactEquals*(a, b: TLineInfo): bool =
proc writeContext(conf: ConfigRef; lastinfo: TLineInfo) =
const instantiationFrom = "template/generic instantiation from here"
const instantiationOfFrom = "template/generic instantiation of `$1` from here"
var info = lastinfo
for i in 0 ..< len(conf.m.msgContext):
if conf.m.msgContext[i] != lastinfo and conf.m.msgContext[i] != info:
for i in 0..<conf.m.msgContext.len:
let context = conf.m.msgContext[i]
if context.info != lastinfo and context.info != info:
if conf.structuredErrorHook != nil:
conf.structuredErrorHook(conf, conf.m.msgContext[i], instantiationFrom,
Severity.Error)
conf.structuredErrorHook(conf, context.info, instantiationFrom,
Severity.Error)
else:
let message = if context.detail == "":
instantiationFrom
else:
instantiationOfFrom.format(context.detail)
styledMsgWriteln(styleBright,
PosFormat % [toMsgFilename(conf, conf.m.msgContext[i]),
coordToStr(conf.m.msgContext[i].line.int),
coordToStr(conf.m.msgContext[i].col+1)],
PosFormat % [toMsgFilename(conf, context.info),
coordToStr(context.info.line.int),
coordToStr(context.info.col+ColOffset)],
resetStyle,
instantiationFrom)
info = conf.m.msgContext[i]
message)
info = context.info
proc ignoreMsgBecauseOfIdeTools(conf: ConfigRef; msg: TMsgKind): bool =
msg >= errGenerated and conf.cmd == cmdIdeTools and optIdeDebug notin conf.globalOptions
@@ -367,22 +405,20 @@ proc rawMessage*(conf: ConfigRef; msg: TMsgKind, args: openArray[string]) =
case msg
of errMin..errMax:
sev = Severity.Error
writeContext(conf, unknownLineInfo())
writeContext(conf, unknownLineInfo)
title = ErrorTitle
color = ErrorColor
of warnMin..warnMax:
sev = Severity.Warning
if optWarns notin conf.options: return
if msg notin conf.notes: return
writeContext(conf, unknownLineInfo())
if not conf.hasWarn(msg): return
writeContext(conf, unknownLineInfo)
title = WarningTitle
color = WarningColor
kind = WarningsToStr[ord(msg) - ord(warnMin)]
inc(conf.warnCounter)
of hintMin..hintMax:
sev = Severity.Hint
if optHints notin conf.options: return
if msg notin conf.notes: return
if not conf.hasHint(msg): return
title = HintTitle
color = HintColor
if msg != hintUserRaw: kind = HintsToStr[ord(msg) - ord(hintMin)]
@@ -390,7 +426,7 @@ proc rawMessage*(conf: ConfigRef; msg: TMsgKind, args: openArray[string]) =
let s = msgKindToString(msg) % args
if conf.structuredErrorHook != nil:
conf.structuredErrorHook(conf, unknownLineInfo(),
conf.structuredErrorHook(conf, unknownLineInfo,
s & (if kind.len > 0: KindFormat % kind else: ""), sev)
if not ignoreMsgBecauseOfIdeTools(conf, msg):
@@ -414,9 +450,9 @@ proc addSourceLine(conf: ConfigRef; fileIdx: FileIndex, line: string) =
proc sourceLine*(conf: ConfigRef; i: TLineInfo): string =
if i.fileIndex.int32 < 0: return ""
if not optPreserveOrigSource(conf) and conf.m.fileInfos[i.fileIndex.int32].lines.len == 0:
if conf.m.fileInfos[i.fileIndex.int32].lines.len == 0:
try:
for line in lines(toFullPath(conf, i)):
for line in lines(toFullPathConsiderDirty(conf, i)):
addSourceLine conf, i.fileIndex, line.string
except IOError:
discard
@@ -429,7 +465,8 @@ proc sourceLine*(conf: ConfigRef; i: TLineInfo): string =
proc writeSurroundingSrc(conf: ConfigRef; info: TLineInfo) =
const indent = " "
msgWriteln(conf, indent & $sourceLine(conf, info))
msgWriteln(conf, indent & spaces(info.col) & '^')
if info.col >= 0:
msgWriteln(conf, indent & spaces(info.col) & '^')
proc formatMsg*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string): string =
let title = case msg
@@ -437,7 +474,7 @@ proc formatMsg*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string): s
of hintMin..hintMax: HintTitle
else: ErrorTitle
result = PosFormat % [toMsgFilename(conf, info), coordToStr(info.line.int),
coordToStr(info.col+1)] &
coordToStr(info.col+ColOffset)] &
title &
getMessageStr(msg, arg)
@@ -461,7 +498,7 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
conf.m.lastError = info
of warnMin..warnMax:
sev = Severity.Warning
ignoreMsg = optWarns notin conf.options or msg notin conf.notes
ignoreMsg = not conf.hasWarn(msg)
if not ignoreMsg: writeContext(conf, info)
title = WarningTitle
color = WarningColor
@@ -469,16 +506,13 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
inc(conf.warnCounter)
of hintMin..hintMax:
sev = Severity.Hint
ignoreMsg = optHints notin conf.options or msg notin conf.notes
ignoreMsg = not conf.hasHint(msg)
title = HintTitle
color = HintColor
if msg != hintUserRaw: kind = HintsToStr[ord(msg) - ord(hintMin)]
inc(conf.hintCounter)
# NOTE: currently line info line numbers start with 1,
# but column numbers start with 0, however most editors expect
# first column to be 1, so we need to +1 here
let x = PosFormat % [toMsgFilename(conf, info), coordToStr(info.line.int),
coordToStr(info.col+1)]
coordToStr(info.col+ColOffset)]
let s = getMessageStr(msg, arg)
if not ignoreMsg:
@@ -490,7 +524,7 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
KindColor, `%`(KindFormat, kind))
else:
styledMsgWriteln(styleBright, x, resetStyle, color, title, resetStyle, s)
if hintSource in conf.notes:
if conf.hasHint(hintSource):
conf.writeSurroundingSrc(info)
handleError(conf, msg, eh, s)
@@ -512,7 +546,7 @@ proc localError*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
proc localError*(conf: ConfigRef; info: TLineInfo, arg: string) =
liMessage(conf, info, errGenerated, arg, doNothing)
proc localError*(conf: ConfigRef; info: TLineInfo, format: string, params: openarray[string]) =
proc localError*(conf: ConfigRef; info: TLineInfo, format: string, params: openArray[string]) =
localError(conf, info, format % params)
proc message*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
@@ -525,7 +559,7 @@ proc internalError*(conf: ConfigRef; info: TLineInfo, errMsg: string) =
proc internalError*(conf: ConfigRef; errMsg: string) =
if conf.cmd == cmdIdeTools and conf.structuredErrorHook.isNil: return
writeContext(conf, unknownLineInfo())
writeContext(conf, unknownLineInfo)
rawMessage(conf, errInternal, errMsg)
template assertNotNil*(conf: ConfigRef; e): untyped =
@@ -536,8 +570,9 @@ template internalAssert*(conf: ConfigRef, e: bool) =
if not e: internalError(conf, $instantiationInfo())
proc quotedFilename*(conf: ConfigRef; i: TLineInfo): Rope =
assert i.fileIndex.int32 >= 0
if optExcessiveStackTrace in conf.globalOptions:
if i.fileIndex.int32 < 0:
result = makeCString "???"
elif optExcessiveStackTrace in conf.globalOptions:
result = conf.m.fileInfos[i.fileIndex.int32].quotedFullName
else:
result = conf.m.fileInfos[i.fileIndex.int32].quotedName
@@ -557,3 +592,10 @@ proc listHints*(conf: ConfigRef) =
if hint in conf.notes: "x" else: " ",
lineinfos.HintsToStr[ord(hint) - ord(hintMin)]
])
proc lintReport*(conf: ConfigRef; info: TLineInfo, beau, got: string) =
let m = "'$2' should be: '$1'" % [beau, got]
if optStyleError in conf.globalOptions:
localError(conf, info, m)
else:
message(conf, info, hintName, m)

View File

@@ -17,24 +17,33 @@ type
enabled: bool
f: File
buf: string
filename: AbsoluteFile
syms: seq[PSym]
proc doWrite(f: var NdiFile; s: PSym; conf: ConfigRef) =
f.buf.setLen 0
f.buf.add s.info.line.int
f.buf.addInt s.info.line.int
f.buf.add "\t"
f.buf.add s.info.col.int
f.buf.addInt s.info.col.int
f.f.write(s.name.s, "\t")
f.f.writeRope(s.loc.r)
f.f.writeLine("\t", toFullPath(conf, s.info), "\t", f.buf)
template writeMangledName*(f: NdiFile; s: PSym; conf: ConfigRef) =
if f.enabled: doWrite(f, s, conf)
if f.enabled: f.syms.add s
proc open*(f: var NdiFile; filename: AbsoluteFile; conf: ConfigRef) =
f.enabled = not filename.isEmpty
if f.enabled:
f.f = open(filename.string, fmWrite, 8000)
f.filename = filename
f.buf = newStringOfCap(20)
proc close*(f: var NdiFile) =
if f.enabled: close(f.f)
proc close*(f: var NdiFile, conf: ConfigRef) =
if f.enabled:
f.f = open(f.filename.string, fmWrite, 8000)
doAssert f.f != nil, f.filename.string
for s in f.syms:
doWrite(f, s, conf)
close(f.f)
f.syms.reset
f.filename.reset

View File

@@ -7,11 +7,17 @@ define:nimcore
#define:nimIncremental
#import:"$projectpath/testability"
#define:staticSqlite
@if windows:
cincludes: "$lib/wrappers/libffi/common"
@end
define:useStdoutAsStdmsg
@if nimHasStyleChecks:
styleCheck:error
@end
#define:useNodeIds
#gc:markAndSweep

View File

@@ -9,21 +9,23 @@
when defined(gcc) and defined(windows):
when defined(x86):
{.link: "icons/nim.res".}
{.link: "../icons/nim.res".}
else:
{.link: "icons/nim_icon.o".}
{.link: "../icons/nim_icon.o".}
when defined(amd64) and defined(windows) and defined(vcc):
{.link: "icons/nim-amd64-windows-vcc.res".}
{.link: "../icons/nim-amd64-windows-vcc.res".}
when defined(i386) and defined(windows) and defined(vcc):
{.link: "icons/nim-i386-windows-vcc.res".}
{.link: "../icons/nim-i386-windows-vcc.res".}
import
commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes,
extccomp, strutils, os, osproc, platform, main, parseopt,
nodejs, scriptconfig, idents, modulegraphs, lineinfos, cmdlinehelper,
commands, options, msgs,
extccomp, strutils, os, main, parseopt,
idents, lineinfos, cmdlinehelper,
pathutils
include nodejs
when hasTinyCBackend:
import tccgen
@@ -38,23 +40,44 @@ proc prependCurDir(f: AbsoluteFile): AbsoluteFile =
else:
result = f
proc addCmdPrefix*(result: var string, kind: CmdLineKind) =
# consider moving this to std/parseopt
case kind
of cmdLongOption: result.add "--"
of cmdShortOption: result.add "-"
of cmdArgument, cmdEnd: discard
proc processCmdLine(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
var p = parseopt.initOptParser(cmd)
var argsCount = 0
config.commandLine.setLen 0
# bugfix: otherwise, config.commandLine ends up duplicated
while true:
parseopt.next(p)
case p.kind
of cmdEnd: break
of cmdLongoption, cmdShortOption:
of cmdLongOption, cmdShortOption:
config.commandLine.add " "
config.commandLine.addCmdPrefix p.kind
config.commandLine.add p.key.quoteShell # quoteShell to be future proof
if p.val.len > 0:
config.commandLine.add ':'
config.commandLine.add p.val.quoteShell
if p.key == " ":
p.key = "-"
if processArgument(pass, p, argsCount, config): break
else:
processSwitch(pass, p, config)
of cmdArgument:
config.commandLine.add " "
config.commandLine.add p.key.quoteShell
if processArgument(pass, p, argsCount, config): break
if pass == passCmd2:
if optRun notin config.globalOptions and config.arguments.len > 0 and config.command.normalize != "run":
if {optRun, optWasNimscript} * config.globalOptions == {} and
config.arguments.len > 0 and config.command.normalize notin ["run", "e"]:
rawMessage(config, errGenerated, errArgsNeedRunOption)
proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
@@ -65,35 +88,22 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
)
self.initDefinesProg(conf, "nim_compiler")
if paramCount() == 0:
writeCommandLineUsage(conf, conf.helpWritten)
writeCommandLineUsage(conf)
return
self.processCmdLineAndProjectPath(conf)
if not self.loadConfigsAndRunMainCommand(cache, conf): return
if optHints in conf.options and hintGCStats in conf.notes: echo(GC_getStatistics())
if conf.hasHint(hintGCStats): echo(GC_getStatistics())
#echo(GC_getStatistics())
if conf.errorCounter != 0: return
when hasTinyCBackend:
if conf.cmd == cmdRun:
tccgen.run(conf.arguments)
tccgen.run(conf, conf.arguments)
if optRun in conf.globalOptions:
var ex = quoteShell conf.absOutFile
if conf.cmd == cmdCompileToJS:
var ex: string
if not conf.outFile.isEmpty:
ex = conf.outFile.prependCurDir.quoteShell
else:
ex = quoteShell(
completeCFilePath(conf, changeFileExt(conf.projectFull, "js").prependCurDir))
execExternalProgram(conf, findNodeJs() & " " & ex & ' ' & conf.arguments)
else:
var binPath: AbsoluteFile
if not conf.outFile.isEmpty:
# If the user specified an outFile path, use that directly.
binPath = conf.outFile.prependCurDir
else:
# Figure out ourselves a valid binary name.
binPath = changeFileExt(conf.projectFull, ExeExt).prependCurDir
var ex = quoteShell(binPath)
execExternalProgram(conf, ex & ' ' & conf.arguments)
when declared(GC_setMaxPause):

View File

@@ -48,7 +48,7 @@ proc `<`*(ver: Version, ver2: Version): bool =
# Handling for normal versions such as "0.1.0" or "1.0".
var sVer = string(ver).split('.')
var sVer2 = string(ver2).split('.')
for i in 0..max(sVer.len, sVer2.len)-1:
for i in 0..<max(sVer.len, sVer2.len):
var sVerI = 0
if i < sVer.len:
discard parseInt(sVer[i], sVerI)
@@ -69,9 +69,10 @@ proc getPathVersion*(p: string): tuple[name, version: string] =
result.version = ""
const specialSeparator = "-#"
var sepIdx = p.find(specialSeparator)
let last = p.rfind(p.lastPathPart) # the index where the last path part begins
var sepIdx = p.find(specialSeparator, start = last)
if sepIdx == -1:
sepIdx = p.rfind('-')
sepIdx = p.rfind('-', start = last)
if sepIdx == -1:
result.name = p
@@ -82,7 +83,7 @@ proc getPathVersion*(p: string): tuple[name, version: string] =
result.name = p
return
result.name = p[0 .. sepIdx - 1]
result.name = p[0..sepIdx - 1]
result.version = p.substr(sepIdx + 1)
proc addPackage(conf: ConfigRef; packages: StringTableRef, p: string; info: TLineInfo) =
@@ -129,6 +130,10 @@ proc addPathRec(conf: ConfigRef; dir: string, info: TLineInfo) =
proc nimblePath*(conf: ConfigRef; path: AbsoluteDir, info: TLineInfo) =
addPathRec(conf, path.string, info)
addNimblePath(conf, path.string, info)
let i = conf.nimblePaths.find(path)
if i != -1:
conf.nimblePaths.delete(i)
conf.nimblePaths.insert(path, 0)
when isMainModule:
proc v(s: string): Version = s.newVersion
@@ -142,16 +147,16 @@ when isMainModule:
let conf = newConfigRef()
var rr = newStringTable()
addPackage conf, rr, "irc-#a111", unknownLineInfo()
addPackage conf, rr, "irc-#head", unknownLineInfo()
addPackage conf, rr, "irc-0.1.0", unknownLineInfo()
#addPackage conf, rr, "irc", unknownLineInfo()
#addPackage conf, rr, "another", unknownLineInfo()
addPackage conf, rr, "another-0.1", unknownLineInfo()
addPackage conf, rr, "irc-#a111", unknownLineInfo
addPackage conf, rr, "irc-#head", unknownLineInfo
addPackage conf, rr, "irc-0.1.0", unknownLineInfo
#addPackage conf, rr, "irc", unknownLineInfo
#addPackage conf, rr, "another", unknownLineInfo
addPackage conf, rr, "another-0.1", unknownLineInfo
addPackage conf, rr, "ab-0.1.3", unknownLineInfo()
addPackage conf, rr, "ab-0.1", unknownLineInfo()
addPackage conf, rr, "justone-1.0", unknownLineInfo()
addPackage conf, rr, "ab-0.1.3", unknownLineInfo
addPackage conf, rr, "ab-0.1", unknownLineInfo
addPackage conf, rr, "justone-1.0", unknownLineInfo
doAssert toSeq(rr.chosen) ==
@["irc-#head", "another-0.1", "ab-0.1.3", "justone-1.0"]

View File

@@ -10,8 +10,8 @@
# This module handles the reading of the config file.
import
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer,
options, idents, wordrecg, strtabs, lineinfos, pathutils
llstream, commands, os, strutils, msgs, lexer,
options, idents, wordrecg, strtabs, lineinfos, pathutils, scriptconfig
# ---------------- configuration file parser -----------------------------
# we use Nim's scanner here to save space and work
@@ -28,7 +28,7 @@ proc parseAtom(L: var TLexer, tok: var TToken; config: ConfigRef): bool =
result = parseExpr(L, tok, config)
if tok.tokType == tkParRi: ppGetTok(L, tok)
else: lexMessage(L, errGenerated, "expected closing ')'")
elif tok.ident.id == ord(wNot):
elif tok.tokType == tkNot:
ppGetTok(L, tok)
result = not parseAtom(L, tok, config)
else:
@@ -37,14 +37,14 @@ proc parseAtom(L: var TLexer, tok: var TToken; config: ConfigRef): bool =
proc parseAndExpr(L: var TLexer, tok: var TToken; config: ConfigRef): bool =
result = parseAtom(L, tok, config)
while tok.ident.id == ord(wAnd):
while tok.tokType == tkAnd:
ppGetTok(L, tok) # skip "and"
var b = parseAtom(L, tok, config)
result = result and b
proc parseExpr(L: var TLexer, tok: var TToken; config: ConfigRef): bool =
result = parseAndExpr(L, tok, config)
while tok.ident.id == ord(wOr):
while tok.tokType == tkOr:
ppGetTok(L, tok) # skip "or"
var b = parseAndExpr(L, tok, config)
result = result or b
@@ -114,7 +114,7 @@ proc parseDirective(L: var TLexer, tok: var TToken; config: ConfigRef; condStack
ppGetTok(L, tok) # skip @
case whichKeyword(tok.ident)
of wIf:
setLen(condStack, len(condStack) + 1)
setLen(condStack, condStack.len + 1)
let res = evalppIf(L, tok, config)
condStack[high(condStack)] = res
if not res: jumpToDirective(L, tok, jdElseEndif, config, condStack)
@@ -123,31 +123,31 @@ proc parseDirective(L: var TLexer, tok: var TToken; config: ConfigRef; condStack
of wEnd: doEnd(L, tok, condStack)
of wWrite:
ppGetTok(L, tok)
msgs.msgWriteln(config, strtabs.`%`(tokToStr(tok), config.configVars,
msgs.msgWriteln(config, strtabs.`%`($tok, config.configVars,
{useEnvironment, useKey}))
ppGetTok(L, tok)
else:
case tok.ident.s.normalize
of "putenv":
ppGetTok(L, tok)
var key = tokToStr(tok)
var key = $tok
ppGetTok(L, tok)
os.putEnv(key, tokToStr(tok))
os.putEnv(key, $tok)
ppGetTok(L, tok)
of "prependenv":
ppGetTok(L, tok)
var key = tokToStr(tok)
var key = $tok
ppGetTok(L, tok)
os.putEnv(key, tokToStr(tok) & os.getEnv(key))
os.putEnv(key, $tok & os.getEnv(key))
ppGetTok(L, tok)
of "appendenv":
ppGetTok(L, tok)
var key = tokToStr(tok)
var key = $tok
ppGetTok(L, tok)
os.putEnv(key, os.getEnv(key) & tokToStr(tok))
os.putEnv(key, os.getEnv(key) & $tok)
ppGetTok(L, tok)
else:
lexMessage(L, errGenerated, "invalid directive: '$1'" % tokToStr(tok))
lexMessage(L, errGenerated, "invalid directive: '$1'" % $tok)
proc confTok(L: var TLexer, tok: var TToken; config: ConfigRef; condStack: var seq[bool]) =
ppGetTok(L, tok)
@@ -156,44 +156,51 @@ proc confTok(L: var TLexer, tok: var TToken; config: ConfigRef; condStack: var s
proc checkSymbol(L: TLexer, tok: TToken) =
if tok.tokType notin {tkSymbol..tkInt64Lit, tkStrLit..tkTripleStrLit}:
lexMessage(L, errGenerated, "expected identifier, but got: " & tokToStr(tok))
lexMessage(L, errGenerated, "expected identifier, but got: " & $tok)
proc parseAssignment(L: var TLexer, tok: var TToken;
config: ConfigRef; condStack: var seq[bool]) =
if tok.ident.s == "-" or tok.ident.s == "--":
confTok(L, tok, config, condStack) # skip unnecessary prefix
if tok.ident != nil:
if tok.ident.s == "-" or tok.ident.s == "--":
confTok(L, tok, config, condStack) # skip unnecessary prefix
var info = getLineInfo(L, tok) # save for later in case of an error
checkSymbol(L, tok)
var s = tokToStr(tok)
var s = $tok
confTok(L, tok, config, condStack) # skip symbol
var val = ""
while tok.tokType == tkDot:
add(s, '.')
s.add('.')
confTok(L, tok, config, condStack)
checkSymbol(L, tok)
add(s, tokToStr(tok))
s.add($tok)
confTok(L, tok, config, condStack)
if tok.tokType == tkBracketLe:
# BUGFIX: val, not s!
confTok(L, tok, config, condStack)
checkSymbol(L, tok)
add(val, '[')
add(val, tokToStr(tok))
val.add('[')
val.add($tok)
confTok(L, tok, config, condStack)
if tok.tokType == tkBracketRi: confTok(L, tok, config, condStack)
else: lexMessage(L, errGenerated, "expected closing ']'")
add(val, ']')
val.add(']')
let percent = tok.ident != nil and tok.ident.s == "%="
if tok.tokType in {tkColon, tkEquals} or percent:
if len(val) > 0: add(val, ':')
if val.len > 0: val.add(':')
confTok(L, tok, config, condStack) # skip ':' or '=' or '%'
checkSymbol(L, tok)
add(val, tokToStr(tok))
val.add($tok)
confTok(L, tok, config, condStack) # skip symbol
if tok.tokType in {tkColon, tkEquals}:
val.add($tok) # add the :
confTok(L, tok, config, condStack) # skip symbol
checkSymbol(L, tok)
val.add($tok) # add the token after it
confTok(L, tok, config, condStack) # skip symbol
while tok.ident != nil and tok.ident.s == "&":
confTok(L, tok, config, condStack)
checkSymbol(L, tok)
add(val, tokToStr(tok))
val.add($tok)
confTok(L, tok, config, condStack)
if percent:
processSwitch(s, strtabs.`%`(val, config.configVars,
@@ -201,7 +208,7 @@ proc parseAssignment(L: var TLexer, tok: var TToken;
else:
processSwitch(s, val, passPP, info, config)
proc readConfigFile(filename: AbsoluteFile; cache: IdentCache;
proc readConfigFile*(filename: AbsoluteFile; cache: IdentCache;
config: ConfigRef): bool =
var
L: TLexer
@@ -215,7 +222,7 @@ proc readConfigFile(filename: AbsoluteFile; cache: IdentCache;
var condStack: seq[bool] = @[]
confTok(L, tok, config, condStack) # read in the first token
while tok.tokType != tkEof: parseAssignment(L, tok, config, condStack)
if len(condStack) > 0: lexMessage(L, errGenerated, "expected @end")
if condStack.len > 0: lexMessage(L, errGenerated, "expected @end")
closeLexer(L)
return true
@@ -239,19 +246,34 @@ proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef) =
template readConfigFile(path) =
let configPath = path
if readConfigFile(configPath, cache, conf):
add(configFiles, configPath)
configFiles.add(configPath)
template runNimScriptIfExists(path: AbsoluteFile) =
let p = path # eval once
if fileExists(p):
configFiles.add(p)
runNimScript(cache, p, freshDefines = false, conf)
if optSkipSystemConfigFile notin conf.globalOptions:
readConfigFile(getSystemConfigPath(conf, cfg))
if cfg == DefaultConfig:
runNimScriptIfExists(getSystemConfigPath(conf, DefaultConfigNims))
if optSkipUserConfigFile notin conf.globalOptions:
readConfigFile(getUserConfigPath(cfg))
if cfg == DefaultConfig:
runNimScriptIfExists(getUserConfigPath(DefaultConfigNims))
let pd = if not conf.projectPath.isEmpty: conf.projectPath else: AbsoluteDir(getCurrentDir())
if optSkipParentConfigFiles notin conf.globalOptions:
for dir in parentDirs(pd.string, fromRoot=true, inclusive=false):
readConfigFile(AbsoluteDir(dir) / cfg)
if cfg == DefaultConfig:
runNimScriptIfExists(AbsoluteDir(dir) / DefaultConfigNims)
if optSkipProjConfigFile notin conf.globalOptions:
readConfigFile(pd / cfg)
@@ -262,6 +284,20 @@ proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef) =
projectConfig = changeFileExt(conf.projectFull, "nim.cfg")
readConfigFile(projectConfig)
if cfg == DefaultConfig:
runNimScriptIfExists(pd / DefaultConfigNims)
for filename in configFiles:
# delayed to here so that `hintConf` is honored
rawMessage(conf, hintConf, filename.string)
block:
let scriptFile = conf.projectFull.changeFileExt("nims")
if conf.command != "nimsuggest":
runNimScriptIfExists(scriptFile)
else:
if scriptFile != conf.projectFull:
runNimScriptIfExists(scriptFile)
else:
# 'nimsuggest foo.nims' means to just auto-complete the NimScript file
discard

Some files were not shown because too many files have changed in this diff Show More