mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-31 10:53:40 +00:00
Compare commits
368 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d274b56256 | ||
|
|
dd6833297f | ||
|
|
e885d89f63 | ||
|
|
2b53216152 | ||
|
|
d33e112766 | ||
|
|
e7e8f437c4 | ||
|
|
789b1bcbb6 | ||
|
|
251bdc1d5a | ||
|
|
b41226001c | ||
|
|
a4fdaa88cc | ||
|
|
ab47707586 | ||
|
|
2f4900615a | ||
|
|
8fa2c0b532 | ||
|
|
e2e663a143 | ||
|
|
ac89eead8a | ||
|
|
6f4bacff67 | ||
|
|
1e5dd9022b | ||
|
|
8cde6ba6bc | ||
|
|
eefca1b81f | ||
|
|
1972005439 | ||
|
|
25d89269eb | ||
|
|
836b95c896 | ||
|
|
415689323c | ||
|
|
e1702ae1e6 | ||
|
|
f2b16c490d | ||
|
|
b024a45163 | ||
|
|
d0232f0e5b | ||
|
|
4341b06f65 | ||
|
|
f7a13f62d6 | ||
|
|
68aeb4c1a6 | ||
|
|
4e3eb7414c | ||
|
|
d30c6419a0 | ||
|
|
15f0b48676 | ||
|
|
497af2c0d9 | ||
|
|
004fc23a3f | ||
|
|
14960fa754 | ||
|
|
d81edcacc6 | ||
|
|
ec0cec3170 | ||
|
|
b1b5e3ab10 | ||
|
|
05c0419658 | ||
|
|
a8426fc789 | ||
|
|
63cca93ea9 | ||
|
|
06f02bb771 | ||
|
|
33888a7384 | ||
|
|
19001c070b | ||
|
|
c61eb5df32 | ||
|
|
b9f243eb2a | ||
|
|
85bc8326ac | ||
|
|
b2b878f4d6 | ||
|
|
61c1142667 | ||
|
|
8c100a37b9 | ||
|
|
2c73e84436 | ||
|
|
0455d24d55 | ||
|
|
a4401054cc | ||
|
|
278ecad973 | ||
|
|
2ecae20c43 | ||
|
|
832b8c5034 | ||
|
|
927978345b | ||
|
|
4680ab61c0 | ||
|
|
e4a2c2d474 | ||
|
|
8bfc396a4d | ||
|
|
ef4ac5a0d2 | ||
|
|
82680a12a7 | ||
|
|
42ac50e988 | ||
|
|
ee0a470294 | ||
|
|
15ae9323e8 | ||
|
|
465fd06d50 | ||
|
|
2f32b450d3 | ||
|
|
efaa6777a4 | ||
|
|
8e6136dd59 | ||
|
|
b10f0e7bca | ||
|
|
02e8aa9660 | ||
|
|
bb839029d5 | ||
|
|
dc4cc2dca5 | ||
|
|
ef7d7f2459 | ||
|
|
98cebad7de | ||
|
|
26bcf18f91 | ||
|
|
26acc97864 | ||
|
|
a77ffdb7ea | ||
|
|
152dab0983 | ||
|
|
ded8b0e541 | ||
|
|
00775f6880 | ||
|
|
e78ef57c93 | ||
|
|
1807de38e5 | ||
|
|
c8aeea9d62 | ||
|
|
810d5e91e4 | ||
|
|
0978276ed9 | ||
|
|
e1929deac7 | ||
|
|
065f568470 | ||
|
|
cb6ce80cb8 | ||
|
|
e649ddd09b | ||
|
|
abe3b0eb64 | ||
|
|
c322faaf38 | ||
|
|
5a995ffc53 | ||
|
|
83dabb69ae | ||
|
|
c3f03cfa5d | ||
|
|
a7024f49af | ||
|
|
1275763284 | ||
|
|
49844415ce | ||
|
|
eae29e8eaf | ||
|
|
7d32425a57 | ||
|
|
82319ef00d | ||
|
|
8cdd8867c0 | ||
|
|
86e93eb293 | ||
|
|
84ac003519 | ||
|
|
4dfe420c2f | ||
|
|
51df9ff1c7 | ||
|
|
12a0f88a52 | ||
|
|
afbcba909b | ||
|
|
400e0260b8 | ||
|
|
7c3c61f2f1 | ||
|
|
a262a87bbe | ||
|
|
2c01c9c4c8 | ||
|
|
b0bd4320a0 | ||
|
|
d7a966c4eb | ||
|
|
d14e8e8dcc | ||
|
|
e93eaac223 | ||
|
|
7f6e800caf | ||
|
|
a8b5ad845c | ||
|
|
4c8934305c | ||
|
|
c4a0d4c5e3 | ||
|
|
731eabc930 | ||
|
|
3e83d73f27 | ||
|
|
7b811deeff | ||
|
|
7a50d66346 | ||
|
|
4c76f9f152 | ||
|
|
6773ffa63d | ||
|
|
2beefb9aa0 | ||
|
|
0d6795a771 | ||
|
|
8f9dd5b349 | ||
|
|
6454472938 | ||
|
|
488e18f90d | ||
|
|
590d397852 | ||
|
|
d6d36093b1 | ||
|
|
207237cec2 | ||
|
|
c870ff5946 | ||
|
|
c2c9fbd745 | ||
|
|
f0bfc0bd3f | ||
|
|
9c17a32e0e | ||
|
|
ef3f343ec2 | ||
|
|
fe791c67b4 | ||
|
|
9a49451124 | ||
|
|
340b5a1676 | ||
|
|
0c915b5e47 | ||
|
|
516db3bac3 | ||
|
|
f019e999d4 | ||
|
|
30e9f23ec0 | ||
|
|
b2c5d7b4ff | ||
|
|
2ef71c0a46 | ||
|
|
8e8231f9d6 | ||
|
|
42eeab5fd1 | ||
|
|
cda77c1520 | ||
|
|
551225d888 | ||
|
|
ed0dce7292 | ||
|
|
b936bfd01a | ||
|
|
27e548140b | ||
|
|
801c0f0369 | ||
|
|
4b0636fba0 | ||
|
|
28180e47a9 | ||
|
|
6b302bb71b | ||
|
|
d0287748fe | ||
|
|
7b09fd70ab | ||
|
|
33bfe5b12c | ||
|
|
772ed5eff2 | ||
|
|
891329cd4b | ||
|
|
486cb09ec2 | ||
|
|
1830a3b505 | ||
|
|
22ae0bef63 | ||
|
|
56a901f9e1 | ||
|
|
33cd883e27 | ||
|
|
cb894c7094 | ||
|
|
520881af9a | ||
|
|
0c3892c3c7 | ||
|
|
6319b00ef7 | ||
|
|
4b723c0f53 | ||
|
|
6ea6225523 | ||
|
|
f7c4fb0014 | ||
|
|
15f54de5c4 | ||
|
|
2bd1aa186e | ||
|
|
1563cb2f6e | ||
|
|
927fa890ec | ||
|
|
851e515bba | ||
|
|
4a38092ac1 | ||
|
|
ce44cf03cc | ||
|
|
08261cb9e3 | ||
|
|
5d34e81f23 | ||
|
|
23c4bbedcb | ||
|
|
b3c178c202 | ||
|
|
aac54b9c7f | ||
|
|
d7869a8009 | ||
|
|
5d303762f1 | ||
|
|
bc3bee5469 | ||
|
|
07c7a8a526 | ||
|
|
dc8ac66873 | ||
|
|
4f6b59de96 | ||
|
|
2c5b367001 | ||
|
|
15e3813d96 | ||
|
|
d102b2f54c | ||
|
|
a95399143f | ||
|
|
342b74ef70 | ||
|
|
7bdfeb7819 | ||
|
|
a93f6e7acc | ||
|
|
9b9ae8a487 | ||
|
|
5853303be0 | ||
|
|
40a9c33eff | ||
|
|
a9135095f0 | ||
|
|
ada815e459 | ||
|
|
9a32905d89 | ||
|
|
9888a29c3d | ||
|
|
bcbeff3632 | ||
|
|
92e5573b20 | ||
|
|
955040f0f1 | ||
|
|
b098546da0 | ||
|
|
ae92eac060 | ||
|
|
58656aa5bb | ||
|
|
4306d8fb36 | ||
|
|
c7d5b8c83d | ||
|
|
5ec8b60942 | ||
|
|
9df195ef58 | ||
|
|
1869826668 | ||
|
|
0bcd7062c6 | ||
|
|
39a27783fc | ||
|
|
35cae73aa5 | ||
|
|
fcf1df6e56 | ||
|
|
526a32e169 | ||
|
|
19bcb43a0e | ||
|
|
bd4f76a2e3 | ||
|
|
e49d52eb61 | ||
|
|
bbd5086bc3 | ||
|
|
53e1d57419 | ||
|
|
61d682e733 | ||
|
|
ef634cc251 | ||
|
|
faaf271928 | ||
|
|
ac37eed5a2 | ||
|
|
dc5c88ca79 | ||
|
|
23d64be860 | ||
|
|
a9223d4cdd | ||
|
|
77ad8b81e4 | ||
|
|
a61bbf7d8d | ||
|
|
fdbec969d8 | ||
|
|
fa96e56ad0 | ||
|
|
81d32cf7e5 | ||
|
|
7a5314c571 | ||
|
|
19898e1225 | ||
|
|
4da7dbffc5 | ||
|
|
ea475a4e98 | ||
|
|
b812431f83 | ||
|
|
610516e027 | ||
|
|
3d9b6cfebc | ||
|
|
5ddaf3e1fb | ||
|
|
609388e33f | ||
|
|
5d2bab7558 | ||
|
|
c17baaefbc | ||
|
|
3e31f55aed | ||
|
|
c55930f2e6 | ||
|
|
78b86b7942 | ||
|
|
0ff4b2ba7e | ||
|
|
4b5cecd902 | ||
|
|
a3ef5df680 | ||
|
|
1a92edeb89 | ||
|
|
908fc2a22e | ||
|
|
7ff43d07b2 | ||
|
|
9338aa2497 | ||
|
|
c989542339 | ||
|
|
d39147219a | ||
|
|
69aabdab80 | ||
|
|
32d4bf3525 | ||
|
|
4f64c9fae5 | ||
|
|
99f8793502 | ||
|
|
742e9d65ad | ||
|
|
502ac4ed5e | ||
|
|
0992854941 | ||
|
|
7806ec525e | ||
|
|
cd592ed85b | ||
|
|
93c8427fca | ||
|
|
ebd88725f9 | ||
|
|
0213c7313b | ||
|
|
7e3da693f5 | ||
|
|
faacd63bf6 | ||
|
|
e5475768ba | ||
|
|
1ef945668d | ||
|
|
c658de24b0 | ||
|
|
1cbdc1573a | ||
|
|
f90620fb32 | ||
|
|
d584dd5b99 | ||
|
|
23c117a950 | ||
|
|
373c909300 | ||
|
|
0d0c249074 | ||
|
|
f91867aa31 | ||
|
|
a59ad20062 | ||
|
|
a0073d2d4c | ||
|
|
c7c6b13a32 | ||
|
|
ff39f6e260 | ||
|
|
2859069dbe | ||
|
|
5933aece9b | ||
|
|
040d23e799 | ||
|
|
7772ca303c | ||
|
|
1b143f5e79 | ||
|
|
eb5358dcdb | ||
|
|
a8611c665f | ||
|
|
fe46c8b5f1 | ||
|
|
92d6fb86c6 | ||
|
|
309ec7167e | ||
|
|
6976d18519 | ||
|
|
bec4900165 | ||
|
|
270a5a372d | ||
|
|
ade85ee91f | ||
|
|
0a1049881e | ||
|
|
c6fc3b2eae | ||
|
|
f8b71f7075 | ||
|
|
3aaa12dbe5 | ||
|
|
528ef6c218 | ||
|
|
cde83d90aa | ||
|
|
7313b70a6a | ||
|
|
036d894e6a | ||
|
|
77b696c2c9 | ||
|
|
a78ee8ae84 | ||
|
|
15157d06c3 | ||
|
|
997ccc5889 | ||
|
|
46fb855425 | ||
|
|
b0f4a9b845 | ||
|
|
6ff61766da | ||
|
|
b7c66ce860 | ||
|
|
83a9c3ba31 | ||
|
|
b21eb1ed36 | ||
|
|
b423ab138f | ||
|
|
fce89cb60a | ||
|
|
f2f15e9726 | ||
|
|
b2edc3468c | ||
|
|
f7cfc46ae1 | ||
|
|
dbbafd320c | ||
|
|
5fed1c05ce | ||
|
|
539bced70d | ||
|
|
b155864967 | ||
|
|
9d51197aa4 | ||
|
|
a55b90827e | ||
|
|
efaaa38eef | ||
|
|
12d2901e89 | ||
|
|
e01e543fce | ||
|
|
2e0db988e7 | ||
|
|
cc984217a9 | ||
|
|
24a7584299 | ||
|
|
4c510d5577 | ||
|
|
2f730afe9e | ||
|
|
2bda4a30a6 | ||
|
|
f755e452d2 | ||
|
|
cfdac6666f | ||
|
|
ee703c5db4 | ||
|
|
7ba2659f73 | ||
|
|
c80e2c1736 | ||
|
|
cd2b093d07 | ||
|
|
ee65767d44 | ||
|
|
f50bcf82c3 | ||
|
|
dde556665a | ||
|
|
8d5a275189 | ||
|
|
83a2515af7 | ||
|
|
3ecb369ca1 | ||
|
|
582468da1c | ||
|
|
141b76e365 | ||
|
|
41d9918591 | ||
|
|
6621e1a3ea | ||
|
|
490c4226a5 | ||
|
|
4d8108046b | ||
|
|
d634587423 | ||
|
|
5e2b9341f3 | ||
|
|
1a45da9150 | ||
|
|
62701cd3b9 | ||
|
|
c239db4817 |
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -2,7 +2,7 @@
|
||||
name: Feature request
|
||||
about: Do you want to suggest a new feature? Use this template.
|
||||
title: ''
|
||||
labels: ''
|
||||
labels: ["Feature"]
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
2
.github/workflows/ci_docs.yml
vendored
2
.github/workflows/ci_docs.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
- target: windows
|
||||
os: windows-2019
|
||||
- target: osx
|
||||
os: macos-11
|
||||
os: macos-10.15
|
||||
|
||||
name: ${{ matrix.target }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
2
.github/workflows/ci_packages.yml
vendored
2
.github/workflows/ci_packages.yml
vendored
@@ -6,7 +6,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-11]
|
||||
os: [ubuntu-20.04, macos-10.15]
|
||||
cpu: [amd64]
|
||||
batch: ["allowed_failures", "0_3", "1_3", "2_3"] # list of `index_num`
|
||||
name: '${{ matrix.os }} (batch: ${{ matrix.batch }})'
|
||||
|
||||
@@ -28,10 +28,10 @@ jobs:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
CPU: i386
|
||||
OSX_amd64:
|
||||
vmImage: 'macOS-11'
|
||||
vmImage: 'macOS-10.15'
|
||||
CPU: amd64
|
||||
OSX_amd64_cpp:
|
||||
vmImage: 'macOS-11'
|
||||
vmImage: 'macOS-10.15'
|
||||
CPU: amd64
|
||||
NIM_COMPILE_TO_CPP: true
|
||||
Windows_amd64_batch0_3:
|
||||
|
||||
@@ -24,6 +24,6 @@ if not exist %nim_csources% (
|
||||
cd ..
|
||||
copy /y bin\nim.exe %nim_csources%
|
||||
)
|
||||
bin\nim.exe c --noNimblePath --skipUserCfg --skipParentCfg --hints:off koch
|
||||
bin\nim.exe c --skipUserCfg --skipParentCfg --hints:off koch
|
||||
koch boot -d:release --skipUserCfg --skipParentCfg --hints:off
|
||||
koch tools --skipUserCfg --skipParentCfg --hints:off
|
||||
|
||||
@@ -11,7 +11,7 @@ set -e # exit on first error
|
||||
. ci/funs.sh
|
||||
nimBuildCsourcesIfNeeded "$@"
|
||||
|
||||
echo_run bin/nim c --noNimblePath --skipUserCfg --skipParentCfg --hints:off koch
|
||||
echo_run bin/nim c --skipUserCfg --skipParentCfg --hints:off koch
|
||||
echo_run ./koch boot -d:release --skipUserCfg --skipParentCfg --hints:off
|
||||
echo_run ./koch tools --skipUserCfg --skipParentCfg --hints:off
|
||||
|
||||
|
||||
89
changelog.md
89
changelog.md
@@ -3,65 +3,67 @@
|
||||
|
||||
## Changes affecting backward compatibility
|
||||
|
||||
- `addr` is now available for all addressable locations,
|
||||
`unsafeAddr` is now deprecated and an alias for `addr`.
|
||||
- The `Math.trunc` polyfill for targeting Internet Explorer was
|
||||
previously emitted for every JavaScript output file except if
|
||||
the symbol `nodejs` was defined via `-d:nodejs`. Now, it is only
|
||||
emitted if the symbol `nimJsMathTruncPolyfill` is defined. If you are
|
||||
targeting Internet Explorer, you may choose to enable this option
|
||||
or define your own `Math.trunc` polyfill using the [`emit` pragma](https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-emit-pragma). Nim uses
|
||||
`Math.trunc` for the division and modulo operators for integers.
|
||||
|
||||
- `io`, `assertions`, `formatfloat`, and `` dollars.`$` `` for objects are about to move out of the `system` module. You may instead import `std/syncio`, `std/assertions`, `std/formatfloat` and `std/objectdollar`.
|
||||
The `-d:nimPreviewSlimSystem` option makes these imports required.
|
||||
|
||||
- The `gc:v2` option is removed.
|
||||
|
||||
- The `mainmodule` and `m` options are removed.
|
||||
|
||||
- The `threads:on` option is now the default.
|
||||
- Deprecated `std/sums`.
|
||||
|
||||
- Optional parameters in combination with `: body` syntax (RFC #405) are now opt-in via
|
||||
`experimental:flexibleOptionalParams`.
|
||||
|
||||
## Standard library additions and changes
|
||||
- `std/sharedstrings` module is removed.
|
||||
- Constants `colors.colPaleVioletRed` and `colors.colMediumPurple` changed to match the CSS color standard.
|
||||
|
||||
- Pointer to `cstring` conversion now triggers a `[PtrToCstringConv]` warning.
|
||||
This warning will become an error in future versions! Use a `cast` operation
|
||||
like `cast[cstring](x)` instead.
|
||||
- `addr` is now available for all addressable locations, `unsafeAddr` is deprecated and
|
||||
becomes an alias for `addr`.
|
||||
|
||||
- `logging` will default to flushing all log level messages. To get the legacy behaviour of only flushing Error and Fatal messages, use `-d:nimV1LogFlushBehavior`.
|
||||
- io is about to move out of system; use `-d:nimPreviewSlimSystem` and import `std/syncio`.
|
||||
|
||||
- Object fields now support default values, see https://nim-lang.github.io/Nim/manual.html#types-default-values-for-object-fields for details.
|
||||
|
||||
- Redefining templates with the same signature was previously
|
||||
allowed to support certain macro code. To do this explicitly, the
|
||||
`{.redefine.}` pragma has been added. Note that this is only for templates.
|
||||
Implicit redefinition of templates is now deprecated and will give an error in the future.
|
||||
|
||||
- Using an unnamed break in a block is deprecated. This warning will become an error in future versions! Use a named block with a named break instead.
|
||||
|
||||
- Several Standard libraries are moved to nimble packages, use `nimble` to install them:
|
||||
- `std/punycode` => `punycode`
|
||||
- `std/asyncftpclient` => `asyncftpclient`
|
||||
- `std/smtp` => `smtp`
|
||||
- `std/db_common` => `db_connector/db_common`
|
||||
- `std/db_sqlite` => `db_connector/db_sqlite`
|
||||
- `std/db_mysql` => `db_connector/db_mysql`
|
||||
- `std/db_postgres` => `db_connector/db_postgres`
|
||||
- `std/db_odbc` => `db_connector/db_odbc`
|
||||
|
||||
- Previously, calls like `foo(a, b): ...` or `foo(a, b) do: ...` where the final argument of
|
||||
`foo` had type `proc ()` were assumed by the compiler to mean `foo(a, b, proc () = ...)`.
|
||||
This behavior is now deprecated. Use `foo(a, b) do (): ...` or `foo(a, b, proc () = ...)` instead.
|
||||
|
||||
- If no exception or any exception deriving from Exception but not Defect or CatchableError given in except, a `warnBareExcept` warning will be triggered.
|
||||
- The `gc:v2` option is removed.
|
||||
|
||||
## Standard library additions and changes
|
||||
|
||||
- `macros.parseExpr` and `macros.parseStmt` now accept an optional
|
||||
[//]: # "Changes:"
|
||||
- `macros.parseExpr` and `macros.parseStmt` now accept an optional.
|
||||
filename argument for more informative errors.
|
||||
- Module `colors` expanded with missing colors from the CSS color standard.
|
||||
- Fixed `lists.SinglyLinkedList` being broken after removing the last node ([#19353](https://github.com/nim-lang/Nim/pull/19353)).
|
||||
- `md5` now works at compile time and in JavaScript.
|
||||
- `std/smtp` sends `ehlo` first. If the mail server does not understand, it sends `helo` as a fallback.
|
||||
- Changed mimedb to use an `OrderedTable` instead of `OrderedTableRef`, to use it in a const.
|
||||
- `strutils.find` now use and default to `last=-1` for whole string searches, making limiting it to just the first char (`last=0`) valid.
|
||||
|
||||
[//]: # "Additions:"
|
||||
- Added `IsoWeekRange`, a range type to represent the number of weeks in an ISO week-based year.
|
||||
- Added `IsoYear`, a distinct int type to prevent bugs from confusing the week-based year and the regular year.
|
||||
- Added `initDateTime` in `times` to create a datetime from a weekday, and ISO 8601 week number and week-based year.
|
||||
- Added `getIsoWeekAndYear` in `times` to get an ISO week number along with the corresponding ISO week-based year from a datetime.
|
||||
- Added `getIsoWeeksInYear` in `times` to return the number of weeks in an ISO week-based year.
|
||||
- Added `std/oserrors` for OS error reporting. Added `std/envvars` for environment variables handling.
|
||||
- Added `sep` parameter in `std/uri` to specify the query separator.
|
||||
- Added [`Array.shift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift) for JavaScript targets.
|
||||
- Added [`queueMicrotask`](https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask) for JavaScript targets.
|
||||
|
||||
[//]: # "Deprecations:"
|
||||
- Deprecated `selfExe` for Nimscript.
|
||||
|
||||
[//]: # "Removals:"
|
||||
- Removed deprecated `oids.oidToString`.
|
||||
- Removed define `nimExperimentalAsyncjsThen` for `std/asyncjs.then` and `std/jsfetch`.
|
||||
- Removed deprecated `jsre.test` and `jsre.toString`.
|
||||
- Removed deprecated `math.c_frexp`.
|
||||
- Removed deprecated `` httpcore.`==` ``.
|
||||
- Removed deprecated `std/dom_extensions`.
|
||||
- Removed deprecated `std/posix.CMSG_SPACE` and `std/posix.CMSG_LEN` that takes wrong argument types.
|
||||
- Removed deprecated `osproc.poDemon`, symbol with typo.
|
||||
|
||||
## Language changes
|
||||
|
||||
|
||||
- Pragma macros on type definitions can now return `nnkTypeSection` nodes as well as `nnkTypeDef`,
|
||||
allowing multiple type definitions to be injected in place of the original type definition.
|
||||
|
||||
@@ -94,14 +96,15 @@
|
||||
```
|
||||
- [Case statement macros](manual.html#macros-case-statement-macros) are no longer experimental,
|
||||
meaning you no longer need to enable the experimental switch `caseStmtMacros` to use them.
|
||||
- Full command syntax and block arguments i.e. `foo a, b: c` are now allowed
|
||||
for the right-hand side of type definitions in type sections. Previously
|
||||
they would error with "invalid indentation".
|
||||
|
||||
## Compiler changes
|
||||
|
||||
- `nim` can now compile version 1.4.0 as follows: `nim c --lib:lib --stylecheck:off compiler/nim`,
|
||||
without requiring `-d:nimVersion140` which is now a noop.
|
||||
|
||||
- `--styleCheck` now only applies to the current package.
|
||||
|
||||
|
||||
## Tool changes
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
## Standard library additions and changes
|
||||
|
||||
- `std/sharedlist` and `std/sharedtables` are now deprecated, see RFC [#433](https://github.com/nim-lang/RFCs/issues/433).
|
||||
|
||||
### New compile flag (`-d:nimNoGetRandom`) when building `std/sysrand` to remove dependency on linux `getrandom` syscall
|
||||
|
||||
This compile flag only affects linux builds and is necessary if either compiling on a linux kernel version < 3.17, or if code built will be executing on kernel < 3.17.
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
- Removed the deprecated `asyncdispatch.newAsyncNativeSocket`.
|
||||
- Removed the deprecated `dom.releaseEvents` and `dom.captureEvents`.
|
||||
|
||||
- Removed `sharedlists.initSharedList`, was deprecated and produces undefined behaviour.
|
||||
- Removed `sharedlist.initSharedList`, was deprecated and produces undefined behaviour.
|
||||
|
||||
- There is a new experimental feature called "strictFuncs" which makes the definition of
|
||||
`.noSideEffect` stricter. [See here](manual_experimental.html#stricts-funcs)
|
||||
|
||||
@@ -76,6 +76,8 @@ _nimBuildCsourcesIfNeeded(){
|
||||
makeX=gmake
|
||||
elif [ "$unamestr" = 'CROSSOS' ]; then
|
||||
makeX=gmake
|
||||
elif [ "$unamestr" = 'SunOS' ]; then
|
||||
makeX=gmake
|
||||
else
|
||||
makeX=make
|
||||
fi
|
||||
|
||||
9
compiler.nimble
Normal file
9
compiler.nimble
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
version = system.NimVersion
|
||||
author = "Andreas Rumpf"
|
||||
description = "Compiler package providing the compiler sources as a library."
|
||||
license = "MIT"
|
||||
|
||||
installDirs = @["compiler", "nimsuggest"]
|
||||
|
||||
requires "nim >= 0.14.0"
|
||||
@@ -12,6 +12,9 @@
|
||||
import
|
||||
ast, astalgo, types, trees, intsets
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
TAnalysisResult* = enum
|
||||
arNo, arMaybe, arYes
|
||||
|
||||
@@ -13,6 +13,9 @@ import
|
||||
lineinfos, hashes, options, ropes, idents, int128, tables
|
||||
from strutils import toLowerAscii
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
export int128
|
||||
|
||||
type
|
||||
@@ -777,8 +780,6 @@ type
|
||||
ident*: PIdent
|
||||
else:
|
||||
sons*: TNodeSeq
|
||||
when defined(nimsuggest):
|
||||
endInfo*: TLineInfo
|
||||
|
||||
TStrTable* = object # a table[PIdent] of PSym
|
||||
counter*: int
|
||||
@@ -875,8 +876,6 @@ type
|
||||
typ*: PType
|
||||
name*: PIdent
|
||||
info*: TLineInfo
|
||||
when defined(nimsuggest):
|
||||
endInfo*: TLineInfo
|
||||
owner*: PSym
|
||||
flags*: TSymFlags
|
||||
ast*: PNode # syntax tree of proc, iterator, etc.:
|
||||
@@ -1507,7 +1506,7 @@ proc assignType*(dest, src: PType) =
|
||||
# this fixes 'type TLock = TSysLock':
|
||||
if src.sym != nil:
|
||||
if dest.sym != nil:
|
||||
dest.sym.flags.incl src.sym.flags-{sfExported}
|
||||
dest.sym.flags.incl src.sym.flags-{sfUsed, sfExported}
|
||||
if dest.sym.annex == nil: dest.sym.annex = src.sym.annex
|
||||
mergeLoc(dest.sym.loc, src.sym.loc)
|
||||
else:
|
||||
@@ -1661,8 +1660,6 @@ proc copyNode*(src: PNode): PNode =
|
||||
of nkIdent: result.ident = src.ident
|
||||
of nkStrLit..nkTripleStrLit: result.strVal = src.strVal
|
||||
else: discard
|
||||
when defined(nimsuggest):
|
||||
result.endInfo = src.endInfo
|
||||
|
||||
template transitionNodeKindCommon(k: TNodeKind) =
|
||||
let obj {.inject.} = n[]
|
||||
@@ -1711,8 +1708,6 @@ template copyNodeImpl(dst, src, processSonsStmt) =
|
||||
if src == nil: return
|
||||
dst = newNode(src.kind)
|
||||
dst.info = src.info
|
||||
when defined(nimsuggest):
|
||||
result.endInfo = src.endInfo
|
||||
dst.typ = src.typ
|
||||
dst.flags = src.flags * PersistentNodeFlags
|
||||
dst.comment = src.comment
|
||||
|
||||
@@ -15,6 +15,9 @@ import
|
||||
ast, hashes, intsets, strutils, options, lineinfos, ropes, idents, rodutils,
|
||||
msgs
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
proc hashNode*(p: RootRef): Hash
|
||||
proc treeToYaml*(conf: ConfigRef; n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope
|
||||
# Convert a tree into its YAML representation; this is used by the
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
# this unit handles Nim sets; it implements bit sets
|
||||
# the code here should be reused in the Nim standard library
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
ElemType = byte
|
||||
TBitSet* = seq[ElemType] # we use byte here to avoid issues with
|
||||
@@ -23,53 +26,40 @@ const
|
||||
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)
|
||||
proc bitSetDiff*(x: var TBitSet, y: TBitSet)
|
||||
proc bitSetSymDiff*(x: var TBitSet, y: TBitSet)
|
||||
proc bitSetIntersect*(x: var TBitSet, y: TBitSet)
|
||||
proc bitSetIncl*(x: var TBitSet, elem: BiggestInt)
|
||||
proc bitSetExcl*(x: var TBitSet, elem: BiggestInt)
|
||||
proc bitSetIn*(x: TBitSet, e: BiggestInt): bool
|
||||
proc bitSetEquals*(x, y: TBitSet): bool
|
||||
proc bitSetContains*(x, y: TBitSet): bool
|
||||
proc bitSetCard*(x: TBitSet): BiggestInt
|
||||
# implementation
|
||||
|
||||
proc bitSetIn(x: TBitSet, e: BiggestInt): bool =
|
||||
proc bitSetIn*(x: TBitSet, e: BiggestInt): bool =
|
||||
result = (x[int(e.divElemSize)] and (One shl e.modElemSize)) != Zero
|
||||
|
||||
proc bitSetIncl(x: var TBitSet, elem: BiggestInt) =
|
||||
proc bitSetIncl*(x: var TBitSet, elem: BiggestInt) =
|
||||
assert(elem >= 0)
|
||||
x[int(elem.divElemSize)] = x[int(elem.divElemSize)] or
|
||||
(One shl elem.modElemSize)
|
||||
|
||||
proc bitSetExcl(x: var TBitSet, elem: BiggestInt) =
|
||||
proc bitSetExcl*(x: var TBitSet, elem: BiggestInt) =
|
||||
x[int(elem.divElemSize)] = x[int(elem.divElemSize)] and
|
||||
not(One shl elem.modElemSize)
|
||||
|
||||
proc bitSetInit(b: var TBitSet, length: int) =
|
||||
proc bitSetInit*(b: var TBitSet, length: int) =
|
||||
newSeq(b, length)
|
||||
|
||||
proc bitSetUnion(x: var TBitSet, y: TBitSet) =
|
||||
proc bitSetUnion*(x: var TBitSet, y: TBitSet) =
|
||||
for i in 0..high(x): x[i] = x[i] or y[i]
|
||||
|
||||
proc bitSetDiff(x: var TBitSet, y: TBitSet) =
|
||||
proc bitSetDiff*(x: var TBitSet, y: TBitSet) =
|
||||
for i in 0..high(x): x[i] = x[i] and not y[i]
|
||||
|
||||
proc bitSetSymDiff(x: var TBitSet, y: TBitSet) =
|
||||
proc bitSetSymDiff*(x: var TBitSet, y: TBitSet) =
|
||||
for i in 0..high(x): x[i] = x[i] xor y[i]
|
||||
|
||||
proc bitSetIntersect(x: var TBitSet, y: TBitSet) =
|
||||
proc bitSetIntersect*(x: var TBitSet, y: TBitSet) =
|
||||
for i in 0..high(x): x[i] = x[i] and y[i]
|
||||
|
||||
proc bitSetEquals(x, y: TBitSet): bool =
|
||||
proc bitSetEquals*(x, y: TBitSet): bool =
|
||||
for i in 0..high(x):
|
||||
if x[i] != y[i]:
|
||||
return false
|
||||
result = true
|
||||
|
||||
proc bitSetContains(x, y: TBitSet): bool =
|
||||
proc bitSetContains*(x, y: TBitSet): bool =
|
||||
for i in 0..high(x):
|
||||
if (x[i] and not y[i]) != Zero:
|
||||
return false
|
||||
@@ -96,6 +86,6 @@ const populationCount: array[uint8, uint8] = block:
|
||||
|
||||
arr
|
||||
|
||||
proc bitSetCard(x: TBitSet): BiggestInt =
|
||||
proc bitSetCard*(x: TBitSet): BiggestInt =
|
||||
for it in x:
|
||||
result.inc int(populationCount[it])
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
## BTree implementation with few features, but good enough for the
|
||||
## Nim compiler's needs.
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
const
|
||||
M = 512 # max children per B-tree node = M-1
|
||||
# (must be even and greater than 2)
|
||||
|
||||
@@ -155,7 +155,7 @@ proc reifiedOpenArray(n: PNode): bool {.inline.} =
|
||||
else:
|
||||
result = true
|
||||
|
||||
proc genOpenArraySlice(p: BProc; q: PNode; formalType, destType: PType; prepareForMutation = false): (Rope, Rope) =
|
||||
proc genOpenArraySlice(p: BProc; q: PNode; formalType, destType: PType): (Rope, Rope) =
|
||||
var a, b, c: TLoc
|
||||
initLocExpr(p, q[1], a)
|
||||
initLocExpr(p, q[2], b)
|
||||
@@ -163,8 +163,6 @@ proc genOpenArraySlice(p: BProc; q: PNode; formalType, destType: PType; prepareF
|
||||
# but first produce the required index checks:
|
||||
if optBoundsCheck in p.options:
|
||||
genBoundsCheck(p, a, b, c)
|
||||
if prepareForMutation:
|
||||
linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)])
|
||||
let ty = skipTypes(a.t, abstractVar+{tyPtr})
|
||||
let dest = getTypeDesc(p.module, destType)
|
||||
let lengthExpr = "($1)-($2)+1" % [rdLoc(c), rdLoc(b)]
|
||||
@@ -194,12 +192,10 @@ proc genOpenArraySlice(p: BProc; q: PNode; formalType, destType: PType; prepareF
|
||||
optSeqDestructors in p.config.globalOptions:
|
||||
linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)])
|
||||
if atyp.kind in {tyVar} and not compileToCpp(p.module):
|
||||
result = ("(($5) ? (($4*)(*$1)$3+($2)) : NIM_NIL)" %
|
||||
[rdLoc(a), rdLoc(b), dataField(p), dest, dataFieldAccessor(p, "*" & rdLoc(a))],
|
||||
result = ("($4*)(*$1)$3+($2)" % [rdLoc(a), rdLoc(b), dataField(p), dest],
|
||||
lengthExpr)
|
||||
else:
|
||||
result = ("(($5) ? (($4*)$1$3+($2)) : NIM_NIL)" %
|
||||
[rdLoc(a), rdLoc(b), dataField(p), dest, dataFieldAccessor(p, rdLoc(a))],
|
||||
result = ("($4*)$1$3+($2)" % [rdLoc(a), rdLoc(b), dataField(p), dest],
|
||||
lengthExpr)
|
||||
else:
|
||||
internalError(p.config, "openArrayLoc: " & typeToString(a.t))
|
||||
@@ -240,12 +236,9 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode): Rope =
|
||||
if ntyp.kind in {tyVar} and not compileToCpp(p.module):
|
||||
var t: TLoc
|
||||
t.r = "(*$1)" % [a.rdLoc]
|
||||
result = "($4) ? ((*$1)$3) : NIM_NIL, $2" %
|
||||
[a.rdLoc, lenExpr(p, t), dataField(p),
|
||||
dataFieldAccessor(p, "*" & a.rdLoc)]
|
||||
result = "(*$1)$3, $2" % [a.rdLoc, lenExpr(p, t), dataField(p)]
|
||||
else:
|
||||
result = "($4) ? ($1$3) : NIM_NIL, $2" %
|
||||
[a.rdLoc, lenExpr(p, a), dataField(p), dataFieldAccessor(p, a.rdLoc)]
|
||||
result = "$1$3, $2" % [a.rdLoc, lenExpr(p, a), dataField(p)]
|
||||
of tyArray:
|
||||
result = "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, a.t))]
|
||||
of tyPtr, tyRef:
|
||||
@@ -253,9 +246,7 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode): Rope =
|
||||
of tyString, tySequence:
|
||||
var t: TLoc
|
||||
t.r = "(*$1)" % [a.rdLoc]
|
||||
result = "($4) ? ((*$1)$3) : NIM_NIL, $2" %
|
||||
[a.rdLoc, lenExpr(p, t), dataField(p),
|
||||
dataFieldAccessor(p, "*" & a.rdLoc)]
|
||||
result = "(*$1)$3, $2" % [a.rdLoc, lenExpr(p, t), dataField(p)]
|
||||
of tyArray:
|
||||
result = "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, lastSon(a.t)))]
|
||||
else:
|
||||
|
||||
@@ -292,8 +292,8 @@ proc genOpenArrayConv(p: BProc; d: TLoc; a: TLoc) =
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $2Len_0;$n",
|
||||
[rdLoc(d), a.rdLoc])
|
||||
of tySequence:
|
||||
linefmt(p, cpsStmts, "$1.Field0 = ($5) ? ($2$3) : NIM_NIL; $1.Field1 = $4;$n",
|
||||
[rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a), dataFieldAccessor(p, a.rdLoc)])
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2$3; $1.Field1 = $4;$n",
|
||||
[rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a)])
|
||||
of tyArray:
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $3;$n",
|
||||
[rdLoc(d), rdLoc(a), rope(lengthOrd(p.config, a.t))])
|
||||
@@ -302,8 +302,8 @@ proc genOpenArrayConv(p: BProc; d: TLoc; a: TLoc) =
|
||||
if etyp.kind in {tyVar} and optSeqDestructors in p.config.globalOptions:
|
||||
linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)])
|
||||
|
||||
linefmt(p, cpsStmts, "$1.Field0 = ($5) ? ($2$3) : NIM_NIL; $1.Field1 = $4;$n",
|
||||
[rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a), dataFieldAccessor(p, a.rdLoc)])
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2$3; $1.Field1 = $4;$n",
|
||||
[rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a)])
|
||||
else:
|
||||
internalError(p.config, a.lode.info, "cannot handle " & $a.t.kind)
|
||||
|
||||
@@ -731,22 +731,7 @@ proc isCppRef(p: BProc; typ: PType): bool {.inline.} =
|
||||
skipTypes(typ, abstractInstOwned).kind in {tyVar} and
|
||||
tfVarIsPtr notin skipTypes(typ, abstractInstOwned).flags
|
||||
|
||||
proc derefBlock(p: BProc, e: PNode, d: var TLoc) =
|
||||
# We transform (block: x)[] to (block: x[])
|
||||
let e0 = e[0]
|
||||
var n = shallowCopy(e0)
|
||||
n.typ = e.typ
|
||||
for i in 0 ..< e0.len - 1:
|
||||
n[i] = e0[i]
|
||||
n[e0.len-1] = newTreeIT(nkHiddenDeref, e.info, e.typ, e0[e0.len-1])
|
||||
expr p, n, d
|
||||
|
||||
proc genDeref(p: BProc, e: PNode, d: var TLoc) =
|
||||
if e.kind == nkHiddenDeref and e[0].kind in {nkBlockExpr, nkBlockStmt}:
|
||||
# bug #20107. Watch out to not deref the pointer too late.
|
||||
derefBlock(p, e, d)
|
||||
return
|
||||
|
||||
let mt = mapType(p.config, e[0].typ, mapTypeChooser(e[0]))
|
||||
if mt in {ctArray, ctPtrToArray} and lfEnforceDeref notin d.flags:
|
||||
# XXX the amount of hacks for C's arrays is incredible, maybe we should
|
||||
@@ -1003,12 +988,12 @@ proc genBoundsCheck(p: BProc; arr, a, b: TLoc) =
|
||||
if reifiedOpenArray(arr.lode):
|
||||
linefmt(p, cpsStmts,
|
||||
"if ($2-$1 != -1 && " &
|
||||
"($1 < 0 || $1 >= $3.Field1 || $2 < 0 || $2 >= $3.Field1)){ #raiseIndexError(); $4}$n",
|
||||
"($1 < 0 || $1 >= $3.Field1 || $2 < 0 || $2 >= $3.Field1)){ #raiseIndexError4($1, $2, $3.Field1); $4}$n",
|
||||
[rdLoc(a), rdLoc(b), rdLoc(arr), raiseInstr(p)])
|
||||
else:
|
||||
linefmt(p, cpsStmts,
|
||||
"if ($2-$1 != -1 && ($1 < 0 || $1 >= $3Len_0 || $2 < 0 || $2 >= $3Len_0))" &
|
||||
"{ #raiseIndexError(); $4}$n",
|
||||
"{ #raiseIndexError4($1, $2, $3Len_0); $4}$n",
|
||||
[rdLoc(a), rdLoc(b), rdLoc(arr), raiseInstr(p)])
|
||||
of tyArray:
|
||||
let first = intLiteral(firstOrd(p.config, ty))
|
||||
@@ -1019,7 +1004,7 @@ proc genBoundsCheck(p: BProc; arr, a, b: TLoc) =
|
||||
of tySequence, tyString:
|
||||
linefmt(p, cpsStmts,
|
||||
"if ($2-$1 != -1 && " &
|
||||
"($1 < 0 || $1 >= $3 || $2 < 0 || $2 >= $3)){ #raiseIndexError(); $4}$n",
|
||||
"($1 < 0 || $1 >= $3 || $2 < 0 || $2 >= $3)){ #raiseIndexError4($1, $2, $3); $4}$n",
|
||||
[rdLoc(a), rdLoc(b), lenExpr(p, arr), raiseInstr(p)])
|
||||
else: discard
|
||||
|
||||
@@ -1577,7 +1562,6 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
|
||||
return
|
||||
if d.k == locNone:
|
||||
getTemp(p, n.typ, d)
|
||||
initLocExpr(p, n[1], a)
|
||||
# generate call to newSeq before adding the elements per hand:
|
||||
let L = toInt(lengthOrd(p.config, n[1].typ))
|
||||
if optSeqDestructors in p.config.globalOptions:
|
||||
@@ -1587,6 +1571,7 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
|
||||
getSeqPayloadType(p.module, seqtype)])
|
||||
else:
|
||||
genNewSeqAux(p, d, intLiteral(L), L == 0)
|
||||
initLocExpr(p, n[1], a)
|
||||
# bug #5007; do not produce excessive C source code:
|
||||
if L < 10:
|
||||
for i in 0..<L:
|
||||
@@ -1714,9 +1699,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||
putIntoDest(p, b, e, "$1, $1Len_0" % [rdLoc(a)], a.storage)
|
||||
of tyString, tySequence:
|
||||
putIntoDest(p, b, e,
|
||||
"($4) ? ($1$3) : NIM_NIL, $2" %
|
||||
[rdLoc(a), lenExpr(p, a), dataField(p), dataFieldAccessor(p, a.rdLoc)],
|
||||
a.storage)
|
||||
"$1$3, $2" % [rdLoc(a), lenExpr(p, a), dataField(p)], a.storage)
|
||||
of tyArray:
|
||||
putIntoDest(p, b, e,
|
||||
"$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, a.t))], a.storage)
|
||||
@@ -1796,13 +1779,9 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
# Bug #9279, len(toOpenArray()) has to work:
|
||||
if a.kind in nkCallKinds and a[0].kind == nkSym and a[0].sym.magic == mSlice:
|
||||
# magic: pass slice to openArray:
|
||||
var m: TLoc
|
||||
var b, c: TLoc
|
||||
initLocExpr(p, a[1], m)
|
||||
initLocExpr(p, a[2], b)
|
||||
initLocExpr(p, a[3], c)
|
||||
if optBoundsCheck in p.options:
|
||||
genBoundsCheck(p, m, b, c)
|
||||
if op == mHigh:
|
||||
putIntoDest(p, d, e, ropecg(p.module, "($2)-($1)", [rdLoc(b), rdLoc(c)]))
|
||||
else:
|
||||
@@ -2098,11 +2077,6 @@ proc genSomeCast(p: BProc, e: PNode, d: var TLoc) =
|
||||
elif etyp.kind == tyBool and srcTyp.kind in IntegralTypes:
|
||||
putIntoDest(p, d, e, "(($1) != 0)" % [rdCharLoc(a)], a.storage)
|
||||
else:
|
||||
if etyp.kind == tyPtr:
|
||||
# generates the definition of structs for casts like cast[ptr object](addr x)[]
|
||||
let internalType = etyp.skipTypes({tyPtr})
|
||||
if internalType.kind == tyObject:
|
||||
discard getTypeDesc(p.module, internalType)
|
||||
putIntoDest(p, d, e, "(($1) ($2))" %
|
||||
[getTypeDesc(p.module, e.typ), rdCharLoc(a)], a.storage)
|
||||
|
||||
@@ -2299,10 +2273,7 @@ proc genDispose(p: BProc; n: PNode) =
|
||||
lineCg(p, cpsStmts, ["#nimDestroyAndDispose($#)", rdLoc(a)])
|
||||
|
||||
proc genSlice(p: BProc; e: PNode; d: var TLoc) =
|
||||
let (x, y) = genOpenArraySlice(p, e, e.typ, e.typ.lastSon,
|
||||
prepareForMutation = e[1].kind == nkHiddenDeref and
|
||||
e[1].typ.skipTypes(abstractInst).kind == tyString and
|
||||
p.config.selectedGC in {gcArc, gcOrc})
|
||||
let (x, y) = genOpenArraySlice(p, e, e.typ, e.typ.lastSon)
|
||||
if d.k == locNone: getTemp(p, e.typ, d)
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $3;$n", [rdLoc(d), x, y])
|
||||
when false:
|
||||
@@ -2974,7 +2945,21 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||
nkFromStmt, nkTemplateDef, nkMacroDef, nkStaticStmt:
|
||||
discard
|
||||
of nkPragma: genPragma(p, n)
|
||||
of nkPragmaBlock: expr(p, n.lastSon, d)
|
||||
of nkPragmaBlock:
|
||||
var inUncheckedAssignSection = 0
|
||||
let pragmaList = n[0]
|
||||
for pi in pragmaList:
|
||||
if whichPragma(pi) == wCast:
|
||||
case whichPragma(pi[1])
|
||||
of wUncheckedAssign:
|
||||
inUncheckedAssignSection = 1
|
||||
else:
|
||||
discard
|
||||
|
||||
inc p.inUncheckedAssignSection, inUncheckedAssignSection
|
||||
expr(p, n.lastSon, d)
|
||||
dec p.inUncheckedAssignSection, inUncheckedAssignSection
|
||||
|
||||
of nkProcDef, nkFuncDef, nkMethodDef, nkConverterDef:
|
||||
if n[genericParamsPos].kind == nkEmpty:
|
||||
var prc = n[namePos].sym
|
||||
|
||||
@@ -87,20 +87,7 @@ proc specializeResetT(p: BProc, accessor: Rope, typ: PType) =
|
||||
lineCg(p, cpsStmts, "$1 = 0;$n", [accessor])
|
||||
of tyCstring, tyPointer, tyPtr, tyVar, tyLent:
|
||||
lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [accessor])
|
||||
of tySet:
|
||||
case mapSetType(p.config, typ)
|
||||
of ctArray:
|
||||
lineCg(p, cpsStmts, "#nimZeroMem($1, sizeof($2));$n",
|
||||
[accessor, getTypeDesc(p.module, typ)])
|
||||
of ctInt8, ctInt16, ctInt32, ctInt64:
|
||||
lineCg(p, cpsStmts, "$1 = 0;$n", [accessor])
|
||||
else:
|
||||
doAssert false, "unexpected set type kind"
|
||||
of {tyNone, tyEmpty, tyNil, tyUntyped, tyTyped, tyGenericInvocation,
|
||||
tyGenericParam, tyOrdinal, tyRange, tyOpenArray, tyForward, tyVarargs,
|
||||
tyUncheckedArray, tyProxy, tyBuiltInTypeClass, tyUserTypeClass,
|
||||
tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot,
|
||||
tyAnything, tyStatic, tyFromExpr, tyConcept, tyVoid, tyIterable}:
|
||||
else:
|
||||
discard
|
||||
|
||||
proc specializeReset(p: BProc, a: TLoc) =
|
||||
|
||||
@@ -16,7 +16,7 @@ const
|
||||
# above X strings a hash-switch for strings is generated
|
||||
|
||||
proc getTraverseProc(p: BProc, v: PSym): Rope =
|
||||
if p.config.selectedGC in {gcMarkAndSweep, gcHooks, gcV2, gcRefc} and
|
||||
if p.config.selectedGC in {gcMarkAndSweep, gcHooks, gcRefc} and
|
||||
optOwnedRefs notin p.config.globalOptions and
|
||||
containsGarbageCollectedRef(v.loc.t):
|
||||
# we register a specialized marked proc here; this has the advantage
|
||||
@@ -1367,18 +1367,13 @@ proc genTrySetjmp(p: BProc, t: PNode, d: var TLoc) =
|
||||
linefmt(p, cpsStmts, "$1.status = __builtin_setjmp($1.context);$n", [safePoint])
|
||||
elif isDefined(p.config, "nimRawSetjmp"):
|
||||
if isDefined(p.config, "mswindows"):
|
||||
if isDefined(p.config, "vcc") or isDefined(p.config, "clangcl"):
|
||||
# For the vcc compiler, use `setjmp()` with one argument.
|
||||
# See https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setjmp?view=msvc-170
|
||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
|
||||
else:
|
||||
# The Windows `_setjmp()` takes two arguments, with the second being an
|
||||
# undocumented buffer used by the SEH mechanism for stack unwinding.
|
||||
# Mingw-w64 has been trying to get it right for years, but it's still
|
||||
# prone to stack corruption during unwinding, so we disable that by setting
|
||||
# it to NULL.
|
||||
# More details: https://github.com/status-im/nimbus-eth2/issues/3121
|
||||
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context, 0);$n", [safePoint])
|
||||
# The Windows `_setjmp()` takes two arguments, with the second being an
|
||||
# undocumented buffer used by the SEH mechanism for stack unwinding.
|
||||
# Mingw-w64 has been trying to get it right for years, but it's still
|
||||
# prone to stack corruption during unwinding, so we disable that by setting
|
||||
# it to NULL.
|
||||
# More details: https://github.com/status-im/nimbus-eth2/issues/3121
|
||||
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context, 0);$n", [safePoint])
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", [safePoint])
|
||||
else:
|
||||
@@ -1571,7 +1566,7 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) =
|
||||
initLocExpr(p, e[0], a)
|
||||
getTemp(p, a.t, tmp)
|
||||
expr(p, e[1], tmp)
|
||||
if optTinyRtti notin p.config.globalOptions:
|
||||
if optTinyRtti notin p.config.globalOptions and p.inUncheckedAssignSection == 0:
|
||||
let field = dotExpr[1].sym
|
||||
genDiscriminantCheck(p, a, tmp, dotExpr[0].typ, field)
|
||||
message(p.config, e.info, warnCaseTransition)
|
||||
|
||||
@@ -45,7 +45,7 @@ proc mangleName(m: BModule; s: PSym): Rope =
|
||||
result.add rope s.itemId.item
|
||||
if m.hcrOn:
|
||||
result.add "_"
|
||||
result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts, m.config))
|
||||
result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts))
|
||||
s.loc.r = result
|
||||
writeMangledName(m.ndi, s, m.config)
|
||||
|
||||
@@ -311,7 +311,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
|
||||
else: result = nil
|
||||
|
||||
if result != nil and typ.isImportedType():
|
||||
let sig = hashType(typ, m.config)
|
||||
let sig = hashType typ
|
||||
if cacheGetType(m.typeCache, sig) == nil:
|
||||
m.typeCache[sig] = result
|
||||
|
||||
@@ -371,10 +371,10 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet; kind: TSymKind): R
|
||||
if isImportedCppType(etB) and t.kind == tyGenericInst:
|
||||
result = getTypeDescAux(m, t, check, kind)
|
||||
else:
|
||||
result = getTypeForward(m, t, hashType(t, m.config))
|
||||
result = getTypeForward(m, t, hashType(t))
|
||||
pushType(m, t)
|
||||
of tySequence:
|
||||
let sig = hashType(t, m.config)
|
||||
let sig = hashType(t)
|
||||
if optSeqDestructors in m.config.globalOptions:
|
||||
if skipTypes(etB[0], typedescInst).kind == tyEmpty:
|
||||
internalError(m.config, "cannot map the empty seq type to a C type")
|
||||
@@ -407,7 +407,7 @@ proc getSeqPayloadType(m: BModule; t: PType): Rope =
|
||||
#result = getTypeForward(m, t, hashType(t)) & "_Content"
|
||||
|
||||
proc seqV2ContentType(m: BModule; t: PType; check: var IntSet) =
|
||||
let sig = hashType(t, m.config)
|
||||
let sig = hashType(t)
|
||||
let result = cacheGetType(m.typeCache, sig)
|
||||
if result == nil:
|
||||
discard getTypeDescAux(m, t, check, skVar)
|
||||
@@ -672,7 +672,7 @@ proc resolveStarsInCppType(typ: PType, idx, stars: int): PType =
|
||||
else: result.elemType
|
||||
|
||||
proc getOpenArrayDesc(m: BModule, t: PType, check: var IntSet; kind: TSymKind): Rope =
|
||||
let sig = hashType(t, m.config)
|
||||
let sig = hashType(t)
|
||||
if kind == skParam:
|
||||
result = getTypeDescWeak(m, t[0], check, kind) & "*"
|
||||
else:
|
||||
@@ -696,7 +696,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin
|
||||
# C type generation into an analysis and a code generation phase somehow.
|
||||
if t.sym != nil: useHeader(m, t.sym)
|
||||
if t != origTyp and origTyp.sym != nil: useHeader(m, origTyp.sym)
|
||||
let sig = hashType(origTyp, m.config)
|
||||
let sig = hashType(origTyp)
|
||||
|
||||
defer: # defer is the simplest in this case
|
||||
if isImportedType(t) and not m.typeABICache.containsOrIncl(sig):
|
||||
@@ -725,7 +725,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin
|
||||
result = getTypeDescAux(m, et, check, kind) & star
|
||||
else:
|
||||
# no restriction! We have a forward declaration for structs
|
||||
let name = getTypeForward(m, et, hashType(et, m.config))
|
||||
let name = getTypeForward(m, et, hashType et)
|
||||
result = name & star
|
||||
m.typeCache[sig] = result
|
||||
of tySequence:
|
||||
@@ -734,7 +734,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin
|
||||
m.typeCache[sig] = result
|
||||
else:
|
||||
# no restriction! We have a forward declaration for structs
|
||||
let name = getTypeForward(m, et, hashType(et, m.config))
|
||||
let name = getTypeForward(m, et, hashType et)
|
||||
result = name & seqStar(m) & star
|
||||
m.typeCache[sig] = result
|
||||
pushType(m, et)
|
||||
@@ -897,7 +897,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin
|
||||
discard # addAbiCheck(m, t, result) # already handled elsewhere
|
||||
of tySet:
|
||||
# Don't use the imported name as it may be scoped: 'Foo::SomeKind'
|
||||
result = $t.kind & '_' & t.lastSon.typeName & $t.lastSon.hashType(m.config)
|
||||
result = $t.kind & '_' & t.lastSon.typeName & $t.lastSon.hashType
|
||||
m.typeCache[sig] = result
|
||||
if not isImportedType(t):
|
||||
let s = int(getSize(m.config, t))
|
||||
@@ -1070,7 +1070,7 @@ proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): Rope =
|
||||
objtype = objtype[0].skipTypes(abstractPtrs)
|
||||
if objtype.sym == nil:
|
||||
internalError(m.config, d.info, "anonymous obj with discriminator")
|
||||
result = "NimDT_$1_$2" % [rope($hashType(objtype, m.config)), rope(d.name.s.mangle)]
|
||||
result = "NimDT_$1_$2" % [rope($hashType(objtype)), rope(d.name.s.mangle)]
|
||||
|
||||
proc rope(arg: Int128): Rope = rope($arg)
|
||||
|
||||
@@ -1278,7 +1278,7 @@ proc genTypeInfo2Name(m: BModule; t: PType): Rope =
|
||||
var it = t
|
||||
while it != nil:
|
||||
it = it.skipTypes(skipPtrs)
|
||||
if it.sym != nil and tfFromGeneric notin it.flags:
|
||||
if it.sym != nil:
|
||||
var m = it.sym.owner
|
||||
while m != nil and m.kind != skModule: m = m.owner
|
||||
if m == nil or sfSystemModule in m.flags:
|
||||
@@ -1291,7 +1291,7 @@ proc genTypeInfo2Name(m: BModule; t: PType): Rope =
|
||||
res.add m.name.s & "."
|
||||
res.add it.sym.name.s
|
||||
else:
|
||||
res.add $hashType(it, m.config)
|
||||
res.add $hashType(it)
|
||||
res.add "|"
|
||||
it = it[0]
|
||||
result = makeCString(res)
|
||||
@@ -1355,7 +1355,7 @@ proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||
|
||||
let prefixTI = if m.hcrOn: "(" else: "(&"
|
||||
|
||||
let sig = hashType(origType, m.config)
|
||||
let sig = hashType(origType)
|
||||
result = m.typeInfoMarkerV2.getOrDefault(sig)
|
||||
if result != nil:
|
||||
return prefixTI.rope & result & ")".rope
|
||||
@@ -1426,7 +1426,7 @@ proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||
|
||||
let prefixTI = if m.hcrOn: "(" else: "(&"
|
||||
|
||||
let sig = hashType(origType, m.config)
|
||||
let sig = hashType(origType)
|
||||
result = m.typeInfoMarker.getOrDefault(sig)
|
||||
if result != nil:
|
||||
return prefixTI.rope & result & ")".rope
|
||||
@@ -1483,12 +1483,12 @@ proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||
genTupleInfo(m, x, x, result, info)
|
||||
of tySequence:
|
||||
genTypeInfoAux(m, t, t, result, info)
|
||||
if m.config.selectedGC in {gcMarkAndSweep, gcRefc, gcV2, gcGo}:
|
||||
if m.config.selectedGC in {gcMarkAndSweep, gcRefc, gcGo}:
|
||||
let markerProc = genTraverseProc(m, origType, sig)
|
||||
m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc])
|
||||
of tyRef:
|
||||
genTypeInfoAux(m, t, t, result, info)
|
||||
if m.config.selectedGC in {gcMarkAndSweep, gcRefc, gcV2, gcGo}:
|
||||
if m.config.selectedGC in {gcMarkAndSweep, gcRefc, gcGo}:
|
||||
let markerProc = genTraverseProc(m, origType, sig)
|
||||
m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc])
|
||||
of tyPtr, tyRange, tyUncheckedArray: genTypeInfoAux(m, t, t, result, info)
|
||||
|
||||
@@ -13,6 +13,9 @@ import
|
||||
ast, types, hashes, strutils, msgs, wordrecg,
|
||||
platform, trees, options, cgendata
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
|
||||
case n.kind
|
||||
of nkStmtList:
|
||||
|
||||
@@ -17,6 +17,9 @@ import
|
||||
lowerings, tables, sets, ndi, lineinfos, pathutils, transf,
|
||||
injectdestructors, astmsgs, modulepaths
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
when not defined(leanCompiler):
|
||||
import spawn, semparallel
|
||||
|
||||
@@ -307,12 +310,6 @@ proc lenExpr(p: BProc; a: TLoc): Rope =
|
||||
else:
|
||||
result = "($1 ? $1->$2 : 0)" % [rdLoc(a), lenField(p)]
|
||||
|
||||
proc dataFieldAccessor(p: BProc, sym: Rope): Rope =
|
||||
if optSeqDestructors in p.config.globalOptions:
|
||||
result = "(" & sym & ").p"
|
||||
else:
|
||||
result = sym
|
||||
|
||||
proc dataField(p: BProc): Rope =
|
||||
if optSeqDestructors in p.config.globalOptions:
|
||||
result = rope".p->data"
|
||||
@@ -1067,9 +1064,11 @@ proc genProcAux(m: BModule, prc: PSym) =
|
||||
# the 'unsureAsgn' is a nop. If it points to a global variable the
|
||||
# global is either 'nil' or points to valid memory and so the RC operation
|
||||
# succeeds without touching not-initialized memory.
|
||||
if sfNoInit in prc.flags: discard
|
||||
if sfNoInit in prc.flags and p.config.selectedGC notin {gcArc, gcOrc}: discard
|
||||
elif allPathsAsgnResult(procBody) == InitSkippable: discard
|
||||
else:
|
||||
if sfNoInit in prc.flags and p.config.selectedGC in {gcArc, gcOrc}:
|
||||
message(m.config, resNode.info, warnNoInitIgnored, "")
|
||||
resetLoc(p, res.loc)
|
||||
if skipTypes(res.typ, abstractInst).kind == tyArray:
|
||||
#incl(res.loc.flags, lfIndirect)
|
||||
@@ -1600,7 +1599,7 @@ proc registerModuleToMain(g: BModuleList; m: BModule) =
|
||||
hcrModuleMeta.addf("\t\"\"};$n", [])
|
||||
hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(void**, HcrGetImportedModules)() { return (void**)hcr_module_list; }$n", [])
|
||||
hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(char*, HcrGetSigHash)() { return \"$1\"; }$n$n",
|
||||
[($sigHash(m.module, m.config)).rope])
|
||||
[($sigHash(m.module)).rope])
|
||||
if sfMainModule in m.module.flags:
|
||||
g.mainModProcs.add(hcrModuleMeta)
|
||||
g.mainModProcs.addf("static void* hcr_handle;$N", [])
|
||||
|
||||
@@ -99,6 +99,7 @@ type
|
||||
withinTryWithExcept*: int # required for goto based exception handling
|
||||
withinBlockLeaveActions*: int # complex to explain
|
||||
sigConflicts*: CountTable[string]
|
||||
inUncheckedAssignSection*: int
|
||||
|
||||
TTypeSeq* = seq[PType]
|
||||
TypeCache* = Table[SigHash, Rope]
|
||||
|
||||
@@ -13,6 +13,10 @@ import
|
||||
intsets, options, ast, msgs, idents, renderer, types, magicsys,
|
||||
sempass2, strutils, modulegraphs, lineinfos
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
|
||||
proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
|
||||
var dest = skipTypes(d, abstractPtrs)
|
||||
var source = skipTypes(n.typ, abstractPtrs)
|
||||
@@ -46,7 +50,6 @@ proc methodCall*(n: PNode; conf: ConfigRef): PNode =
|
||||
# replace ordinary method by dispatcher method:
|
||||
let disp = getDispatcher(result[0].sym)
|
||||
if disp != nil:
|
||||
result[0].typ = disp.typ
|
||||
result[0].sym = disp
|
||||
# change the arguments to up/downcasts to fit the dispatcher's parameters:
|
||||
for i in 1..<result.len:
|
||||
|
||||
@@ -121,10 +121,7 @@
|
||||
# yield 2
|
||||
# if :unrollFinally: # This node is created by `newEndFinallyNode`
|
||||
# if :curExc.isNil:
|
||||
# if nearestFinally == 0:
|
||||
# return :tmpResult
|
||||
# else:
|
||||
# :state = nearestFinally # bubble up
|
||||
# return :tmpResult
|
||||
# else:
|
||||
# closureIterSetupExc(nil)
|
||||
# raise
|
||||
@@ -136,6 +133,9 @@ import
|
||||
renderer, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos,
|
||||
tables, options
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
Ctx = object
|
||||
g: ModuleGraph
|
||||
@@ -807,10 +807,7 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
|
||||
# Generate the following code:
|
||||
# if :unrollFinally:
|
||||
# if :curExc.isNil:
|
||||
# if nearestFinally == 0:
|
||||
# return :tmpResult
|
||||
# else:
|
||||
# :state = nearestFinally # bubble up
|
||||
# return :tmpResult
|
||||
# else:
|
||||
# raise
|
||||
let curExc = ctx.newCurExcAccess()
|
||||
@@ -819,20 +816,11 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
|
||||
let cmp = newTree(nkCall, newSymNode(ctx.g.getSysMagic(info, "==", mEqRef), info), curExc, nilnode)
|
||||
cmp.typ = ctx.g.getSysType(info, tyBool)
|
||||
|
||||
let retStmt =
|
||||
if ctx.nearestFinally == 0:
|
||||
# last finally, we can return
|
||||
let retValue = if ctx.fn.typ[0].isNil:
|
||||
ctx.g.emptyNode
|
||||
else:
|
||||
newTree(nkFastAsgn,
|
||||
newSymNode(getClosureIterResult(ctx.g, ctx.fn, ctx.idgen), info),
|
||||
ctx.newTmpResultAccess())
|
||||
newTree(nkReturnStmt, retValue)
|
||||
else:
|
||||
# bubble up to next finally
|
||||
newTree(nkGotoState, ctx.g.newIntLit(info, ctx.nearestFinally))
|
||||
let asgn = newTree(nkFastAsgn,
|
||||
newSymNode(getClosureIterResult(ctx.g, ctx.fn, ctx.idgen), info),
|
||||
ctx.newTmpResultAccess())
|
||||
|
||||
let retStmt = newTree(nkReturnStmt, asgn)
|
||||
let branch = newTree(nkElifBranch, cmp, retStmt)
|
||||
|
||||
let nullifyExc = newTree(nkCall, newSymNode(ctx.g.getCompilerProc("closureIterSetupExc")), nilnode)
|
||||
@@ -876,13 +864,6 @@ proc transformReturnsInTry(ctx: var Ctx, n: PNode): PNode =
|
||||
|
||||
of nkSkip:
|
||||
discard
|
||||
of nkTryStmt:
|
||||
if n.hasYields:
|
||||
# the inner try will handle these transformations
|
||||
discard
|
||||
else:
|
||||
for i in 0..<n.len:
|
||||
n[i] = ctx.transformReturnsInTry(n[i])
|
||||
else:
|
||||
for i in 0..<n.len:
|
||||
n[i] = ctx.transformReturnsInTry(n[i])
|
||||
@@ -1152,7 +1133,7 @@ proc newArrayType(g: ModuleGraph; n: int, t: PType; idgen: IdGenerator; owner: P
|
||||
result = newType(tyArray, nextTypeId(idgen), owner)
|
||||
|
||||
let rng = newType(tyRange, nextTypeId(idgen), owner)
|
||||
rng.n = newTree(nkRange, g.newIntLit(owner.info, 0), g.newIntLit(owner.info, n - 1))
|
||||
rng.n = newTree(nkRange, g.newIntLit(owner.info, 0), g.newIntLit(owner.info, n))
|
||||
rng.rawAddSon(t)
|
||||
|
||||
result.rawAddSon(rng)
|
||||
@@ -1369,7 +1350,6 @@ proc preprocess(c: var PreprocessContext; n: PNode): PNode =
|
||||
# detect: 'finally: raises X' which is currently not supported. We produce
|
||||
# an error for this case for now. All this will be done properly with Yuriy's
|
||||
# patch.
|
||||
|
||||
result = n
|
||||
case n.kind
|
||||
of nkTryStmt:
|
||||
@@ -1386,7 +1366,6 @@ proc preprocess(c: var PreprocessContext; n: PNode): PNode =
|
||||
discard c.finallys.pop()
|
||||
|
||||
of nkWhileStmt, nkBlockStmt:
|
||||
if n.hasYields == false: return n
|
||||
c.blocks.add((n, c.finallys.len))
|
||||
for i in 0 ..< n.len:
|
||||
result[i] = preprocess(c, n[i])
|
||||
|
||||
@@ -31,6 +31,9 @@ import
|
||||
|
||||
from ast import setUseIc, eqTypeFlags, tfGcSafe, tfNoSideEffect
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
# but some have deps to imported modules. Yay.
|
||||
bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc")
|
||||
bootSwitch(usedFFI, hasFFI, "-d:nimHasLibFFI")
|
||||
@@ -259,7 +262,6 @@ proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo
|
||||
of "go": result = conf.selectedGC == gcGo
|
||||
of "none": result = conf.selectedGC == gcNone
|
||||
of "stack", "regions": result = conf.selectedGC == gcRegions
|
||||
of "v2", "generational": warningOptionNoop(arg)
|
||||
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
|
||||
of "opt":
|
||||
case arg.normalize
|
||||
@@ -332,6 +334,7 @@ proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool
|
||||
result = contains(conf.options, optTrMacros)
|
||||
of "excessivestacktrace": result = contains(conf.globalOptions, optExcessiveStackTrace)
|
||||
of "nilseqs", "nilchecks", "taintmode": warningOptionNoop(switch)
|
||||
of "panics": result = contains(conf.globalOptions, optPanics)
|
||||
else: invalidCmdLineOption(conf, passCmd1, switch, info)
|
||||
|
||||
proc processPath(conf: ConfigRef; path: string, info: TLineInfo,
|
||||
@@ -497,6 +500,75 @@ proc specialDefine(conf: ConfigRef, key: string; pass: TCmdLinePass) =
|
||||
optOverflowCheck, optAssert, optStackTrace, optLineTrace, optLineDir}
|
||||
conf.globalOptions.excl {optCDebug}
|
||||
|
||||
proc registerArcOrc(pass: TCmdLinePass, conf: ConfigRef, isOrc: bool) =
|
||||
if isOrc:
|
||||
conf.selectedGC = gcOrc
|
||||
defineSymbol(conf.symbols, "gcorc")
|
||||
else:
|
||||
conf.selectedGC = gcArc
|
||||
defineSymbol(conf.symbols, "gcarc")
|
||||
|
||||
defineSymbol(conf.symbols, "gcdestructors")
|
||||
incl conf.globalOptions, optSeqDestructors
|
||||
incl conf.globalOptions, optTinyRtti
|
||||
if pass in {passCmd2, passPP}:
|
||||
defineSymbol(conf.symbols, "nimSeqsV2")
|
||||
defineSymbol(conf.symbols, "nimV2")
|
||||
if conf.exc == excNone and conf.backend != backendCpp:
|
||||
conf.exc = excGoto
|
||||
|
||||
proc unregisterArcOrc(conf: ConfigRef) =
|
||||
undefSymbol(conf.symbols, "gcdestructors")
|
||||
undefSymbol(conf.symbols, "gcarc")
|
||||
undefSymbol(conf.symbols, "gcorc")
|
||||
undefSymbol(conf.symbols, "nimSeqsV2")
|
||||
undefSymbol(conf.symbols, "nimV2")
|
||||
excl conf.globalOptions, optSeqDestructors
|
||||
excl conf.globalOptions, optTinyRtti
|
||||
|
||||
proc processMemoryManagementOption(switch, arg: string, pass: TCmdLinePass,
|
||||
info: TLineInfo; conf: ConfigRef) =
|
||||
if conf.backend == backendJs: return # for: bug #16033
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}:
|
||||
case arg.normalize
|
||||
of "boehm":
|
||||
unregisterArcOrc(conf)
|
||||
conf.selectedGC = gcBoehm
|
||||
defineSymbol(conf.symbols, "boehmgc")
|
||||
incl conf.globalOptions, optTlsEmulation # Boehm GC doesn't scan the real TLS
|
||||
of "refc":
|
||||
unregisterArcOrc(conf)
|
||||
conf.selectedGC = gcRefc
|
||||
of "markandsweep":
|
||||
unregisterArcOrc(conf)
|
||||
conf.selectedGC = gcMarkAndSweep
|
||||
defineSymbol(conf.symbols, "gcmarkandsweep")
|
||||
of "destructors", "arc":
|
||||
registerArcOrc(pass, conf, false)
|
||||
of "orc":
|
||||
registerArcOrc(pass, conf, true)
|
||||
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":
|
||||
unregisterArcOrc(conf)
|
||||
conf.selectedGC = gcGo
|
||||
defineSymbol(conf.symbols, "gogc")
|
||||
of "none":
|
||||
unregisterArcOrc(conf)
|
||||
conf.selectedGC = gcNone
|
||||
defineSymbol(conf.symbols, "nogc")
|
||||
of "stack", "regions":
|
||||
unregisterArcOrc(conf)
|
||||
conf.selectedGC = gcRegions
|
||||
defineSymbol(conf.symbols, "gcregions")
|
||||
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
|
||||
|
||||
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
conf: ConfigRef) =
|
||||
var
|
||||
@@ -596,60 +668,11 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
processOnOffSwitchG(conf, {optForceFullMake}, arg, pass, info)
|
||||
of "project":
|
||||
processOnOffSwitchG(conf, {optWholeProject, optGenIndex}, arg, pass, info)
|
||||
of "gc", "mm":
|
||||
if conf.backend == backendJs: return # for: bug #16033
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}:
|
||||
case arg.normalize
|
||||
of "boehm":
|
||||
conf.selectedGC = gcBoehm
|
||||
defineSymbol(conf.symbols, "boehmgc")
|
||||
incl conf.globalOptions, optTlsEmulation # Boehm GC doesn't scan the real TLS
|
||||
of "refc":
|
||||
conf.selectedGC = gcRefc
|
||||
of "markandsweep":
|
||||
conf.selectedGC = gcMarkAndSweep
|
||||
defineSymbol(conf.symbols, "gcmarkandsweep")
|
||||
of "destructors", "arc":
|
||||
conf.selectedGC = gcArc
|
||||
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")
|
||||
if conf.exc == excNone and conf.backend != backendCpp:
|
||||
conf.exc = excGoto
|
||||
of "orc":
|
||||
conf.selectedGC = gcOrc
|
||||
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")
|
||||
if conf.exc == excNone and conf.backend != backendCpp:
|
||||
conf.exc = excGoto
|
||||
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")
|
||||
of "v2": warningOptionNoop(arg)
|
||||
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
|
||||
of "gc":
|
||||
warningDeprecated(conf, info, "`gc:option` is deprecated; use `mm:option` instead")
|
||||
processMemoryManagementOption(switch, arg, pass, info, conf)
|
||||
of "mm":
|
||||
processMemoryManagementOption(switch, arg, pass, info, conf)
|
||||
of "warnings", "w":
|
||||
if processOnOffSwitchOrList(conf, {optWarns}, arg, pass, info): listWarnings(conf)
|
||||
of "warning": processSpecificNote(arg, wWarning, pass, info, switch, conf)
|
||||
@@ -717,7 +740,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
of "linedir": processOnOffSwitch(conf, {optLineDir}, arg, pass, info)
|
||||
of "assertions", "a": processOnOffSwitch(conf, {optAssert}, arg, pass, info)
|
||||
of "threads":
|
||||
if conf.backend == backendJs: discard
|
||||
if conf.backend == backendJs or conf.cmd == cmdNimscript: discard
|
||||
else: processOnOffSwitchG(conf, {optThreads}, arg, pass, info)
|
||||
#if optThreads in conf.globalOptions: conf.setNote(warnGcUnsafe)
|
||||
of "tlsemulation": processOnOffSwitchG(conf, {optTlsEmulation}, arg, pass, info)
|
||||
@@ -1028,6 +1051,10 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
defineSymbol(conf.symbols, "NimMajor", "1")
|
||||
defineSymbol(conf.symbols, "NimMinor", "2")
|
||||
conf.globalOptions.incl optNimV12Emulation
|
||||
of "1.6":
|
||||
defineSymbol(conf.symbols, "NimMajor", "1")
|
||||
defineSymbol(conf.symbols, "NimMinor", "6")
|
||||
conf.globalOptions.incl optNimV16Emulation
|
||||
else:
|
||||
localError(conf, info, "unknown Nim version; currently supported values are: `1.0`, `1.2`")
|
||||
# always be compatible with 1.x.100:
|
||||
@@ -1052,7 +1079,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
processOnOffSwitchG(conf, {optEnableDeepCopy}, arg, pass, info)
|
||||
of "": # comes from "-" in for example: `nim c -r -` (gets stripped from -)
|
||||
handleStdinInput(conf)
|
||||
of "nilseqs", "nilchecks", "symbol", "taintmode", "cs", "deadcodeelim": warningOptionNoop(switch)
|
||||
of "nilseqs", "nilchecks", "mainmodule", "m", "symbol", "taintmode", "cs", "deadcodeelim": warningOptionNoop(switch)
|
||||
of "nimmainprefix": conf.nimMainPrefix = arg
|
||||
else:
|
||||
if strutils.find(switch, '.') >= 0: options.setConfigVar(conf, switch, arg)
|
||||
|
||||
@@ -15,6 +15,9 @@ import ast, astalgo, semdata, lookups, lineinfos, idents, msgs, renderer, types,
|
||||
|
||||
from magicsys import addSonSkipIntLit
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
const
|
||||
logBindings = false
|
||||
|
||||
|
||||
@@ -140,4 +140,3 @@ proc initDefines*(symbols: StringTableRef) =
|
||||
defineSymbol("nimHasEffectsOf")
|
||||
|
||||
defineSymbol("nimHasEnforceNoRaises")
|
||||
defineSymbol("nimHasWarnBareExcept")
|
||||
|
||||
@@ -54,3 +54,19 @@ proc isCompilerDebug*(): bool =
|
||||
{.undef(nimCompilerDebug).}
|
||||
echo 'x'
|
||||
conf0.isDefined("nimCompilerDebug")
|
||||
|
||||
proc enteringDebugSection*() {.exportc, dynlib.} =
|
||||
## Provides a way for native debuggers to enable breakpoints, watchpoints, etc
|
||||
## when code of interest is being compiled.
|
||||
##
|
||||
## Set your debugger to break on entering `nimCompilerIsEnteringDebugSection`
|
||||
## and then execute a desired command.
|
||||
discard
|
||||
|
||||
proc exitingDebugSection*() {.exportc, dynlib.} =
|
||||
## Provides a way for native debuggers to disable breakpoints, watchpoints, etc
|
||||
## when code of interest is no longer being compiled.
|
||||
##
|
||||
## Set your debugger to break on entering `exitingDebugSection`
|
||||
## and then execute a desired command.
|
||||
discard
|
||||
|
||||
@@ -9,12 +9,10 @@
|
||||
|
||||
# This module implements a dependency file generator.
|
||||
|
||||
import options, ast, ropes, passes, pathutils, msgs, lineinfos
|
||||
import
|
||||
options, ast, ropes, idents, passes, modulepaths, pathutils
|
||||
|
||||
import modulegraphs
|
||||
|
||||
import std/[os, strutils, parseutils]
|
||||
import std/private/globs
|
||||
from modulegraphs import ModuleGraph, PPassContext
|
||||
|
||||
type
|
||||
TGen = object of PPassContext
|
||||
@@ -30,50 +28,6 @@ proc addDependencyAux(b: Backend; importing, imported: string) =
|
||||
b.dotGraph.addf("\"$1\" -> \"$2\";$n", [rope(importing), rope(imported)])
|
||||
# s1 -> s2_4[label="[0-9]"];
|
||||
|
||||
proc toNimblePath(s: string, isStdlib: bool): string =
|
||||
const stdPrefix = "std/"
|
||||
const pkgPrefix = "pkg/"
|
||||
if isStdlib:
|
||||
let sub = "lib/"
|
||||
var start = s.find(sub)
|
||||
if start < 0:
|
||||
doAssert false
|
||||
else:
|
||||
start += sub.len
|
||||
let base = s[start..^1]
|
||||
|
||||
if base.startsWith("system") or base.startsWith("std"):
|
||||
result = base
|
||||
else:
|
||||
for dir in stdlibDirs:
|
||||
if base.startsWith(dir):
|
||||
return stdPrefix & base.splitFile.name
|
||||
|
||||
result = stdPrefix & base
|
||||
else:
|
||||
var sub = getEnv("NIMBLE_DIR")
|
||||
if sub.len == 0:
|
||||
sub = ".nimble/pkgs/"
|
||||
else:
|
||||
sub.add "/pkgs/"
|
||||
var start = s.find(sub)
|
||||
if start < 0:
|
||||
result = s
|
||||
else:
|
||||
start += sub.len
|
||||
start += skipUntil(s, '/', start)
|
||||
start += 1
|
||||
result = pkgPrefix & s[start..^1]
|
||||
|
||||
proc addDependency(c: PPassContext, g: PGen, b: Backend, n: PNode) =
|
||||
doAssert n.kind == nkSym, $n.kind
|
||||
|
||||
let path = splitFile(toProjPath(g.config, n.sym.position.FileIndex))
|
||||
let modulePath = splitFile(toProjPath(g.config, g.module.position.FileIndex))
|
||||
let parent = nativeToUnixPath(modulePath.dir / modulePath.name).toNimblePath(belongsToStdlib(g.graph, g.module))
|
||||
let child = nativeToUnixPath(path.dir / path.name).toNimblePath(belongsToStdlib(g.graph, n.sym))
|
||||
addDependencyAux(b, parent, child)
|
||||
|
||||
proc addDotDependency(c: PPassContext, n: PNode): PNode =
|
||||
result = n
|
||||
let g = PGen(c)
|
||||
@@ -81,9 +35,11 @@ proc addDotDependency(c: PPassContext, n: PNode): PNode =
|
||||
case n.kind
|
||||
of nkImportStmt:
|
||||
for i in 0..<n.len:
|
||||
addDependency(c, g, b, n[i])
|
||||
var imported = getModuleName(g.config, n[i])
|
||||
addDependencyAux(b, g.module.name.s, imported)
|
||||
of nkFromStmt, nkImportExceptStmt:
|
||||
addDependency(c, g, b, n[0])
|
||||
var imported = getModuleName(g.config, n[0])
|
||||
addDependencyAux(b, g.module.name.s, imported)
|
||||
of nkStmtList, nkBlockStmt, nkStmtListExpr, nkBlockExpr:
|
||||
for i in 0..<n.len: discard addDotDependency(c, n[i])
|
||||
else:
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
import ast, intsets, lineinfos, renderer
|
||||
import std/private/asciitables
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
InstrKind* = enum
|
||||
goto, fork, def, use
|
||||
@@ -605,11 +608,11 @@ proc aliases*(obj, field: PNode): AliasKind =
|
||||
var n = n
|
||||
while true:
|
||||
case n.kind
|
||||
of PathKinds0 - {nkDotExpr, nkCheckedFieldExpr, nkBracketExpr}:
|
||||
of PathKinds0 - {nkDotExpr, nkBracketExpr}:
|
||||
n = n[0]
|
||||
of PathKinds1:
|
||||
n = n[1]
|
||||
of nkDotExpr, nkCheckedFieldExpr, nkBracketExpr:
|
||||
of nkDotExpr, nkBracketExpr:
|
||||
result.add n
|
||||
n = n[0]
|
||||
of nkSym:
|
||||
@@ -642,8 +645,6 @@ proc aliases*(obj, field: PNode): AliasKind =
|
||||
if currFieldPath.sym != currObjPath.sym: return no
|
||||
of nkDotExpr:
|
||||
if currFieldPath[1].sym != currObjPath[1].sym: return no
|
||||
of nkCheckedFieldExpr:
|
||||
if currFieldPath[0][1].sym != currObjPath[0][1].sym: return no
|
||||
of nkBracketExpr:
|
||||
if currFieldPath[1].kind in nkLiterals and currObjPath[1].kind in nkLiterals:
|
||||
if currFieldPath[1].intVal != currObjPath[1].intVal:
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
import
|
||||
ast, strutils, strtabs, algorithm, sequtils, options, msgs, os, idents,
|
||||
wordrecg, syntaxes, renderer, lexer,
|
||||
packages/docutils/rst, packages/docutils/rstgen,
|
||||
packages/docutils/[rst, rstgen, dochelpers],
|
||||
json, xmltree, trees, types,
|
||||
typesrenderer, astalgo, lineinfos, intsets,
|
||||
pathutils, tables, nimpaths, renderverbatim, osproc, packages
|
||||
@@ -44,8 +44,14 @@ type
|
||||
## runnableExamples).
|
||||
substitutions: seq[string] ## Variable names in `doc.item`...
|
||||
sortName: string ## The string used for sorting in output
|
||||
info: rstast.TLineInfo ## place where symbol was defined (for messages)
|
||||
anchor: string ## e.g. HTML anchor
|
||||
name: string ## short name of the symbol, not unique
|
||||
## (includes backticks ` if present)
|
||||
detailedName: string ## longer name like `proc search(x: int): int`
|
||||
ModSection = object ## Section like Procs, Types, etc.
|
||||
secItems: seq[Item] ## Pre-processed items.
|
||||
secItems: Table[string, seq[Item]]
|
||||
## Map basic name -> pre-processed items.
|
||||
finalMarkup: string ## The items, after RST pass 2 and rendering.
|
||||
ModSections = array[TSymKind, ModSection]
|
||||
TocItem = object ## HTML TOC item
|
||||
@@ -91,12 +97,22 @@ type
|
||||
thisDir*: AbsoluteDir
|
||||
exampleGroups: OrderedTable[string, ExampleGroup]
|
||||
wroteSupportFiles*: bool
|
||||
nimToRstFid: Table[lineinfos.FileIndex, rstast.FileIndex]
|
||||
## map Nim FileIndex -> RST one, it's needed because we keep them separate
|
||||
|
||||
PDoc* = ref TDocumentor ## Alias to type less.
|
||||
|
||||
proc add(dest: var ItemPre, rst: PRstNode) = dest.add ItemFragment(isRst: true, rst: rst)
|
||||
proc add(dest: var ItemPre, str: string) = dest.add ItemFragment(isRst: false, str: str)
|
||||
|
||||
proc addRstFileIndex(d: PDoc, info: lineinfos.TLineInfo): rstast.FileIndex =
|
||||
let invalid = rstast.FileIndex(-1)
|
||||
result = d.nimToRstFid.getOrDefault(info.fileIndex, default = invalid)
|
||||
if result == invalid:
|
||||
let fname = toFullPath(d.conf, info)
|
||||
result = addFilename(d.sharedState, fname)
|
||||
d.nimToRstFid[info.fileIndex] = result
|
||||
|
||||
proc cmpDecimalsIgnoreCase(a, b: string): int =
|
||||
## For sorting with correct handling of cases like 'uint8' and 'uint16'.
|
||||
## Also handles leading zeros well (however note that leading zeros are
|
||||
@@ -216,6 +232,7 @@ template declareClosures =
|
||||
of meExpected: k = errXExpected
|
||||
of meGridTableNotImplemented: k = errRstGridTableNotImplemented
|
||||
of meMarkdownIllformedTable: k = errRstMarkdownIllformedTable
|
||||
of meIllformedTable: k = errRstIllformedTable
|
||||
of meNewSectionExpected: k = errRstNewSectionExpected
|
||||
of meGeneralParseError: k = errRstGeneralParseError
|
||||
of meInvalidDirective: k = errRstInvalidDirectiveX
|
||||
@@ -224,6 +241,7 @@ template declareClosures =
|
||||
of meSandboxedDirective: k = errRstSandboxedDirective
|
||||
of mwRedefinitionOfLabel: k = warnRstRedefinitionOfLabel
|
||||
of mwUnknownSubstitution: k = warnRstUnknownSubstitutionX
|
||||
of mwAmbiguousLink: k = warnRstAmbiguousLink
|
||||
of mwBrokenLink: k = warnRstBrokenLink
|
||||
of mwUnsupportedLanguage: k = warnRstLanguageXNotSupported
|
||||
of mwUnsupportedField: k = warnRstFieldXNotSupported
|
||||
@@ -237,7 +255,7 @@ template declareClosures =
|
||||
result = getCurrentDir() / s
|
||||
if not fileExists(result): result = ""
|
||||
|
||||
proc parseRst(text, filename: string,
|
||||
proc parseRst(text: string,
|
||||
line, column: int,
|
||||
conf: ConfigRef, sharedState: PRstSharedState): PRstNode =
|
||||
declareClosures()
|
||||
@@ -275,10 +293,6 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
|
||||
conf.configVars, filename.string,
|
||||
docgenFindFile, compilerMsgHandler)
|
||||
|
||||
if conf.configVars.hasKey("doc.googleAnalytics") and
|
||||
conf.configVars.hasKey("doc.plausibleAnalytics"):
|
||||
doAssert false, "Either use googleAnalytics or plausibleAnalytics"
|
||||
|
||||
if conf.configVars.hasKey("doc.googleAnalytics"):
|
||||
result.analytics = """
|
||||
<script>
|
||||
@@ -292,10 +306,6 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
|
||||
|
||||
</script>
|
||||
""" % [conf.configVars.getOrDefault"doc.googleAnalytics"]
|
||||
elif conf.configVars.hasKey("doc.plausibleAnalytics"):
|
||||
result.analytics = """
|
||||
<script defer data-domain="$1" src="https://plausible.io/js/plausible.js"></script>
|
||||
""" % [conf.configVars.getOrDefault"doc.plausibleAnalytics"]
|
||||
else:
|
||||
result.analytics = ""
|
||||
|
||||
@@ -361,7 +371,8 @@ proc getVarIdx(varnames: openArray[string], id: string): int =
|
||||
|
||||
proc genComment(d: PDoc, n: PNode): PRstNode =
|
||||
if n.comment.len > 0:
|
||||
result = parseRst(n.comment, toFullPath(d.conf, n.info),
|
||||
d.sharedState.currFileIdx = addRstFileIndex(d, n.info)
|
||||
result = parseRst(n.comment,
|
||||
toLinenumber(n.info),
|
||||
toColumn(n.info) + DocColOffset,
|
||||
d.conf, d.sharedState)
|
||||
@@ -891,6 +902,64 @@ proc genSeeSrc(d: PDoc, path: string, line: int): string =
|
||||
"path", path.string, "line", $line, "url", gitUrl,
|
||||
"commit", commit, "devel", develBranch]])
|
||||
|
||||
proc symbolPriority(k: TSymKind): int =
|
||||
result = case k
|
||||
of skMacro: -3
|
||||
of skTemplate: -2
|
||||
of skIterator: -1
|
||||
else: 0 # including skProc which have higher priority
|
||||
# documentation itself has even higher priority 1
|
||||
|
||||
proc toLangSymbol(k: TSymKind, n: PNode, baseName: string): LangSymbol =
|
||||
## Converts symbol info (names/types/parameters) in `n` into format
|
||||
## `LangSymbol` convenient for ``rst.nim``/``dochelpers.nim``.
|
||||
result.name = baseName.nimIdentNormalize
|
||||
result.symKind = k.toHumanStr
|
||||
if k in routineKinds:
|
||||
var
|
||||
paramTypes: seq[string]
|
||||
renderParamTypes(paramTypes, n[paramsPos], toNormalize=true)
|
||||
let paramNames = renderParamNames(n[paramsPos], toNormalize=true)
|
||||
# In some rare cases (system.typeof) parameter type is not set for default:
|
||||
doAssert paramTypes.len <= paramNames.len
|
||||
for i in 0 ..< paramNames.len:
|
||||
if i < paramTypes.len:
|
||||
result.parameters.add (paramNames[i], paramTypes[i])
|
||||
else:
|
||||
result.parameters.add (paramNames[i], "")
|
||||
result.parametersProvided = true
|
||||
|
||||
result.outType = renderOutType(n[paramsPos], toNormalize=true)
|
||||
|
||||
if k in {skProc, skFunc, skType, skIterator}:
|
||||
# Obtain `result.generics`
|
||||
# Use `n[miscPos]` since n[genericParamsPos] does not contain constraints
|
||||
var genNode: PNode = nil
|
||||
if k == skType:
|
||||
genNode = n[1] # FIXME: what is index 1?
|
||||
else:
|
||||
if n[miscPos].kind != nkEmpty:
|
||||
genNode = n[miscPos][1] # FIXME: what is index 1?
|
||||
if genNode != nil:
|
||||
var literal = ""
|
||||
var r: TSrcGen
|
||||
initTokRender(r, genNode, {renderNoBody, renderNoComments,
|
||||
renderNoPragmas, renderNoProcDefs})
|
||||
var kind = tkEof
|
||||
while true:
|
||||
getNextTok(r, kind, literal)
|
||||
if kind == tkEof:
|
||||
break
|
||||
if kind != tkSpaces:
|
||||
result.generics.add(literal.nimIdentNormalize)
|
||||
|
||||
if k == skType:
|
||||
case n[2].kind
|
||||
of nkEnumTy: result.symTypeKind = "enum"
|
||||
of nkObjectTy: result.symTypeKind = "object"
|
||||
of nkTupleTy: result.symTypeKind = "tuple"
|
||||
else: discard
|
||||
|
||||
proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
|
||||
if (docFlags != kForceExport) and not isVisible(d, nameNode): return
|
||||
let
|
||||
@@ -921,6 +990,8 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
|
||||
inc(d.id)
|
||||
let
|
||||
plainNameEsc = esc(d.target, plainName.strip)
|
||||
detailedName = k.toHumanStr & " " & (
|
||||
if k in routineKinds: plainName else: name)
|
||||
uniqueName = if k in routineKinds: plainNameEsc else: name
|
||||
sortName = if k in routineKinds: plainName.strip else: name
|
||||
cleanPlainSymbol = renderPlainSymbolName(nameNode)
|
||||
@@ -929,20 +1000,32 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
|
||||
symbolOrId = d.newUniquePlainSymbol(complexSymbol)
|
||||
symbolOrIdEnc = encodeUrl(symbolOrId, usePlus = false)
|
||||
deprecationMsg = genDeprecationMsg(d, pragmaNode)
|
||||
rstLangSymbol = toLangSymbol(k, n, cleanPlainSymbol)
|
||||
|
||||
# we generate anchors automatically for subsequent use in doc comments
|
||||
let lineinfo = rstast.TLineInfo(
|
||||
line: nameNode.info.line, col: nameNode.info.col,
|
||||
fileIndex: addRstFileIndex(d, nameNode.info))
|
||||
addAnchorNim(d.sharedState, refn = symbolOrId, tooltip = detailedName,
|
||||
rstLangSymbol, priority = symbolPriority(k), info = lineinfo)
|
||||
|
||||
nodeToHighlightedHtml(d, n, result, {renderNoBody, renderNoComments,
|
||||
renderDocComments, renderSyms}, symbolOrIdEnc)
|
||||
|
||||
let seeSrc = genSeeSrc(d, toFullPath(d.conf, n.info), n.info.line.int)
|
||||
|
||||
d.section[k].secItems.add Item(
|
||||
d.section[k].secItems.mgetOrPut(cleanPlainSymbol, newSeq[Item]()).add Item(
|
||||
descRst: comm,
|
||||
sortName: sortName,
|
||||
info: lineinfo,
|
||||
anchor: symbolOrId,
|
||||
detailedName: detailedName,
|
||||
name: name,
|
||||
substitutions: @[
|
||||
"name", name, "uniqueName", uniqueName,
|
||||
"uniqueName", uniqueName,
|
||||
"header", result, "itemID", $d.id,
|
||||
"header_plain", plainNameEsc, "itemSym", cleanPlainSymbol,
|
||||
"itemSymOrID", symbolOrId, "itemSymEnc", plainSymbolEnc,
|
||||
"itemSymEnc", plainSymbolEnc,
|
||||
"itemSymOrIDEnc", symbolOrIdEnc, "seeSrc", seeSrc,
|
||||
"deprecationMsg", deprecationMsg])
|
||||
|
||||
@@ -1190,6 +1273,11 @@ proc generateDoc*(d: PDoc, n, orig: PNode, docFlags: DocFlags = kDefault) =
|
||||
if comm.len != 0: d.modDescPre.add(comm)
|
||||
else: discard
|
||||
|
||||
proc overloadGroupName(s: string, k: TSymKind): string =
|
||||
## Turns a name like `f` into anchor `f-procs-all`
|
||||
#s & " " & k.toHumanStr & "s all"
|
||||
s & "-" & k.toHumanStr & "s-all"
|
||||
|
||||
proc finishGenerateDoc*(d: var PDoc) =
|
||||
## Perform 2nd RST pass for resolution of links/footnotes/headings...
|
||||
# copy file map `filenames` to ``rstgen.nim`` for its warnings
|
||||
@@ -1203,6 +1291,22 @@ proc finishGenerateDoc*(d: var PDoc) =
|
||||
break
|
||||
preparePass2(d.sharedState, firstRst)
|
||||
|
||||
# add anchors to overload groups before RST resolution
|
||||
for k in TSymKind:
|
||||
if k in routineKinds:
|
||||
for plainName, overloadChoices in d.section[k].secItems:
|
||||
if overloadChoices.len > 1:
|
||||
let refn = overloadGroupName(plainName, k)
|
||||
let tooltip = "$1 ($2 overloads)" % [
|
||||
k.toHumanStr & " " & plainName, $overloadChoices.len]
|
||||
addAnchorNim(d.sharedState, refn, tooltip,
|
||||
LangSymbol(symKind: k.toHumanStr,
|
||||
name: nimIdentBackticksNormalize(plainName),
|
||||
isGroup: true),
|
||||
priority = symbolPriority(k),
|
||||
# select index `0` just to have any meaningful warning:
|
||||
info = overloadChoices[0].info)
|
||||
|
||||
# Finalize fragments of ``.nim`` or ``.rst`` file
|
||||
proc renderItemPre(d: PDoc, fragments: ItemPre, result: var string) =
|
||||
for f in fragments:
|
||||
@@ -1213,14 +1317,33 @@ proc finishGenerateDoc*(d: var PDoc) =
|
||||
of false: result &= f.str
|
||||
proc cmp(x, y: Item): int = cmpDecimalsIgnoreCase(x.sortName, y.sortName)
|
||||
for k in TSymKind:
|
||||
for item in d.section[k].secItems.sorted(cmp):
|
||||
var itemDesc: string
|
||||
renderItemPre(d, item.descRst, itemDesc)
|
||||
d.section[k].finalMarkup.add(
|
||||
getConfigVar(d.conf, "doc.item") % (
|
||||
item.substitutions & @["desc", itemDesc]))
|
||||
itemDesc = ""
|
||||
d.section[k].secItems.setLen 0
|
||||
# add symbols to section for each `k`, while optionally wrapping
|
||||
# overloadable items with the same basic name by ``doc.item2``
|
||||
let overloadableNames = toSeq(keys(d.section[k].secItems))
|
||||
for plainName in overloadableNames.sorted(cmpDecimalsIgnoreCase):
|
||||
var overloadChoices = d.section[k].secItems[plainName]
|
||||
overloadChoices.sort(cmp)
|
||||
var nameContent = ""
|
||||
for item in overloadChoices:
|
||||
var itemDesc: string
|
||||
renderItemPre(d, item.descRst, itemDesc)
|
||||
nameContent.add(
|
||||
getConfigVar(d.conf, "doc.item") % (
|
||||
item.substitutions & @[
|
||||
"desc", itemDesc,
|
||||
"name", item.name,
|
||||
"itemSymOrID", item.anchor]))
|
||||
if k in routineKinds:
|
||||
let plainNameEsc1 = esc(d.target, plainName.strip)
|
||||
let plainNameEsc2 = esc(d.target, plainName.strip, escMode=emUrl)
|
||||
d.section[k].finalMarkup.add(
|
||||
getConfigVar(d.conf, "doc.item2") % (
|
||||
@["header_plain", plainNameEsc1,
|
||||
"overloadGroupName", overloadGroupName(plainNameEsc2, k),
|
||||
"content", nameContent]))
|
||||
else:
|
||||
d.section[k].finalMarkup.add(nameContent)
|
||||
d.section[k].secItems.clear
|
||||
renderItemPre(d, d.modDescPre, d.modDescFinal)
|
||||
d.modDescPre.setLen 0
|
||||
d.hasToc = d.hasToc or d.sharedState.hasToc
|
||||
@@ -1232,10 +1355,9 @@ proc finishGenerateDoc*(d: var PDoc) =
|
||||
var str: string
|
||||
renderRstToOut(d[], resolved, str)
|
||||
entry.json[entry.rstField] = %str
|
||||
d.jEntriesFinal.add entry.json
|
||||
d.jEntriesPre[i].rst = nil
|
||||
|
||||
d.jEntriesFinal.add entry.json # generates docs
|
||||
|
||||
proc add(d: PDoc; j: JsonItem) =
|
||||
if j.json != nil or j.rst != nil: d.jEntriesPre.add j
|
||||
|
||||
@@ -1375,7 +1497,10 @@ proc genOutFile(d: PDoc, groupedToc = false): string =
|
||||
# Extract the title. Non API modules generate an entry in the index table.
|
||||
if d.meta[metaTitle].len != 0:
|
||||
title = d.meta[metaTitle]
|
||||
let external = presentationPath(d.conf, AbsoluteFile d.filename).changeFileExt(HtmlExt).string.nativeToUnixPath
|
||||
let external = AbsoluteFile(d.destFile)
|
||||
.relativeTo(d.conf.outDir, '/')
|
||||
.changeFileExt(HtmlExt)
|
||||
.string
|
||||
setIndexTerm(d[], external, "", title)
|
||||
else:
|
||||
# Modules get an automatic title for the HTML, but no entry in the index.
|
||||
@@ -1449,7 +1574,11 @@ proc writeOutput*(d: PDoc, useWarning = false, groupedToc = false) =
|
||||
outfile.string)
|
||||
if not d.wroteSupportFiles: # nimdoc.css + dochack.js
|
||||
let nimr = $d.conf.getPrefixDir()
|
||||
copyFile(docCss.interp(nimr = nimr), $d.conf.outDir / nimdocOutCss)
|
||||
case d.target
|
||||
of outHtml:
|
||||
copyFile(docCss.interp(nimr = nimr), $d.conf.outDir / nimdocOutCss)
|
||||
of outLatex:
|
||||
copyFile(docCls.interp(nimr = nimr), $d.conf.outDir / nimdocOutCls)
|
||||
if optGenIndex in d.conf.globalOptions:
|
||||
let docHackJs2 = getDocHacksJs(nimr, nim = getAppFilename())
|
||||
copyFile(docHackJs2, $d.conf.outDir / docHackJs2.lastPathPart)
|
||||
@@ -1500,7 +1629,7 @@ proc commandRstAux(cache: IdentCache, conf: ConfigRef;
|
||||
filename: AbsoluteFile, outExt: string) =
|
||||
var filen = addFileExt(filename, "txt")
|
||||
var d = newDocumentor(filen, cache, conf, outExt, isPureRst = true)
|
||||
let rst = parseRst(readFile(filen.string), filen.string,
|
||||
let rst = parseRst(readFile(filen.string),
|
||||
line=LineRstInit, column=ColRstInit,
|
||||
conf, d.sharedState)
|
||||
d.modDescPre = @[ItemFragment(isRst: true, rst: rst)]
|
||||
@@ -1536,7 +1665,7 @@ proc commandJson*(cache: IdentCache, conf: ConfigRef) =
|
||||
let filename = getOutFile(conf, RelativeFile conf.projectName, JsonExt)
|
||||
try:
|
||||
writeFile(filename, content)
|
||||
except IOError:
|
||||
except:
|
||||
rawMessage(conf, errCannotOpenFile, filename.string)
|
||||
|
||||
proc commandTags*(cache: IdentCache, conf: ConfigRef) =
|
||||
@@ -1559,7 +1688,7 @@ proc commandTags*(cache: IdentCache, conf: ConfigRef) =
|
||||
let filename = getOutFile(conf, RelativeFile conf.projectName, TagsExt)
|
||||
try:
|
||||
writeFile(filename, content)
|
||||
except IOError:
|
||||
except:
|
||||
rawMessage(conf, errCannotOpenFile, filename.string)
|
||||
|
||||
proc commandBuildIndex*(conf: ConfigRef, dir: string, outFile = RelativeFile"") =
|
||||
@@ -1580,5 +1709,5 @@ proc commandBuildIndex*(conf: ConfigRef, dir: string, outFile = RelativeFile"")
|
||||
|
||||
try:
|
||||
writeFile(filename, code)
|
||||
except IOError:
|
||||
except:
|
||||
rawMessage(conf, errCannotOpenFile, filename.string)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
|
||||
import ast, idents, lineinfos, modulegraphs, magicsys
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
|
||||
proc genEnumToStrProc*(t: PType; info: TLineInfo; g: ModuleGraph; idgen: IdGenerator): PSym =
|
||||
result = newSym(skProc, getIdent(g.cache, "$"), nextSymId idgen, t.owner, info)
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
import ast, renderer, options, strutils, types
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
ErrorKind* = enum ## expand as you need.
|
||||
RawTypeMismatchError
|
||||
|
||||
@@ -110,8 +110,8 @@ proc mapCallConv(conf: ConfigRef, cc: TCallingConvention, info: TLineInfo): TABI
|
||||
else:
|
||||
globalError(conf, info, "cannot map calling convention to FFI")
|
||||
|
||||
template rd(typ, p: untyped): untyped = (cast[ptr typ](p))[]
|
||||
template wr(typ, p, v: untyped): untyped = (cast[ptr typ](p))[] = v
|
||||
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)
|
||||
|
||||
@@ -177,8 +177,8 @@ const maxPackDepth = 20
|
||||
var packRecCheck = 0
|
||||
|
||||
proc pack(conf: ConfigRef, v: PNode, typ: PType, res: pointer) =
|
||||
template awr(typ, v: untyped): untyped =
|
||||
wr(typ, res, v)
|
||||
template awr(T, v: untyped): untyped =
|
||||
wr(T, res, v)
|
||||
|
||||
case typ.kind
|
||||
of tyBool: awr(bool, v.intVal != 0)
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
|
||||
import ropes, platform, condsyms, options, msgs, lineinfos, pathutils, modulepaths
|
||||
|
||||
import std/[os, strutils, osproc, sha1, streams, sequtils, times, strtabs, json, jsonutils, sugar, parseutils]
|
||||
import std/[os, strutils, osproc, sha1, streams, sequtils, times, strtabs, json, jsonutils, sugar]
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/syncio
|
||||
|
||||
type
|
||||
TInfoCCProp* = enum # properties of the C compiler:
|
||||
@@ -431,7 +434,13 @@ proc noAbsolutePaths(conf: ConfigRef): bool {.inline.} =
|
||||
# really: Cross compilation from Linux to Linux for example is entirely
|
||||
# reasonable.
|
||||
# `optGenMapping` is included here for niminst.
|
||||
result = conf.globalOptions * {optGenScript, optGenMapping} != {}
|
||||
# We use absolute paths for vcc / cl, see issue #19883.
|
||||
let options =
|
||||
if conf.cCompiler == ccVcc:
|
||||
{optGenMapping}
|
||||
else:
|
||||
{optGenScript, optGenMapping}
|
||||
result = conf.globalOptions * options != {}
|
||||
|
||||
proc cFileSpecificOptions(conf: ConfigRef; nimname, fullNimFile: string): string =
|
||||
result = conf.compileOptions
|
||||
@@ -484,10 +493,7 @@ proc needsExeExt(conf: ConfigRef): bool {.inline.} =
|
||||
(conf.target.hostOS == osWindows)
|
||||
|
||||
proc useCpp(conf: ConfigRef; cfile: AbsoluteFile): bool =
|
||||
# List of possible file extensions taken from gcc
|
||||
for ext in [".C", ".cc", ".cpp", ".CPP", ".c++", ".cp", ".cxx"]:
|
||||
if cfile.string.endsWith(ext): return true
|
||||
false
|
||||
conf.backend == backendCpp and not cfile.string.endsWith(".c")
|
||||
|
||||
proc envFlags(conf: ConfigRef): string =
|
||||
result = if conf.backend == backendCpp:
|
||||
@@ -495,14 +501,14 @@ proc envFlags(conf: ConfigRef): string =
|
||||
else:
|
||||
getEnv("CFLAGS")
|
||||
|
||||
proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; isCpp: bool): string =
|
||||
proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; cfile: AbsoluteFile): string =
|
||||
if compiler == ccEnv:
|
||||
result = if isCpp:
|
||||
result = if useCpp(conf, cfile):
|
||||
getEnv("CXX")
|
||||
else:
|
||||
getEnv("CC")
|
||||
else:
|
||||
result = if isCpp:
|
||||
result = if useCpp(conf, cfile):
|
||||
CC[compiler].cppCompiler
|
||||
else:
|
||||
CC[compiler].compilerExe
|
||||
@@ -516,36 +522,47 @@ proc ccHasSaneOverflow*(conf: ConfigRef): bool =
|
||||
result = false # assume an old or crappy GCC
|
||||
var exe = getConfigVar(conf, conf.cCompiler, ".exe")
|
||||
if exe.len == 0: exe = CC[conf.cCompiler].compilerExe
|
||||
# NOTE: should we need the full version, use -dumpfullversion
|
||||
let (s, exitCode) = try: execCmdEx(exe & " -dumpversion") except IOError, OSError, ValueError: ("", 1)
|
||||
let (s, exitCode) = try: execCmdEx(exe & " --version") except: ("", 1)
|
||||
if exitCode == 0:
|
||||
var major: int
|
||||
discard parseInt(s, major)
|
||||
result = major >= 5
|
||||
var i = 0
|
||||
var j = 0
|
||||
# the version is the last part of the first line:
|
||||
while i < s.len and s[i] != '\n':
|
||||
if s[i] in {' ', '\t'}: j = i+1
|
||||
inc i
|
||||
if j > 0:
|
||||
var major = 0
|
||||
while j < s.len and s[j] in {'0'..'9'}:
|
||||
major = major * 10 + (ord(s[j]) - ord('0'))
|
||||
inc j
|
||||
if i < s.len and s[j] == '.': inc j
|
||||
while j < s.len and s[j] in {'0'..'9'}:
|
||||
inc j
|
||||
if j+1 < s.len and s[j] == '.' and s[j+1] in {'0'..'9'}:
|
||||
# we found a third version number, chances are high
|
||||
# we really parsed the version:
|
||||
result = major >= 5
|
||||
else:
|
||||
result = conf.cCompiler == ccCLang
|
||||
|
||||
proc getLinkerExe(conf: ConfigRef; compiler: TSystemCC): string =
|
||||
result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe
|
||||
else: getCompilerExe(conf, compiler, optMixedMode in conf.globalOptions or conf.backend == backendCpp)
|
||||
elif optMixedMode in conf.globalOptions and conf.backend != backendCpp: CC[compiler].cppCompiler
|
||||
else: getCompilerExe(conf, compiler, AbsoluteFile"")
|
||||
|
||||
proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
|
||||
isMainFile = false; produceOutput = false): string =
|
||||
let
|
||||
c = conf.cCompiler
|
||||
isCpp = useCpp(conf, cfile.cname)
|
||||
let c = conf.cCompiler
|
||||
# We produce files like module.nim.cpp, so the absolute Nim filename is not
|
||||
# cfile.name but `cfile.cname.changeFileExt("")`:
|
||||
var options = cFileSpecificOptions(conf, cfile.nimname, cfile.cname.changeFileExt("").string)
|
||||
if isCpp:
|
||||
if useCpp(conf, cfile.cname):
|
||||
# needs to be prepended so that --passc:-std=c++17 can override default.
|
||||
# we could avoid allocation by making cFileSpecificOptions inplace
|
||||
options = CC[c].cppXsupport & ' ' & options
|
||||
# If any C++ file was compiled, we need to use C++ driver for linking as well
|
||||
incl conf.globalOptions, optMixedMode
|
||||
|
||||
var exe = getConfigVar(conf, c, ".exe")
|
||||
if exe.len == 0: exe = getCompilerExe(conf, c, isCpp)
|
||||
if exe.len == 0: exe = getCompilerExe(conf, c, cfile.cname)
|
||||
|
||||
if needsExeExt(conf): exe = addFileExt(exe, "exe")
|
||||
if (optGenDynLib in conf.globalOptions or (conf.hcrOn and not isMainFile)) and
|
||||
@@ -565,7 +582,7 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
|
||||
|
||||
compilePattern = joinPath(conf.cCompilerPath, exe)
|
||||
else:
|
||||
compilePattern = getCompilerExe(conf, c, isCpp)
|
||||
compilePattern = getCompilerExe(conf, c, cfile.cname)
|
||||
|
||||
includeCmd.add(join([CC[c].includeCmd, quoteShell(conf.projectPath.string)]))
|
||||
|
||||
@@ -910,7 +927,7 @@ proc callCCompiler*(conf: ConfigRef) =
|
||||
objfiles.add(' ')
|
||||
objfiles.add(quoteShell(objFile))
|
||||
let mainOutput = if optGenScript notin conf.globalOptions: conf.prepareToWriteOutput
|
||||
else: AbsoluteFile(conf.projectName)
|
||||
else: AbsoluteFile(conf.outFile)
|
||||
|
||||
linkCmd = getLinkCmd(conf, mainOutput, objfiles, removeStaticFile = true)
|
||||
extraCmds = getExtraCmds(conf, mainOutput)
|
||||
@@ -1006,7 +1023,7 @@ proc changeDetectedViaJsonBuildInstructions*(conf: ConfigRef; jsonFile: Absolute
|
||||
proc runJsonBuildInstructions*(conf: ConfigRef; jsonFile: AbsoluteFile) =
|
||||
var bcache: BuildCache
|
||||
try: bcache.fromJson(jsonFile.string.parseFile)
|
||||
except ValueError, KeyError, JsonKindError:
|
||||
except:
|
||||
let e = getCurrentException()
|
||||
conf.quitOrRaise "\ncaught exception:\n$#\nstacktrace:\n$#error evaluating JSON file: $#" %
|
||||
[e.msg, e.getStackTrace(), jsonFile.string]
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
import msgs, std / sha1, os, osproc, streams, options,
|
||||
lineinfos, pathutils
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/syncio
|
||||
|
||||
proc readOutput(p: Process): (string, int) =
|
||||
result[0] = ""
|
||||
var output = p.outputStream
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer, idents,
|
||||
saturate, modulegraphs, options, lineinfos, int128
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
const
|
||||
someEq = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
|
||||
mEqStr, mEqSet, mEqCString}
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
# This include implements the high level optimization pass.
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
proc hlo(c: PContext, n: PNode): PNode
|
||||
|
||||
proc evalPattern(c: PContext, n, orig: PNode): PNode =
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
import hashes, rodfiles
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
LitId* = distinct uint32
|
||||
|
||||
@@ -90,13 +93,13 @@ proc getOrIncl*[T](t: var BiTable[T]; v: T): LitId =
|
||||
t.vals.add v
|
||||
|
||||
|
||||
proc `[]`*[T](t: var BiTable[T]; litId: LitId): var T {.inline.} =
|
||||
let idx = idToIdx litId
|
||||
proc `[]`*[T](t: var BiTable[T]; LitId: LitId): var T {.inline.} =
|
||||
let idx = idToIdx LitId
|
||||
assert idx < t.vals.len
|
||||
result = t.vals[idx]
|
||||
|
||||
proc `[]`*[T](t: BiTable[T]; litId: LitId): lent T {.inline.} =
|
||||
let idx = idToIdx litId
|
||||
proc `[]`*[T](t: BiTable[T]; LitId: LitId): lent T {.inline.} =
|
||||
let idx = idToIdx LitId
|
||||
assert idx < t.vals.len
|
||||
result = t.vals[idx]
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
import std/packedsets, algorithm, tables
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
import ".."/[ast, options, lineinfos, modulegraphs, cgendata, cgen,
|
||||
pathutils, extccomp, msgs, modulepaths]
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
## Dead code elimination (=DCE) for IC.
|
||||
|
||||
import std/[intsets, tables]
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
import ".." / [ast, options, lineinfos, types]
|
||||
|
||||
import packed_ast, ic, bitabs
|
||||
|
||||
@@ -14,6 +14,9 @@ import ".." / [ast, idents, lineinfos, msgs, ropes, options,
|
||||
#import ".." / [renderer, astalgo]
|
||||
from os import removeFile, isAbsolute
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions]
|
||||
|
||||
type
|
||||
PackedConfig* = object
|
||||
backend: TBackend
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
## The set must cover a complete Nim project.
|
||||
|
||||
import sets
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
import ".." / [ast, modulegraphs]
|
||||
import packed_ast, bitabs, ic
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ import sets
|
||||
from os import nil
|
||||
from std/private/miscdollars import toLocation
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
import ".." / [ast, modulegraphs, msgs, options]
|
||||
import packed_ast, bitabs, ic
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ import hashes, tables, strtabs
|
||||
import bitabs
|
||||
import ".." / [ast, options]
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
SymId* = distinct int32
|
||||
ModuleId* = distinct int32
|
||||
|
||||
@@ -16,6 +16,9 @@ import ".." / [ast, modulegraphs, trees, extccomp, btrees,
|
||||
|
||||
import tables
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
import packed_ast, ic, bitabs
|
||||
|
||||
proc replayStateChanges*(module: PSym; g: ModuleGraph) =
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
from typetraits import supportsCopyMem
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions]
|
||||
|
||||
## Overview
|
||||
## ========
|
||||
## `RodFile` represents a Rod File (versioned binary format), and the
|
||||
@@ -34,7 +37,8 @@ from typetraits import supportsCopyMem
|
||||
##
|
||||
## Now read the bits below to understand what's missing.
|
||||
##
|
||||
## ### Issues with the Example
|
||||
## Issues with the Example
|
||||
## ```````````````````````
|
||||
## Missing Sections:
|
||||
## This is a low level API, so headers and sections need to be stored and
|
||||
## loaded by the user, see `storeHeader` & `loadHeader` and `storeSection` &
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
import
|
||||
hashes, wordrecg
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
PIdent* = ref TIdent
|
||||
TIdent*{.acyclic.} = object
|
||||
|
||||
@@ -15,6 +15,9 @@ import
|
||||
modulegraphs, wordrecg, tables
|
||||
from strutils import `%`
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
proc readExceptSet*(c: PContext, n: PNode): IntSet =
|
||||
assert n.kind in {nkImportExceptStmt, nkExportExceptStmt}
|
||||
result = initIntSet()
|
||||
|
||||
@@ -19,6 +19,9 @@ import
|
||||
lineinfos, parampatterns, sighashes, liftdestructors, optimizer,
|
||||
varpartitions
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
from trees import exprStructuralEquivalent, getRoot
|
||||
|
||||
type
|
||||
@@ -275,7 +278,7 @@ proc genOp(c: var Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode
|
||||
var op = getAttachedOp(c.graph, t, kind)
|
||||
if op == nil or op.ast.isGenericRoutine:
|
||||
# give up and find the canonical type instead:
|
||||
let h = sighashes.hashType(t, c.graph.config, {CoType, CoConsiderOwned, CoDistinct})
|
||||
let h = sighashes.hashType(t, {CoType, CoConsiderOwned, CoDistinct})
|
||||
let canon = c.graph.canonTypes.getOrDefault(h)
|
||||
if canon != nil:
|
||||
op = getAttachedOp(c.graph, canon, kind)
|
||||
@@ -573,7 +576,7 @@ proc processScope(c: var Con; s: var Scope; ret: PNode): PNode =
|
||||
|
||||
template processScopeExpr(c: var Con; s: var Scope; ret: PNode, processCall: untyped): PNode =
|
||||
assert not ret.typ.isEmptyType
|
||||
var result = newNodeIT(nkStmtListExpr, ret.info, ret.typ)
|
||||
var result = newNodeI(nkStmtListExpr, ret.info)
|
||||
# There is a possibility to do this check: s.wasMoved.len > 0 or s.final.len > 0
|
||||
# later and use it to eliminate the temporary when theres no need for it, but its
|
||||
# tricky because you would have to intercept moveOrCopy at a certain point
|
||||
@@ -1018,26 +1021,6 @@ proc sameLocation*(a, b: PNode): bool =
|
||||
of nkHiddenStdConv, nkHiddenSubConv: sameLocation(a[1], b)
|
||||
else: false
|
||||
|
||||
proc genFieldAccessSideEffects(c: var Con; dest, ri: PNode, isDecl: bool): PNode =
|
||||
# with side effects
|
||||
var temp = newSym(skLet, getIdent(c.graph.cache, "bracketTmp"), nextSymId c.idgen, c.owner, ri[1].info)
|
||||
temp.typ = ri[1].typ
|
||||
var v = newNodeI(nkLetSection, ri[1].info)
|
||||
let tempAsNode = newSymNode(temp)
|
||||
|
||||
var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3)
|
||||
vpart[0] = tempAsNode
|
||||
vpart[1] = newNodeI(nkEmpty, tempAsNode.info)
|
||||
vpart[2] = ri[1]
|
||||
v.add(vpart)
|
||||
|
||||
var newAccess = copyNode(ri)
|
||||
newAccess.add ri[0]
|
||||
newAccess.add tempAsNode
|
||||
|
||||
var snk = c.genSink(dest, newAccess, isDecl)
|
||||
result = newTree(nkStmtList, v, snk, c.genWasMoved(newAccess))
|
||||
|
||||
proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNode =
|
||||
if sameLocation(dest, ri):
|
||||
# rule (self-assignment-removal):
|
||||
@@ -1061,11 +1044,8 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNod
|
||||
elif isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c):
|
||||
if aliases(dest, ri) == no:
|
||||
# Rule 3: `=sink`(x, z); wasMoved(z)
|
||||
if isAtom(ri[1]):
|
||||
var snk = c.genSink(dest, ri, isDecl)
|
||||
result = newTree(nkStmtList, snk, c.genWasMoved(ri))
|
||||
else:
|
||||
result = genFieldAccessSideEffects(c, dest, ri, isDecl)
|
||||
var snk = c.genSink(dest, ri, isDecl)
|
||||
result = newTree(nkStmtList, snk, c.genWasMoved(ri))
|
||||
else:
|
||||
result = c.genSink(dest, destructiveMoveVar(ri, c, s), isDecl)
|
||||
else:
|
||||
|
||||
@@ -141,5 +141,5 @@ shortDesc: "The Nim Compiler"
|
||||
licenses: "bin/nim,MIT;lib/*,MIT;"
|
||||
|
||||
[nimble]
|
||||
pkgName: "nim"
|
||||
pkgName: "compiler"
|
||||
pkgFiles: "compiler/*;doc/basicopt.txt;doc/advopt.txt;doc/nimdoc.css"
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
from math import trunc
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
Int128* = object
|
||||
udata: array[4, uint32]
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
import
|
||||
ast, types, renderer, intsets
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
proc canAlias(arg, ret: PType; marker: var IntSet): bool
|
||||
|
||||
proc canAliasN(arg: PType; n: PNode; marker: var IntSet): bool =
|
||||
@@ -71,7 +74,7 @@ proc isValueOnlyType(t: PType): bool =
|
||||
|
||||
proc canAlias*(arg, ret: PType): bool =
|
||||
if isValueOnlyType(arg):
|
||||
# can alias only with unsafeAddr(arg.x) and we don't care if it is not safe
|
||||
# can alias only with addr(arg.x) and we don't care if it is not safe
|
||||
result = false
|
||||
else:
|
||||
var marker = initIntSet()
|
||||
|
||||
@@ -259,7 +259,7 @@ proc mangleName(m: BModule, s: PSym): Rope =
|
||||
if m.config.hcrOn:
|
||||
# When hot reloading is enabled, we must ensure that the names
|
||||
# of functions and types will be preserved across rebuilds:
|
||||
result.add(idOrSig(s, m.module.name.s, m.sigConflicts, m.config))
|
||||
result.add(idOrSig(s, m.module.name.s, m.sigConflicts))
|
||||
else:
|
||||
result.add("_")
|
||||
result.add(rope(s.id))
|
||||
@@ -771,9 +771,6 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||
if catchBranchesExist:
|
||||
p.body.add("++excHandler;\L")
|
||||
var tmpFramePtr = rope"F"
|
||||
if optStackTrace notin p.options:
|
||||
tmpFramePtr = p.getTemp(true)
|
||||
line(p, tmpFramePtr & " = framePtr;\L")
|
||||
lineF(p, "try {$n", [])
|
||||
var a: TCompRes
|
||||
gen(p, n[0], a)
|
||||
@@ -782,7 +779,8 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||
if catchBranchesExist:
|
||||
p.body.addf("--excHandler;$n} catch (EXCEPTION) {$n var prevJSError = lastJSError;$n" &
|
||||
" lastJSError = EXCEPTION;$n --excHandler;$n", [])
|
||||
line(p, "framePtr = $1;$n" % [tmpFramePtr])
|
||||
if hasFrameInfo(p):
|
||||
line(p, "framePtr = $1;$n" % [tmpFramePtr])
|
||||
while i < n.len and n[i].kind == nkExceptBranch:
|
||||
if n[i].len == 1:
|
||||
# general except section:
|
||||
@@ -841,7 +839,8 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||
line(p, "}\L")
|
||||
lineF(p, "lastJSError = prevJSError;$n")
|
||||
line(p, "} finally {\L")
|
||||
line(p, "framePtr = $1;$n" % [tmpFramePtr])
|
||||
if hasFrameInfo(p):
|
||||
line(p, "framePtr = $1;$n" % [tmpFramePtr])
|
||||
if i < n.len and n[i].kind == nkFinally:
|
||||
genStmt(p, n[i][0])
|
||||
line(p, "}\L")
|
||||
@@ -1297,75 +1296,89 @@ template isIndirect(x: PSym): bool =
|
||||
v.kind notin {skProc, skFunc, skConverter, skMethod, skIterator,
|
||||
skConst, skTemp, skLet})
|
||||
|
||||
proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||
case n[0].kind
|
||||
of nkSym:
|
||||
let s = n[0].sym
|
||||
if s.loc.r == nil: internalError(p.config, n.info, "genAddr: 3")
|
||||
case s.kind
|
||||
of skParam:
|
||||
r.res = s.loc.r
|
||||
r.address = nil
|
||||
r.typ = etyNone
|
||||
of skVar, skLet, skResult:
|
||||
r.kind = resExpr
|
||||
let jsType = mapType(p, n.typ)
|
||||
if jsType == etyObject:
|
||||
# make addr() a no-op:
|
||||
r.typ = etyNone
|
||||
if isIndirect(s):
|
||||
r.res = s.loc.r & "[0]"
|
||||
else:
|
||||
r.res = s.loc.r
|
||||
r.address = nil
|
||||
elif {sfGlobal, sfAddrTaken} * s.flags != {} or jsType == etyBaseIndex:
|
||||
# for ease of code generation, we do not distinguish between
|
||||
# sfAddrTaken and sfGlobal.
|
||||
r.typ = etyBaseIndex
|
||||
r.address = s.loc.r
|
||||
r.res = rope("0")
|
||||
proc genSymAddr(p: PProc, n: PNode, typ: PType, r: var TCompRes) =
|
||||
let s = n.sym
|
||||
if s.loc.r == nil: internalError(p.config, n.info, "genAddr: 3")
|
||||
case s.kind
|
||||
of skParam:
|
||||
r.res = s.loc.r
|
||||
r.address = nil
|
||||
r.typ = etyNone
|
||||
of skVar, skLet, skResult:
|
||||
r.kind = resExpr
|
||||
let jsType = mapType(p):
|
||||
if typ.isNil:
|
||||
n.typ
|
||||
else:
|
||||
# 'var openArray' for instance produces an 'addr' but this is harmless:
|
||||
gen(p, n[0], r)
|
||||
#internalError(p.config, n.info, "genAddr: 4 " & renderTree(n))
|
||||
else: internalError(p.config, n.info, $("genAddr: 2", s.kind))
|
||||
of nkCheckedFieldExpr:
|
||||
genCheckedFieldOp(p, n[0], n.typ, r)
|
||||
of nkDotExpr:
|
||||
if mapType(p, n.typ) == etyBaseIndex:
|
||||
genFieldAddr(p, n[0], r)
|
||||
typ
|
||||
if jsType == etyObject:
|
||||
# make addr() a no-op:
|
||||
r.typ = etyNone
|
||||
if isIndirect(s):
|
||||
r.res = s.loc.r & "[0]"
|
||||
else:
|
||||
r.res = s.loc.r
|
||||
r.address = nil
|
||||
elif {sfGlobal, sfAddrTaken} * s.flags != {} or jsType == etyBaseIndex:
|
||||
# for ease of code generation, we do not distinguish between
|
||||
# sfAddrTaken and sfGlobal.
|
||||
r.typ = etyBaseIndex
|
||||
r.address = s.loc.r
|
||||
r.res = rope("0")
|
||||
else:
|
||||
genFieldAccess(p, n[0], r)
|
||||
of nkBracketExpr:
|
||||
var ty = skipTypes(n[0].typ, abstractVarRange)
|
||||
if ty.kind in MappedToObject:
|
||||
gen(p, n[0], r)
|
||||
else:
|
||||
let kindOfIndexedExpr = skipTypes(n[0][0].typ, abstractVarRange).kind
|
||||
case kindOfIndexedExpr
|
||||
of tyArray, tyOpenArray, tySequence, tyString, tyCstring, tyVarargs:
|
||||
genArrayAddr(p, n[0], r)
|
||||
of tyTuple:
|
||||
genFieldAddr(p, n[0], r)
|
||||
else: internalError(p.config, n[0].info, "expr(nkBracketExpr, " & $kindOfIndexedExpr & ')')
|
||||
of nkObjDownConv:
|
||||
gen(p, n[0], r)
|
||||
of nkHiddenDeref:
|
||||
gen(p, n[0], r)
|
||||
of nkHiddenAddr:
|
||||
gen(p, n[0], r)
|
||||
of nkStmtListExpr:
|
||||
if n.len == 1: gen(p, n[0], r)
|
||||
else: internalError(p.config, n[0].info, "genAddr for complex nkStmtListExpr")
|
||||
of nkCallKinds:
|
||||
if n[0].typ.kind == tyOpenArray:
|
||||
# 'var openArray' for instance produces an 'addr' but this is harmless:
|
||||
# namely toOpenArray(a, 1, 3)
|
||||
gen(p, n, r)
|
||||
#internalError(p.config, n.info, "genAddr: 4 " & renderTree(n))
|
||||
else: internalError(p.config, n.info, $("genAddr: 2", s.kind))
|
||||
|
||||
proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||
if n.kind == nkSym:
|
||||
genSymAddr(p, n, nil, r)
|
||||
else:
|
||||
case n[0].kind
|
||||
of nkSym:
|
||||
genSymAddr(p, n[0], n.typ, r)
|
||||
of nkCheckedFieldExpr:
|
||||
genCheckedFieldOp(p, n[0], n.typ, r)
|
||||
of nkDotExpr:
|
||||
if mapType(p, n.typ) == etyBaseIndex:
|
||||
genFieldAddr(p, n[0], r)
|
||||
else:
|
||||
genFieldAccess(p, n[0], r)
|
||||
of nkBracketExpr:
|
||||
var ty = skipTypes(n[0].typ, abstractVarRange)
|
||||
if ty.kind in MappedToObject:
|
||||
gen(p, n[0], r)
|
||||
else:
|
||||
let kindOfIndexedExpr = skipTypes(n[0][0].typ, abstractVarRange).kind
|
||||
case kindOfIndexedExpr
|
||||
of tyArray, tyOpenArray, tySequence, tyString, tyCstring, tyVarargs:
|
||||
genArrayAddr(p, n[0], r)
|
||||
of tyTuple:
|
||||
genFieldAddr(p, n[0], r)
|
||||
of tyGenericBody:
|
||||
genAddr(p, n[^1], r)
|
||||
else: internalError(p.config, n[0].info, "expr(nkBracketExpr, " & $kindOfIndexedExpr & ')')
|
||||
of nkObjDownConv:
|
||||
gen(p, n[0], r)
|
||||
of nkHiddenDeref:
|
||||
gen(p, n[0], r)
|
||||
of nkHiddenAddr:
|
||||
gen(p, n[0], r)
|
||||
of nkConv:
|
||||
genAddr(p, n[0], r)
|
||||
of nkStmtListExpr:
|
||||
if n.len == 1: gen(p, n[0], r)
|
||||
else: internalError(p.config, n[0].info, "genAddr for complex nkStmtListExpr")
|
||||
of nkCallKinds:
|
||||
if n[0].typ.kind == tyOpenArray:
|
||||
# 'var openArray' for instance produces an 'addr' but this is harmless:
|
||||
# namely toOpenArray(a, 1, 3)
|
||||
gen(p, n[0], r)
|
||||
else:
|
||||
internalError(p.config, n[0].info, "genAddr: " & $n[0].kind)
|
||||
else:
|
||||
internalError(p.config, n[0].info, "genAddr: " & $n[0].kind)
|
||||
else:
|
||||
internalError(p.config, n[0].info, "genAddr: " & $n[0].kind)
|
||||
|
||||
proc attachProc(p: PProc; content: Rope; s: PSym) =
|
||||
p.g.code.add(content)
|
||||
@@ -2379,6 +2392,7 @@ proc optionalLine(p: Rope): Rope =
|
||||
return p & "\L"
|
||||
|
||||
proc genProc(oldProc: PProc, prc: PSym): Rope =
|
||||
## Generate a JS procedure ('function').
|
||||
var
|
||||
resultSym: PSym
|
||||
a: TCompRes
|
||||
@@ -2393,18 +2407,17 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
|
||||
if prc.typ[0] != nil and sfPure notin prc.flags:
|
||||
resultSym = prc.ast[resultPos].sym
|
||||
let mname = mangleName(p.module, resultSym)
|
||||
# otherwise uses "fat pointers"
|
||||
let useRawPointer = not isIndirect(resultSym) and
|
||||
let returnAddress = not isIndirect(resultSym) and
|
||||
resultSym.typ.kind in {tyVar, tyPtr, tyLent, tyRef, tyOwned} and
|
||||
mapType(p, resultSym.typ) == etyBaseIndex
|
||||
if useRawPointer:
|
||||
if returnAddress:
|
||||
resultAsgn = p.indentLine(("var $# = null;$n") % [mname])
|
||||
resultAsgn.add p.indentLine("var $#_Idx = 0;$n" % [mname])
|
||||
else:
|
||||
let resVar = createVar(p, resultSym.typ, isIndirect(resultSym))
|
||||
resultAsgn = p.indentLine(("var $# = $#;$n") % [mname, resVar])
|
||||
gen(p, prc.ast[resultPos], a)
|
||||
if mapType(p, resultSym.typ) == etyBaseIndex:
|
||||
if returnAddress:
|
||||
returnStmt = "return [$#, $#];$n" % [a.address, a.res]
|
||||
else:
|
||||
returnStmt = "return $#;$n" % [a.res]
|
||||
@@ -2661,6 +2674,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||
else: internalError(p.config, n.info, "gen: unknown node type: " & $n.kind)
|
||||
|
||||
proc newModule(g: ModuleGraph; module: PSym): BModule =
|
||||
## Create a new JS backend module node.
|
||||
new(result)
|
||||
result.module = module
|
||||
result.sigConflicts = initCountTable[SigHash]()
|
||||
@@ -2672,6 +2686,7 @@ proc newModule(g: ModuleGraph; module: PSym): BModule =
|
||||
PGlobals(g.backend).inSystem = true
|
||||
|
||||
proc genHeader(): Rope =
|
||||
## Generate the JS header.
|
||||
result = rope("""/* Generated by the Nim Compiler v$1 */
|
||||
var framePtr = null;
|
||||
var excHandler = 0;
|
||||
@@ -2702,6 +2717,8 @@ proc addHcrInitGuards(p: PProc, n: PNode,
|
||||
genStmt(p, n)
|
||||
|
||||
proc genModule(p: PProc, n: PNode) =
|
||||
## Generate the JS module code.
|
||||
## Called for each top level node in a Nim module.
|
||||
if optStackTrace in p.options:
|
||||
p.body.add(frameCreate(p,
|
||||
makeJSString("module " & p.module.module.name.s),
|
||||
@@ -2712,7 +2729,7 @@ proc genModule(p: PProc, n: PNode) =
|
||||
if p.config.hcrOn and n.kind == nkStmtList:
|
||||
let moduleSym = p.module.module
|
||||
var moduleLoadedVar = rope(moduleSym.name.s) & "_loaded" &
|
||||
idOrSig(moduleSym, moduleSym.name.s, p.module.sigConflicts, p.config)
|
||||
idOrSig(moduleSym, moduleSym.name.s, p.module.sigConflicts)
|
||||
lineF(p, "var $1;$n", [moduleLoadedVar])
|
||||
var inGuardedBlock = false
|
||||
|
||||
@@ -2730,6 +2747,7 @@ proc genModule(p: PProc, n: PNode) =
|
||||
p.body.add(frameDestroy(p))
|
||||
|
||||
proc myProcess(b: PPassContext, n: PNode): PNode =
|
||||
## Generate JS code for a node.
|
||||
result = n
|
||||
let m = BModule(b)
|
||||
if passes.skipCodegen(m.config, n): return n
|
||||
@@ -2742,6 +2760,7 @@ proc myProcess(b: PPassContext, n: PNode): PNode =
|
||||
p.g.code.add(p.body)
|
||||
|
||||
proc wholeCode(graph: ModuleGraph; m: BModule): Rope =
|
||||
## Combine source code from all nodes.
|
||||
let globals = PGlobals(graph.backend)
|
||||
for prc in globals.forwarded:
|
||||
if not globals.generatedSyms.containsOrIncl(prc.id):
|
||||
@@ -2767,26 +2786,41 @@ proc getClassName(t: PType): Rope =
|
||||
else: result = rope(s.name.s)
|
||||
|
||||
proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
|
||||
result = myProcess(b, n)
|
||||
## Finalize JS code generation of a Nim module.
|
||||
## Param `n` may contain nodes returned from the last module close call.
|
||||
var m = BModule(b)
|
||||
if sfMainModule in m.module.flags:
|
||||
for destructorCall in graph.globalDestructors:
|
||||
n.add destructorCall
|
||||
# Add global destructors to the module.
|
||||
# This must come before the last call to `myProcess`.
|
||||
for i in countdown(high(graph.globalDestructors), 0):
|
||||
n.add graph.globalDestructors[i]
|
||||
# Process any nodes left over from the last call to `myClose`.
|
||||
result = myProcess(b, n)
|
||||
# Some codegen is different (such as no stacktraces; see `initProcOptions`)
|
||||
# when `std/system` is being processed.
|
||||
if sfSystemModule in m.module.flags:
|
||||
PGlobals(graph.backend).inSystem = false
|
||||
# Check if codegen should continue before any files are generated.
|
||||
# It may bail early is if too many errors have been raised.
|
||||
if passes.skipCodegen(m.config, n): return n
|
||||
# Nim modules are compiled into a single JS file.
|
||||
# If this is the main module, then this is the final call to `myClose`.
|
||||
if sfMainModule in m.module.flags:
|
||||
var code = genHeader() & wholeCode(graph, m)
|
||||
let outFile = m.config.prepareToWriteOutput()
|
||||
|
||||
# Generate an optional source map.
|
||||
if optSourcemap in m.config.globalOptions:
|
||||
var map: SourceMap
|
||||
(code, map) = genSourceMap($(code), outFile.string)
|
||||
writeFile(outFile.string & ".map", $(%map))
|
||||
discard writeRopeIfNotEqual(code, outFile)
|
||||
|
||||
# Check if the generated JS code matches the output file, or else
|
||||
# write it to the file.
|
||||
if not equalsFile(code, outFile):
|
||||
if not writeRope(code, outFile):
|
||||
rawMessage(m.config, errCannotOpenFile, outFile.string)
|
||||
|
||||
proc myOpen(graph: ModuleGraph; s: PSym; idgen: IdGenerator): PPassContext =
|
||||
## Create the JS backend pass context `BModule` for a Nim module.
|
||||
result = newModule(graph, s)
|
||||
result.idgen = idgen
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@ import
|
||||
idents, renderer, types, magicsys, lowerings, tables, modulegraphs, lineinfos,
|
||||
transf, liftdestructors, typeallowed
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
discard """
|
||||
The basic approach is that captured vars need to be put on the heap and
|
||||
that the calling chain needs to be explicitly modelled. Things to consider:
|
||||
@@ -285,7 +288,8 @@ proc markAsClosure(g: ModuleGraph; owner: PSym; n: PNode) =
|
||||
if illegalCapture(s):
|
||||
localError(g.config, n.info,
|
||||
("'$1' is of type <$2> which cannot be captured as it would violate memory" &
|
||||
" safety, declared here: $3; using '-d:nimNoLentIterators' helps in some cases") %
|
||||
" safety, declared here: $3; using '-d:nimNoLentIterators' helps in some cases." &
|
||||
" Consider using a <ref $2> which can be captured.") %
|
||||
[s.name.s, typeToString(s.typ), g.config$s.info])
|
||||
elif not (owner.typ.callConv == ccClosure or owner.typ.callConv == ccNimCall and tfExplicitCallConv notin owner.typ.flags):
|
||||
localError(g.config, n.info, "illegal capture '$1' because '$2' has the calling convention: <$3>" %
|
||||
|
||||
@@ -551,15 +551,11 @@ proc emitTok*(em: var Emitter; L: Lexer; tok: Token) =
|
||||
if not preventComment:
|
||||
emitComment(em, tok, dontIndent = false)
|
||||
of tkIntLit..tkStrLit, tkRStrLit, tkTripleStrLit, tkGStrLit, tkGTripleStrLit, tkCharLit:
|
||||
if not em.inquote:
|
||||
let lit = fileSection(em.config, em.fid, tok.offsetA, tok.offsetB)
|
||||
if endsInAlpha(em) and tok.tokType notin {tkGStrLit, tkGTripleStrLit}: wrSpace(em)
|
||||
em.lineSpan = countNewlines(lit)
|
||||
if em.lineSpan > 0: calcCol(em, lit)
|
||||
wr em, lit, ltLit
|
||||
else:
|
||||
if endsInAlpha(em): wrSpace(em)
|
||||
wr em, tok.literal, ltLit
|
||||
let lit = fileSection(em.config, em.fid, tok.offsetA, tok.offsetB)
|
||||
if endsInAlpha(em) and tok.tokType notin {tkGStrLit, tkGTripleStrLit}: wrSpace(em)
|
||||
em.lineSpan = countNewlines(lit)
|
||||
if em.lineSpan > 0: calcCol(em, lit)
|
||||
wr em, lit, ltLit
|
||||
of tkEof: discard
|
||||
else:
|
||||
let lit = if tok.ident != nil: tok.ident.s else: tok.literal
|
||||
|
||||
@@ -19,6 +19,9 @@ import
|
||||
hashes, options, msgs, strutils, platform, idents, nimlexbase, llstream,
|
||||
wordrecg, lineinfos, pathutils, parseutils
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
const
|
||||
MaxLineLength* = 80 # lines longer than this lead to a warning
|
||||
numChars*: set[char] = {'0'..'9', 'a'..'z', 'A'..'Z'}
|
||||
@@ -121,8 +124,6 @@ type
|
||||
cache*: IdentCache
|
||||
when defined(nimsuggest):
|
||||
previousToken: TLineInfo
|
||||
tokenEnd*: TLineInfo
|
||||
previousTokenEnd*: TLineInfo
|
||||
config*: ConfigRef
|
||||
|
||||
proc getLineInfo*(L: Lexer, tok: Token): TLineInfo {.inline.} =
|
||||
@@ -914,7 +915,7 @@ proc getSymbol(L: var Lexer, tok: var Token) =
|
||||
else: break
|
||||
tokenEnd(tok, pos-1)
|
||||
h = !$h
|
||||
tok.ident = L.cache.getIdent(cast[cstring](addr(L.buf[L.bufpos])), pos - L.bufpos, h)
|
||||
tok.ident = L.cache.getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h)
|
||||
if (tok.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or
|
||||
(tok.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)):
|
||||
tok.tokType = tkSymbol
|
||||
@@ -928,7 +929,7 @@ proc getSymbol(L: var Lexer, tok: var Token) =
|
||||
proc endOperator(L: var Lexer, tok: var Token, pos: int,
|
||||
hash: Hash) {.inline.} =
|
||||
var h = !$hash
|
||||
tok.ident = L.cache.getIdent(cast[cstring](addr(L.buf[L.bufpos])), pos - L.bufpos, h)
|
||||
tok.ident = L.cache.getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h)
|
||||
if (tok.ident.id < oprLow) or (tok.ident.id > oprHigh): tok.tokType = tkOpr
|
||||
else: tok.tokType = TokType(tok.ident.id - oprLow + ord(tkColon))
|
||||
L.bufpos = pos
|
||||
@@ -1218,10 +1219,6 @@ proc skip(L: var Lexer, tok: var Token) =
|
||||
proc rawGetTok*(L: var Lexer, tok: var Token) =
|
||||
template atTokenEnd() {.dirty.} =
|
||||
when defined(nimsuggest):
|
||||
L.previousTokenEnd.line = L.tokenEnd.line
|
||||
L.previousTokenEnd.col = L.tokenEnd.col
|
||||
L.tokenEnd.line = tok.line.uint16
|
||||
L.tokenEnd.col = getColNumber(L, L.bufpos).int16
|
||||
# we attach the cursor to the last *strong* token
|
||||
if tok.tokType notin weakTokens:
|
||||
L.previousToken.line = tok.line.uint16
|
||||
|
||||
@@ -15,6 +15,9 @@ import modulegraphs, lineinfos, idents, ast, renderer, semdata,
|
||||
|
||||
from trees import isCaseObj
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
TLiftCtx = object
|
||||
g: ModuleGraph
|
||||
@@ -162,12 +165,9 @@ proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode; enforceDefaultOp: bool)
|
||||
# the value needs to be destroyed before we assign the selector
|
||||
# or the value is lost
|
||||
let prevKind = c.kind
|
||||
let prevAddMemReset = c.addMemReset
|
||||
c.kind = attachedDestructor
|
||||
c.addMemReset = true
|
||||
fillBodyObj(c, n, body, x, y, enforceDefaultOp = false)
|
||||
c.kind = prevKind
|
||||
c.addMemReset = prevAddMemReset
|
||||
localEnforceDefaultOp = true
|
||||
|
||||
if c.kind != attachedDestructor:
|
||||
@@ -528,7 +528,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
# operation here:
|
||||
var t = t
|
||||
if t.assignment == nil or t.destructor == nil:
|
||||
let h = sighashes.hashType(t,c.g.config, {CoType, CoConsiderOwned, CoDistinct})
|
||||
let h = sighashes.hashType(t, {CoType, CoConsiderOwned, CoDistinct})
|
||||
let canon = c.g.canonTypes.getOrDefault(h)
|
||||
if canon != nil: t = canon
|
||||
|
||||
@@ -1072,7 +1072,7 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
|
||||
let skipped = orig.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||
if isEmptyContainer(skipped) or skipped.kind == tyStatic: return
|
||||
|
||||
let h = sighashes.hashType(skipped, g.config, {CoType, CoConsiderOwned, CoDistinct})
|
||||
let h = sighashes.hashType(skipped, {CoType, CoConsiderOwned, CoDistinct})
|
||||
var canon = g.canonTypes.getOrDefault(h)
|
||||
if canon == nil:
|
||||
g.canonTypes[h] = skipped
|
||||
|
||||
@@ -34,6 +34,7 @@ type
|
||||
errXExpected,
|
||||
errRstGridTableNotImplemented,
|
||||
errRstMarkdownIllformedTable,
|
||||
errRstIllformedTable,
|
||||
errRstNewSectionExpected,
|
||||
errRstGeneralParseError,
|
||||
errRstInvalidDirectiveX,
|
||||
@@ -51,6 +52,7 @@ type
|
||||
warnSmallLshouldNotBeUsed = "SmallLshouldNotBeUsed", warnUnknownMagic = "UnknownMagic",
|
||||
warnRstRedefinitionOfLabel = "RedefinitionOfLabel",
|
||||
warnRstUnknownSubstitutionX = "UnknownSubstitutionX",
|
||||
warnRstAmbiguousLink = "AmbiguousLink",
|
||||
warnRstBrokenLink = "BrokenLink",
|
||||
warnRstLanguageXNotSupported = "LanguageXNotSupported",
|
||||
warnRstFieldXNotSupported = "FieldXNotSupported",
|
||||
@@ -76,9 +78,8 @@ type
|
||||
warnAnyEnumConv = "AnyEnumConv",
|
||||
warnHoleEnumConv = "HoleEnumConv",
|
||||
warnCstringConv = "CStringConv",
|
||||
warnPtrToCstringConv = "PtrToCstringConv",
|
||||
warnNoInitIgnored = "NoInitIgnored"
|
||||
warnEffect = "Effect",
|
||||
warnBareExcept = "BareExcept",
|
||||
warnUser = "User",
|
||||
# hints
|
||||
hintSuccess = "Success", hintSuccessX = "SuccessX",
|
||||
@@ -107,6 +108,7 @@ const
|
||||
errXExpected: "'$1' expected",
|
||||
errRstGridTableNotImplemented: "grid table is not implemented",
|
||||
errRstMarkdownIllformedTable: "illformed delimiter row of a markdown table",
|
||||
errRstIllformedTable: "Illformed table: $1",
|
||||
errRstNewSectionExpected: "new section expected $1",
|
||||
errRstGeneralParseError: "general parse error",
|
||||
errRstInvalidDirectiveX: "invalid directive: '$1'",
|
||||
@@ -127,6 +129,7 @@ const
|
||||
warnUnknownMagic: "unknown magic '$1' might crash the compiler",
|
||||
warnRstRedefinitionOfLabel: "redefinition of label '$1'",
|
||||
warnRstUnknownSubstitutionX: "unknown substitution '$1'",
|
||||
warnRstAmbiguousLink: "ambiguous doc link $1",
|
||||
warnRstBrokenLink: "broken link '$1'",
|
||||
warnRstLanguageXNotSupported: "language '$1' not supported",
|
||||
warnRstFieldXNotSupported: "field '$1' not supported",
|
||||
@@ -168,9 +171,8 @@ const
|
||||
warnAnyEnumConv: "$1",
|
||||
warnHoleEnumConv: "$1",
|
||||
warnCstringConv: "$1",
|
||||
warnPtrToCstringConv: "unsafe conversion to 'cstring' from '$1'; this will become a compile time error in the future",
|
||||
warnNoInitIgnored: "noinit pragma is ignored",
|
||||
warnEffect: "$1",
|
||||
warnBareExcept: "$1",
|
||||
warnUser: "$1",
|
||||
hintSuccess: "operation successful: $#",
|
||||
# keep in sync with `testament.isSuccess`
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
import std/strutils
|
||||
from std/sugar import dup
|
||||
|
||||
import options, ast, msgs, idents, lineinfos, wordrecg, astmsgs, semdata, packages
|
||||
export packages
|
||||
import options, ast, msgs, idents, lineinfos, wordrecg, astmsgs
|
||||
|
||||
const
|
||||
Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'}
|
||||
@@ -86,33 +85,24 @@ proc differ*(line: string, a, b: int, x: string): string =
|
||||
result = y
|
||||
|
||||
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:
|
||||
lintReport(conf, info, beau, s.name.s)
|
||||
|
||||
template styleCheckDef*(ctx: PContext; info: TLineInfo; sym: PSym; k: TSymKind) =
|
||||
## Check symbol definitions adhere to NEP1 style rules.
|
||||
if optStyleCheck in ctx.config.options and # ignore if styleChecks are off
|
||||
{optStyleHint, optStyleError} * ctx.config.globalOptions != {} and # check only if hint/error is enabled
|
||||
hintName in ctx.config.notes and # ignore if name checks are not requested
|
||||
ctx.config.belongsToProjectPackage(ctx.module) and # ignore foreign packages
|
||||
optStyleUsages notin ctx.config.globalOptions and # ignore if requested to only check name usage
|
||||
sym.kind != skResult and # ignore `result`
|
||||
sym.kind != skTemp and # ignore temporary variables created by the compiler
|
||||
sym.name.s[0] in Letters and # ignore operators TODO: what about unicode symbols???
|
||||
k notin {skType, skGenericParam} and # ignore types and generic params
|
||||
(sym.typ == nil or sym.typ.kind != tyTypeDesc) and # ignore `typedesc`
|
||||
{sfImportc, sfExportc} * sym.flags == {} and # ignore FFI
|
||||
sfAnon notin sym.flags: # ignore if created by compiler
|
||||
nep1CheckDefImpl(ctx.config, info, sym, k)
|
||||
template styleCheckDef*(conf: ConfigRef; info: TLineInfo; s: PSym; k: TSymKind) =
|
||||
if {optStyleHint, optStyleError} * conf.globalOptions != {} and optStyleUsages notin conf.globalOptions:
|
||||
nep1CheckDefImpl(conf, info, s, k)
|
||||
|
||||
template styleCheckDef*(ctx: PContext; info: TLineInfo; s: PSym) =
|
||||
## Check symbol definitions adhere to NEP1 style rules.
|
||||
styleCheckDef(ctx, info, s, s.kind)
|
||||
|
||||
template styleCheckDef*(ctx: PContext; s: PSym) =
|
||||
## Check symbol definitions adhere to NEP1 style rules.
|
||||
styleCheckDef(ctx, s.info, s, s.kind)
|
||||
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 differs(conf: ConfigRef; info: TLineInfo; newName: string): string =
|
||||
let line = sourceLine(conf, info)
|
||||
@@ -126,27 +116,23 @@ proc differs(conf: ConfigRef; info: TLineInfo; newName: string): string =
|
||||
let last = first+identLen(line, first)-1
|
||||
result = differ(line, first, last, newName)
|
||||
|
||||
proc styleCheckUseImpl(conf: ConfigRef; info: TLineInfo; s: PSym) =
|
||||
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 == skTemp or s.name.s[0] notin Letters or sfAnon in s.flags:
|
||||
return
|
||||
|
||||
let newName = s.name.s
|
||||
let badName = differs(conf, info, newName)
|
||||
if badName.len > 0:
|
||||
lintReport(conf, info, newName, badName, "".dup(addDeclaredLoc(conf, s)))
|
||||
# special rules for historical reasons
|
||||
let forceHint = badName == "nnkArgList" and newName == "nnkArglist" or badName == "nnkArglist" and newName == "nnkArgList"
|
||||
lintReport(conf, info, newName, badName, forceHint = forceHint, extraMsg = "".dup(addDeclaredLoc(conf, s)))
|
||||
|
||||
template styleCheckUse*(ctx: PContext; info: TLineInfo; sym: PSym) =
|
||||
## Check symbol uses match their definition's style.
|
||||
if {optStyleHint, optStyleError} * ctx.config.globalOptions != {} and # ignore if styleChecks are off
|
||||
hintName in ctx.config.notes and # ignore if name checks are not requested
|
||||
ctx.config.belongsToProjectPackage(ctx.module) and # ignore foreign packages
|
||||
sym.kind != skTemp and # ignore temporary variables created by the compiler
|
||||
sym.name.s[0] in Letters and # ignore operators TODO: what about unicode symbols???
|
||||
sfAnon notin sym.flags: # ignore temporary variables created by the compiler
|
||||
styleCheckUseImpl(ctx.config, info, sym)
|
||||
|
||||
proc checkPragmaUseImpl(conf: ConfigRef; info: TLineInfo; w: TSpecialWord; pragmaName: string) =
|
||||
proc checkPragmaUse*(conf: ConfigRef; info: TLineInfo; w: TSpecialWord; pragmaName: string) =
|
||||
let wanted = $w
|
||||
if pragmaName != wanted:
|
||||
lintReport(conf, info, wanted, pragmaName)
|
||||
|
||||
template checkPragmaUse*(conf: ConfigRef; info: TLineInfo; w: TSpecialWord; pragmaName: string) =
|
||||
if {optStyleHint, optStyleError} * conf.globalOptions != {}:
|
||||
checkPragmaUseImpl(conf, info, w, pragmaName)
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
import
|
||||
pathutils
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/syncio
|
||||
|
||||
# support `useGnuReadline`, `useLinenoise` for backwards compatibility
|
||||
const hasRstdin = (defined(nimUseLinenoise) or defined(useLinenoise) or defined(useGnuReadline)) and
|
||||
not defined(windows)
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
|
||||
# This module implements lookup helpers.
|
||||
import std/[algorithm, strutils]
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
import
|
||||
intsets, ast, astalgo, idents, semdata, types, msgs, options,
|
||||
renderer, nimfix/prettybase, lineinfos, modulegraphs, astmsgs
|
||||
@@ -44,11 +48,6 @@ proc considerQuotedIdent*(c: PContext; n: PNode, origin: PNode = nil): PIdent =
|
||||
case x.kind
|
||||
of nkIdent: id.add(x.ident.s)
|
||||
of nkSym: id.add(x.sym.name.s)
|
||||
of nkSymChoices:
|
||||
if x[0].kind == nkSym:
|
||||
id.add(x[0].sym.name.s)
|
||||
else:
|
||||
handleError(n, origin)
|
||||
of nkLiterals - nkFloatLiterals: id.add(x.renderTree)
|
||||
else: handleError(n, origin)
|
||||
result = getIdent(c.cache, id)
|
||||
|
||||
@@ -15,6 +15,9 @@ const
|
||||
import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs,
|
||||
lineinfos
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
proc newDeref*(n: PNode): PNode {.inline.} =
|
||||
result = newNodeIT(nkHiddenDeref, n.info, n.typ[0])
|
||||
result.add n
|
||||
|
||||
@@ -22,6 +22,10 @@ import
|
||||
modules,
|
||||
modulegraphs, lineinfos, pathutils, vmprofiler
|
||||
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions]
|
||||
|
||||
import ic / [cbackend, integrity, navigator]
|
||||
from ic / ic import rodViewer
|
||||
|
||||
@@ -61,6 +65,8 @@ proc commandCheck(graph: ModuleGraph) =
|
||||
if optWasNimscript in conf.globalOptions:
|
||||
defineSymbol(conf.symbols, "nimscript")
|
||||
defineSymbol(conf.symbols, "nimconfig")
|
||||
elif conf.backend == backendJs:
|
||||
setTarget(conf.target, osJS, cpuJS)
|
||||
semanticPasses(graph) # use an empty backend for semantic checking only
|
||||
compileProject(graph)
|
||||
|
||||
|
||||
297
compiler/md5_old.nim
Normal file
297
compiler/md5_old.nim
Normal file
@@ -0,0 +1,297 @@
|
||||
#
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# `std/md5` without VM and JavaScript support, to circumvent a bug with
|
||||
# openarrays on Nim < 1.4.
|
||||
|
||||
when defined(nimHasStyleChecks):
|
||||
{.push styleChecks: off.}
|
||||
|
||||
type
|
||||
MD5State = array[0..3, uint32]
|
||||
MD5Block = array[0..15, uint32]
|
||||
MD5CBits = array[0..7, uint8]
|
||||
MD5Digest* = array[0..15, uint8]
|
||||
## MD5 checksum of a string, obtained with the `toMD5 proc <#toMD5,string>`_.
|
||||
MD5Buffer = array[0..63, uint8]
|
||||
MD5Context* {.final.} = object
|
||||
state: MD5State
|
||||
count: array[0..1, uint32]
|
||||
buffer: MD5Buffer
|
||||
|
||||
const
|
||||
padding: array[0..63, uint8] = [
|
||||
0x80'u8, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
|
||||
proc F(x, y, z: uint32): uint32 {.inline.} =
|
||||
result = (x and y) or ((not x) and z)
|
||||
|
||||
proc G(x, y, z: uint32): uint32 {.inline.} =
|
||||
result = (x and z) or (y and (not z))
|
||||
|
||||
proc H(x, y, z: uint32): uint32 {.inline.} =
|
||||
result = x xor y xor z
|
||||
|
||||
proc I(x, y, z: uint32): uint32 {.inline.} =
|
||||
result = y xor (x or (not z))
|
||||
|
||||
proc rot(x: var uint32, n: uint8) {.inline.} =
|
||||
x = (x shl n) or (x shr (32'u32 - n))
|
||||
|
||||
proc FF(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
|
||||
a = a + F(b, c, d) + x + ac
|
||||
rot(a, s)
|
||||
a = a + b
|
||||
|
||||
proc GG(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
|
||||
a = a + G(b, c, d) + x + ac
|
||||
rot(a, s)
|
||||
a = a + b
|
||||
|
||||
proc HH(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
|
||||
a = a + H(b, c, d) + x + ac
|
||||
rot(a, s)
|
||||
a = a + b
|
||||
|
||||
proc II(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
|
||||
a = a + I(b, c, d) + x + ac
|
||||
rot(a, s)
|
||||
a = a + b
|
||||
|
||||
proc encode(dest: var MD5Block, src: openArray[uint8]) =
|
||||
var j = 0
|
||||
for i in 0..high(dest):
|
||||
dest[i] = uint32(ord(src[j])) or
|
||||
uint32(ord(src[j+1])) shl 8 or
|
||||
uint32(ord(src[j+2])) shl 16 or
|
||||
uint32(ord(src[j+3])) shl 24
|
||||
inc(j, 4)
|
||||
|
||||
proc decode(dest: var openArray[uint8], src: openArray[uint32]) =
|
||||
var i = 0
|
||||
for j in 0..high(src):
|
||||
dest[i] = uint8(src[j] and 0xff'u32)
|
||||
dest[i+1] = uint8(src[j] shr 8 and 0xff'u32)
|
||||
dest[i+2] = uint8(src[j] shr 16 and 0xff'u32)
|
||||
dest[i+3] = uint8(src[j] shr 24 and 0xff'u32)
|
||||
inc(i, 4)
|
||||
|
||||
template slice(s: string | cstring, a, b): openArray[uint8] =
|
||||
s.toOpenArrayByte(a, b)
|
||||
|
||||
template slice(s: openArray[uint8], a, b): openArray[uint8] =
|
||||
s.toOpenArray(a, b)
|
||||
|
||||
proc transform(buffer: openArray[uint8], state: var MD5State) =
|
||||
var
|
||||
myBlock: MD5Block
|
||||
encode(myBlock, buffer)
|
||||
var a = state[0]
|
||||
var b = state[1]
|
||||
var c = state[2]
|
||||
var d = state[3]
|
||||
FF(a, b, c, d, myBlock[0], 7'u8, 0xD76AA478'u32)
|
||||
FF(d, a, b, c, myBlock[1], 12'u8, 0xE8C7B756'u32)
|
||||
FF(c, d, a, b, myBlock[2], 17'u8, 0x242070DB'u32)
|
||||
FF(b, c, d, a, myBlock[3], 22'u8, 0xC1BDCEEE'u32)
|
||||
FF(a, b, c, d, myBlock[4], 7'u8, 0xF57C0FAF'u32)
|
||||
FF(d, a, b, c, myBlock[5], 12'u8, 0x4787C62A'u32)
|
||||
FF(c, d, a, b, myBlock[6], 17'u8, 0xA8304613'u32)
|
||||
FF(b, c, d, a, myBlock[7], 22'u8, 0xFD469501'u32)
|
||||
FF(a, b, c, d, myBlock[8], 7'u8, 0x698098D8'u32)
|
||||
FF(d, a, b, c, myBlock[9], 12'u8, 0x8B44F7AF'u32)
|
||||
FF(c, d, a, b, myBlock[10], 17'u8, 0xFFFF5BB1'u32)
|
||||
FF(b, c, d, a, myBlock[11], 22'u8, 0x895CD7BE'u32)
|
||||
FF(a, b, c, d, myBlock[12], 7'u8, 0x6B901122'u32)
|
||||
FF(d, a, b, c, myBlock[13], 12'u8, 0xFD987193'u32)
|
||||
FF(c, d, a, b, myBlock[14], 17'u8, 0xA679438E'u32)
|
||||
FF(b, c, d, a, myBlock[15], 22'u8, 0x49B40821'u32)
|
||||
GG(a, b, c, d, myBlock[1], 5'u8, 0xF61E2562'u32)
|
||||
GG(d, a, b, c, myBlock[6], 9'u8, 0xC040B340'u32)
|
||||
GG(c, d, a, b, myBlock[11], 14'u8, 0x265E5A51'u32)
|
||||
GG(b, c, d, a, myBlock[0], 20'u8, 0xE9B6C7AA'u32)
|
||||
GG(a, b, c, d, myBlock[5], 5'u8, 0xD62F105D'u32)
|
||||
GG(d, a, b, c, myBlock[10], 9'u8, 0x02441453'u32)
|
||||
GG(c, d, a, b, myBlock[15], 14'u8, 0xD8A1E681'u32)
|
||||
GG(b, c, d, a, myBlock[4], 20'u8, 0xE7D3FBC8'u32)
|
||||
GG(a, b, c, d, myBlock[9], 5'u8, 0x21E1CDE6'u32)
|
||||
GG(d, a, b, c, myBlock[14], 9'u8, 0xC33707D6'u32)
|
||||
GG(c, d, a, b, myBlock[3], 14'u8, 0xF4D50D87'u32)
|
||||
GG(b, c, d, a, myBlock[8], 20'u8, 0x455A14ED'u32)
|
||||
GG(a, b, c, d, myBlock[13], 5'u8, 0xA9E3E905'u32)
|
||||
GG(d, a, b, c, myBlock[2], 9'u8, 0xFCEFA3F8'u32)
|
||||
GG(c, d, a, b, myBlock[7], 14'u8, 0x676F02D9'u32)
|
||||
GG(b, c, d, a, myBlock[12], 20'u8, 0x8D2A4C8A'u32)
|
||||
HH(a, b, c, d, myBlock[5], 4'u8, 0xFFFA3942'u32)
|
||||
HH(d, a, b, c, myBlock[8], 11'u8, 0x8771F681'u32)
|
||||
HH(c, d, a, b, myBlock[11], 16'u8, 0x6D9D6122'u32)
|
||||
HH(b, c, d, a, myBlock[14], 23'u8, 0xFDE5380C'u32)
|
||||
HH(a, b, c, d, myBlock[1], 4'u8, 0xA4BEEA44'u32)
|
||||
HH(d, a, b, c, myBlock[4], 11'u8, 0x4BDECFA9'u32)
|
||||
HH(c, d, a, b, myBlock[7], 16'u8, 0xF6BB4B60'u32)
|
||||
HH(b, c, d, a, myBlock[10], 23'u8, 0xBEBFBC70'u32)
|
||||
HH(a, b, c, d, myBlock[13], 4'u8, 0x289B7EC6'u32)
|
||||
HH(d, a, b, c, myBlock[0], 11'u8, 0xEAA127FA'u32)
|
||||
HH(c, d, a, b, myBlock[3], 16'u8, 0xD4EF3085'u32)
|
||||
HH(b, c, d, a, myBlock[6], 23'u8, 0x04881D05'u32)
|
||||
HH(a, b, c, d, myBlock[9], 4'u8, 0xD9D4D039'u32)
|
||||
HH(d, a, b, c, myBlock[12], 11'u8, 0xE6DB99E5'u32)
|
||||
HH(c, d, a, b, myBlock[15], 16'u8, 0x1FA27CF8'u32)
|
||||
HH(b, c, d, a, myBlock[2], 23'u8, 0xC4AC5665'u32)
|
||||
II(a, b, c, d, myBlock[0], 6'u8, 0xF4292244'u32)
|
||||
II(d, a, b, c, myBlock[7], 10'u8, 0x432AFF97'u32)
|
||||
II(c, d, a, b, myBlock[14], 15'u8, 0xAB9423A7'u32)
|
||||
II(b, c, d, a, myBlock[5], 21'u8, 0xFC93A039'u32)
|
||||
II(a, b, c, d, myBlock[12], 6'u8, 0x655B59C3'u32)
|
||||
II(d, a, b, c, myBlock[3], 10'u8, 0x8F0CCC92'u32)
|
||||
II(c, d, a, b, myBlock[10], 15'u8, 0xFFEFF47D'u32)
|
||||
II(b, c, d, a, myBlock[1], 21'u8, 0x85845DD1'u32)
|
||||
II(a, b, c, d, myBlock[8], 6'u8, 0x6FA87E4F'u32)
|
||||
II(d, a, b, c, myBlock[15], 10'u8, 0xFE2CE6E0'u32)
|
||||
II(c, d, a, b, myBlock[6], 15'u8, 0xA3014314'u32)
|
||||
II(b, c, d, a, myBlock[13], 21'u8, 0x4E0811A1'u32)
|
||||
II(a, b, c, d, myBlock[4], 6'u8, 0xF7537E82'u32)
|
||||
II(d, a, b, c, myBlock[11], 10'u8, 0xBD3AF235'u32)
|
||||
II(c, d, a, b, myBlock[2], 15'u8, 0x2AD7D2BB'u32)
|
||||
II(b, c, d, a, myBlock[9], 21'u8, 0xEB86D391'u32)
|
||||
state[0] = state[0] + a
|
||||
state[1] = state[1] + b
|
||||
state[2] = state[2] + c
|
||||
state[3] = state[3] + d
|
||||
|
||||
proc md5Init*(c: var MD5Context) {.raises: [], tags: [], gcsafe.}
|
||||
proc md5Update*(c: var MD5Context, input: openArray[uint8]) {.raises: [],
|
||||
tags: [], gcsafe.}
|
||||
proc md5Final*(c: var MD5Context, digest: var MD5Digest) {.raises: [], tags: [], gcsafe.}
|
||||
|
||||
proc md5Update*(c: var MD5Context, input: cstring, len: int) {.raises: [],
|
||||
tags: [], gcsafe.} =
|
||||
## Updates the `MD5Context` with the `input` data of length `len`.
|
||||
##
|
||||
## If you use the `toMD5 proc <#toMD5,string>`_, there's no need to call this
|
||||
## function explicitly.
|
||||
md5Update(c, input.slice(0, len - 1))
|
||||
|
||||
|
||||
proc toMD5*(s: string): MD5Digest =
|
||||
## Computes the `MD5Digest` value for a string `s`.
|
||||
##
|
||||
## **See also:**
|
||||
## * `getMD5 proc <#getMD5,string>`_ which returns a string representation
|
||||
## of the `MD5Digest`
|
||||
## * `$ proc <#$,MD5Digest>`_ for converting MD5Digest to string
|
||||
runnableExamples:
|
||||
assert $toMD5("abc") == "900150983cd24fb0d6963f7d28e17f72"
|
||||
|
||||
var c: MD5Context
|
||||
md5Init(c)
|
||||
md5Update(c, s.slice(0, s.len - 1))
|
||||
md5Final(c, result)
|
||||
|
||||
proc `$`*(d: MD5Digest): string =
|
||||
## Converts a `MD5Digest` value into its string representation.
|
||||
const digits = "0123456789abcdef"
|
||||
result = ""
|
||||
for i in 0..15:
|
||||
add(result, digits[(d[i].int shr 4) and 0xF])
|
||||
add(result, digits[d[i].int and 0xF])
|
||||
|
||||
proc getMD5*(s: string): string =
|
||||
## Computes an MD5 value of `s` and returns its string representation.
|
||||
##
|
||||
## **See also:**
|
||||
## * `toMD5 proc <#toMD5,string>`_ which returns the `MD5Digest` of a string
|
||||
runnableExamples:
|
||||
assert getMD5("abc") == "900150983cd24fb0d6963f7d28e17f72"
|
||||
|
||||
var
|
||||
c: MD5Context
|
||||
d: MD5Digest
|
||||
md5Init(c)
|
||||
md5Update(c, s.slice(0, s.len - 1))
|
||||
md5Final(c, d)
|
||||
result = $d
|
||||
|
||||
proc `==`*(D1, D2: MD5Digest): bool =
|
||||
## Checks if two `MD5Digest` values are identical.
|
||||
for i in 0..15:
|
||||
if D1[i] != D2[i]: return false
|
||||
return true
|
||||
|
||||
|
||||
proc clearBuffer(c: var MD5Context) {.inline.} =
|
||||
zeroMem(addr(c.buffer), sizeof(MD5Buffer))
|
||||
|
||||
proc md5Init*(c: var MD5Context) =
|
||||
## Initializes an `MD5Context`.
|
||||
##
|
||||
## If you use the `toMD5 proc <#toMD5,string>`_, there's no need to call this
|
||||
## function explicitly.
|
||||
c.state[0] = 0x67452301'u32
|
||||
c.state[1] = 0xEFCDAB89'u32
|
||||
c.state[2] = 0x98BADCFE'u32
|
||||
c.state[3] = 0x10325476'u32
|
||||
c.count[0] = 0'u32
|
||||
c.count[1] = 0'u32
|
||||
clearBuffer(c)
|
||||
|
||||
proc writeBuffer(c: var MD5Context, index: int,
|
||||
input: openArray[uint8], inputIndex, len: int) {.inline.} =
|
||||
copyMem(addr(c.buffer[index]), unsafeAddr(input[inputIndex]), len)
|
||||
|
||||
proc md5Update*(c: var MD5Context, input: openArray[uint8]) =
|
||||
## Updates the `MD5Context` with the `input` data.
|
||||
##
|
||||
## If you use the `toMD5 proc <#toMD5,string>`_, there's no need to call this
|
||||
## function explicitly.
|
||||
var Index = int((c.count[0] shr 3) and 0x3F)
|
||||
c.count[0] = c.count[0] + (uint32(input.len) shl 3)
|
||||
if c.count[0] < (uint32(input.len) shl 3): c.count[1] = c.count[1] + 1'u32
|
||||
c.count[1] = c.count[1] + (uint32(input.len) shr 29)
|
||||
var PartLen = 64 - Index
|
||||
if input.len >= PartLen:
|
||||
writeBuffer(c, Index, input, 0, PartLen)
|
||||
transform(c.buffer, c.state)
|
||||
var i = PartLen
|
||||
while i + 63 < input.len:
|
||||
transform(input.slice(i, i + 63), c.state)
|
||||
inc(i, 64)
|
||||
if i < input.len:
|
||||
writeBuffer(c, 0, input, i, input.len - i)
|
||||
elif input.len > 0:
|
||||
writeBuffer(c, Index, input, 0, input.len)
|
||||
|
||||
proc md5Final*(c: var MD5Context, digest: var MD5Digest) =
|
||||
## Finishes the `MD5Context` and stores the result in `digest`.
|
||||
##
|
||||
## If you use the `toMD5 proc <#toMD5,string>`_, there's no need to call this
|
||||
## function explicitly.
|
||||
var
|
||||
Bits: MD5CBits
|
||||
PadLen: int
|
||||
decode(Bits, c.count)
|
||||
var Index = int((c.count[0] shr 3) and 0x3F)
|
||||
if Index < 56: PadLen = 56 - Index
|
||||
else: PadLen = 120 - Index
|
||||
md5Update(c, padding.slice(0, PadLen - 1))
|
||||
md5Update(c, Bits)
|
||||
decode(digest, c.state)
|
||||
clearBuffer(c)
|
||||
|
||||
|
||||
when defined(nimHasStyleChecks):
|
||||
{.pop.} #{.push styleChecks: off.}
|
||||
@@ -11,10 +11,13 @@
|
||||
## represents a complete Nim project. Single modules can either be kept in RAM
|
||||
## or stored in a rod-file.
|
||||
|
||||
import intsets, tables, hashes, md5, sequtils
|
||||
import intsets, tables, hashes, md5_old, sequtils
|
||||
import ast, astalgo, options, lineinfos,idents, btrees, ropes, msgs, pathutils, packages
|
||||
import ic / [packed_ast, ic]
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
SigHash* = distinct MD5Digest
|
||||
|
||||
@@ -50,10 +53,6 @@ type
|
||||
concreteTypes*: seq[FullId]
|
||||
inst*: PInstantiation
|
||||
|
||||
SymInfoPair* = object
|
||||
sym*: PSym
|
||||
info*: TLineInfo
|
||||
|
||||
ModuleGraph* {.acyclic.} = ref object
|
||||
ifaces*: seq[Iface] ## indexed by int32 fileIdx
|
||||
packed*: PackedModuleGraph
|
||||
@@ -84,7 +83,7 @@ type
|
||||
doStopCompile*: proc(): bool {.closure.}
|
||||
usageSym*: PSym # for nimsuggest
|
||||
owners*: seq[PSym]
|
||||
suggestSymbols*: Table[FileIndex, seq[SymInfoPair]]
|
||||
suggestSymbols*: Table[FileIndex, seq[tuple[sym: PSym, info: TLineInfo]]]
|
||||
suggestErrors*: Table[FileIndex, seq[Suggest]]
|
||||
methods*: seq[tuple[methods: seq[PSym], dispatcher: PSym]] # needs serialization!
|
||||
systemModule*: PSym
|
||||
@@ -373,13 +372,34 @@ template getPContext(): untyped =
|
||||
when c is PContext: c
|
||||
else: c.c
|
||||
|
||||
when defined(nimsuggest):
|
||||
template onUse*(info: TLineInfo; s: PSym) = discard
|
||||
template onDefResolveForward*(info: TLineInfo; s: PSym) = discard
|
||||
when defined(nimfind):
|
||||
template onUse*(info: TLineInfo; s: PSym) =
|
||||
let c = getPContext()
|
||||
if c.graph.onUsage != nil: c.graph.onUsage(c.graph, s, info)
|
||||
|
||||
template onDef*(info: TLineInfo; s: PSym) =
|
||||
let c = getPContext()
|
||||
if c.graph.onDefinition != nil: c.graph.onDefinition(c.graph, s, info)
|
||||
|
||||
template onDefResolveForward*(info: TLineInfo; s: PSym) =
|
||||
let c = getPContext()
|
||||
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
|
||||
when defined(nimsuggest):
|
||||
template onUse*(info: TLineInfo; s: PSym) = discard
|
||||
|
||||
template onDef*(info: TLineInfo; s: PSym) =
|
||||
let c = getPContext()
|
||||
if c.graph.config.suggestVersion == 3:
|
||||
suggestSym(c.graph, info, s, c.graph.usageSym)
|
||||
|
||||
template onDefResolveForward*(info: TLineInfo; s: PSym) = discard
|
||||
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()
|
||||
@@ -437,7 +457,7 @@ proc initModuleGraphFields(result: ModuleGraph) =
|
||||
result.importStack = @[]
|
||||
result.inclToMod = initTable[FileIndex, FileIndex]()
|
||||
result.owners = @[]
|
||||
result.suggestSymbols = initTable[FileIndex, seq[SymInfoPair]]()
|
||||
result.suggestSymbols = initTable[FileIndex, seq[tuple[sym: PSym, info: TLineInfo]]]()
|
||||
result.suggestErrors = initTable[FileIndex, seq[Suggest]]()
|
||||
result.methods = @[]
|
||||
initStrTable(result.compilerprocs)
|
||||
@@ -573,12 +593,7 @@ proc markClientsDirty*(g: ModuleGraph; fileIdx: FileIndex) =
|
||||
# every module that *depends* on this file is also dirty:
|
||||
for i in 0i32..<g.ifaces.len.int32:
|
||||
if g.deps.contains(i.dependsOn(fileIdx.int)):
|
||||
let
|
||||
fi = FileIndex(i)
|
||||
module = g.getModule(fi)
|
||||
if module != nil and not g.isDirty(module):
|
||||
g.markDirty(fi)
|
||||
g.markClientsDirty(fi)
|
||||
g.markDirty(FileIndex(i))
|
||||
|
||||
proc needsCompilation*(g: ModuleGraph): bool =
|
||||
# every module that *depends* on this file is also dirty:
|
||||
@@ -641,15 +656,9 @@ func belongsToStdlib*(graph: ModuleGraph, sym: PSym): bool =
|
||||
## Check if symbol belongs to the 'stdlib' package.
|
||||
sym.getPackageSymbol.getPackageId == graph.systemModule.getPackageId
|
||||
|
||||
proc `==`*(a, b: SymInfoPair): bool =
|
||||
result = a.sym == b.sym and a.info.exactEquals(b.info)
|
||||
|
||||
proc fileSymbols*(graph: ModuleGraph, fileIdx: FileIndex): seq[SymInfoPair] =
|
||||
result = graph.suggestSymbols.getOrDefault(fileIdx, @[])
|
||||
|
||||
iterator suggestSymbolsIter*(g: ModuleGraph): SymInfoPair =
|
||||
iterator suggestSymbolsIter*(g: ModuleGraph): tuple[sym: PSym, info: TLineInfo] =
|
||||
for xs in g.suggestSymbols.values:
|
||||
for x in xs:
|
||||
for x in xs.deduplicate:
|
||||
yield x
|
||||
|
||||
iterator suggestErrorsIter*(g: ModuleGraph): Suggest =
|
||||
|
||||
@@ -14,6 +14,9 @@ import
|
||||
idents, lexer, passes, syntaxes, llstream, modulegraphs,
|
||||
lineinfos, pathutils, tables, packages
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions]
|
||||
|
||||
import ic / replayer
|
||||
|
||||
proc resetSystemArtifacts*(g: ModuleGraph) =
|
||||
|
||||
@@ -12,6 +12,10 @@ import
|
||||
std/private/miscdollars,
|
||||
options, ropes, lineinfos, pathutils, strutils2
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions]
|
||||
|
||||
|
||||
type InstantiationInfo* = typeof(instantiationInfo())
|
||||
template instLoc*(): InstantiationInfo = instantiationInfo(-2, fullPaths = true)
|
||||
|
||||
@@ -123,13 +127,6 @@ proc fileInfoIdx*(conf: ConfigRef; filename: AbsoluteFile): FileIndex =
|
||||
var dummy: bool
|
||||
result = fileInfoIdx(conf, filename, dummy)
|
||||
|
||||
proc fileInfoIdx*(conf: ConfigRef; filename: RelativeFile; isKnownFile: var bool): FileIndex =
|
||||
fileInfoIdx(conf, AbsoluteFile expandFilename(filename.string), isKnownFile)
|
||||
|
||||
proc fileInfoIdx*(conf: ConfigRef; filename: RelativeFile): FileIndex =
|
||||
var dummy: bool
|
||||
fileInfoIdx(conf, AbsoluteFile expandFilename(filename.string), dummy)
|
||||
|
||||
proc newLineInfo*(fileInfoIdx: FileIndex, line, col: int): TLineInfo =
|
||||
result.fileIndex = fileInfoIdx
|
||||
if line < int high(uint16):
|
||||
@@ -625,9 +622,9 @@ template internalAssert*(conf: ConfigRef, e: bool) =
|
||||
let arg = info2.toFileLineCol
|
||||
internalErrorImpl(conf, unknownLineInfo, arg, info2)
|
||||
|
||||
template lintReport*(conf: ConfigRef; info: TLineInfo, beau, got: string, extraMsg = "") =
|
||||
template lintReport*(conf: ConfigRef; info: TLineInfo, beau, got: string, forceHint = false, extraMsg = "") =
|
||||
let m = "'$1' should be: '$2'$3" % [got, beau, extraMsg]
|
||||
let msg = if optStyleError in conf.globalOptions: errGenerated else: hintName
|
||||
let msg = if optStyleError in conf.globalOptions and not forceHint: errGenerated else: hintName
|
||||
liMessage(conf, info, msg, m, doNothing, instLoc())
|
||||
|
||||
proc quotedFilename*(conf: ConfigRef; i: TLineInfo): Rope =
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
import ast, msgs, ropes, options, pathutils
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions]
|
||||
|
||||
type
|
||||
NdiFile* = object
|
||||
enabled: bool
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
import ast, renderer, intsets, tables, msgs, options, lineinfos, strformat, idents, treetab, hashes
|
||||
import sequtils, strutils, sets
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
# IMPORTANT: notes not up to date, i'll update this comment again
|
||||
#
|
||||
# notes:
|
||||
|
||||
@@ -10,7 +10,6 @@ define:nimPreviewFloatRoundtrip
|
||||
|
||||
@if windows:
|
||||
cincludes: "$lib/wrappers/libffi/common"
|
||||
tlsEmulation:off
|
||||
@end
|
||||
|
||||
define:useStdoutAsStdmsg
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#
|
||||
|
||||
import std/[os, strutils, parseopt]
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
when defined(windows) and not defined(nimKochBootstrap):
|
||||
# remove workaround pending bootstrap >= 1.5.1
|
||||
# refs https://github.com/nim-lang/Nim/issues/18334#issuecomment-867114536
|
||||
@@ -37,15 +41,6 @@ when defined(profiler) or defined(memProfiler):
|
||||
{.hint: "Profiling support is turned on!".}
|
||||
import nimprof
|
||||
|
||||
proc nimbleLockExists(config: ConfigRef): bool =
|
||||
const nimbleLock = "nimble.lock"
|
||||
let pd = if not config.projectPath.isEmpty: config.projectPath else: AbsoluteDir(getCurrentDir())
|
||||
if optSkipParentConfigFiles notin config.globalOptions:
|
||||
for dir in parentDirs(pd.string, fromRoot=true, inclusive=false):
|
||||
if fileExists(dir / nimbleLock):
|
||||
return true
|
||||
return fileExists(pd.string / nimbleLock)
|
||||
|
||||
proc processCmdLine(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
|
||||
var p = parseopt.initOptParser(cmd)
|
||||
var argsCount = 0
|
||||
@@ -79,11 +74,6 @@ proc processCmdLine(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
|
||||
config.arguments.len > 0 and config.cmd notin {cmdTcc, cmdNimscript, cmdCrun}:
|
||||
rawMessage(config, errGenerated, errArgsNeedRunOption)
|
||||
|
||||
if config.nimbleLockExists:
|
||||
# disable nimble path if nimble.lock is present.
|
||||
# see https://github.com/nim-lang/nimble/issues/1004
|
||||
disableNimblePath(config)
|
||||
|
||||
proc getNimRunExe(conf: ConfigRef): string =
|
||||
# xxx consider defining `conf.getConfigVar("nimrun.exe")` to allow users to
|
||||
# customize the binary to run the command with, e.g. for custom `nodejs` or `wine`.
|
||||
@@ -130,7 +120,8 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
|
||||
if cmdPrefix.len > 0: cmdPrefix.add " "
|
||||
# without the `cmdPrefix.len > 0` check, on windows you'd get a cryptic:
|
||||
# `The parameter is incorrect`
|
||||
execExternalProgram(conf, cmdPrefix & output.quoteShell & ' ' & conf.arguments)
|
||||
let cmd = cmdPrefix & output.quoteShell & ' ' & conf.arguments
|
||||
execExternalProgram(conf, cmd.strip(leading=false,trailing=true))
|
||||
of cmdDocLike, cmdRst2html, cmdRst2tex: # bugfix(cmdRst2tex was missing)
|
||||
if conf.arguments.len > 0:
|
||||
# reserved for future use
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
import parseutils, strutils, os, options, msgs, sequtils, lineinfos, pathutils,
|
||||
std/sha1, tables
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions]
|
||||
|
||||
proc addPath*(conf: ConfigRef; path: AbsoluteDir, info: TLineInfo) =
|
||||
if not conf.searchPaths.contains(path):
|
||||
conf.searchPaths.insert(path, 0)
|
||||
|
||||
@@ -13,6 +13,9 @@ import
|
||||
llstream, commands, os, strutils, msgs, lexer, ast,
|
||||
options, idents, wordrecg, strtabs, lineinfos, pathutils, scriptconfig
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/syncio
|
||||
|
||||
# ---------------- configuration file parser -----------------------------
|
||||
# we use Nim's lexer here to save space and work
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
import
|
||||
llstream, strutils
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
const
|
||||
Lrz* = ' '
|
||||
Apo* = '\''
|
||||
|
||||
@@ -19,13 +19,19 @@ Unstable API
|
||||
|
||||
import os, strutils
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
|
||||
const
|
||||
docCss* = "$nimr/doc/nimdoc.css"
|
||||
docCls* = "$nimr/doc/nimdoc.cls"
|
||||
docHackNim* = "$nimr/tools/dochack/dochack.nim"
|
||||
docHackJs* = docHackNim.changeFileExt("js")
|
||||
docHackJsFname* = docHackJs.lastPathPart
|
||||
theindexFname* = "theindex.html"
|
||||
nimdocOutCss* = "nimdoc.out.css"
|
||||
nimdocOutCls* = "nimdoc.cls"
|
||||
# `out` to make it easier to use with gitignore in user's repos
|
||||
htmldocsDirname* = "htmldocs"
|
||||
dotdotMangle* = "_._" ## refs #13223
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
import
|
||||
ast, astalgo, lineinfos, bitsets, types, options
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
proc inSet*(s: PNode, elem: PNode): bool =
|
||||
assert s.kind == nkCurly
|
||||
if s.kind != nkCurly:
|
||||
|
||||
@@ -127,11 +127,11 @@ proc analyse(c: var Con; b: var BasicBlock; n: PNode) =
|
||||
for i in 0 ..< n.len:
|
||||
analyse(c, b, n[i])
|
||||
else:
|
||||
#[ Test tmatrix.test3:
|
||||
#[ Test destructor/tmatrix.test3:
|
||||
Prevent this from being elided. We should probably
|
||||
find a better solution...
|
||||
|
||||
`=sink`(b, - (
|
||||
`=sink`(b, -
|
||||
let blitTmp = b;
|
||||
wasMoved(b);
|
||||
blitTmp + a)
|
||||
|
||||
@@ -14,12 +14,17 @@ import
|
||||
from terminal import isatty
|
||||
from times import utc, fromUnix, local, getTime, format, DateTime
|
||||
from std/private/globs import nativeToUnixPath
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions]
|
||||
|
||||
|
||||
const
|
||||
hasTinyCBackend* = defined(tinyc)
|
||||
useEffectSystem* = true
|
||||
useWriteTracking* = false
|
||||
hasFFI* = defined(nimHasLibFFI)
|
||||
copyrightYear* = "2023"
|
||||
copyrightYear* = "2022"
|
||||
|
||||
nimEnableCovariance* = defined(nimEnableCovariance)
|
||||
|
||||
@@ -96,6 +101,7 @@ type # please make sure we have under 32 options
|
||||
optPanics # turn panics (sysFatal) into a process termination
|
||||
optNimV1Emulation # emulate Nim v1.0
|
||||
optNimV12Emulation # emulate Nim v1.2
|
||||
optNimV16Emulation # emulate Nim v1.6
|
||||
optSourcemap
|
||||
optProfileVM # enable VM profiler
|
||||
optEnableDeepCopy # ORC specific: enable 'deepcopy' for all types.
|
||||
@@ -177,7 +183,6 @@ type
|
||||
gcMarkAndSweep = "markAndSweep"
|
||||
gcHooks = "hooks"
|
||||
gcRefc = "refc"
|
||||
gcV2 = "v2"
|
||||
gcGo = "go"
|
||||
# gcRefc and the GCs that follow it use a write barrier,
|
||||
# as far as usesWriteBarrier() is concerned
|
||||
@@ -185,7 +190,7 @@ type
|
||||
IdeCmd* = enum
|
||||
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideChkFile, ideMod,
|
||||
ideHighlight, ideOutline, ideKnown, ideMsg, ideProject, ideGlobalSymbols,
|
||||
ideRecompile, ideChanged, ideType, ideDeclaration, ideExpand
|
||||
ideRecompile, ideChanged
|
||||
|
||||
Feature* = enum ## experimental features; DO NOT RENAME THESE!
|
||||
implicitDeref,
|
||||
@@ -196,7 +201,7 @@ type
|
||||
notnil,
|
||||
dynamicBindSym,
|
||||
forLoopMacros, # not experimental anymore; remains here for backwards compatibility
|
||||
caseStmtMacros,
|
||||
caseStmtMacros, # ditto
|
||||
codeReordering,
|
||||
compiletimeFFI,
|
||||
## This requires building nim with `-d:nimHasLibFFI`
|
||||
@@ -264,9 +269,6 @@ type
|
||||
scope*, localUsages*, globalUsages*: int # more usages is better
|
||||
tokenLen*: int
|
||||
version*: int
|
||||
endLine*: uint16
|
||||
endCol*: int
|
||||
|
||||
Suggestions* = seq[Suggest]
|
||||
|
||||
ProfileInfo* = object
|
||||
@@ -397,11 +399,6 @@ type
|
||||
nimMainPrefix*: string
|
||||
vmProfileData*: ProfileData
|
||||
|
||||
expandProgress*: bool
|
||||
expandLevels*: int
|
||||
expandNodeResult*: string
|
||||
expandPosition*: TLineInfo
|
||||
|
||||
proc parseNimVersion*(a: string): NimVer =
|
||||
# could be moved somewhere reusable
|
||||
if a.len > 0:
|
||||
@@ -855,7 +852,7 @@ when (NimMajor, NimMinor) < (1, 1) or not declared(isRelativeTo):
|
||||
let ret = relativePath(path, base)
|
||||
result = path.len > 0 and not ret.startsWith ".."
|
||||
|
||||
const stdlibDirs* = [
|
||||
const stdlibDirs = [
|
||||
"pure", "core", "arch",
|
||||
"pure/collections",
|
||||
"pure/concurrency",
|
||||
@@ -989,9 +986,6 @@ proc isDynlibOverride*(conf: ConfigRef; lib: string): bool =
|
||||
result = optDynlibOverrideAll in conf.globalOptions or
|
||||
conf.dllOverrides.hasKey(lib.canonDynlibName)
|
||||
|
||||
proc expandDone*(conf: ConfigRef): bool =
|
||||
result = conf.ideCmd == ideExpand and conf.expandLevels == 0 and conf.expandProgress
|
||||
|
||||
proc parseIdeCmd*(s: string): IdeCmd =
|
||||
case s:
|
||||
of "sug": ideSug
|
||||
@@ -1010,7 +1004,6 @@ proc parseIdeCmd*(s: string): IdeCmd =
|
||||
of "globalSymbols": ideGlobalSymbols
|
||||
of "recompile": ideRecompile
|
||||
of "changed": ideChanged
|
||||
of "type": ideType
|
||||
else: ideNone
|
||||
|
||||
proc `$`*(c: IdeCmd): string =
|
||||
@@ -1030,11 +1023,8 @@ proc `$`*(c: IdeCmd): string =
|
||||
of ideMsg: "msg"
|
||||
of ideProject: "project"
|
||||
of ideGlobalSymbols: "globalSymbols"
|
||||
of ideDeclaration: "declaration"
|
||||
of ideExpand: "expand"
|
||||
of ideRecompile: "recompile"
|
||||
of ideChanged: "changed"
|
||||
of ideType: "type"
|
||||
|
||||
proc floatInt64Align*(conf: ConfigRef): int16 =
|
||||
## Returns either 4 or 8 depending on reasons.
|
||||
|
||||
@@ -143,8 +143,11 @@ proc checkForSideEffects*(n: PNode): TSideEffectAnalysis =
|
||||
let s = op.sym
|
||||
if sfSideEffect in s.flags:
|
||||
return seSideEffect
|
||||
# assume no side effect:
|
||||
result = seNoSideEffect
|
||||
elif tfNoSideEffect in op.typ.flags:
|
||||
result = seNoSideEffect
|
||||
else:
|
||||
# assume side effect:
|
||||
result = seSideEffect
|
||||
elif tfNoSideEffect in op.typ.flags:
|
||||
# indirect call without side effects:
|
||||
result = seNoSideEffect
|
||||
@@ -176,6 +179,7 @@ type
|
||||
arLocalLValue, # is an l-value, but local var; must not escape
|
||||
# its stack frame!
|
||||
arDiscriminant, # is a discriminant
|
||||
arAddressableConst, # an addressable const
|
||||
arLentValue, # lent value
|
||||
arStrange # it is a strange beast like 'typedesc[var T]'
|
||||
|
||||
@@ -209,7 +213,7 @@ proc exprRoot*(n: PNode): PSym =
|
||||
else:
|
||||
break
|
||||
|
||||
proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult =
|
||||
proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
|
||||
## 'owner' can be nil!
|
||||
result = arNone
|
||||
case n.kind
|
||||
@@ -217,20 +221,20 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
|
||||
if n.typ != nil and n.typ.kind in {tyVar}:
|
||||
result = arLValue
|
||||
of nkSym:
|
||||
let kinds = if isUnsafeAddr: {skVar, skResult, skTemp, skParam, skLet, skForVar}
|
||||
else: {skVar, skResult, skTemp}
|
||||
if n.sym.kind == skParam and n.sym.typ.kind in {tyVar, tySink}:
|
||||
result = arLValue
|
||||
elif isUnsafeAddr and n.sym.kind == skParam:
|
||||
result = arLValue
|
||||
elif isUnsafeAddr and n.sym.kind == skConst and dontInlineConstant(n, n.sym.ast):
|
||||
result = arLValue
|
||||
const kinds = {skVar, skResult, skTemp, skParam, skLet, skForVar}
|
||||
if n.sym.kind == skParam:
|
||||
result = if n.sym.typ.kind in {tyVar, tySink}: arLValue else: arAddressableConst
|
||||
elif n.sym.kind == skConst and dontInlineConstant(n, n.sym.ast):
|
||||
result = arAddressableConst
|
||||
elif n.sym.kind in kinds:
|
||||
if owner != nil and owner == n.sym.owner and
|
||||
sfGlobal notin n.sym.flags:
|
||||
result = arLocalLValue
|
||||
if n.sym.kind in {skParam, skLet, skForVar}:
|
||||
result = arAddressableConst
|
||||
else:
|
||||
result = arLValue
|
||||
if owner != nil and owner == n.sym.owner and
|
||||
sfGlobal notin n.sym.flags:
|
||||
result = arLocalLValue
|
||||
else:
|
||||
result = arLValue
|
||||
elif n.sym.kind == skType:
|
||||
let t = n.sym.typ.skipTypes({tyTypeDesc})
|
||||
if t.kind in {tyVar}: result = arStrange
|
||||
@@ -238,10 +242,10 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
|
||||
let t = skipTypes(n[0].typ, abstractInst-{tyTypeDesc})
|
||||
if t.kind in {tyVar, tySink, tyPtr, tyRef}:
|
||||
result = arLValue
|
||||
elif isUnsafeAddr and t.kind == tyLent:
|
||||
result = arLValue
|
||||
elif t.kind == tyLent:
|
||||
result = arAddressableConst
|
||||
else:
|
||||
result = isAssignable(owner, n[0], isUnsafeAddr)
|
||||
result = isAssignable(owner, n[0])
|
||||
if result != arNone and n[1].kind == nkSym and
|
||||
sfDiscriminant in n[1].sym.flags:
|
||||
result = arDiscriminant
|
||||
@@ -249,23 +253,23 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
|
||||
let t = skipTypes(n[0].typ, abstractInst-{tyTypeDesc})
|
||||
if t.kind in {tyVar, tySink, tyPtr, tyRef}:
|
||||
result = arLValue
|
||||
elif isUnsafeAddr and t.kind == tyLent:
|
||||
result = arLValue
|
||||
elif t.kind == tyLent:
|
||||
result = arAddressableConst
|
||||
else:
|
||||
result = isAssignable(owner, n[0], isUnsafeAddr)
|
||||
result = isAssignable(owner, n[0])
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||
# Object and tuple conversions are still addressable, so we skip them
|
||||
# XXX why is 'tyOpenArray' allowed here?
|
||||
if skipTypes(n.typ, abstractPtrs-{tyTypeDesc}).kind in
|
||||
{tyOpenArray, tyTuple, tyObject}:
|
||||
result = isAssignable(owner, n[1], isUnsafeAddr)
|
||||
result = isAssignable(owner, n[1])
|
||||
elif compareTypes(n.typ, n[1].typ, dcEqIgnoreDistinct):
|
||||
# types that are equal modulo distinction preserve l-value:
|
||||
result = isAssignable(owner, n[1], isUnsafeAddr)
|
||||
result = isAssignable(owner, n[1])
|
||||
of nkHiddenDeref:
|
||||
let n0 = n[0]
|
||||
if n0.typ.kind == tyLent:
|
||||
if isUnsafeAddr or (n0.kind == nkSym and n0.sym.kind == skResult):
|
||||
if n0.kind == nkSym and n0.sym.kind == skResult:
|
||||
result = arLValue
|
||||
else:
|
||||
result = arLentValue
|
||||
@@ -274,18 +278,19 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
|
||||
of nkDerefExpr, nkHiddenAddr:
|
||||
result = arLValue
|
||||
of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
|
||||
result = isAssignable(owner, n[0], isUnsafeAddr)
|
||||
result = isAssignable(owner, n[0])
|
||||
of nkCallKinds:
|
||||
# builtin slice keeps lvalue-ness:
|
||||
if getMagic(n) in {mArrGet, mSlice}:
|
||||
result = isAssignable(owner, n[1], isUnsafeAddr)
|
||||
elif n.typ != nil and n.typ.kind in {tyVar}:
|
||||
result = arLValue
|
||||
elif isUnsafeAddr and n.typ != nil and n.typ.kind == tyLent:
|
||||
result = arLValue
|
||||
result = isAssignable(owner, n[1])
|
||||
elif n.typ != nil:
|
||||
case n.typ.kind
|
||||
of tyVar: result = arLValue
|
||||
of tyLent: result = arLentValue
|
||||
else: discard
|
||||
of nkStmtList, nkStmtListExpr:
|
||||
if n.typ != nil:
|
||||
result = isAssignable(owner, n.lastSon, isUnsafeAddr)
|
||||
result = isAssignable(owner, n.lastSon)
|
||||
of nkVarTy:
|
||||
# XXX: The fact that this is here is a bit of a hack.
|
||||
# The goal is to allow the use of checks such as "foo(var T)"
|
||||
|
||||
@@ -36,6 +36,9 @@ import
|
||||
when defined(nimpretty):
|
||||
import layouter
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
Parser* = object # A Parser object represents a file that
|
||||
# is being parsed
|
||||
@@ -331,12 +334,6 @@ proc colcom(p: var Parser, n: PNode) =
|
||||
|
||||
const tkBuiltInMagics = {tkType, tkStatic, tkAddr}
|
||||
|
||||
template setEndInfo() =
|
||||
when defined(nimsuggest):
|
||||
result.endInfo = TLineInfo(fileIndex: p.lex.fileIdx,
|
||||
line: p.lex.previousTokenEnd.line,
|
||||
col: p.lex.previousTokenEnd.col)
|
||||
|
||||
proc parseSymbol(p: var Parser, mode = smNormal): PNode =
|
||||
#| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
|
||||
#| | IDENT | KEYW
|
||||
@@ -389,7 +386,6 @@ proc parseSymbol(p: var Parser, mode = smNormal): PNode =
|
||||
# if it is a keyword:
|
||||
#if not isKeyword(p.tok.tokType): getTok(p)
|
||||
result = p.emptyNode
|
||||
setEndInfo()
|
||||
|
||||
proc colonOrEquals(p: var Parser, a: PNode): PNode =
|
||||
if p.tok.tokType == tkColon:
|
||||
@@ -531,7 +527,6 @@ proc parseCast(p: var Parser): PNode =
|
||||
result.add(exprColonEqExpr(p))
|
||||
optPar(p)
|
||||
eat(p, tkParRi)
|
||||
setEndInfo()
|
||||
|
||||
proc setBaseFlags(n: PNode, base: NumericalBase) =
|
||||
case base
|
||||
@@ -554,7 +549,6 @@ proc parseGStrLit(p: var Parser, a: PNode): PNode =
|
||||
getTok(p)
|
||||
else:
|
||||
result = a
|
||||
setEndInfo()
|
||||
|
||||
proc complexOrSimpleStmt(p: var Parser): PNode
|
||||
proc simpleExpr(p: var Parser, mode = pmNormal): PNode
|
||||
@@ -659,7 +653,6 @@ proc parsePar(p: var Parser): PNode =
|
||||
skipComment(p, a)
|
||||
optPar(p)
|
||||
eat(p, tkParRi)
|
||||
setEndInfo()
|
||||
|
||||
proc identOrLiteral(p: var Parser, mode: PrimaryMode): PNode =
|
||||
#| literal = | INT_LIT | INT8_LIT | INT16_LIT | INT32_LIT | INT64_LIT
|
||||
@@ -821,7 +814,7 @@ proc primarySuffix(p: var Parser, r: PNode,
|
||||
#| | DOTLIKEOP optInd symbol generalizedLit?
|
||||
#| | '[' optInd exprColonEqExprList optPar ']'
|
||||
#| | '{' optInd exprColonEqExprList optPar '}'
|
||||
#| | &( '`'|IDENT|literal|'cast'|'addr'|'type') expr # command syntax
|
||||
#| | &( '`'|IDENT|literal|'cast'|'addr'|'type') expr (comma expr)* # command syntax
|
||||
result = r
|
||||
|
||||
# progress guaranteed
|
||||
@@ -831,14 +824,14 @@ proc primarySuffix(p: var Parser, r: PNode,
|
||||
of tkParLe:
|
||||
# progress guaranteed
|
||||
if p.tok.strongSpaceA > 0:
|
||||
# inside type sections, expressions such as `ref (int, bar)`
|
||||
# are parsed as a nkCommand with a single tuple argument (nkPar)
|
||||
result = commandExpr(p, result, mode)
|
||||
# type sections allow full command syntax
|
||||
if mode == pmTypeDef:
|
||||
result = newNodeP(nkCommand, p)
|
||||
result.add r
|
||||
result.add primary(p, pmNormal)
|
||||
else:
|
||||
result = commandExpr(p, result, mode)
|
||||
var isFirstParam = false
|
||||
while p.tok.tokType == tkComma:
|
||||
getTok(p)
|
||||
optInd(p, result)
|
||||
result.add(commandParam(p, isFirstParam, mode))
|
||||
break
|
||||
result = namedParams(p, result, nkCall, tkParRi)
|
||||
if result.len > 1 and result[1].kind == nkExprColonExpr:
|
||||
@@ -879,9 +872,18 @@ proc primarySuffix(p: var Parser, r: PNode,
|
||||
# actually parsing {.push hints:off.} as {.push(hints:off).} is a sweet
|
||||
# solution, but pragmas.nim can't handle that
|
||||
result = commandExpr(p, result, mode)
|
||||
if mode == pmTypeDef:
|
||||
var isFirstParam = false
|
||||
while p.tok.tokType == tkComma:
|
||||
getTok(p)
|
||||
optInd(p, result)
|
||||
result.add(commandParam(p, isFirstParam, mode))
|
||||
break
|
||||
else:
|
||||
break
|
||||
# type sections allow post-expr blocks
|
||||
if mode == pmTypeDef:
|
||||
result = postExprBlocks(p, result)
|
||||
|
||||
proc parseOperators(p: var Parser, headNode: PNode,
|
||||
limit: int, mode: PrimaryMode): PNode =
|
||||
@@ -906,7 +908,6 @@ proc parseOperators(p: var Parser, headNode: PNode,
|
||||
a.add(b)
|
||||
result = a
|
||||
opPrec = getPrecedence(p.tok)
|
||||
setEndInfo()
|
||||
|
||||
proc simpleExprAux(p: var Parser, limit: int, mode: PrimaryMode): PNode =
|
||||
result = primary(p, mode)
|
||||
@@ -953,7 +954,6 @@ proc parsePragma(p: var Parser): PNode =
|
||||
when defined(nimpretty):
|
||||
dec p.em.doIndentMore
|
||||
dec p.em.keepIndents
|
||||
setEndInfo()
|
||||
|
||||
proc identVis(p: var Parser; allowDot=false): PNode =
|
||||
#| identVis = symbol OPR? # postfix position
|
||||
@@ -1022,7 +1022,6 @@ proc parseIdentColonEquals(p: var Parser, flags: DeclaredIdentFlags): PNode =
|
||||
result.add(parseExpr(p))
|
||||
else:
|
||||
result.add(newNodeP(nkEmpty, p))
|
||||
setEndInfo()
|
||||
|
||||
proc parseTuple(p: var Parser, indentAllowed = false): PNode =
|
||||
#| tupleDecl = 'tuple'
|
||||
@@ -1066,7 +1065,6 @@ proc parseTuple(p: var Parser, indentAllowed = false): PNode =
|
||||
parMessage(p, errGenerated, "the syntax for tuple types is 'tuple[...]', not 'tuple(...)'")
|
||||
else:
|
||||
result = newNodeP(nkTupleClassTy, p)
|
||||
setEndInfo()
|
||||
|
||||
proc parseParamList(p: var Parser, retColon = true): PNode =
|
||||
#| paramList = '(' declColonEquals ^* (comma/semicolon) ')'
|
||||
@@ -1115,7 +1113,6 @@ proc parseParamList(p: var Parser, retColon = true): PNode =
|
||||
when defined(nimpretty):
|
||||
dec p.em.doIndentMore
|
||||
dec p.em.keepIndents
|
||||
setEndInfo()
|
||||
|
||||
proc optPragmas(p: var Parser): PNode =
|
||||
if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)):
|
||||
@@ -1125,20 +1122,23 @@ proc optPragmas(p: var Parser): PNode =
|
||||
|
||||
proc parseDoBlock(p: var Parser; info: TLineInfo): PNode =
|
||||
#| doBlock = 'do' paramListArrow pragma? colcom stmt
|
||||
let params = parseParamList(p, retColon=false)
|
||||
var params = parseParamList(p, retColon=false)
|
||||
let pragmas = optPragmas(p)
|
||||
colcom(p, result)
|
||||
result = parseStmt(p)
|
||||
if params.kind != nkEmpty:
|
||||
if params.kind != nkEmpty or pragmas.kind != nkEmpty:
|
||||
if params.kind == nkEmpty:
|
||||
params = newNodeP(nkFormalParams, p)
|
||||
params.add(p.emptyNode) # return type
|
||||
result = newProcNode(nkDo, info,
|
||||
body = result, params = params, name = p.emptyNode, pattern = p.emptyNode,
|
||||
genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode)
|
||||
setEndInfo()
|
||||
|
||||
proc parseProcExpr(p: var Parser; isExpr: bool; kind: TNodeKind): PNode =
|
||||
#| routineExpr = ('proc' | 'func' | 'iterator') paramListColon pragma? ('=' COMMENT? stmt)?
|
||||
# either a proc type or a anonymous proc
|
||||
let info = parLineInfo(p)
|
||||
getTok(p)
|
||||
let hasSignature = p.tok.tokType in {tkParLe, tkColon} and p.tok.indent < 0
|
||||
let params = parseParamList(p)
|
||||
let pragmas = optPragmas(p)
|
||||
@@ -1149,20 +1149,19 @@ proc parseProcExpr(p: var Parser; isExpr: bool; kind: TNodeKind): PNode =
|
||||
params = params, name = p.emptyNode, pattern = p.emptyNode,
|
||||
genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode)
|
||||
else:
|
||||
result = newNodeI(if kind == nkIteratorDef: nkIteratorTy else: nkProcTy, info)
|
||||
result = newNodeI(nkProcTy, info)
|
||||
if hasSignature:
|
||||
result.add(params)
|
||||
if kind == nkFuncDef:
|
||||
parMessage(p, "func keyword is not allowed in type descriptions, use proc with {.noSideEffect.} pragma instead")
|
||||
result.add(pragmas)
|
||||
setEndInfo()
|
||||
|
||||
proc isExprStart(p: Parser): bool =
|
||||
case p.tok.tokType
|
||||
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf, tkFor,
|
||||
tkProc, tkFunc, tkIterator, tkBind, tkBuiltInMagics,
|
||||
tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCustomLit, tkVar, tkRef, tkPtr,
|
||||
tkTuple, tkObject, tkWhen, tkCase, tkOut:
|
||||
tkTuple, tkObject, tkWhen, tkCase, tkOut, tkTry, tkBlock:
|
||||
result = true
|
||||
else: result = false
|
||||
|
||||
@@ -1175,7 +1174,6 @@ proc parseSymbolList(p: var Parser, result: PNode) =
|
||||
if p.tok.tokType != tkComma: break
|
||||
getTok(p)
|
||||
optInd(p, s)
|
||||
setEndInfo()
|
||||
|
||||
proc parseTypeDescKAux(p: var Parser, kind: TNodeKind,
|
||||
mode: PrimaryMode): PNode =
|
||||
@@ -1198,7 +1196,6 @@ proc parseTypeDescKAux(p: var Parser, kind: TNodeKind,
|
||||
let list = newNodeP(nodeKind, p)
|
||||
result.add list
|
||||
parseSymbolList(p, list)
|
||||
setEndInfo()
|
||||
|
||||
proc parseVarTuple(p: var Parser): PNode
|
||||
|
||||
@@ -1224,7 +1221,6 @@ proc parseFor(p: var Parser): PNode =
|
||||
result.add(parseExpr(p))
|
||||
colcom(p, result)
|
||||
result.add(parseStmt(p))
|
||||
setEndInfo()
|
||||
|
||||
template nimprettyDontTouch(body) =
|
||||
when defined(nimpretty):
|
||||
@@ -1263,7 +1259,6 @@ proc parseExpr(p: var Parser): PNode =
|
||||
nimprettyDontTouch:
|
||||
result = parseTry(p, isExpr=true)
|
||||
else: result = simpleExpr(p)
|
||||
setEndInfo()
|
||||
|
||||
proc parseEnum(p: var Parser): PNode
|
||||
proc parseObject(p: var Parser): PNode
|
||||
@@ -1295,15 +1290,12 @@ proc primary(p: var Parser, mode: PrimaryMode): PNode =
|
||||
|
||||
case p.tok.tokType
|
||||
of tkTuple: result = parseTuple(p, mode == pmTypeDef)
|
||||
of tkProc:
|
||||
getTok(p)
|
||||
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkLambda)
|
||||
of tkFunc:
|
||||
getTok(p)
|
||||
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkFuncDef)
|
||||
of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkLambda)
|
||||
of tkFunc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkFuncDef)
|
||||
of tkIterator:
|
||||
getTok(p)
|
||||
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkIteratorDef)
|
||||
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkLambda)
|
||||
if result.kind == nkLambda: result.transitionSonsKind(nkIteratorDef)
|
||||
else: result.transitionSonsKind(nkIteratorTy)
|
||||
of tkEnum:
|
||||
if mode == pmTypeDef:
|
||||
prettySection:
|
||||
@@ -1360,13 +1352,12 @@ proc parseTypeDesc(p: var Parser): PNode =
|
||||
newlineWasSplitting(p)
|
||||
result = simpleExpr(p, pmTypeDesc)
|
||||
result = binaryNot(p, result)
|
||||
setEndInfo()
|
||||
|
||||
proc parseTypeDefAux(p: var Parser): PNode =
|
||||
#| typeDefAux = simpleExpr ('not' expr)?
|
||||
#| typeDefAux = simpleExpr ('not' expr
|
||||
#| | postExprBlocks)?
|
||||
result = simpleExpr(p, pmTypeDef)
|
||||
result = binaryNot(p, result)
|
||||
setEndInfo()
|
||||
|
||||
proc makeCall(n: PNode): PNode =
|
||||
## Creates a call if the given node isn't already a call.
|
||||
@@ -1406,7 +1397,10 @@ proc postExprBlocks(p: var Parser, x: PNode): PNode =
|
||||
if stmtList[0].kind == nkStmtList: stmtList = stmtList[0]
|
||||
|
||||
stmtList.flags.incl nfBlockArg
|
||||
if openingParams.kind != nkEmpty:
|
||||
if openingParams.kind != nkEmpty or openingPragmas.kind != nkEmpty:
|
||||
if openingParams.kind == nkEmpty:
|
||||
openingParams = newNodeP(nkFormalParams, p)
|
||||
openingParams.add(p.emptyNode) # return type
|
||||
result.add newProcNode(nkDo, stmtList.info, body = stmtList,
|
||||
params = openingParams,
|
||||
name = p.emptyNode, pattern = p.emptyNode,
|
||||
@@ -1489,7 +1483,6 @@ proc parseExprStmt(p: var Parser): PNode =
|
||||
else:
|
||||
result = a
|
||||
result = postExprBlocks(p, result)
|
||||
setEndInfo()
|
||||
|
||||
proc parseModuleName(p: var Parser, kind: TNodeKind): PNode =
|
||||
result = parseExpr(p)
|
||||
@@ -1501,7 +1494,6 @@ proc parseModuleName(p: var Parser, kind: TNodeKind): PNode =
|
||||
getTok(p)
|
||||
result.add(a)
|
||||
result.add(parseExpr(p))
|
||||
setEndInfo()
|
||||
|
||||
proc parseImport(p: var Parser, kind: TNodeKind): PNode =
|
||||
#| importStmt = 'import' optInd expr
|
||||
@@ -1530,7 +1522,6 @@ proc parseImport(p: var Parser, kind: TNodeKind): PNode =
|
||||
getTok(p)
|
||||
optInd(p, a)
|
||||
#expectNl(p)
|
||||
setEndInfo()
|
||||
|
||||
proc parseIncludeStmt(p: var Parser): PNode =
|
||||
#| includeStmt = 'include' optInd expr ^+ comma
|
||||
@@ -1547,7 +1538,6 @@ proc parseIncludeStmt(p: var Parser): PNode =
|
||||
getTok(p)
|
||||
optInd(p, a)
|
||||
#expectNl(p)
|
||||
setEndInfo()
|
||||
|
||||
proc parseFromStmt(p: var Parser): PNode =
|
||||
#| fromStmt = 'from' expr 'import' optInd expr (comma expr)*
|
||||
@@ -1568,7 +1558,6 @@ proc parseFromStmt(p: var Parser): PNode =
|
||||
getTok(p)
|
||||
optInd(p, a)
|
||||
#expectNl(p)
|
||||
setEndInfo()
|
||||
|
||||
proc parseReturnOrRaise(p: var Parser, kind: TNodeKind): PNode =
|
||||
#| returnStmt = 'return' optInd expr?
|
||||
@@ -1590,7 +1579,6 @@ proc parseReturnOrRaise(p: var Parser, kind: TNodeKind): PNode =
|
||||
var e = parseExpr(p)
|
||||
e = postExprBlocks(p, e)
|
||||
result.add(e)
|
||||
setEndInfo()
|
||||
|
||||
proc parseIfOrWhen(p: var Parser, kind: TNodeKind): PNode =
|
||||
#| condStmt = expr colcom stmt COMMENT?
|
||||
@@ -1615,7 +1603,6 @@ proc parseIfOrWhen(p: var Parser, kind: TNodeKind): PNode =
|
||||
colcom(p, branch)
|
||||
branch.add(parseStmt(p))
|
||||
result.add(branch)
|
||||
setEndInfo()
|
||||
|
||||
proc parseIfOrWhenExpr(p: var Parser, kind: TNodeKind): PNode =
|
||||
#| condExpr = expr colcom expr optInd
|
||||
@@ -1640,7 +1627,6 @@ proc parseIfOrWhenExpr(p: var Parser, kind: TNodeKind): PNode =
|
||||
colcom(p, branch)
|
||||
branch.add(parseStmt(p))
|
||||
result.add(branch)
|
||||
setEndInfo()
|
||||
|
||||
proc parseWhile(p: var Parser): PNode =
|
||||
#| whileStmt = 'while' expr colcom stmt
|
||||
@@ -1650,7 +1636,6 @@ proc parseWhile(p: var Parser): PNode =
|
||||
result.add(parseExpr(p))
|
||||
colcom(p, result)
|
||||
result.add(parseStmt(p))
|
||||
setEndInfo()
|
||||
|
||||
proc parseCase(p: var Parser): PNode =
|
||||
#| ofBranch = 'of' exprList colcom stmt
|
||||
@@ -1698,7 +1683,6 @@ proc parseCase(p: var Parser): PNode =
|
||||
|
||||
if wasIndented:
|
||||
p.currInd = oldInd
|
||||
setEndInfo()
|
||||
|
||||
proc parseTry(p: var Parser; isExpr: bool): PNode =
|
||||
#| tryStmt = 'try' colcom stmt &(IND{=}? 'except'|'finally')
|
||||
@@ -1725,14 +1709,12 @@ proc parseTry(p: var Parser; isExpr: bool): PNode =
|
||||
b.add(parseStmt(p))
|
||||
result.add(b)
|
||||
if b == nil: parMessage(p, "expected 'except'")
|
||||
setEndInfo()
|
||||
|
||||
proc parseExceptBlock(p: var Parser, kind: TNodeKind): PNode =
|
||||
result = newNodeP(kind, p)
|
||||
getTok(p)
|
||||
colcom(p, result)
|
||||
result.add(parseStmt(p))
|
||||
setEndInfo()
|
||||
|
||||
proc parseBlock(p: var Parser): PNode =
|
||||
#| blockStmt = 'block' symbol? colcom stmt
|
||||
@@ -1743,7 +1725,6 @@ proc parseBlock(p: var Parser): PNode =
|
||||
else: result.add(parseSymbol(p))
|
||||
colcom(p, result)
|
||||
result.add(parseStmt(p))
|
||||
setEndInfo()
|
||||
|
||||
proc parseStaticOrDefer(p: var Parser; k: TNodeKind): PNode =
|
||||
#| staticStmt = 'static' colcom stmt
|
||||
@@ -1752,7 +1733,6 @@ proc parseStaticOrDefer(p: var Parser; k: TNodeKind): PNode =
|
||||
getTok(p)
|
||||
colcom(p, result)
|
||||
result.add(parseStmt(p))
|
||||
setEndInfo()
|
||||
|
||||
proc parseAsm(p: var Parser): PNode =
|
||||
#| asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLESTR_LIT)
|
||||
@@ -1769,7 +1749,6 @@ proc parseAsm(p: var Parser): PNode =
|
||||
result.add(p.emptyNode)
|
||||
return
|
||||
getTok(p)
|
||||
setEndInfo()
|
||||
|
||||
proc parseGenericParam(p: var Parser): PNode =
|
||||
#| genericParam = symbol (comma symbol)* (colon expr)? ('=' optInd expr)?
|
||||
@@ -1805,7 +1784,6 @@ proc parseGenericParam(p: var Parser): PNode =
|
||||
result.add(parseExpr(p))
|
||||
else:
|
||||
result.add(p.emptyNode)
|
||||
setEndInfo()
|
||||
|
||||
proc parseGenericParamList(p: var Parser): PNode =
|
||||
#| genericParamList = '[' optInd
|
||||
@@ -1824,14 +1802,12 @@ proc parseGenericParamList(p: var Parser): PNode =
|
||||
skipComment(p, a)
|
||||
optPar(p)
|
||||
eat(p, tkBracketRi)
|
||||
setEndInfo()
|
||||
|
||||
proc parsePattern(p: var Parser): PNode =
|
||||
#| pattern = '{' stmt '}'
|
||||
eat(p, tkCurlyLe)
|
||||
result = parseStmt(p)
|
||||
eat(p, tkCurlyRi)
|
||||
setEndInfo()
|
||||
|
||||
proc parseRoutine(p: var Parser, kind: TNodeKind): PNode =
|
||||
#| indAndComment = (IND{>} COMMENT)? | COMMENT?
|
||||
@@ -1840,12 +1816,6 @@ proc parseRoutine(p: var Parser, kind: TNodeKind): PNode =
|
||||
result = newNodeP(kind, p)
|
||||
getTok(p)
|
||||
optInd(p, result)
|
||||
if kind in {nkProcDef, nkLambda, nkIteratorDef, nkFuncDef} and
|
||||
p.tok.tokType notin {tkSymbol, tokKeywordLow..tokKeywordHigh, tkAccent}:
|
||||
# no name; lambda or proc type
|
||||
# in every context that we can parse a routine, we can also parse these
|
||||
result = parseProcExpr(p, true, if kind == nkProcDef: nkLambda else: kind)
|
||||
return
|
||||
result.add(identVis(p))
|
||||
if p.tok.tokType == tkCurlyLe and p.validInd: result.add(p.parsePattern)
|
||||
else: result.add(p.emptyNode)
|
||||
@@ -1876,7 +1846,6 @@ proc parseRoutine(p: var Parser, kind: TNodeKind): PNode =
|
||||
#else:
|
||||
# assert false, p.lex.config$body.info # avoids hard to track bugs, fail early.
|
||||
# Yeah, that worked so well. There IS a bug in this logic, now what?
|
||||
setEndInfo()
|
||||
|
||||
proc newCommentStmt(p: var Parser): PNode =
|
||||
#| commentStmt = COMMENT
|
||||
@@ -1912,7 +1881,6 @@ proc parseSection(p: var Parser, kind: TNodeKind,
|
||||
result.add(defparser(p))
|
||||
else:
|
||||
parMessage(p, errIdentifierExpected, p.tok)
|
||||
setEndInfo()
|
||||
|
||||
proc parseEnum(p: var Parser): PNode =
|
||||
#| enumDecl = 'enum' optInd (symbol pragma? optInd ('=' optInd expr COMMENT?)? comma?)+
|
||||
@@ -1959,7 +1927,6 @@ proc parseEnum(p: var Parser): PNode =
|
||||
break
|
||||
if result.len <= 1:
|
||||
parMessage(p, errIdentifierExpected, p.tok)
|
||||
setEndInfo()
|
||||
|
||||
proc parseObjectPart(p: var Parser): PNode
|
||||
proc parseObjectWhen(p: var Parser): PNode =
|
||||
@@ -1985,7 +1952,6 @@ proc parseObjectWhen(p: var Parser): PNode =
|
||||
branch.add(parseObjectPart(p))
|
||||
flexComment(p, branch)
|
||||
result.add(branch)
|
||||
setEndInfo()
|
||||
|
||||
proc parseObjectCase(p: var Parser): PNode =
|
||||
#| objectBranch = 'of' exprList colcom objectPart
|
||||
@@ -2031,7 +1997,6 @@ proc parseObjectCase(p: var Parser): PNode =
|
||||
if b.kind == nkElse: break
|
||||
if wasIndented:
|
||||
p.currInd = oldInd
|
||||
setEndInfo()
|
||||
|
||||
proc parseObjectPart(p: var Parser): PNode =
|
||||
#| objectPart = IND{>} objectPart^+IND{=} DED
|
||||
@@ -2064,7 +2029,6 @@ proc parseObjectPart(p: var Parser): PNode =
|
||||
result = p.emptyNode
|
||||
else:
|
||||
result = p.emptyNode
|
||||
setEndInfo()
|
||||
|
||||
proc parseObject(p: var Parser): PNode =
|
||||
#| objectDecl = 'object' pragma? ('of' typeDesc)? COMMENT? objectPart
|
||||
@@ -2090,7 +2054,6 @@ proc parseObject(p: var Parser): PNode =
|
||||
result.add(p.emptyNode)
|
||||
else:
|
||||
result.add(parseObjectPart(p))
|
||||
setEndInfo()
|
||||
|
||||
proc parseTypeClassParam(p: var Parser): PNode =
|
||||
let modifier =
|
||||
@@ -2108,7 +2071,6 @@ proc parseTypeClassParam(p: var Parser): PNode =
|
||||
result.add(p.parseSymbol)
|
||||
else:
|
||||
result = p.parseSymbol
|
||||
setEndInfo()
|
||||
|
||||
proc parseTypeClass(p: var Parser): PNode =
|
||||
#| conceptParam = ('var' | 'out')? symbol
|
||||
@@ -2152,7 +2114,6 @@ proc parseTypeClass(p: var Parser): PNode =
|
||||
result.add(p.emptyNode)
|
||||
else:
|
||||
result.add(parseStmt(p))
|
||||
setEndInfo()
|
||||
|
||||
proc parseTypeDef(p: var Parser): PNode =
|
||||
#|
|
||||
@@ -2201,7 +2162,6 @@ proc parseTypeDef(p: var Parser): PNode =
|
||||
else:
|
||||
result.add(p.emptyNode)
|
||||
indAndComment(p, result) # special extension!
|
||||
setEndInfo()
|
||||
|
||||
proc parseVarTuple(p: var Parser): PNode =
|
||||
#| varTuple = '(' optInd identWithPragma ^+ comma optPar ')' '=' optInd expr
|
||||
@@ -2218,7 +2178,6 @@ proc parseVarTuple(p: var Parser): PNode =
|
||||
result.add(p.emptyNode) # no type desc
|
||||
optPar(p)
|
||||
eat(p, tkParRi)
|
||||
setEndInfo()
|
||||
|
||||
proc parseVariable(p: var Parser): PNode =
|
||||
#| colonBody = colcom stmt postExprBlocks?
|
||||
@@ -2231,7 +2190,6 @@ proc parseVariable(p: var Parser): PNode =
|
||||
else: result = parseIdentColonEquals(p, {withPragma, withDot})
|
||||
result[^1] = postExprBlocks(p, result[^1])
|
||||
indAndComment(p, result)
|
||||
setEndInfo()
|
||||
|
||||
proc parseConstant(p: var Parser): PNode =
|
||||
#| constant = (varTuple / identWithPragma) (colon typeDesc)? '=' optInd expr indAndComment
|
||||
@@ -2251,7 +2209,6 @@ proc parseConstant(p: var Parser): PNode =
|
||||
result.add(parseExpr(p))
|
||||
result[^1] = postExprBlocks(p, result[^1])
|
||||
indAndComment(p, result)
|
||||
setEndInfo()
|
||||
|
||||
proc parseBind(p: var Parser, k: TNodeKind): PNode =
|
||||
#| bindStmt = 'bind' optInd qualifiedIdent ^+ comma
|
||||
@@ -2267,7 +2224,6 @@ proc parseBind(p: var Parser, k: TNodeKind): PNode =
|
||||
getTok(p)
|
||||
optInd(p, a)
|
||||
#expectNl(p)
|
||||
setEndInfo()
|
||||
|
||||
proc parseStmtPragma(p: var Parser): PNode =
|
||||
#| pragmaStmt = pragma (':' COMMENT? stmt)?
|
||||
@@ -2279,7 +2235,6 @@ proc parseStmtPragma(p: var Parser): PNode =
|
||||
skipComment(p, result)
|
||||
result.add a
|
||||
result.add parseStmt(p)
|
||||
setEndInfo()
|
||||
|
||||
proc simpleStmt(p: var Parser): PNode =
|
||||
#| simpleStmt = ((returnStmt | raiseStmt | yieldStmt | discardStmt | breakStmt
|
||||
@@ -2422,7 +2377,6 @@ proc parseStmt(p: var Parser): PNode =
|
||||
if p.tok.tokType != tkSemiColon: break
|
||||
getTok(p)
|
||||
if err and p.tok.tokType == tkEof: break
|
||||
setEndInfo()
|
||||
|
||||
proc parseAll(p: var Parser): PNode =
|
||||
## Parses the rest of the input stream held by the parser into a PNode.
|
||||
@@ -2438,7 +2392,10 @@ proc parseAll(p: var Parser): PNode =
|
||||
getTok(p)
|
||||
if p.tok.indent != 0:
|
||||
parMessage(p, errInvalidIndentation)
|
||||
setEndInfo()
|
||||
|
||||
proc checkFirstLineIndentation*(p: var Parser) =
|
||||
if p.tok.indent != 0 and p.tok.strongSpaceA > 0:
|
||||
parMessage(p, errInvalidIndentation)
|
||||
|
||||
proc parseTopLevelStmt(p: var Parser): PNode =
|
||||
## Implements an iterator which, when called repeatedly, returns the next
|
||||
@@ -2468,7 +2425,6 @@ proc parseTopLevelStmt(p: var Parser): PNode =
|
||||
result = complexOrSimpleStmt(p)
|
||||
if result.kind == nkEmpty: parMessage(p, errExprExpected, p.tok)
|
||||
break
|
||||
setEndInfo()
|
||||
|
||||
proc parseString*(s: string; cache: IdentCache; config: ConfigRef;
|
||||
filename: string = ""; line: int = 0;
|
||||
@@ -2480,10 +2436,9 @@ proc parseString*(s: string; cache: IdentCache; config: ConfigRef;
|
||||
var stream = llStreamOpen(s)
|
||||
stream.lineOffset = line
|
||||
|
||||
var p: Parser
|
||||
p.lex.errorHandler = errorHandler
|
||||
openParser(p, AbsoluteFile filename, stream, cache, config)
|
||||
var parser: Parser
|
||||
parser.lex.errorHandler = errorHandler
|
||||
openParser(parser, AbsoluteFile filename, stream, cache, config)
|
||||
|
||||
result = p.parseAll
|
||||
closeParser(p)
|
||||
setEndInfo()
|
||||
result = parser.parseAll
|
||||
closeParser(parser)
|
||||
|
||||
@@ -16,6 +16,8 @@ import
|
||||
syntaxes, modulegraphs, reorder,
|
||||
lineinfos, pathutils, std/sha1, packages
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/syncio
|
||||
|
||||
type
|
||||
TPassData* = tuple[input: PNode, closeOutput: PNode]
|
||||
@@ -147,6 +149,7 @@ proc processModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator;
|
||||
processImplicits graph, graph.config.implicitImports, nkImportStmt, a, module
|
||||
processImplicits graph, graph.config.implicitIncludes, nkIncludeStmt, a, module
|
||||
|
||||
checkFirstLineIndentation(p)
|
||||
while true:
|
||||
if graph.stopCompile(): break
|
||||
var n = parseTopLevelStmt(p)
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
## Path handling utilities for Nim. Strictly typed code in order
|
||||
## to avoid the never ending time sink in getting path handling right.
|
||||
|
||||
import os, pathnorm, strutils
|
||||
import os, pathnorm
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions]
|
||||
|
||||
type
|
||||
AbsoluteFile* = distinct string
|
||||
@@ -99,52 +102,3 @@ when true:
|
||||
proc addFileExt*(x: RelativeFile; ext: string): RelativeFile {.borrow.}
|
||||
|
||||
proc writeFile*(x: AbsoluteFile; content: string) {.borrow.}
|
||||
|
||||
proc skipHomeDir(x: string): int =
|
||||
when defined(windows):
|
||||
if x.continuesWith("Users/", len("C:/")):
|
||||
result = 3
|
||||
else:
|
||||
result = 0
|
||||
else:
|
||||
if x.startsWith("/home/") or x.startsWith("/Users/"):
|
||||
result = 3
|
||||
elif x.startsWith("/mnt/") and x.continuesWith("/Users/", len("/mnt/c")):
|
||||
result = 5
|
||||
else:
|
||||
result = 0
|
||||
|
||||
proc relevantPart(s: string; afterSlashX: int): string =
|
||||
result = newStringOfCap(s.len - 8)
|
||||
var slashes = afterSlashX
|
||||
for i in 0..<s.len:
|
||||
if slashes == 0:
|
||||
result.add s[i]
|
||||
elif s[i] == '/':
|
||||
dec slashes
|
||||
|
||||
template canonSlashes(x: string): string =
|
||||
when defined(windows):
|
||||
x.replace('\\', '/')
|
||||
else:
|
||||
x
|
||||
|
||||
proc customPathImpl(x: string): string =
|
||||
# Idea: Encode a "protocol" via "//protocol/path" which is not ambiguous
|
||||
# as path canonicalization would have removed the double slashes.
|
||||
# /mnt/X/Users/Y
|
||||
# X:\\Users\Y
|
||||
# /home/Y
|
||||
# -->
|
||||
# //user/
|
||||
if not isAbsolute(x):
|
||||
result = customPathImpl(canonSlashes(getCurrentDir() / x))
|
||||
else:
|
||||
let slashes = skipHomeDir(x)
|
||||
if slashes > 0:
|
||||
result = "//user/" & relevantPart(x, slashes)
|
||||
else:
|
||||
result = x
|
||||
|
||||
proc customPath*(x: string): string =
|
||||
customPathImpl canonSlashes x
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
import
|
||||
ast, types, semdata, sigmatch, idents, aliases, parampatterns, trees
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
TPatternContext = object
|
||||
owner: PSym
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
import
|
||||
strutils
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
|
||||
type
|
||||
TSystemOS* = enum # Also add OS in initialization section and alias
|
||||
# conditionals to condsyms (end of module).
|
||||
@@ -201,7 +205,8 @@ type
|
||||
cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64,
|
||||
cpuPowerpc64el, cpuSparc, cpuVm, cpuHppa, cpuIa64, cpuAmd64, cpuMips,
|
||||
cpuMipsel, cpuArm, cpuArm64, cpuJS, cpuNimVM, cpuAVR, cpuMSP430,
|
||||
cpuSparc64, cpuMips64, cpuMips64el, cpuRiscV32, cpuRiscV64, cpuEsp, cpuWasm32
|
||||
cpuSparc64, cpuMips64, cpuMips64el, cpuRiscV32, cpuRiscV64, cpuEsp, cpuWasm32,
|
||||
cpuE2k, cpuLoongArch64
|
||||
|
||||
type
|
||||
TInfoCPU* = tuple[name: string, intSize: int, endian: Endianness,
|
||||
@@ -236,7 +241,9 @@ const
|
||||
(name: "riscv32", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
|
||||
(name: "riscv64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
|
||||
(name: "esp", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
|
||||
(name: "wasm32", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32)]
|
||||
(name: "wasm32", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
|
||||
(name: "e2k", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
|
||||
(name: "loongarch64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64)]
|
||||
|
||||
type
|
||||
Target* = object
|
||||
|
||||
@@ -15,7 +15,7 @@ import ".." / [ast, astalgo,
|
||||
proc semLocals*(c: PContext, n: PNode): PNode =
|
||||
var counter = 0
|
||||
var tupleType = newTypeS(tyTuple, c)
|
||||
result = newNodeIT(nkTupleConstr, n.info, tupleType)
|
||||
result = newNodeIT(nkPar, n.info, tupleType)
|
||||
tupleType.n = newNodeI(nkRecList, n.info)
|
||||
let owner = getCurrOwner(c)
|
||||
# for now we skip openarrays ...
|
||||
|
||||
@@ -14,6 +14,9 @@ import
|
||||
wordrecg, ropes, options, strutils, extccomp, math, magicsys, trees,
|
||||
types, lookups, lineinfos, pathutils, linter
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
from ic / ic import addCompilerProc
|
||||
|
||||
const
|
||||
@@ -44,18 +47,21 @@ const
|
||||
wDiscardable, wGensym, wInject, wRaises, wEffectsOf,
|
||||
wTags, wLocks, wGcSafe, wRequires, wEnsures}
|
||||
exprPragmas* = {wLine, wLocks, wNoRewrite, wGcSafe, wNoSideEffect}
|
||||
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangeChecks,
|
||||
wBoundChecks, wOverflowChecks, wNilChecks, wStaticBoundchecks,
|
||||
wStyleChecks, wAssertions,
|
||||
wWarnings, wHints,
|
||||
wLineDir, wStackTrace, wLineTrace, wOptimization, wHint, wWarning, wError,
|
||||
stmtPragmas* = {
|
||||
wHint, wWarning, wError,
|
||||
wFatal, wDefine, wUndef, wCompile, wLink, wLinksys, wPure, wPush, wPop,
|
||||
wPassl, wPassc, wLocalPassc,
|
||||
wDeadCodeElimUnused, # deprecated, always on
|
||||
wDeprecated,
|
||||
wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
|
||||
wPragma, wEmit, wUnroll,
|
||||
wLinearScanEnd, wPatterns, wTrMacros, wEffects, wNoForward, wReorder, wComputedGoto,
|
||||
wExperimental, wThis, wUsed, wInvariant, wAssume, wAssert}
|
||||
stmtPragmasTopLevel* = {wChecks, wObjChecks, wFieldChecks, wRangeChecks,
|
||||
wBoundChecks, wOverflowChecks, wNilChecks, wStaticBoundchecks,
|
||||
wStyleChecks, wAssertions,
|
||||
wWarnings, wHints,
|
||||
wLineDir, wStackTrace, wLineTrace, wOptimization,
|
||||
wFloatChecks, wInfChecks, wNanChecks}
|
||||
lambdaPragmas* = {FirstCallConv..LastCallConv,
|
||||
wNoSideEffect, wSideEffect, wNoreturn, wNosinks, wDynlib, wHeader,
|
||||
wThread, wAsmNoStackFrame,
|
||||
@@ -498,11 +504,8 @@ proc processCompile(c: PContext, n: PNode) =
|
||||
var cf = Cfile(nimname: splitFile(src).name,
|
||||
cname: src, obj: dest, flags: {CfileFlag.External},
|
||||
customArgs: customArgs)
|
||||
if not fileExists(src):
|
||||
localError(c.config, n.info, "cannot find: " & src.string)
|
||||
else:
|
||||
extccomp.addExternalFileToCompile(c.config, cf)
|
||||
recordPragma(c, it, "compile", src.string, dest.string, customArgs)
|
||||
extccomp.addExternalFileToCompile(c.config, cf)
|
||||
recordPragma(c, it, "compile", src.string, dest.string, customArgs)
|
||||
|
||||
proc getStrLit(c: PContext, n: PNode; i: int): string =
|
||||
n[i] = c.semConstExpr(c, n[i])
|
||||
@@ -654,7 +657,7 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode) =
|
||||
x.typ = makeTypeFromExpr(c, x)
|
||||
else:
|
||||
var t = skipTypes(c.semTypeNode(c, x, nil), skipPtrs)
|
||||
if t.kind != tyObject and not t.isMetaType:
|
||||
if t.kind notin {tyObject, tyOr}:
|
||||
localError(c.config, x.info, errGenerated, "invalid type for raises/tags list")
|
||||
x.typ = t
|
||||
|
||||
@@ -826,7 +829,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
let ident = considerQuotedIdent(c, key)
|
||||
var userPragma = strTableGet(c.userPragmas, ident)
|
||||
if userPragma != nil:
|
||||
styleCheckUse(c, key.info, userPragma)
|
||||
if {optStyleHint, optStyleError} * c.config.globalOptions != {}:
|
||||
styleCheckUse(c.config, key.info, userPragma)
|
||||
|
||||
# number of pragmas increase/decrease with user pragma expansion
|
||||
inc c.instCounter
|
||||
@@ -840,7 +844,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
else:
|
||||
let k = whichKeyword(ident)
|
||||
if k in validPragmas:
|
||||
checkPragmaUse(c.config, key.info, k, ident.s)
|
||||
if {optStyleHint, optStyleError} * c.config.globalOptions != {}:
|
||||
checkPragmaUse(c.config, key.info, k, ident.s)
|
||||
case k
|
||||
of wExportc, wExportCpp:
|
||||
makeExternExport(c, sym, getOptionalStr(c, it, "$1"), it.info)
|
||||
@@ -1245,7 +1250,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
elif comesFromPush and whichKeyword(ident) != wInvalid:
|
||||
discard "ignore the .push pragma; it doesn't apply"
|
||||
else:
|
||||
if sym == nil or (sym.kind in {skVar, skLet, skParam, skIterator,
|
||||
if sym == nil or (sym.kind in {skVar, skLet, skParam,
|
||||
skField, skProc, skFunc, skConverter, skMethod, skType}):
|
||||
n[i] = semCustomPragma(c, it)
|
||||
elif sym != nil:
|
||||
|
||||
@@ -17,6 +17,9 @@ when defined(nimHasUsed):
|
||||
import
|
||||
lexer, options, idents, strutils, ast, msgs, lineinfos
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions]
|
||||
|
||||
type
|
||||
TRenderFlag* = enum
|
||||
renderNone, renderNoBody, renderNoComments, renderDocComments,
|
||||
|
||||
@@ -4,6 +4,9 @@ import
|
||||
msgs, modulegraphs, syntaxes, options, modulepaths,
|
||||
lineinfos
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
type
|
||||
DepN = ref object
|
||||
pnode: PNode
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
## Serialization utilities for the compiler.
|
||||
import strutils, math
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
# bcc on windows doesn't have C99 functions
|
||||
when defined(windows) and defined(bcc):
|
||||
{.emit: """#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
|
||||
@@ -60,6 +60,10 @@ import
|
||||
|
||||
from pathutils import AbsoluteFile
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[assertions, syncio]
|
||||
|
||||
|
||||
type
|
||||
FormatStr* = string # later we may change it to CString for better
|
||||
# performance of the code generator (assignments
|
||||
@@ -329,10 +333,3 @@ proc equalsFile*(r: Rope, filename: AbsoluteFile): bool =
|
||||
if result:
|
||||
result = equalsFile(r, f)
|
||||
close(f)
|
||||
|
||||
proc writeRopeIfNotEqual*(r: Rope, filename: AbsoluteFile): bool =
|
||||
# returns true if overwritten
|
||||
if not equalsFile(r, filename):
|
||||
result = writeRope(r, filename)
|
||||
else:
|
||||
result = false
|
||||
|
||||
@@ -16,6 +16,9 @@ import
|
||||
os, times, osproc, wordrecg, strtabs, modulegraphs,
|
||||
pathutils
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/syncio
|
||||
|
||||
# we support 'cmpIgnoreStyle' natively for efficiency:
|
||||
from strutils import cmpIgnoreStyle, contains
|
||||
|
||||
|
||||
@@ -288,23 +288,8 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
|
||||
# fail fast:
|
||||
globalError(c.config, n.info, "type mismatch")
|
||||
return
|
||||
# see getMsgDiagnostic:
|
||||
if nfExplicitCall notin n.flags and {nfDotField, nfDotSetter} * n.flags != {}:
|
||||
let ident = considerQuotedIdent(c, n[0], n).s
|
||||
let sym = n[1].typ.typSym
|
||||
var typeHint = ""
|
||||
if sym == nil:
|
||||
discard
|
||||
else:
|
||||
typeHint = " for type " & getProcHeader(c.config, sym)
|
||||
localError(c.config, n.info, errUndeclaredField % ident & typeHint)
|
||||
return
|
||||
if errors.len == 0:
|
||||
if n[0].kind in nkIdentKinds:
|
||||
let ident = considerQuotedIdent(c, n[0], n).s
|
||||
localError(c.config, n.info, errUndeclaredRoutine % ident)
|
||||
else:
|
||||
localError(c.config, n.info, "expression '$1' cannot be called" % n[0].renderTree)
|
||||
localError(c.config, n.info, "expression '$1' cannot be called" % n[0].renderTree)
|
||||
return
|
||||
|
||||
let (prefer, candidates) = presentFailedCandidates(c, n, errors)
|
||||
@@ -346,7 +331,7 @@ proc getMsgDiagnostic(c: PContext, flags: TExprFlags, n, f: PNode): string =
|
||||
sym = nextOverloadIter(o, c, f)
|
||||
|
||||
let ident = considerQuotedIdent(c, f, n).s
|
||||
if nfExplicitCall notin n.flags and {nfDotField, nfDotSetter} * n.flags != {}:
|
||||
if {nfDotField, nfExplicitCall} * n.flags == {nfDotField}:
|
||||
let sym = n[1].typ.typSym
|
||||
var typeHint = ""
|
||||
if sym == nil:
|
||||
@@ -379,15 +364,11 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||
else:
|
||||
initialBinding = nil
|
||||
|
||||
pickBestCandidate(c, f, n, orig, initialBinding,
|
||||
filter, result, alt, errors, efExplain in flags,
|
||||
errorsEnabled, flags)
|
||||
|
||||
var dummyErrors: CandidateErrors
|
||||
template pickSpecialOp(headSymbol) =
|
||||
template pickBest(headSymbol) =
|
||||
pickBestCandidate(c, headSymbol, n, orig, initialBinding,
|
||||
filter, result, alt, dummyErrors, efExplain in flags,
|
||||
false, flags)
|
||||
filter, result, alt, errors, efExplain in flags,
|
||||
errorsEnabled, flags)
|
||||
pickBest(f)
|
||||
|
||||
let overloadsState = result.state
|
||||
if overloadsState != csMatch:
|
||||
@@ -399,7 +380,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||
n.sons.insert(hiddenArg, 1)
|
||||
orig.sons.insert(hiddenArg, 1)
|
||||
|
||||
pickSpecialOp(f)
|
||||
pickBest(f)
|
||||
|
||||
if result.state != csMatch:
|
||||
n.sons.delete(1)
|
||||
@@ -419,7 +400,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||
let op = newIdentNode(getIdent(c.cache, x), n.info)
|
||||
n[0] = op
|
||||
orig[0] = op
|
||||
pickSpecialOp(op)
|
||||
pickBest(op)
|
||||
|
||||
if nfExplicitCall in n.flags:
|
||||
tryOp ".()"
|
||||
@@ -433,13 +414,23 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||
let callOp = newIdentNode(getIdent(c.cache, ".="), n.info)
|
||||
n.sons[0..1] = [callOp, n[1], calleeName]
|
||||
orig.sons[0..1] = [callOp, orig[1], calleeName]
|
||||
pickSpecialOp(callOp)
|
||||
pickBest(callOp)
|
||||
|
||||
if overloadsState == csEmpty and result.state == csEmpty:
|
||||
if efNoUndeclared notin flags: # for tests/pragmas/tcustom_pragma.nim
|
||||
result.state = csNoMatch
|
||||
# xxx adapt/use errorUndeclaredIdentifierHint(c, n, f.ident)
|
||||
localError(c.config, n.info, getMsgDiagnostic(c, flags, n, f))
|
||||
template impl() =
|
||||
# xxx adapt/use errorUndeclaredIdentifierHint(c, n, f.ident)
|
||||
localError(c.config, n.info, getMsgDiagnostic(c, flags, n, f))
|
||||
if n[0].kind == nkIdent and n[0].ident.s == ".=" and n[2].kind == nkIdent:
|
||||
let sym = n[1].typ.sym
|
||||
if sym == nil:
|
||||
impl()
|
||||
else:
|
||||
let field = n[2].ident.s
|
||||
let msg = errUndeclaredField % field & " for type " & getProcHeader(c.config, sym)
|
||||
localError(c.config, orig[2].info, msg)
|
||||
else:
|
||||
impl()
|
||||
return
|
||||
elif result.state != csMatch:
|
||||
if nfExprCall in n.flags:
|
||||
@@ -663,7 +654,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
|
||||
proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||
assert n.kind == nkBracketExpr
|
||||
for i in 1..<n.len:
|
||||
let e = semExprWithType(c, n[i])
|
||||
let e = semExpr(c, n[i])
|
||||
if e.typ == nil:
|
||||
n[i].typ = errorType(c)
|
||||
else:
|
||||
@@ -712,7 +703,16 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym =
|
||||
call.add(newIdentNode(fn.name, fn.info))
|
||||
for i in 1..<fn.typ.n.len:
|
||||
let param = fn.typ.n[i]
|
||||
let t = skipTypes(param.typ, abstractVar-{tyTypeDesc, tyDistinct})
|
||||
const desiredTypes = abstractVar + {tyCompositeTypeClass} - {tyTypeDesc, tyDistinct}
|
||||
#[.
|
||||
# We only want the type not any modifiers such as `ptr`, `var`, `ref` ...
|
||||
# tyCompositeTypeClass is here for
|
||||
# when using something like:
|
||||
type Foo[T] = distinct int
|
||||
proc `$`(f: Foo): string {.borrow.}
|
||||
# We want to skip the `Foo` to get `int`
|
||||
]#
|
||||
let t = skipTypes(param.typ, desiredTypes)
|
||||
if t.kind == tyDistinct or param.typ.kind == tyDistinct: hasDistinct = true
|
||||
var x: PType
|
||||
if param.typ.kind == tyVar:
|
||||
@@ -730,4 +730,4 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym =
|
||||
result = nil
|
||||
elif result.magic in {mArrPut, mArrGet}:
|
||||
# cannot borrow these magics for now
|
||||
result = nil
|
||||
result = nil
|
||||
@@ -11,6 +11,9 @@
|
||||
|
||||
import tables
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
import
|
||||
intsets, options, ast, astalgo, msgs, idents, renderer,
|
||||
magicsys, vmdef, modulegraphs, lineinfos, sets, pathutils
|
||||
|
||||
@@ -522,7 +522,7 @@ proc overloadedCallOpr(c: PContext, n: PNode): PNode =
|
||||
result = newNodeI(nkCall, n.info)
|
||||
result.add newIdentNode(par, n.info)
|
||||
for i in 0..<n.len: result.add n[i]
|
||||
result = semExpr(c, result, flags = {efNoUndeclared})
|
||||
result = semExpr(c, result)
|
||||
|
||||
proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
|
||||
case n.kind
|
||||
@@ -650,8 +650,8 @@ proc fixAbstractType(c: PContext, n: PNode) =
|
||||
changeType(c, it[1], s, check=true)
|
||||
n[i] = it[1]
|
||||
|
||||
proc isAssignable(c: PContext, n: PNode; isUnsafeAddr=false): TAssignableResult =
|
||||
result = parampatterns.isAssignable(c.p.owner, n, isUnsafeAddr)
|
||||
proc isAssignable(c: PContext, n: PNode): TAssignableResult =
|
||||
result = parampatterns.isAssignable(c.p.owner, n)
|
||||
|
||||
proc isUnresolvedSym(s: PSym): bool =
|
||||
result = s.kind == skGenericParam
|
||||
@@ -925,14 +925,6 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode =
|
||||
return errorNode(c, n)
|
||||
|
||||
result = n
|
||||
|
||||
when defined(nimsuggest):
|
||||
if c.config.expandProgress:
|
||||
if c.config.expandLevels == 0:
|
||||
return n
|
||||
else:
|
||||
c.config.expandLevels -= 1
|
||||
|
||||
let callee = result[0].sym
|
||||
case callee.kind
|
||||
of skMacro: result = semMacroExpr(c, result, orig, callee, flags)
|
||||
@@ -978,9 +970,6 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
if s != nil:
|
||||
setGenericParams(c, n[0])
|
||||
return semDirectOp(c, n, flags)
|
||||
elif isSymChoice(n[0]):
|
||||
# overloaded generic procs e.g. newSeq[int] can end up here
|
||||
return semDirectOp(c, n, flags)
|
||||
|
||||
let nOrig = n.copyTree
|
||||
semOpAux(c, n)
|
||||
@@ -1029,10 +1018,10 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
if n.len == 1: return semObjConstr(c, n, flags)
|
||||
return semConv(c, n)
|
||||
else:
|
||||
result = overloadedCallOpr(c, n) # this uses efNoUndeclared
|
||||
result = overloadedCallOpr(c, n)
|
||||
# Now that nkSym does not imply an iteration over the proc/iterator space,
|
||||
# the old ``prc`` (which is likely an nkIdent) has to be restored:
|
||||
if result == nil or result.kind == nkEmpty:
|
||||
if result == nil:
|
||||
# XXX: hmm, what kind of symbols will end up here?
|
||||
# do we really need to try the overload resolution?
|
||||
n[0] = prc
|
||||
@@ -1674,9 +1663,11 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode =
|
||||
# `proc fun(a: var int): var int = a`
|
||||
discard
|
||||
else: discard
|
||||
let valid = isAssignable(c, n, isLent)
|
||||
let valid = isAssignable(c, n)
|
||||
if valid != arLValue:
|
||||
if valid == arLocalLValue:
|
||||
if valid in {arAddressableConst, arLentValue} and isLent:
|
||||
discard "ok"
|
||||
elif valid == arLocalLValue:
|
||||
localError(c.config, n.info, errXStackEscape % renderTree(n, {renderNoComments}))
|
||||
else:
|
||||
localError(c.config, n.info, errExprHasNoAddress)
|
||||
@@ -1800,7 +1791,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||
if le == nil:
|
||||
localError(c.config, a.info, "expression has no type")
|
||||
elif (skipTypes(le, {tyGenericInst, tyAlias, tySink}).kind notin {tyVar} and
|
||||
isAssignable(c, a) in {arNone, arLentValue}) or (
|
||||
isAssignable(c, a) in {arNone, arLentValue, arAddressableConst}) or (
|
||||
skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs} and views notin c.features):
|
||||
# Direct assignment to a discriminant is allowed!
|
||||
localError(c.config, a.info, errXCannotBeAssignedTo %
|
||||
@@ -1857,9 +1848,6 @@ proc semReturn(c: PContext, n: PNode): PNode =
|
||||
localError(c.config, n.info, "'return' not allowed here")
|
||||
|
||||
proc semProcBody(c: PContext, n: PNode): PNode =
|
||||
when defined(nimsuggest):
|
||||
if c.graph.config.expandDone():
|
||||
return n
|
||||
openScope(c)
|
||||
result = semExpr(c, n)
|
||||
if c.p.resultSym != nil and not isEmptyType(result.typ):
|
||||
@@ -2286,7 +2274,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||
markUsed(c, n.info, s)
|
||||
checkSonsLen(n, 2, c.config)
|
||||
result[0] = newSymNode(s, n[0].info)
|
||||
result[1] = semAddrArg(c, n[1], s.name.s == "unsafeAddr")
|
||||
result[1] = semAddrArg(c, n[1])
|
||||
result.typ = makePtrType(c, result[1].typ)
|
||||
of mTypeOf:
|
||||
markUsed(c, n.info, s)
|
||||
@@ -2598,7 +2586,7 @@ proc semBlock(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
||||
labl.owner = c.p.owner
|
||||
n[0] = newSymNode(labl, n[0].info)
|
||||
suggestSym(c.graph, n[0].info, labl, c.graph.usageSym)
|
||||
styleCheckDef(c, labl)
|
||||
styleCheckDef(c.config, labl)
|
||||
onDef(n[0].info, labl)
|
||||
n[1] = semExpr(c, n[1], flags)
|
||||
n.typ = n[1].typ
|
||||
@@ -2786,6 +2774,12 @@ proc enumFieldSymChoice(c: PContext, n: PNode, s: PSym): PNode =
|
||||
onUse(info, a)
|
||||
a = nextOverloadIter(o, c, n)
|
||||
|
||||
proc semPragmaStmt(c: PContext; n: PNode) =
|
||||
if c.p.owner.kind == skModule:
|
||||
pragma(c, c.p.owner, n, stmtPragmas+stmtPragmasTopLevel, true)
|
||||
else:
|
||||
pragma(c, c.p.owner, n, stmtPragmas, true)
|
||||
|
||||
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
when defined(nimCompilerStacktraceHints):
|
||||
setFrameMsg c.config$n.info & " " & $n.kind
|
||||
@@ -2797,19 +2791,6 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
echo ("<", c.config$n.info, n, ?.result.typ)
|
||||
|
||||
result = n
|
||||
when defined(nimsuggest):
|
||||
var expandStarted = false
|
||||
if c.config.ideCmd == ideExpand and not c.config.expandProgress and
|
||||
((n.kind in {nkFuncDef, nkProcDef, nkIteratorDef, nkTemplateDef, nkMethodDef, nkConverterDef} and
|
||||
n.info.exactEquals(c.config.expandPosition)) or
|
||||
(n.kind in {nkCall, nkCommand} and
|
||||
n[0].info.exactEquals(c.config.expandPosition))):
|
||||
expandStarted = true
|
||||
c.config.expandProgress = true
|
||||
if c.config.expandLevels == 0:
|
||||
c.config.expandNodeResult = $n
|
||||
suggestQuit()
|
||||
|
||||
if c.config.cmd == cmdIdeTools: suggestExpr(c, n)
|
||||
if nfSem in n.flags: return
|
||||
case n.kind
|
||||
@@ -2888,7 +2869,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
of nkBind:
|
||||
message(c.config, n.info, warnDeprecated, "bind is deprecated")
|
||||
result = semExpr(c, n[0], flags)
|
||||
of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy:
|
||||
of nkTypeOfExpr..nkTupleClassTy, nkStaticTy, nkRefTy..nkEnumTy:
|
||||
if c.matchedConcept != nil and n.len == 1:
|
||||
let modifier = n.modifierTypeKindOfNode
|
||||
if modifier != tyNone:
|
||||
@@ -3029,7 +3010,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
# the node is left intact for now
|
||||
discard
|
||||
of nkStaticExpr: result = semStaticExpr(c, n[0])
|
||||
of nkAsgn, nkFastAsgn: result = semAsgn(c, n)
|
||||
of nkAsgn: result = semAsgn(c, n)
|
||||
of nkBlockStmt, nkBlockExpr: result = semBlock(c, n, flags)
|
||||
of nkStmtList, nkStmtListExpr: result = semStmtList(c, n, flags)
|
||||
of nkRaiseStmt: result = semRaise(c, n)
|
||||
@@ -3047,7 +3028,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
of nkUsingStmt: result = semUsing(c, n)
|
||||
of nkAsmStmt: result = semAsm(c, n)
|
||||
of nkYieldStmt: result = semYield(c, n)
|
||||
of nkPragma: pragma(c, c.p.owner, n, stmtPragmas, true)
|
||||
of nkPragma: semPragmaStmt(c, n)
|
||||
of nkIteratorDef: result = semIterator(c, n)
|
||||
of nkProcDef: result = semProc(c, n)
|
||||
of nkFuncDef: result = semFunc(c, n)
|
||||
@@ -3108,8 +3089,3 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
localError(c.config, n.info, "invalid expression: " &
|
||||
renderTree(n, {renderNoComments}))
|
||||
if result != nil: incl(result.flags, nfSem)
|
||||
|
||||
when defined(nimsuggest):
|
||||
if expandStarted:
|
||||
c.config.expandNodeResult = $result
|
||||
suggestQuit()
|
||||
|
||||
@@ -17,6 +17,9 @@ import
|
||||
|
||||
from system/memory import nimCStrLen
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
proc errorType*(g: ModuleGraph): PType =
|
||||
## creates a type representing an error state
|
||||
result = newType(tyError, nextTypeId(g.idgen), g.owners[^1])
|
||||
@@ -292,13 +295,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; idgen: IdGenerator; g: ModuleGraph): P
|
||||
else: result = newStrNodeT("true", n, g)
|
||||
of mFloatToStr: result = newStrNodeT($getFloat(a), n, g)
|
||||
of mCStrToStr, mCharToStr:
|
||||
if a.kind == nkBracket:
|
||||
var s = ""
|
||||
for b in a.sons:
|
||||
s.add b.getStrOrChar
|
||||
result = newStrNodeT(s, n, g)
|
||||
else:
|
||||
result = newStrNodeT(getStrOrChar(a), n, g)
|
||||
result = newStrNodeT(getStrOrChar(a), n, g)
|
||||
of mStrToStr: result = newStrNodeT(getStrOrChar(a), n, g)
|
||||
of mEnumToStr: result = newStrNodeT(ordinalValToString(a, g), n, g)
|
||||
of mArrToSeq:
|
||||
|
||||
@@ -179,7 +179,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
|
||||
proc addTempDecl(c: PContext; n: PNode; kind: TSymKind) =
|
||||
let s = newSymS(skUnknown, getIdentNode(c, n), c)
|
||||
addPrelimDecl(c, s)
|
||||
styleCheckDef(c, n.info, s, kind)
|
||||
styleCheckDef(c.config, n.info, s, kind)
|
||||
onDef(n.info, s)
|
||||
|
||||
proc semGenericStmt(c: PContext, n: PNode,
|
||||
|
||||
@@ -145,7 +145,11 @@ proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) =
|
||||
if sfGenSym in param.flags:
|
||||
idTablePut(symMap, params[i].sym, result.typ.n[param.position+1].sym)
|
||||
freshGenSyms(c, b, result, orig, symMap)
|
||||
b = semProcBody(c, b)
|
||||
|
||||
if sfBorrow notin orig.flags:
|
||||
# We do not want to generate a body for generic borrowed procs.
|
||||
# As body is a sym to the borrowed proc.
|
||||
b = semProcBody(c, b)
|
||||
result.ast[bodyPos] = hloBody(c, b)
|
||||
excl(result.flags, sfForward)
|
||||
trackProc(c, result, result.ast[bodyPos])
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user