Compare commits

..

64 Commits

Author SHA1 Message Date
ringabout
aacf94d72c tiny 2022-12-15 17:07:11 +08:00
ringabout
c1b90783eb fixes setInheritable 2022-12-15 17:01:27 +08:00
metagn
9a50033d5b generic define pragma + string alias (#20979)
* generic `define` pragma + string alias

* clean

* add tests and document

* remove char/float, minimize changelog
2022-12-13 21:20:55 +01:00
Aditya Siram
2564b5c938 Fix #20416. Enable the recursion limit for ref/ptr types. (#21092) 2022-12-13 22:57:07 +08:00
Xavier Noria
e4aadcf1c1 Document that system:pop() may raise IndexDefect (#21070)
* Document system:pop() may raise IndexDefect

* Add backticks to KeyError
2022-12-13 08:47:01 +01:00
Jake Leahy
7ae7832f76 JS backend properly extends string with setLen (#21087)
* Add test case

* Extend string with '0' when setting length to be longer
2022-12-13 08:43:37 +01:00
Jake Leahy
1fefb8e92a Refactor JS sourcemap generator (#21053)
* Parse the new line format

* Fix pattern

Didn't have space after the path

* Remove duplicate sources

Sources would sometimes double up with a new line at the end

* Remove unused variable

* Refactor sourcemap.nim

Removes the multiple translations needed, now goes from single high level type to the final SourceMap

Adds documentation for procs

* Line numbers line up properly now

Files aren't linking correctly though

* Files now link up correctly

Lines are sometimes off but overall seems pretty good

Just need to implement parser

* Add column info to output

Add sourceMappingURL to rope directly to prevent copy

* Properly handle columns

* Remove debug lines

* Add testcase

* Finish testcase

* Use the outdir folder instead of the folder the test is in to find the sourcemap

Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
2022-12-13 12:21:51 +08:00
ringabout
d84f64d2e7 add CI for version-2-0 branch (#21084) 2022-12-13 09:52:35 +08:00
Jake Leahy
b0a850adbf Nimsuggest now defines the backends symbol (#21083)
* Add testcase

* Define the backend symbol

* Remove unneeded whitespace
2022-12-12 22:19:02 +01:00
ringabout
4388636010 fixes #21043; fixes a named exception in the infixAs expression which generate an implicit uninitialized let statement (#21081)
* fixes #21043; fixes a named exception in the infixAs expression which generate an implicit uninitialized let statement

* Update compiler/sempass2.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2022-12-12 23:14:44 +08:00
ringabout
584cfa6af8 remove implicitDeref feature enum (#21075)
remove implicitDeref feature
2022-12-12 15:59:09 +01:00
ringabout
fd7da7da62 add a changelog for nimble (#21078) 2022-12-12 14:57:27 +01:00
ringabout
19923aa8b7 work around chronos (#21079)
* work around chronos

chronos has tests against the devel branch, it will be eventually fine.

* Apply suggestions from code review

* Update testament/important_packages.nim
2022-12-12 21:14:24 +08:00
Andreas Rumpf
28bed059aa closes #20808 (#21077) 2022-12-12 11:46:51 +01:00
Jake Leahy
cbeefc877c Docs expand using parameters (#21076)
* Trying to fix by changing renderer

* add renderExpandUsing flag

This flag makes the renderer expand parameters that use using statement to have their full type

* Update docs

* Make comment better explain why checking for nkSym

* Fix nil access when macro/template has parameter with no type

* Fix nil access when node is not semmed yet
2022-12-12 07:44:17 +01:00
ringabout
b981f3eeb7 ship a modern nimble with lock files support (#21061)
* change `include genode/env` to an import 

ref 0b262e9496 (diff-8718bd20d8f61d6638d3d64b19efc31bcd40a6d5be8215b2a1f0b75ed93e8d56)

* fixes comments

* ship a modern nimble with lock files support

* not sure whether the latest nimble has a regression

now I'm trying  0.14.0

* change `pkgs` to `pkgs2` (#21073)

* overwrite problematic packages

* Apply suggestions from code review

* Apply suggestions from code review

* Apply suggestions from code review
2022-12-12 07:25:39 +01:00
Bung
5917c2d5b7 fix #15836 proc arg return type auto unexpectly match proc with concr… (#21065)
* fix #15836 proc arg return type auto unexpectly match proc with concrete type

* fix #16244

* add test case for #12869
2022-12-12 06:26:18 +01:00
Andreas Rumpf
3812d91390 alternative, much simpler algorithm for strict func checking (#21066)
* alternative, much simpler algorithm for strict func checking

* forgot to git add new compiler module

* new spec is incredibly simple to describe

* fixes bigints regression

* typos

* closes #16305; closes #17387; closes #20863
2022-12-11 16:58:50 +01:00
Jake Leahy
c7493bbdd0 multisync now allows tuples in return type (#21074)
* Add test case

* Use .toStrLit() on param node first

This means that more complex types are fully rendered
2022-12-11 14:44:41 +01:00
Bung
1585bfec3b fix #16758 Nim crashes in fixAbstractType (#20855)
* fix #16758 Nim crashes in fixAbstractType

* Update compiler/semexprs.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2022-12-11 06:58:29 +01:00
ringabout
07be1791ba fix #21045; getTime with vmopsDanger is broken; alternative to #21054 (#21056)
* fix #21045 getTime with vmopsDanger is broken; alternative to #21054

* typo
2022-12-10 18:57:19 +01:00
ringabout
7a18c1ef44 clean up the documentation of threads (#21067)
* clean up the documentation of threads

* cleanup
2022-12-10 23:23:31 +08:00
Andreas Rumpf
b59c657be3 fixes #21062 (#21068) 2022-12-10 16:21:43 +01:00
Andreas Rumpf
2ebd71bfd4 tiny refactoring related to sink parameter inference logic (#21064)
* tiny refactoring related to sink parameter inference logic

* Update compiler/sempass2.nim
2022-12-10 15:42:22 +01:00
Jake Leahy
f330b33e2b Use a unique name for template in async macro return (#21058)
Use unique template name
2022-12-10 09:15:45 +08:00
ringabout
db56fc3bcb Revert "fix #15836 proc arg return type auto unexpectly match proc with concr…" (#21057)
Revert "fix #15836 proc arg return type auto unexpectly match proc with concr… (#21044)"

This reverts commit 0cd9bdcf9f.
2022-12-09 21:38:55 +01:00
Jake Leahy
da3274d1b3 Implicit return working for async proc (#20933)
* Implicit return working for asyncdispatch proc

Closes #11558

* Test case

* Test that return value is actually used

* Update tests/async/t11558.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2022-12-09 18:10:33 +01:00
Bung
0cd9bdcf9f fix #15836 proc arg return type auto unexpectly match proc with concr… (#21044)
fix #15836 proc arg return type auto unexpectly match proc with concrete type
2022-12-09 18:01:13 +01:00
ringabout
ef190f349d remove duplicate assignment (#21050)
`newNodeIT` has already assigned `n.typ` to x.
2022-12-09 08:50:35 +08:00
Juan Carlos
f8e64d879c Remove deprecated rightSize (#21011)
* Remove deprecated rightSize nop

* Remove deprecated rightSize nop
2022-12-08 15:26:58 +01:00
Vindaar
0a1d4ba842 fix issue #20922 by handling missing expr in exprList for tkOf (#20930)
* fix issue #20922 by handling missing expr in `exprList` for `tkOf`

* fix line numbers in test case

* rewrite exprList requiring expr, add optionalExprList for except

As suggested by @metagn.

* update test case to reflect new code

* update grammar.txt

* update line numbers in test case taking into account nimout

Given the number of errors that are produced it seems easier to do it
this way instead of using `tt.Error`.
2022-12-08 10:59:13 +01:00
Xavier Noria
e669835665 Mention toSet in the docs of the set type (#21037) 2022-12-08 10:58:00 +01:00
Emery Hemingway
696def2bf7 macros.customPragmaNode: walk brackets on brackets (#21040) 2022-12-08 10:57:26 +01:00
ringabout
c5eb3fd4f0 fixes #9839; fixes noReturn pragma doesn't work for non-simple templates (#21048) 2022-12-08 10:37:02 +01:00
ringabout
4480fd3e93 fixes #16656; add nre to lib.md (#21042) 2022-12-08 08:51:31 +01:00
ringabout
4da3ead294 fixes strictnotnil documentation; comment unfinished sections (#21041)
fixes documentation; comment unfinished sections
2022-12-08 10:06:48 +08:00
ringabout
53fbb497e9 add a changelog for std/cmdline (#21039)
for a changelog for `std/cmdline`
2022-12-08 10:06:25 +08:00
ringabout
d6b485493d switch to the official URL of nimquery (#21038)
ref 3f728fb480
2022-12-07 11:33:31 +08:00
ringabout
9ba07edb2e build the documentation of official packages (#20986)
* remove db stuffs

* remove punycode

* remove

* fixes script

* add cloner

* patches

* disable

* patch

* fixes external packages

* disable two packages

* preview documentation build

* try again

* fixes URL

* fixes a bug

* simplify

* fixes documentaion

* fixes

* Apply suggestions from code review
2022-12-06 22:37:16 +08:00
metagn
4ca2dcb404 Named arguments in commands + many grammar fixes (#20994)
* Breaking parser changes, implement https://github.com/nim-lang/RFCs/issues/442

Types are separated from expressions and better reflected in the grammar.

* add test

* more accurate grammar

* fix keyword typedescs

* accept expressions in proc argument lists

* CI "fixes"

* fixes

* allow full ref expressions again, adapt old tests

* cleanup, fix some tests

* improve grammar, try and revert semtypes change

* restrict sigil binding to identOrLiteral

* fix, should have caught this immediately

* add changelog entry, fix double not nil bug

* correct grammar

* change section

* fix

* real fix hopefully

* fix test

* support LL(1) for tuples

* make grammar.txt too
2022-12-06 13:11:56 +01:00
ringabout
1564ae650f fixes #21027; cast expressions need a type (#21029)
* fixes #21027; cast expressions need a type

* Apply suggestions from code review

Thanks to @beef331
2022-12-06 13:09:50 +01:00
ringabout
b2c7019006 definite assignment analysis for let (#21024)
* draft for let daa

* patch

* fixes bugs

* errors for global let variable reassignments

* checkpoint

* out param accepts let

* add more tests

* add documentation

* merge tests
2022-12-06 10:19:12 +01:00
metagn
6d8cf25bd7 deprecate do: meaning do (): + misc cleanup (#20927)
* test disable do: block lambda lifting

* fix last test [skip ci]

* deprecate `do:` meaning `do ():` + misc cleanup

closes https://github.com/nim-lang/RFCs/issues/486

* oops

* fix

* no idea what could be causing nimsuggest failure other than this

* ensure ci works
2022-12-06 09:44:26 +01:00
metagn
739e1badb6 stdlib organization & documentation improvements (#20971)
* stdlib organization & documentation improvements

* fix CI

* Update doc/lib.md

Co-authored-by: Juan Carlos <juancarlospaco@gmail.com>

* fix ci, remove jshttpcore, export in jsfetch instead

* fix alphabetical order violations

* add cmdline, db_odbc

Co-authored-by: Juan Carlos <juancarlospaco@gmail.com>
2022-12-06 09:37:03 +01:00
Bung
5d469686b0 fix #20829 Regression in int64 type matching since (#21019)
fix #20829 Regression in int64 type matching
2022-12-06 07:44:54 +01:00
ringabout
feb0481ba3 Revert "fixes #20883; Unspecified generic on default value segfaults the compiler" (#21028)
Revert "fixes #20883; Unspecified generic on default value segfaults the compiler (#20917)"

This reverts commit 10b6e4f5b4.
2022-12-06 12:50:16 +08:00
metagn
e98efdcc5e fix #16639 (#21017) 2022-12-05 22:52:49 +01:00
Yuriy Glukhov
c47d5196be Dont produce initing moves for sfNoInit variables in closure env (#21026) 2022-12-05 22:49:31 +01:00
ringabout
b83bd282dc fixes #20954; bounchecks for len(toOpenArray()) [backport] (#20956)
* bounchecks for len(toOpenArray())

* add a testcase
2022-12-05 22:27:18 +01:00
ringabout
a8090f7d65 fixes isLocalVarSym; an implicit global is a global nonetheless (#21025)
fixes isLocalVarSym; an implicit global is a global nonetheless
2022-12-05 22:24:36 +01:00
Dmitry Arkhipenko
794bcc8029 Add: missing nintendo-switch define (#21009) 2022-12-05 07:24:24 +01:00
ringabout
6f96c4bc96 ref #20846; give a deprecation message for overriding = hook (#21020)
give a deprecation message for overriding `=` hook
2022-12-05 07:13:51 +01:00
Juan Carlos
1b5e03f975 Remove deprecated posix.CLONE_STOPPED (#21012)
* Remove deprecated CLONE_STOPPED

* Remove deprecated CLONE_STOPPED
2022-12-05 06:53:40 +01:00
ringabout
78b387d948 fixes deprecation message by update action versions (#21021) 2022-12-05 12:37:23 +08:00
metagn
5536f74992 fix #20996 (#21016)
* fix #20996

* hopefully fix
2022-12-04 20:37:23 +01:00
ringabout
55373e65b4 unpublic arrayWith and rename it to nimArrayWith (#21006)
* unpublic arrayWith

* unindent
2022-12-04 15:39:14 +08:00
Michal Maršálek
83493e4294 Update prelude example (#21005)
comment to match what's actually being imported.
2022-12-03 21:25:49 +08:00
ringabout
ece41d2605 minor cleanup; correct the module name (#21001)
* minor cleanup 

follow up https://github.com/nim-lang/Nim/pull/20946

* Update lib/std/cmdline.nim

* Update lib/std/cmdline.nim

Co-authored-by: Clay Sweetser <Varriount@users.noreply.github.com>
2022-12-02 15:10:08 -05:00
metagn
79ec6d677c Add back error message to tprevent_forloopvar_mutations (#20992) 2022-12-02 16:19:26 +08:00
ringabout
10b6e4f5b4 fixes #20883; Unspecified generic on default value segfaults the compiler (#20917)
test CI
2022-12-01 22:04:11 +01:00
ringabout
8266750497 [unittest] remove unnecessay export for testing (#20868) 2022-12-01 14:31:48 -05:00
Ikko Ashimine
a104aa4714 IC: fix typo in rodfiles.nim (#20989)
preceeded -> preceded
2022-12-01 14:26:59 -05:00
Bung
658b28dc57 tyInt tyUint fit target int bit width (#20829) 2022-12-01 13:34:00 +01:00
ringabout
a70d3abd37 replace data init function with consts for typeinfov2 (#20977)
* replace data initial function with consts for typeinfov2

* fixes

* fixes

* workaround C++

* C++ keeps the previous implementaion

* fixes
2022-12-01 13:29:58 +01:00
170 changed files with 2447 additions and 4379 deletions

View File

@@ -4,6 +4,7 @@ on:
push:
branches:
- 'devel'
- 'version-2-0'
- 'version-1-6'
- 'version-1-2'
@@ -27,12 +28,12 @@ jobs:
NIM_TESTAMENT_BATCH: ${{ matrix.batch }}
steps:
- name: 'Checkout'
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 2
- name: 'Install node.js 16.x'
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: '16.x'

View File

@@ -17,12 +17,12 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: 'Checkout'
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 2
- name: 'Install node.js 16.x'
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: '16.x'

View File

@@ -80,6 +80,11 @@
- Removed two type pragma syntaxes deprecated since 0.20, namely
`type Foo = object {.final.}`, and `type Foo {.final.} [T] = object`.
- `foo a = b` now means `foo(a = b)` rather than `foo(a) = b`. This is consistent
with the existing behavior of `foo a, b = c` meaning `foo(a, b = c)`.
This decision was made with the assumption that the old syntax was used rarely;
if your code used the old syntax, please be aware of this change.
- [Overloadable enums](https://nim-lang.github.io/Nim/manual.html#overloadable-enum-value-names) and Unicode Operators
are no longer experimental.
@@ -107,8 +112,27 @@
- 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.
## Standard library additions and changes
[//]: # "Changes:"
@@ -145,6 +169,7 @@
- Added new modules which were part of `std/os`:
- Added `std/oserrors` for OS error reporting. Added `std/envvars` for environment variables handling.
- Added `std/paths`, `std/dirs`, `std/files`, `std/symlinks` and `std/appdirs`.
- Added `std/cmdline` for reading command line parameters.
- Added `sep` parameter in `std/uri` to specify the query separator.
- Added bindings to [`Array.shift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift)
and [`queueMicrotask`](https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask)
@@ -181,6 +206,11 @@
- Removed deprecated `` httpcore.`==` ``.
- Removed deprecated `std/posix.CMSG_SPACE` and `std/posix.CMSG_LEN` that takes wrong argument types.
- Removed deprecated `osproc.poDemon`, symbol with typo.
- Removed deprecated `tables.rightSize`.
- Removed deprecated `posix.CLONE_STOPPED`.
## Language changes
@@ -191,9 +221,33 @@
- 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".
- `defined` now accepts identifiers separated by dots, i.e. `defined(a.b.c)`.
In the command line, this is defined as `-d:a.b.c`. Older versions can
use accents as in ``defined(`a.b.c`)`` to access such defines.
- Compile-time define changes:
- `defined` now accepts identifiers separated by dots, i.e. `defined(a.b.c)`.
In the command line, this is defined as `-d:a.b.c`. Older versions can
use accents as in ``defined(`a.b.c`)`` to access such defines.
- [Define pragmas for constants](https://nim-lang.github.io/Nim/manual.html#implementation-specific-pragmas-compileminustime-define-pragmas)
now support a string argument for qualified define names.
```nim
# -d:package.FooBar=42
const FooBar {.intdefine: "package.FooBar".}: int = 5
echo FooBar # 42
```
This was added to help disambiguate similar define names for different packages.
In older versions, this could only be achieved with something like the following:
```nim
const FooBar = block:
const `package.FooBar` {.intdefine.}: int = 5
`package.FooBar`
```
- A generic `define` pragma for constants has been added that interprets
the value of the define based on the type of the constant value.
See the [experimental manual](https://nim-lang.github.io/Nim/manual_experimental.html#generic-define-pragma)
for a list of supported types.
- [Macro pragmas](https://nim-lang.github.io/Nim/manual.html#userminusdefined-pragmas-macro-pragmas) changes:
- Templates now accept macro pragmas.
- Macro pragmas for var/let/const sections have been redesigned in a way that works
@@ -226,12 +280,6 @@
Baz = object
```
- Redefining templates with the same signature implicitly was previously
allowed to support certain macro code. A `{.redefine.}` pragma has been
added to make this work explicitly, and a warning is generated in the case
where it is implicit. This behavior only applies to templates, redefinition
is generally disallowed for other symbols.
- A new form of type inference called [top-down inference](https://nim-lang.github.io/Nim/manual_experimental.html#topminusdown-type-inference)
has been implemented for a variety of basic cases. For example, code like the following now compiles:
@@ -268,6 +316,4 @@
## Tool changes
- Nim now supports Nimble version 0.14 which added support for lock-files. This is done by
a simple configuration change setting that you can do yourself too. In `$nim/config/nim.cfg`
replace `pkgs` by `pkgs2`.
- Nim now ships Nimble version 0.14 which added support for lock-files. Libraries are stored in `$nimbleDir/pkgs2` (it was `$nimbleDir/pkgs`).

View File

@@ -712,7 +712,7 @@ type
mEqIdent, mEqNimrodNode, mSameNodeType, mGetImpl, mNGenSym,
mNHint, mNWarning, mNError,
mInstantiationInfo, mGetTypeInfo, mGetTypeInfoV2,
mNimvm, mIntDefine, mStrDefine, mBoolDefine, mRunnableExamples,
mNimvm, mIntDefine, mStrDefine, mBoolDefine, mGenericDefine, mRunnableExamples,
mException, mBuiltinType, mSymOwner, mUncheckedArray, mGetImplTransf,
mSymIsInstantiationOf, mNodeId, mPrivateAccess, mZeroDefault
@@ -2047,6 +2047,9 @@ template detailedInfo*(sym: PSym): string =
proc isInlineIterator*(typ: PType): bool {.inline.} =
typ.kind == tyProc and tfIterator in typ.flags and typ.callConv != ccClosure
proc isIterator*(typ: PType): bool {.inline.} =
typ.kind == tyProc and tfIterator in typ.flags
proc isClosureIterator*(typ: PType): bool {.inline.} =
typ.kind == tyProc and tfIterator in typ.flags and typ.callConv == ccClosure

View File

@@ -1879,9 +1879,13 @@ 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:
@@ -3279,6 +3283,7 @@ proc getNullValueAux(p: BProc; t: PType; obj, constOrNil: PNode,
if constOrNil != nil:
for i in 1..<constOrNil.len:
if constOrNil[i].kind == nkExprColonExpr:
assert constOrNil[i][0].kind == nkSym, "illformed object constr; the field is not a sym"
if constOrNil[i][0].sym.name.id == field.name.id:
genBracedInit(p, constOrNil[i][1], isConst, field.typ, result)
return

View File

@@ -1348,7 +1348,7 @@ proc genDisplay(t: PType, depth: int): Rope =
result.add seqs[0]
result.add "}"
proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineInfo) =
proc genTypeInfoV2OldImpl(m: BModule; t, origType: PType, name: Rope; info: TLineInfo) =
cgsym(m, "TNimTypeV2")
m.s[cfsStrData].addf("N_LIB_PRIVATE TNimTypeV2 $1;$n", [name])
@@ -1364,7 +1364,6 @@ proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineIn
let objDepth = if t.kind == tyObject: getObjDepth(t) else: -1
if t.kind in {tyObject, tyDistinct} and incompleteType(t):
localError(m.config, info, "request for RTTI generation for incomplete object: " &
typeToString(t))
@@ -1390,6 +1389,48 @@ proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineIn
if t.kind == tyObject and t.len > 0 and t[0] != nil and optEnableDeepCopy in m.config.globalOptions:
discard genTypeInfoV1(m, t, info)
proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineInfo) =
cgsym(m, "TNimTypeV2")
m.s[cfsStrData].addf("N_LIB_PRIVATE TNimTypeV2 $1;$n", [name])
var flags = 0
if not canFormAcycle(t): flags = flags or 1
var typeEntry = newRopeAppender()
addf(typeEntry, "N_LIB_PRIVATE TNimTypeV2 $1 = {", [name])
add(typeEntry, ".destructor = (void*)")
genHook(m, t, info, attachedDestructor, typeEntry)
let objDepth = if t.kind == tyObject: getObjDepth(t) else: -1
if t.kind in {tyObject, tyDistinct} and incompleteType(t):
localError(m.config, info, "request for RTTI generation for incomplete object: " &
typeToString(t))
addf(typeEntry, ", .size = sizeof($1), .align = (NI16) NIM_ALIGNOF($1), .depth = $2",
[getTypeDesc(m, t), rope(objDepth)])
if objDepth >= 0:
let objDisplay = genDisplay(t, objDepth)
let objDisplayStore = getTempName(m)
m.s[cfsVars].addf("static NIM_CONST $1 $2[$3] = $4;$n", [getTypeDesc(m, getSysType(m.g.graph, unknownLineInfo, tyUInt32), skVar), objDisplayStore, rope(objDepth+1), objDisplay])
addf(typeEntry, ", .display = $1", [rope(objDisplayStore)])
if isDefined(m.config, "nimTypeNames"):
var typeName: Rope
if t.kind in {tyObject, tyDistinct}:
typeName = genTypeInfo2Name(m, t)
else:
typeName = rope("NIM_NIL")
addf(typeEntry, ", .name = $1", [typeName])
add(typeEntry, ", .traceImpl = (void*)")
genHook(m, t, info, attachedTrace, typeEntry)
addf(typeEntry, ", .flags = $1};$n", [rope(flags)])
m.s[cfsVars].add typeEntry
if t.kind == tyObject and t.len > 0 and t[0] != nil and optEnableDeepCopy in m.config.globalOptions:
discard genTypeInfoV1(m, t, info)
proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
let origType = t
# distinct types can have their own destructors
@@ -1423,7 +1464,10 @@ proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
return prefixTI.rope & result & ")".rope
m.g.typeInfoMarkerV2[sig] = (str: result, owner: owner)
genTypeInfoV2Impl(m, t, origType, result, info)
if m.compileToCpp:
genTypeInfoV2OldImpl(m, t, origType, result, info)
else:
genTypeInfoV2Impl(m, t, origType, result, info)
result = prefixTI.rope & result & ")".rope
proc openArrayToTuple(m: BModule; t: PType): PType =

View File

@@ -149,3 +149,5 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasOutParams")
defineSymbol("nimHasSystemRaisesDefect")
defineSymbol("nimHasWarnUnnamedBreak")
defineSymbol("nimHasGenericDefine")
defineSymbol("nimHasDefineAliases")

View File

@@ -558,7 +558,7 @@ proc runAllExamples(d: PDoc) =
proc quoted(a: string): string = result.addQuoted(a)
proc toInstantiationInfo(conf: ConfigRef, info: TLineInfo): auto =
proc toInstantiationInfo(conf: ConfigRef, info: TLineInfo): (string, int, int) =
# xxx expose in compiler/lineinfos.nim
(conf.toMsgFilename(info), info.line.int, info.col.int + ColOffset)
@@ -962,7 +962,7 @@ proc toLangSymbol(k: TSymKind, n: PNode, baseName: string): LangSymbol =
var literal = ""
var r: TSrcGen
initTokRender(r, genNode, {renderNoBody, renderNoComments,
renderNoPragmas, renderNoProcDefs})
renderNoPragmas, renderNoProcDefs, renderExpandUsing})
var kind = tkEof
while true:
getNextTok(r, kind, literal)
@@ -995,7 +995,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
var r: TSrcGen
# Obtain the plain rendered string for hyperlink titles.
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments,
renderNoPragmas, renderNoProcDefs})
renderNoPragmas, renderNoProcDefs, renderExpandUsing})
while true:
getNextTok(r, kind, literal)
if kind == tkEof:
@@ -1028,7 +1028,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
rstLangSymbol, priority = symbolPriority(k), info = lineinfo)
nodeToHighlightedHtml(d, n, result, {renderNoBody, renderNoComments,
renderDocComments, renderSyms}, symbolOrIdEnc)
renderDocComments, renderSyms, renderExpandUsing}, symbolOrIdEnc)
let seeSrc = genSeeSrc(d, toFullPath(d.conf, n.info), n.info.line.int)
@@ -1094,7 +1094,7 @@ proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonItem =
name = getName(d, nameNode)
comm = genRecComment(d, n)
r: TSrcGen
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments, renderExpandUsing})
result.json = %{ "name": %name, "type": %($k), "line": %n.info.line.int,
"col": %n.info.col}
if comm != nil:

View File

@@ -24,7 +24,7 @@ when defined(nimPreviewSlimSystem):
## `RodFile` represents a Rod File (versioned binary format), and the
## associated data for common interactions such as IO and error tracking
## (`RodFileError`). The file format broken up into sections (`RodSection`)
## and preceeded by a header (see: `cookie`). The precise layout, section
## and preceded by a header (see: `cookie`). The precise layout, section
## ordering and data following the section are determined by the user. See
## `ic.loadRodFile`.
##

View File

@@ -829,7 +829,10 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSing
if ri.kind != nkEmpty:
result.add moveOrCopy(v, ri, c, s, if v.kind == nkSym: {IsDecl} else: {})
elif ri.kind == nkEmpty and c.inLoop > 0:
result.add moveOrCopy(v, genDefaultCall(v.typ, c, v.info), c, s, if v.kind == nkSym: {IsDecl} else: {})
let skipInit = v.kind == nkDotExpr and # Closure var
sfNoInit in v[1].sym.flags
if not skipInit:
result.add moveOrCopy(v, genDefaultCall(v.typ, c, v.info), c, s, if v.kind == nkSym: {IsDecl} else: {})
else: # keep the var but transform 'ri':
var v = copyNode(n)
var itCopy = copyNode(it)

View File

@@ -724,8 +724,9 @@ proc hasFrameInfo(p: PProc): bool =
((p.prc == nil) or not (sfPure in p.prc.flags))
proc lineDir(config: ConfigRef, info: TLineInfo, line: int): Rope =
ropes.`%`("/* line $2 \"$1\" */$n",
[rope(toFullPath(config, info)), rope(line)])
"/* line $2:$3 \"$1\" */$n" % [
rope(toFullPath(config, info)), rope(line), rope(info.toColumn)
]
proc genLineDir(p: PProc, n: PNode) =
let line = toLinenumber(n.info)
@@ -2208,7 +2209,9 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2")
else: binaryExpr(p, n, r, "subInt", "$1 = subInt($3, $2)", true)
of mSetLengthStr:
binaryExpr(p, n, r, "mnewString", "($1.length = $2)")
binaryExpr(p, n, r, "mnewString",
"""if ($1.length < $2) { for (var i = $3.length; i < $4; ++i) $3.push(0); }
else {$3.length = $4; }""")
of mSetLengthSeq:
var x, y: TCompRes
gen(p, n[1], x)
@@ -2885,7 +2888,8 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
# Generate an optional source map.
if optSourcemap in m.config.globalOptions:
var map: SourceMap
(code, map) = genSourceMap($(code), outFile.string)
map = genSourceMap($code, outFile.string)
code &= "\n//# sourceMappingURL=$#.map" % [outFile.string]
writeFile(outFile.string & ".map", $(%map))
# Check if the generated JS code matches the output file, or else
# write it to the file.

View File

@@ -83,8 +83,9 @@ type
warnPtrToCstringConv = "PtrToCstringConv",
warnEffect = "Effect",
warnCastSizes = "CastSizes"
warnTemplateRedefinition = "TemplateRedefinition",
warnImplicitTemplateRedefinition = "ImplicitTemplateRedefinition",
warnUnnamedBreak = "UnnamedBreak",
warnStmtListLambda = "StmtListLambda",
warnUser = "User",
# hints
hintSuccess = "Success", hintSuccessX = "SuccessX",
@@ -181,8 +182,9 @@ const
warnPtrToCstringConv: "unsafe conversion to 'cstring' from '$1'; this will become a compile time error in the future",
warnEffect: "$1",
warnCastSizes: "$1",
warnTemplateRedefinition: "template '$1' is implicitly redefined, consider adding an explicit .redefine pragma",
warnImplicitTemplateRedefinition: "template '$1' is implicitly redefined; this is deprecated, add an explicit .redefine pragma",
warnUnnamedBreak: "Using an unnamed break in a block is deprecated; Use a named block with a named break instead",
warnStmtListLambda: "statement list expression assumed to be anonymous proc; this is deprecated, use `do (): ...` or `proc () = ...` instead",
warnUser: "$1",
hintSuccess: "operation successful: $#",
# keep in sync with `testament.isSuccess`

View File

@@ -422,7 +422,7 @@ type SpellCandidate = object
msg: string
sym: PSym
template toOrderTup(a: SpellCandidate): auto =
template toOrderTup(a: SpellCandidate): (int, int, string) =
# `dist` is first, to favor nearby matches
# `depth` is next, to favor nearby enclosing scopes among ties
# `sym.name.s` is last, to make the list ordered and deterministic among ties

View File

@@ -196,7 +196,6 @@ type
ideRecompile, ideChanged, ideType, ideDeclaration
Feature* = enum ## experimental features; DO NOT RENAME THESE!
implicitDeref, # deadcode; remains here for backwards compatibility
dotOperators,
callOperator,
parallel,
@@ -457,7 +456,7 @@ when false:
fn(globalOptions)
fn(selectedGC)
const oldExperimentalFeatures* = {implicitDeref, dotOperators, callOperator, parallel}
const oldExperimentalFeatures* = {dotOperators, callOperator, parallel}
const
ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck,
@@ -865,7 +864,8 @@ const stdlibDirs* = [
"pure/concurrency",
"pure/unidecode", "impure",
"wrappers", "wrappers/linenoise",
"windows", "posix", "js"]
"windows", "posix", "js",
"deprecated/pure"]
const
pkgPrefix = "pkg/"

View File

@@ -79,7 +79,7 @@ type
smNormal, smAllowNil, smAfterDot
PrimaryMode = enum
pmNormal, pmTypeDesc, pmTypeDef, pmSkipSuffix
pmNormal, pmTypeDesc, pmTypeDef, pmTrySimple
proc parseAll*(p: var Parser): PNode
proc closeParser*(p: var Parser)
@@ -286,7 +286,8 @@ proc newIdentNodeP(ident: PIdent, p: Parser): PNode =
proc parseExpr(p: var Parser): PNode
proc parseStmt(p: var Parser): PNode
proc parseTypeDesc(p: var Parser): PNode
proc parseTypeDesc(p: var Parser, fullExpr = false): PNode
proc parseTypeDefValue(p: var Parser): PNode
proc parseParamList(p: var Parser, retColon = true): PNode
proc isSigilLike(tok: Token): bool {.inline.} =
@@ -406,6 +407,16 @@ proc parseSymbol(p: var Parser, mode = smNormal): PNode =
#if not isKeyword(p.tok.tokType): getTok(p)
result = p.emptyNode
proc equals(p: var Parser, a: PNode): PNode =
if p.tok.tokType == tkEquals:
result = newNodeP(nkExprEqExpr, p)
getTok(p)
#optInd(p, result)
result.add(a)
result.add(parseExpr(p))
else:
result = a
proc colonOrEquals(p: var Parser, a: PNode): PNode =
if p.tok.tokType == tkColon:
result = newNodeP(nkExprColonExpr, p)
@@ -414,14 +425,8 @@ proc colonOrEquals(p: var Parser, a: PNode): PNode =
#optInd(p, result)
result.add(a)
result.add(parseExpr(p))
elif p.tok.tokType == tkEquals:
result = newNodeP(nkExprEqExpr, p)
getTok(p)
#optInd(p, result)
result.add(a)
result.add(parseExpr(p))
else:
result = a
result = equals(p, a)
proc exprColonEqExpr(p: var Parser): PNode =
#| exprColonEqExpr = expr (':'|'=' expr)?
@@ -431,6 +436,14 @@ proc exprColonEqExpr(p: var Parser): PNode =
else:
result = colonOrEquals(p, a)
proc exprEqExpr(p: var Parser): PNode =
#| exprEqExpr = expr ('=' expr)?
var a = parseExpr(p)
if p.tok.tokType == tkDo:
result = postExprBlocks(p, a)
else:
result = equals(p, a)
proc exprList(p: var Parser, endTok: TokType, result: PNode) =
#| exprList = expr ^+ comma
when defined(nimpretty):
@@ -438,6 +451,24 @@ proc exprList(p: var Parser, endTok: TokType, result: PNode) =
getTok(p)
optInd(p, result)
# progress guaranteed
var a = parseExpr(p)
result.add(a)
while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof):
if p.tok.tokType != tkComma: break
getTok(p)
optInd(p, a)
var a = parseExpr(p)
result.add(a)
when defined(nimpretty):
dec p.em.doIndentMore
proc optionalExprList(p: var Parser, endTok: TokType, result: PNode) =
#| optionalExprList = expr ^* comma
when defined(nimpretty):
inc p.em.doIndentMore
getTok(p)
optInd(p, result)
# progress guaranteed
while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof):
var a = parseExpr(p)
result.add(a)
@@ -802,25 +833,24 @@ proc namedParams(p: var Parser, callee: PNode,
proc commandParam(p: var Parser, isFirstParam: var bool; mode: PrimaryMode): PNode =
if mode == pmTypeDesc:
result = simpleExpr(p, mode)
elif not isFirstParam:
result = exprEqExpr(p)
else:
result = parseExpr(p)
if p.tok.tokType == tkDo:
result = postExprBlocks(p, result)
elif p.tok.tokType == tkEquals and not isFirstParam:
let lhs = result
result = newNodeP(nkExprEqExpr, p)
getTok(p)
result.add(lhs)
result.add(parseExpr(p))
if p.tok.tokType == tkDo:
result = postExprBlocks(p, result)
isFirstParam = false
proc commandExpr(p: var Parser; r: PNode; mode: PrimaryMode): PNode =
result = newNodeP(nkCommand, p)
result.add(r)
var isFirstParam = true
# progress NOT guaranteed
p.hasProgress = false
result.add commandParam(p, isFirstParam, mode)
if mode == pmTrySimple:
result = r
else:
result = newNodeP(nkCommand, p)
result.add(r)
var isFirstParam = true
# progress NOT guaranteed
p.hasProgress = false
result.add commandParam(p, isFirstParam, mode)
proc isDotLike(tok: Token): bool =
result = tok.tokType == tkOpr and tok.ident.s.len > 1 and
@@ -833,7 +863,7 @@ proc primarySuffix(p: var Parser, r: PNode,
#| | DOTLIKEOP optInd symbol generalizedLit?
#| | '[' optInd exprColonEqExprList optPar ']'
#| | '{' optInd exprColonEqExprList optPar '}'
#| | &( '`'|IDENT|literal|'cast'|'addr'|'type') expr (comma expr)* # command syntax
# XXX strong spaces need to be reflected above
result = r
# progress guaranteed
@@ -844,13 +874,6 @@ proc primarySuffix(p: var Parser, r: PNode,
# progress guaranteed
if p.tok.strongSpaceA:
result = commandExpr(p, result, mode)
# type sections allow full command syntax
if mode == pmTypeDef:
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:
@@ -891,18 +914,9 @@ 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 =
@@ -929,7 +943,10 @@ proc parseOperators(p: var Parser, headNode: PNode,
opPrec = getPrecedence(p.tok)
proc simpleExprAux(p: var Parser, limit: int, mode: PrimaryMode): PNode =
var mode = mode
result = primary(p, mode)
if mode == pmTrySimple:
mode = pmNormal
if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)) and
mode == pmNormal:
var pragmaExp = newNodeP(nkPragmaExpr, p)
@@ -1010,9 +1027,9 @@ type
proc parseIdentColonEquals(p: var Parser, flags: DeclaredIdentFlags): PNode =
#| declColonEquals = identWithPragma (comma identWithPragma)* comma?
#| (':' optInd typeDesc)? ('=' optInd expr)?
#| (':' optInd typeDescExpr)? ('=' optInd expr)?
#| identColonEquals = IDENT (comma IDENT)* comma?
#| (':' optInd typeDesc)? ('=' optInd expr)?)
#| (':' optInd typeDescExpr)? ('=' optInd expr)?)
var a: PNode
result = newNodeP(nkIdentDefs, p)
# progress guaranteed
@@ -1030,7 +1047,7 @@ proc parseIdentColonEquals(p: var Parser, flags: DeclaredIdentFlags): PNode =
if p.tok.tokType == tkColon:
getTok(p)
optInd(p, result)
result.add(parseTypeDesc(p))
result.add(parseTypeDesc(p, fullExpr = true))
else:
result.add(newNodeP(nkEmpty, p))
if p.tok.tokType != tkEquals and withBothOptional notin flags:
@@ -1043,9 +1060,10 @@ proc parseIdentColonEquals(p: var Parser, flags: DeclaredIdentFlags): PNode =
result.add(newNodeP(nkEmpty, p))
proc parseTuple(p: var Parser, indentAllowed = false): PNode =
#| tupleDecl = 'tuple'
#| '[' optInd (identColonEquals (comma/semicolon)?)* optPar ']' |
#| COMMENT? (IND{>} identColonEquals (IND{=} identColonEquals)*)?
#| tupleTypeBracket = '[' optInd (identColonEquals (comma/semicolon)?)* optPar ']'
#| tupleType = 'tuple' tupleTypeBracket
#| tupleDecl = 'tuple' (tupleTypeBracket /
#| COMMENT? (IND{>} identColonEquals (IND{=} identColonEquals)*)?)
result = newNodeP(nkTupleTy, p)
getTok(p)
if p.tok.tokType == tkBracketLe:
@@ -1155,6 +1173,7 @@ proc parseDoBlock(p: var Parser; info: TLineInfo): PNode =
proc parseProcExpr(p: var Parser; isExpr: bool; kind: TNodeKind): PNode =
#| routineExpr = ('proc' | 'func' | 'iterator') paramListColon pragma? ('=' COMMENT? stmt)?
#| routineType = ('proc' | 'iterator') paramListColon pragma?
# either a proc type or a anonymous proc
let info = parLineInfo(p)
let hasSignature = p.tok.tokType in {tkParLe, tkColon} and p.tok.indent < 0
@@ -1179,7 +1198,7 @@ proc isExprStart(p: Parser): bool =
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, tkTry, tkBlock:
tkEnum, tkTuple, tkObject, tkWhen, tkCase, tkOut, tkTry, tkBlock:
result = true
else: result = false
@@ -1199,8 +1218,12 @@ proc parseTypeDescKAux(p: var Parser, kind: TNodeKind,
getTok(p)
if p.tok.indent != -1 and p.tok.indent <= p.currInd: return
optInd(p, result)
let isTypedef = mode == pmTypeDef and p.tok.tokType in {tkObject, tkTuple}
if not isOperator(p.tok) and isExprStart(p):
result.add(primary(p, mode))
if isTypedef:
result.add(parseTypeDefValue(p))
else:
result.add(primary(p, mode))
if kind == nkDistinctTy and p.tok.tokType == tkSymbol:
# XXX document this feature!
var nodeKind: TNodeKind
@@ -1214,11 +1237,13 @@ proc parseTypeDescKAux(p: var Parser, kind: TNodeKind,
let list = newNodeP(nodeKind, p)
result.add list
parseSymbolList(p, list)
if mode == pmTypeDef and not isTypedef:
result = parseOperators(p, result, -1, mode)
proc parseVarTuple(p: var Parser): PNode
proc parseFor(p: var Parser): PNode =
#| forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt
#| forStmt = 'for' ((varTuple / identWithPragma) ^+ comma) 'in' expr colcom stmt
#| forExpr = forStmt
getTokNoInd(p)
result = newNodeP(nkForStmt, p)
@@ -1283,11 +1308,18 @@ proc parseObject(p: var Parser): PNode
proc parseTypeClass(p: var Parser): PNode
proc primary(p: var Parser, mode: PrimaryMode): PNode =
#| primary = operatorB primary primarySuffix* |
#| tupleDecl | routineExpr | enumDecl
#| objectDecl | conceptDecl | ('bind' primary)
#| ('var' | 'out' | 'ref' | 'ptr' | 'distinct') primary
#| / prefixOperator* identOrLiteral primarySuffix*
#| simplePrimary = SIGILLIKEOP? identOrLiteral primarySuffix*
#| commandStart = &('`'|IDENT|literal|'cast'|'addr'|'type'|'var'|'out'|
#| 'static'|'enum'|'tuple'|'object'|'proc')
#| primary = simplePrimary (commandStart expr)
#| / operatorB primary
#| / routineExpr
#| / rawTypeDesc
#| / prefixOperator primary
# XXX strong spaces need to be reflected in commandStart
# command part is handled in the primarySuffix proc
# prefix operators:
if isOperator(p.tok):
# Note 'sigil like' operators are currently not reflected in the grammar
# and should be removed for Nim 2.0, I don't think anybody uses them.
@@ -1297,60 +1329,39 @@ proc primary(p: var Parser, mode: PrimaryMode): PNode =
result.add(a)
getTok(p)
optInd(p, a)
if isSigil:
#XXX prefix operators
const identOrLiteralKinds = tkBuiltInMagics + {tkSymbol, tkAccent, tkNil,
tkIntLit..tkCustomLit, tkCast, tkOut, tkParLe, tkBracketLe, tkCurlyLe}
if isSigil and p.tok.tokType in identOrLiteralKinds:
let baseInd = p.lex.currLineIndent
result.add(primary(p, pmSkipSuffix))
result.add(identOrLiteral(p, mode))
result = primarySuffix(p, result, baseInd, mode)
else:
result.add(primary(p, pmNormal))
return
case p.tok.tokType
of tkTuple: result = parseTuple(p, mode == pmTypeDef)
of tkProc:
getTok(p)
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkLambda)
result = parseProcExpr(p, mode != pmTypeDesc, nkLambda)
of tkFunc:
getTok(p)
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkFuncDef)
result = parseProcExpr(p, mode != pmTypeDesc, nkFuncDef)
of tkIterator:
getTok(p)
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkIteratorDef)
of tkEnum:
if mode == pmTypeDef:
prettySection:
result = parseEnum(p)
else:
result = newNodeP(nkEnumTy, p)
getTok(p)
of tkObject:
if mode == pmTypeDef:
prettySection:
result = parseObject(p)
else:
result = newNodeP(nkObjectTy, p)
getTok(p)
of tkConcept:
if mode == pmTypeDef:
result = parseTypeClass(p)
else:
parMessage(p, "the 'concept' keyword is only valid in 'type' sections")
result = parseProcExpr(p, mode != pmTypeDesc, nkIteratorDef)
of tkBind:
# legacy syntax, no-op in current nim
result = newNodeP(nkBind, p)
getTok(p)
optInd(p, result)
result.add(primary(p, pmNormal))
of tkVar: result = parseTypeDescKAux(p, nkVarTy, mode)
of tkOut: result = parseTypeDescKAux(p, nkOutTy, mode)
of tkRef: result = parseTypeDescKAux(p, nkRefTy, mode)
of tkPtr: result = parseTypeDescKAux(p, nkPtrTy, mode)
of tkDistinct: result = parseTypeDescKAux(p, nkDistinctTy, mode)
of tkTuple, tkEnum, tkObject, tkConcept,
tkVar, tkOut, tkRef, tkPtr, tkDistinct:
result = parseTypeDesc(p)
else:
let baseInd = p.lex.currLineIndent
result = identOrLiteral(p, mode)
if mode != pmSkipSuffix:
result = primarySuffix(p, result, baseInd, mode)
result = primarySuffix(p, result, baseInd, mode)
proc binaryNot(p: var Parser; a: PNode): PNode =
if p.tok.tokType == tkNot:
@@ -1365,16 +1376,70 @@ proc binaryNot(p: var Parser; a: PNode): PNode =
else:
result = a
proc parseTypeDesc(p: var Parser): PNode =
#| typeDesc = simpleExpr ('not' expr)?
proc parseTypeDesc(p: var Parser, fullExpr = false): PNode =
#| rawTypeDesc = (tupleType | routineType | 'enum' | 'object' |
#| ('var' | 'out' | 'ref' | 'ptr' | 'distinct') typeDesc?)
#| ('not' expr)?
#| typeDescExpr = (routineType / simpleExpr) ('not' expr)?
#| typeDesc = rawTypeDesc / typeDescExpr
newlineWasSplitting(p)
result = simpleExpr(p, pmTypeDesc)
if fullExpr:
result = simpleExpr(p, pmTypeDesc)
else:
case p.tok.tokType
of tkTuple:
result = parseTuple(p, false)
of tkProc:
getTok(p)
result = parseProcExpr(p, false, nkLambda)
of tkIterator:
getTok(p)
result = parseProcExpr(p, false, nkIteratorDef)
of tkEnum:
result = newNodeP(nkEnumTy, p)
getTok(p)
of tkObject:
result = newNodeP(nkObjectTy, p)
getTok(p)
of tkConcept:
parMessage(p, "the 'concept' keyword is only valid in 'type' sections")
of tkVar: result = parseTypeDescKAux(p, nkVarTy, pmTypeDesc)
of tkOut: result = parseTypeDescKAux(p, nkOutTy, pmTypeDesc)
of tkRef: result = parseTypeDescKAux(p, nkRefTy, pmTypeDesc)
of tkPtr: result = parseTypeDescKAux(p, nkPtrTy, pmTypeDesc)
of tkDistinct: result = parseTypeDescKAux(p, nkDistinctTy, pmTypeDesc)
else:
result = simpleExpr(p, pmTypeDesc)
result = binaryNot(p, result)
proc parseTypeDefAux(p: var Parser): PNode =
#| typeDefAux = simpleExpr ('not' expr
#| | postExprBlocks)?
result = simpleExpr(p, pmTypeDef)
proc parseTypeDefValue(p: var Parser): PNode =
#| typeDefValue = ((tupleDecl | enumDecl | objectDecl | conceptDecl |
#| ('ref' | 'ptr' | 'distinct') (tupleDecl | objectDecl))
#| / (simpleExpr (exprEqExpr ^+ comma postExprBlocks)?))
#| ('not' expr)?
case p.tok.tokType
of tkTuple: result = parseTuple(p, true)
of tkRef: result = parseTypeDescKAux(p, nkRefTy, pmTypeDef)
of tkPtr: result = parseTypeDescKAux(p, nkPtrTy, pmTypeDef)
of tkDistinct: result = parseTypeDescKAux(p, nkDistinctTy, pmTypeDef)
of tkEnum:
prettySection:
result = parseEnum(p)
of tkObject:
prettySection:
result = parseObject(p)
of tkConcept:
result = parseTypeClass(p)
else:
result = simpleExpr(p, pmTypeDef)
if p.tok.tokType != tkNot:
if result.kind == nkCommand:
var isFirstParam = false
while p.tok.tokType == tkComma:
getTok(p)
optInd(p, result)
result.add(commandParam(p, isFirstParam, pmTypeDef))
result = postExprBlocks(p, result)
result = binaryNot(p, result)
proc makeCall(n: PNode): PNode =
@@ -1389,7 +1454,7 @@ proc postExprBlocks(p: var Parser, x: PNode): PNode =
#| postExprBlocks = ':' stmt? ( IND{=} doBlock
#| | IND{=} 'of' exprList ':' stmt
#| | IND{=} 'elif' expr ':' stmt
#| | IND{=} 'except' exprList ':' stmt
#| | IND{=} 'except' optionalExprList ':' stmt
#| | IND{=} 'finally' ':' stmt
#| | IND{=} 'else' ':' stmt )*
result = x
@@ -1447,7 +1512,7 @@ proc postExprBlocks(p: var Parser, x: PNode): PNode =
nextBlock.add parseExpr(p)
of tkExcept:
nextBlock = newNodeP(nkExceptBranch, p)
exprList(p, tkColon, nextBlock)
optionalExprList(p, tkColon, nextBlock)
of tkFinally:
nextBlock = newNodeP(nkFinally, p)
getTok(p)
@@ -1467,12 +1532,10 @@ proc postExprBlocks(p: var Parser, x: PNode): PNode =
parMessage(p, "expected ':'")
proc parseExprStmt(p: var Parser): PNode =
#| exprStmt = simpleExpr
#| (( '=' optInd expr colonBody? )
#| / ( expr ^+ comma
#| postExprBlocks
#| ))?
var a = simpleExpr(p)
#| exprStmt = simpleExpr postExprBlocks?
#| / simplePrimary (exprEqExpr ^+ comma) postExprBlocks?
#| / simpleExpr '=' optInd (expr postExprBlocks?)
var a = simpleExpr(p, pmTrySimple)
if p.tok.tokType == tkEquals:
result = newNodeP(nkAsgn, p)
getTok(p)
@@ -1482,20 +1545,17 @@ proc parseExprStmt(p: var Parser): PNode =
result.add(a)
result.add(b)
else:
# simpleExpr parsed 'p a' from 'p a, b'?
var isFirstParam = false
if p.tok.indent < 0 and p.tok.tokType == tkComma and a.kind == nkCommand:
result = a
while true:
getTok(p)
optInd(p, result)
result.add(commandParam(p, isFirstParam, pmNormal))
if p.tok.tokType != tkComma: break
elif p.tok.indent < 0 and isExprStart(p):
# if an expression is starting here, a simplePrimary was parsed and
# this is the start of a command
if p.tok.indent < 0 and isExprStart(p):
result = newTreeI(nkCommand, a.info, a)
let baseIndent = p.currInd
while true:
result.add(commandParam(p, isFirstParam, pmNormal))
if p.tok.tokType != tkComma: break
if p.tok.tokType != tkComma or
(p.tok.indent >= 0 and p.tok.indent < baseIndent):
break
getTok(p)
optInd(p, result)
else:
@@ -1704,10 +1764,10 @@ proc parseCase(p: var Parser): PNode =
proc parseTry(p: var Parser; isExpr: bool): PNode =
#| tryStmt = 'try' colcom stmt &(IND{=}? 'except'|'finally')
#| (IND{=}? 'except' exprList colcom stmt)*
#| (IND{=}? 'except' optionalExprList colcom stmt)*
#| (IND{=}? 'finally' colcom stmt)?
#| tryExpr = 'try' colcom stmt &(optInd 'except'|'finally')
#| (optInd 'except' exprList colcom stmt)*
#| (optInd 'except' optionalExprList colcom stmt)*
#| (optInd 'finally' colcom stmt)?
result = newNodeP(nkTryStmt, p)
getTok(p)
@@ -1718,7 +1778,7 @@ proc parseTry(p: var Parser; isExpr: bool): PNode =
case p.tok.tokType
of tkExcept:
b = newNodeP(nkExceptBranch, p)
exprList(p, tkColon, b)
optionalExprList(p, tkColon, b)
of tkFinally:
b = newNodeP(nkFinally, p)
getTok(p)
@@ -2132,7 +2192,7 @@ proc parseTypeClass(p: var Parser): PNode =
proc parseTypeDef(p: var Parser): PNode =
#|
#| typeDef = identVisDot genericParamList? pragma '=' optInd typeDefAux
#| typeDef = identVisDot genericParamList? pragma '=' optInd typeDefValue
#| indAndComment?
result = newNodeP(nkTypeDef, p)
var identifier = identVis(p, allowDot=true)
@@ -2158,7 +2218,7 @@ proc parseTypeDef(p: var Parser): PNode =
result.info = parLineInfo(p)
getTok(p)
optInd(p, result)
result.add(parseTypeDefAux(p))
result.add(parseTypeDefValue(p))
else:
result.add(p.emptyNode)
indAndComment(p, result) # special extension!

View File

@@ -81,7 +81,8 @@ const
wGuard, wGoto, wCursor, wNoalias, wAlign}
constPragmas* = declPragmas + {wHeader, wMagic,
wGensym, wInject,
wIntDefine, wStrDefine, wBoolDefine, wCompilerProc, wCore}
wIntDefine, wStrDefine, wBoolDefine, wDefine,
wCompilerProc, wCore}
paramPragmas* = {wNoalias, wInject, wGensym}
letPragmas* = varPragmas
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNoSideEffect,
@@ -476,8 +477,16 @@ proc processPop(c: PContext, n: PNode) =
when defined(debugOptions):
echo c.config $ n.info, " POP config is now ", c.config.options
proc processDefine(c: PContext, n: PNode) =
if (n.kind in nkPragmaCallKinds and n.len == 2) and (n[1].kind == nkIdent):
proc processDefineConst(c: PContext, n: PNode, sym: PSym, kind: TMagic) =
sym.magic = kind
if n.kind in nkPragmaCallKinds and n.len == 2:
# could also use TLib
n[1] = getStrLitNode(c, n)
proc processDefine(c: PContext, n: PNode, sym: PSym) =
if sym != nil and sym.kind == skConst:
processDefineConst(c, n, sym, mGenericDefine)
elif (n.kind in nkPragmaCallKinds and n.len == 2) and (n[1].kind == nkIdent):
defineSymbol(c.config.symbols, n[1].ident.s)
else:
invalidPragma(c, n)
@@ -1066,7 +1075,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
recordPragma(c, it, "error", s)
localError(c.config, it.info, errUser, s)
of wFatal: fatal(c.config, it.info, expectStrLit(c, it))
of wDefine: processDefine(c, it)
of wDefine: processDefine(c, it, sym)
of wUndef: processUndef(c, it)
of wCompile: processCompile(c, it)
of wLink: processLink(c, it)
@@ -1213,11 +1222,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
noVal(c, it)
sym.flags.incl sfBase
of wIntDefine:
sym.magic = mIntDefine
processDefineConst(c, n, sym, mIntDefine)
of wStrDefine:
sym.magic = mStrDefine
processDefineConst(c, n, sym, mStrDefine)
of wBoolDefine:
sym.magic = mBoolDefine
processDefineConst(c, n, sym, mBoolDefine)
of wUsed:
noVal(c, it)
if sym == nil: invalidPragma(c, it)

View File

@@ -24,7 +24,7 @@ type
TRenderFlag* = enum
renderNone, renderNoBody, renderNoComments, renderDocComments,
renderNoPragmas, renderIds, renderNoProcDefs, renderSyms, renderRunnableExamples,
renderIr
renderIr, renderExpandUsing
TRenderFlags* = set[TRenderFlag]
TRenderTok* = object
kind*: TokType
@@ -434,6 +434,24 @@ proc lsons(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): int =
result = 0
for i in start..n.len + theEnd: inc(result, lsub(g, n[i]))
proc origUsingType(n: PNode): PSym {.inline.} =
## Returns the type that a parameter references. Check with referencesUsing first
## to check `n` is actually referencing a using node
# If the node is untyped the typ field will be nil
if n[0].sym.typ != nil:
n[0].sym.typ.sym
else: nil
proc referencesUsing(n: PNode): bool =
## Returns true if n references a using statement.
## e.g. proc foo(x) # x doesn't have type or def value so it references a using
result = n.kind == nkIdentDefs and
# Sometimes the node might not have been semmed (e.g. doc0) and will be nkIdent instead
n[0].kind == nkSym and
# Templates/macros can have parameters with no type (But their orig type will be nil)
n.origUsingType != nil and
n[1].kind == nkEmpty and n[2].kind == nkEmpty
proc lsub(g: TSrcGen; n: PNode): int =
# computes the length of a tree
if isNil(n): return 0
@@ -474,8 +492,11 @@ proc lsub(g: TSrcGen; n: PNode): int =
of nkDo: result = lsons(g, n) + len("do__:_")
of nkConstDef, nkIdentDefs:
result = lcomma(g, n, 0, - 3)
if n[^2].kind != nkEmpty: result += lsub(g, n[^2]) + 2
if n[^1].kind != nkEmpty: result += lsub(g, n[^1]) + 3
if n.referencesUsing:
result += lsub(g, newSymNode(n.origUsingType)) + 2
else:
if n[^2].kind != nkEmpty: result += lsub(g, n[^2]) + 2
if n[^1].kind != nkEmpty: result += lsub(g, n[^1]) + 3
of nkVarTuple:
if n[^1].kind == nkEmpty:
result = lcomma(g, n, 0, - 2) + len("()")
@@ -1260,8 +1281,12 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext, fromStmtList = false) =
gsub(g, n, 0)
of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref, nkStringToCString, nkCStringToString:
if renderIds in g.flags:
putWithSpace(g, tkAddr, $n.kind)
put(g, tkAddr, $n.kind)
put(g, tkParLe, "(")
gsub(g, n, 0)
if renderIds in g.flags:
put(g, tkParRi, ")")
of nkLambda:
putWithSpace(g, tkProc, "proc")
gsub(g, n, paramsPos)
@@ -1280,7 +1305,11 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext, fromStmtList = false) =
gcomma(g, n, 0, -3)
if n.len >= 2 and n[^2].kind != nkEmpty:
putWithSpace(g, tkColon, ":")
gsub(g, n, n.len - 2)
gsub(g, n[^2], c)
elif n.referencesUsing and renderExpandUsing in g.flags:
putWithSpace(g, tkColon, ":")
gsub(g, newSymNode(n.origUsingType), c)
if n.len >= 1 and n[^1].kind != nkEmpty:
put(g, tkSpaces, Space)
putWithSpace(g, tkEquals, "=")

View File

@@ -81,7 +81,7 @@ template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
proc fitNodePostMatch(c: PContext, formal: PType, arg: PNode): PNode =
let x = arg.skipConv
if (x.kind == nkCurly and formal.kind == tySet and formal.base.kind != tyGenericParam) or
(x.kind in {nkPar, nkTupleConstr}) and formal.kind notin {tyUntyped, tyBuiltInTypeClass}:
(x.kind in {nkPar, nkTupleConstr}) and formal.kind notin {tyUntyped, tyBuiltInTypeClass, tyAnything}:
changeType(c, x, formal, check=true)
result = arg
result = skipHiddenSubConv(result, c.graph, c.idgen)
@@ -439,7 +439,7 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
# does not mean we expect a tyTypeDesc.
retType = retType[0]
case retType.kind
of tyUntyped:
of tyUntyped, tyAnything:
# Not expecting a type here allows templates like in ``tmodulealias.in``.
result = semExpr(c, result, flags, expectedType)
of tyTyped:
@@ -642,10 +642,10 @@ proc defaultNodeField(c: PContext, a: PNode, aTyp: PType, id: var IntSet): PNode
if child != nil:
let node = newNode(nkIntLit)
node.intVal = toInt64(lengthOrd(c.graph.config, aTypSkip))
result = semExpr(c, newTree(nkCall, newSymNode(getSysSym(c.graph, a.info, "arrayWith"), a.info),
semExprWithType(c, child),
node
))
result = semExpr(c, newTree(nkCall, newSymNode(getCompilerProc(c.graph, "nimArrayWith"), a.info),
semExprWithType(c, child),
node
))
result.typ = aTyp
elif aTypSkip.kind == tyTuple:
var hasDefault = false

View File

@@ -394,6 +394,8 @@ proc semCast(c: PContext, n: PNode): PNode =
let castedExpr = semExprWithType(c, n[1])
if castedExpr.kind == nkClosedSymChoice:
errorUseQualifier(c, n[1].info, castedExpr)
if targetType == nil:
localError(c.config, n.info, "Invalid usage of cast, cast requires a type to convert to, e.g., cast[int](0d).")
if tfHasMeta in targetType.flags:
localError(c.config, n[0].info, "cannot cast to a non concrete type: '$1'" % $targetType)
if not isCastable(c, targetType, castedExpr.typ, n.info):
@@ -691,6 +693,9 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp
proc fixAbstractType(c: PContext, n: PNode) =
for i in 1..<n.len:
let it = n[i]
if it == nil:
localError(c.config, n.info, "'$1' has nil child at index $2" % [renderTree(n, {renderNoComments}), $i])
return
# do not get rid of nkHiddenSubConv for OpenArrays, the codegen needs it:
if it.kind == nkHiddenSubConv and
skipTypes(it.typ, abstractVar).kind notin {tyOpenArray, tyVarargs}:
@@ -736,7 +741,7 @@ proc hasUnresolvedArgs(c: PContext, n: PNode): bool =
if hasUnresolvedArgs(c, n[i]): return true
return false
proc newHiddenAddrTaken(c: PContext, n: PNode): PNode =
proc newHiddenAddrTaken(c: PContext, n: PNode, isOutParam: bool): PNode =
if n.kind == nkHiddenDeref and not (c.config.backend == backendCpp or
sfCompileToCpp in c.module.flags):
checkSonsLen(n, 1, c.config)
@@ -745,13 +750,17 @@ proc newHiddenAddrTaken(c: PContext, n: PNode): PNode =
result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ))
result.add n
let aa = isAssignable(c, n)
let sym = getRoot(n)
if aa notin {arLValue, arLocalLValue}:
if aa == arDiscriminant and c.inUncheckedAssignSection > 0:
discard "allow access within a cast(unsafeAssign) section"
elif strictDefs in c.features and aa == arAddressableConst and
sym != nil and sym.kind == skLet and isOutParam:
discard "allow let varaibles to be passed to out parameters"
else:
localError(c.config, n.info, errVarForOutParamNeededX % renderNotLValue(n))
proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
proc analyseIfAddressTaken(c: PContext, n: PNode, isOutParam: bool): PNode =
result = n
case n.kind
of nkSym:
@@ -759,7 +768,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
if n.sym.typ != nil and
skipTypes(n.sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
incl(n.sym.flags, sfAddrTaken)
result = newHiddenAddrTaken(c, n)
result = newHiddenAddrTaken(c, n, isOutParam)
of nkDotExpr:
checkSonsLen(n, 2, c.config)
if n[1].kind != nkSym:
@@ -767,14 +776,14 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
return
if skipTypes(n[1].sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
incl(n[1].sym.flags, sfAddrTaken)
result = newHiddenAddrTaken(c, n)
result = newHiddenAddrTaken(c, n, isOutParam)
of nkBracketExpr:
checkMinSonsLen(n, 1, c.config)
if skipTypes(n[0].typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
if n[0].kind == nkSym: incl(n[0].sym.flags, sfAddrTaken)
result = newHiddenAddrTaken(c, n)
result = newHiddenAddrTaken(c, n, isOutParam)
else:
result = newHiddenAddrTaken(c, n)
result = newHiddenAddrTaken(c, n, isOutParam)
proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
checkMinSonsLen(n, 1, c.config)
@@ -820,7 +829,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
if i < t.len and
skipTypes(t[i], abstractInst-{tyTypeDesc}).kind in {tyVar}:
if n[i].kind != nkHiddenAddr:
n[i] = analyseIfAddressTaken(c, n[i])
n[i] = analyseIfAddressTaken(c, n[i], isOutParam(skipTypes(t[i], abstractInst-{tyTypeDesc})))
include semmagic
@@ -1266,15 +1275,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
result = newSymNode(s, n.info)
else:
result = newSymNode(s, n.info)
of skMacro:
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or
(n.kind notin nkCallKinds and s.requiredParams > 0):
markUsed(c, n.info, s)
onUse(n.info, s)
result = symChoice(c, n, s, scClosed)
else:
result = semMacroExpr(c, n, n, s, flags)
of skTemplate:
of skMacro, skTemplate:
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or
(n.kind notin nkCallKinds and s.requiredParams > 0) or
sfCustomPragma in sym.flags:
@@ -1283,7 +1284,10 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
onUse(info, s)
result = symChoice(c, n, s, scClosed)
else:
result = semTemplateExpr(c, n, s, flags)
case s.kind
of skMacro: result = semMacroExpr(c, n, n, s, flags)
of skTemplate: result = semTemplateExpr(c, n, s, flags)
else: discard # unreachable
of skParam:
markUsed(c, n.info, s)
onUse(n.info, s)
@@ -1817,11 +1821,16 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
# a = b # both are vars, means: a[] = b[]
# a = b # b no 'var T' means: a = addr(b)
var le = a.typ
let assignable = isAssignable(c, a)
let root = getRoot(a)
let useStrictDefLet = root != nil and root.kind == skLet and
assignable == arAddressableConst and
strictDefs in c.features and isLocalSym(root)
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, arAddressableConst}) or (
skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs} and views notin c.features):
assignable in {arNone, arLentValue, arAddressableConst} and not useStrictDefLet
) 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 %
renderTree(a, {renderNoComments}))
@@ -1834,6 +1843,8 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
var rhsTyp = rhs.typ
if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass:
rhsTyp = rhsTyp.lastSon
if lhs.sym.typ.kind == tyAnything:
rhsTyp = rhsTyp.skipIntLit(c.idgen)
if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}:
internalAssert c.config, c.p.resultSym != nil
# Make sure the type is valid for the result variable
@@ -1907,8 +1918,8 @@ proc semProcBody(c: PContext, n: PNode; expectedType: PType = nil): PNode =
else:
localError(c.config, c.p.resultSym.info, errCannotInferReturnType %
c.p.owner.name.s)
if isInlineIterator(c.p.owner.typ) and c.p.owner.typ[0] != nil and
c.p.owner.typ[0].kind == tyUntyped:
if isIterator(c.p.owner.typ) and c.p.owner.typ[0] != nil and
c.p.owner.typ[0].kind == tyAnything:
localError(c.config, c.p.owner.info, errCannotInferReturnType %
c.p.owner.name.s)
closeScope(c)

View File

@@ -13,7 +13,7 @@
import
strutils, options, ast, trees, nimsets,
platform, math, msgs, idents, renderer, types,
commands, magicsys, modulegraphs, strtabs, lineinfos
commands, magicsys, modulegraphs, strtabs, lineinfos, wordrecg
from system/memory import nimCStrLen
@@ -371,6 +371,11 @@ proc rangeCheck(n: PNode, value: Int128; g: ModuleGraph) =
localError(g.config, n.info, "cannot convert " & $value &
" to " & typeToString(n.typ))
proc floatRangeCheck(n: PNode, value: BiggestFloat; g: ModuleGraph) =
if value < firstFloat(n.typ) or value > lastFloat(n.typ):
localError(g.config, n.info, "cannot convert " & $value &
" to " & typeToString(n.typ))
proc foldConv(n, a: PNode; idgen: IdGenerator; g: ModuleGraph; check = false): PNode =
let dstTyp = skipTypes(n.typ, abstractRange - {tyTypeDesc})
let srcTyp = skipTypes(a.typ, abstractRange - {tyTypeDesc})
@@ -490,6 +495,81 @@ proc newSymNodeTypeDesc*(s: PSym; idgen: IdGenerator; info: TLineInfo): PNode =
else:
result.typ = s.typ
proc foldDefine(m, s: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
var name = s.name.s
let prag = extractPragma(s)
if prag != nil:
for it in prag:
if it.kind in nkPragmaCallKinds and it.len == 2 and it[0].kind == nkIdent:
let word = whichKeyword(it[0].ident)
if word in {wStrDefine, wIntDefine, wBoolDefine, wDefine}:
# should be processed in pragmas.nim already
if it[1].kind in {nkStrLit, nkRStrLit, nkTripleStrLit}:
name = it[1].strVal
if isDefined(g.config, name):
let str = g.config.symbols[name]
case s.magic
of mIntDefine:
try:
result = newIntNodeT(toInt128(str.parseInt), n, idgen, g)
except ValueError:
localError(g.config, s.info,
"{.intdefine.} const was set to an invalid integer: '" &
str & "'")
of mStrDefine:
result = newStrNodeT(str, n, g)
of mBoolDefine:
try:
result = newIntNodeT(toInt128(str.parseBool.int), n, idgen, g)
except ValueError:
localError(g.config, s.info,
"{.booldefine.} const was set to an invalid bool: '" &
str & "'")
of mGenericDefine:
let rawTyp = s.typ
# pretend we don't support distinct types
let typ = rawTyp.skipTypes(abstractVarRange-{tyDistinct})
try:
template intNode(value): PNode =
let val = toInt128(value)
rangeCheck(n, val, g)
newIntNodeT(val, n, idgen, g)
case typ.kind
of tyString, tyCstring:
result = newStrNodeT(str, n, g)
of tyInt..tyInt64:
result = intNode(str.parseBiggestInt)
of tyUInt..tyUInt64:
result = intNode(str.parseBiggestUInt)
of tyBool:
result = intNode(str.parseBool.int)
of tyEnum:
# compile time parseEnum
let ident = getIdent(g.cache, str)
for e in typ.n:
if e.kind != nkSym: internalError(g.config, "foldDefine for enum")
let es = e.sym
let match =
if es.ast.isNil:
es.name.id == ident.id
else:
es.ast.strVal == str
if match:
result = intNode(es.position)
break
if result.isNil:
raise newException(ValueError, "invalid enum value: " & str)
else:
localError(g.config, s.info, "unsupported type $1 for define '$2'" %
[name, typeToString(rawTyp)])
except ValueError as e:
localError(g.config, s.info,
"could not process define '$1' of type $2; $3" %
[name, typeToString(rawTyp), e.msg])
else: result = copyTree(s.astdef) # unreachable
else:
result = copyTree(s.astdef)
proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
result = nil
case n.kind
@@ -509,31 +589,8 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
of mBuildOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.hostOS].name), n, g)
of mBuildCPU: result = newStrNodeT(platform.CPU[g.config.target.hostCPU].name.toLowerAscii, n, g)
of mAppType: result = getAppType(n, g)
of mIntDefine:
if isDefined(g.config, s.name.s):
try:
result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseInt), n, idgen, g)
except ValueError:
localError(g.config, s.info,
"{.intdefine.} const was set to an invalid integer: '" &
g.config.symbols[s.name.s] & "'")
else:
result = copyTree(s.astdef)
of mStrDefine:
if isDefined(g.config, s.name.s):
result = newStrNodeT(g.config.symbols[s.name.s], n, g)
else:
result = copyTree(s.astdef)
of mBoolDefine:
if isDefined(g.config, s.name.s):
try:
result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseBool.int), n, idgen, g)
except ValueError:
localError(g.config, s.info,
"{.booldefine.} const was set to an invalid bool: '" &
g.config.symbols[s.name.s] & "'")
else:
result = copyTree(s.astdef)
of mIntDefine, mStrDefine, mBoolDefine, mGenericDefine:
result = foldDefine(m, s, n, idgen, g)
else:
result = copyTree(s.astdef)
of skProc, skFunc, skMethod:

View File

@@ -10,7 +10,8 @@
import
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
wordrecg, strutils, options, guards, lineinfos, semfold, semdata,
modulegraphs, varpartitions, typeallowed, nilcheck, errorhandling, tables
modulegraphs, varpartitions, typeallowed, nilcheck, errorhandling, tables,
semstrictfuncs
when defined(nimPreviewSlimSystem):
import std/assertions
@@ -75,7 +76,7 @@ type
guards: TModel # nested guards
locked: seq[PNode] # locked locations
gcUnsafe, isRecursive, isTopLevel, hasSideEffect, inEnforcedGcSafe: bool
hasDangerousAssign, isInnerProc: bool
isInnerProc: bool
inEnforcedNoSideEffects: bool
currOptions: TOptions
config: ConfigRef
@@ -84,6 +85,10 @@ type
escapingParams: IntSet
PEffects = var TEffects
const
errXCannotBeAssignedTo = "'$1' cannot be assigned to"
errLetNeedsInit = "'let' symbol requires an initialization"
proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo) =
if typ == nil: return
when false:
@@ -97,8 +102,8 @@ proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo) =
optSeqDestructors in tracked.config.globalOptions:
tracked.owner.flags.incl sfInjectDestructors
proc isLocalVar(a: PEffects, s: PSym): bool =
s.typ != nil and (s.kind in {skVar, skResult} or (s.kind == skParam and isOutParam(s.typ))) and
proc isLocalSym(a: PEffects, s: PSym): bool =
s.typ != nil and (s.kind in {skLet, skVar, skResult} or (s.kind == skParam and isOutParam(s.typ))) and
sfGlobal notin s.flags and s.owner == a.owner
proc lockLocations(a: PEffects; pragma: PNode) =
@@ -173,10 +178,15 @@ proc initVar(a: PEffects, n: PNode; volatileCheck: bool) =
let n = skipHiddenDeref(n)
if n.kind != nkSym: return
let s = n.sym
if isLocalVar(a, s):
if isLocalSym(a, s):
if volatileCheck: makeVolatile(a, s)
for x in a.init:
if x == s.id: return
if x == s.id:
if strictDefs in a.c.features and s.kind == skLet:
localError(a.config, n.info, errXCannotBeAssignedTo %
renderTree(n, {renderNoComments}
))
return
a.init.add s.id
if a.scopes.getOrDefault(s.id) == a.currentBlock:
#[ Consider this case:
@@ -204,7 +214,7 @@ proc initVarViaNew(a: PEffects, n: PNode) =
# 'x' is not nil, but that doesn't mean its "not nil" children
# are initialized:
initVar(a, n, volatileCheck=true)
elif isLocalVar(a, s):
elif isLocalSym(a, s):
makeVolatile(a, s)
proc warnAboutGcUnsafe(n: PNode; conf: ConfigRef) =
@@ -322,7 +332,7 @@ proc useVar(a: PEffects, n: PNode) =
let s = n.sym
if a.inExceptOrFinallyStmt > 0:
incl s.flags, sfUsedInFinallyOrExcept
if isLocalVar(a, s):
if isLocalSym(a, s):
if sfNoInit in s.flags:
# If the variable is explicitly marked as .noinit. do not emit any error
a.init.add s.id
@@ -331,7 +341,10 @@ proc useVar(a: PEffects, n: PNode) =
message(a.config, n.info, warnProveInit, s.name.s)
elif a.leftPartOfAsgn <= 0:
if strictDefs in a.c.features:
message(a.config, n.info, warnUninit, s.name.s)
if s.kind == skLet:
localError(a.config, n.info, errLetNeedsInit)
else:
message(a.config, n.info, warnUninit, s.name.s)
# prevent superfluous warnings about the same variable:
a.init.add s.id
useVarNoInitCheck(a, n, s)
@@ -478,6 +491,10 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
let b = n[i]
if b.kind == nkExceptBranch:
setLen(tracked.init, oldState)
for j in 0..<b.len - 1:
if b[j].isInfixAs(): # skips initialization checks
assert(b[j][2].kind == nkSym)
tracked.init.add b[j][2].sym.id
track(tracked, b[^1])
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
@@ -637,7 +654,7 @@ proc trackOperandForIndirectCall(tracked: PEffects, n: PNode, formals: PType; ar
let paramType = if formals != nil and argIndex < formals.len: formals[argIndex] else: nil
if paramType != nil and paramType.kind in {tyVar}:
invalidateFacts(tracked.guards, n)
if n.kind == nkSym and isLocalVar(tracked, n.sym):
if n.kind == nkSym and isLocalSym(tracked, n.sym):
makeVolatile(tracked, n.sym)
if paramType != nil and paramType.kind == tyProc and tfGcSafe in paramType.flags:
let argtype = skipTypes(a.typ, abstractInst)
@@ -802,9 +819,12 @@ proc passedToEffectsDelayedParam(tracked: PEffects; n: PNode) =
]#
proc checkForSink(tracked: PEffects; n: PNode) =
if tracked.inIfStmt == 0:
if tracked.inIfStmt == 0 and optSinkInference in tracked.config.options:
checkForSink(tracked.config, tracked.c.idgen, tracked.owner, n)
proc strictFuncsActive(tracked: PEffects): bool {.inline.} =
sfNoSideEffect in tracked.owner.flags and strictFuncs in tracked.c.features and not tracked.inEnforcedNoSideEffects
proc trackCall(tracked: PEffects; n: PNode) =
template gcsafeAndSideeffectCheck() =
if notGcSafe(op) and not importedFromC(a):
@@ -909,12 +929,15 @@ proc trackCall(tracked: PEffects; n: PNode) =
createTypeBoundOps(tracked, paramType[0], n.info)
checkForSink(tracked, n[i])
of tyVar:
tracked.hasDangerousAssign = true
if isOutParam(paramType):
# consider this case: p(out x, x); we want to remark that 'x' is not
# initialized until after the call. Since we do this after we analysed the
# call, this is fine.
initVar(tracked, n[i].skipAddr, false)
if tracked.strictFuncsActive and isDangerousLocation(n[i].skipAddr, tracked.owner):
localError(tracked.config, n[i].info,
"cannot pass $1 to `var T` parameter within a strict func" % renderTree(n[i]))
tracked.hasSideEffect = true
else: discard
type
@@ -1025,7 +1048,7 @@ proc track(tracked: PEffects, n: PNode) =
# bug #15038: ensure consistency
if not hasDestructor(n.typ) and sameType(n.typ, n.sym.typ): n.typ = n.sym.typ
of nkHiddenAddr, nkAddr:
if n[0].kind == nkSym and isLocalVar(tracked, n[0].sym):
if n[0].kind == nkSym and isLocalSym(tracked, n[0].sym):
useVarNoInitCheck(tracked, n[0], n[0].sym)
else:
track(tracked, n[0])
@@ -1065,10 +1088,12 @@ proc track(tracked: PEffects, n: PNode) =
when false: cstringCheck(tracked, n)
if tracked.owner.kind != skMacro and n[0].typ.kind notin {tyOpenArray, tyVarargs}:
createTypeBoundOps(tracked, n[0].typ, n.info)
if n[0].kind != nkSym or not isLocalVar(tracked, n[0].sym):
if n[0].kind != nkSym or not isLocalSym(tracked, n[0].sym):
checkForSink(tracked, n[1])
if not tracked.hasDangerousAssign and n[0].kind != nkSym:
tracked.hasDangerousAssign = true
if tracked.strictFuncsActive and isDangerousLocation(n[0], tracked.owner):
tracked.hasSideEffect = true
localError(tracked.config, n[0].info,
"cannot mutate location $1 within a strict func" % renderTree(n[0]))
of nkVarSection, nkLetSection:
for child in n:
let last = lastSon(child)
@@ -1501,17 +1526,9 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
effects[ensuresEffects] = ensuresSpec
var mutationInfo = MutationInfo()
var hasMutationSideEffect = false
if {strictFuncs, views} * c.features != {}:
var goals: set[Goal] = {}
if strictFuncs in c.features: goals.incl constParameters
if views in c.features: goals.incl borrowChecking
var partitions = computeGraphPartitions(s, body, g, goals)
if not t.hasSideEffect and t.hasDangerousAssign:
t.hasSideEffect = varpartitions.hasSideEffect(partitions, mutationInfo)
hasMutationSideEffect = t.hasSideEffect
if views in c.features:
checkBorrowedLocations(partitions, body, g.config)
if views in c.features:
var partitions = computeGraphPartitions(s, body, g, {borrowChecking})
checkBorrowedLocations(partitions, body, g.config)
if sfThread in s.flags and t.gcUnsafe:
if optThreads in g.config.globalOptions and optThreadAnalysis in g.config.globalOptions:
@@ -1524,9 +1541,7 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
when false:
listGcUnsafety(s, onlyWarning=false, g.config)
else:
if hasMutationSideEffect:
localError(g.config, s.info, "'$1' can have side effects$2" % [s.name.s, g.config $ mutationInfo])
elif c.compilesContextId == 0: # don't render extended diagnostic messages in `system.compiles` context
if c.compilesContextId == 0: # don't render extended diagnostic messages in `system.compiles` context
var msg = ""
listSideEffects(msg, s, g.config, t.c)
message(g.config, s.info, errGenerated, msg)

View File

@@ -509,13 +509,6 @@ proc semVarMacroPragma(c: PContext, a: PNode, n: PNode): PNode =
let it = pragmas[i]
let key = if it.kind in nkPragmaCallKinds and it.len >= 1: it[0] else: it
when false:
let lhs = b[0]
let clash = strTableGet(c.currentScope.symbols, lhs.ident)
if clash != nil:
# refs https://github.com/nim-lang/Nim/issues/8275
wrongRedefinition(c, lhs.info, lhs.ident.s, clash.info)
if isPossibleMacroPragma(c, it, key):
# we transform ``var p {.m, rest.}`` into ``m(do: var p {.rest.})`` and
# let the semantic checker deal with it:
@@ -562,38 +555,18 @@ proc semVarMacroPragma(c: PContext, a: PNode, n: PNode): PNode =
doAssert result != nil
# since a macro pragma can set pragmas, we process these here again.
# This is required for SqueakNim-like export pragmas.
if false and result.kind in {nkVarSection, nkLetSection, nkConstSection}:
var validPragmas: TSpecialWords
case result.kind
of nkVarSection:
validPragmas = varPragmas
of nkLetSection:
validPragmas = letPragmas
of nkConstSection:
validPragmas = constPragmas
else:
# unreachable
discard
for defs in result:
for i in 0 ..< defs.len - 2:
let ex = defs[i]
if ex.kind == nkPragmaExpr and
ex[namePos].kind == nkSym and
ex[pragmaPos].kind != nkEmpty:
pragma(c, defs[lhsPos][namePos].sym, defs[lhsPos][pragmaPos], validPragmas)
return result
template isLocalSym(sym: PSym): bool =
sym.kind in {skVar, skLet} and not
({sfGlobal, sfPure} * sym.flags != {} or
sfCompileTime in sym.flags) or
sym.kind in {skProc, skFunc, skIterator} and
sfGlobal notin sym.flags
template isLocalVarSym(n: PNode): bool =
n.kind == nkSym and
(n.sym.kind in {skVar, skLet} and not
({sfGlobal, sfPure} <= n.sym.flags or
sfCompileTime in n.sym.flags) or
n.sym.kind in {skProc, skFunc, skIterator} and
sfGlobal notin n.sym.flags
)
n.kind == nkSym and isLocalSym(n.sym)
proc usesLocalVar(n: PNode): bool =
for z in 1 ..< n.len:
if n[z].isLocalVarSym:
@@ -746,7 +719,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
else:
checkNilable(c, v)
# allow let to not be initialised if imported from C:
if v.kind == skLet and sfImportc notin v.flags:
if v.kind == skLet and sfImportc notin v.flags and (strictDefs notin c.features or not isLocalSym(v)):
localError(c.config, a.info, errLetNeedsInit)
if sfCompileTime in v.flags:
var x = newNodeI(result.kind, v.info)
@@ -1389,7 +1362,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
rawAddSon(s.typ, newTypeS(tyNone, c))
s.ast = a
inc c.inGenericContext
var body = semTypeNode(c, a[2], nil)
var body = semTypeNode(c, a[2], s.typ)
dec c.inGenericContext
if body != nil:
body.sym = s
@@ -1710,12 +1683,6 @@ proc semProcAnnotation(c: PContext, prc: PNode;
doAssert result != nil
# since a proc annotation can set pragmas, we process these here again.
# This is required for SqueakNim-like export pragmas.
if false and result.kind in procDefs and result[namePos].kind == nkSym and
result[pragmasPos].kind != nkEmpty:
pragma(c, result[namePos].sym, result[pragmasPos], validPragmas)
return result
proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode {.nosinks.} =
@@ -1881,6 +1848,8 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
if s.magic == mAsgn: return
incl(s.flags, sfUsed)
incl(s.flags, sfOverriden)
if name == "=":
message(c.config, n.info, warnDeprecated, "Overriding `=` hook is deprecated; Override `=copy` hook instead")
let t = s.typ
if t.len == 3 and t[0] == nil and t[1].kind == tyVar:
var obj = t[1][0]
@@ -2210,8 +2179,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
if hasProto: localError(c.config, n.info, errImplOfXexpected % proto.name.s)
if {sfImportc, sfBorrow, sfError} * s.flags == {} and s.magic == mNone:
# this is a forward declaration and we're building the prototype
if s.kind in {skProc, skFunc} and s.typ[0] != nil and s.typ[0].kind == tyUntyped:
# `auto` is represented as `tyUntyped` at this point in compilation.
if s.kind in {skProc, skFunc} and s.typ[0] != nil and s.typ[0].kind == tyAnything:
localError(c.config, n[paramsPos][0].info, "return type 'auto' cannot be used in forward declarations")
incl(s.flags, sfForward)
@@ -2478,9 +2446,12 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags, expectedType: PType =
else:
n.typ = n[i].typ
if not isEmptyType(n.typ): n.transitionSonsKind(nkStmtListExpr)
if n[i].kind in nkLastBlockStmts or
n[i].kind in nkCallKinds and n[i][0].kind == nkSym and
sfNoReturn in n[i][0].sym.flags:
var m = n[i]
while m.kind in {nkStmtListExpr, nkStmtList} and m.len > 0: # from templates
m = m.lastSon
if m.kind in nkLastBlockStmts or
m.kind in nkCallKinds and m[0].kind == nkSym and
sfNoReturn in m[0].sym.flags:
for j in i + 1..<n.len:
case n[j].kind
of nkPragma, nkCommentStmt, nkNilLit, nkEmpty, nkState: discard

View File

@@ -0,0 +1,55 @@
#
#
# The Nim Compiler
# (c) Copyright 2022 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## New "strict funcs" checking. Much simpler and hopefully easier to teach than
## the old but more advanced algorithm that can/could be found in `varpartitions.nim`.
import ast, typeallowed, renderer
from aliasanalysis import PathKinds0, PathKinds1
from trees import getMagic
proc isDangerousLocation*(n: PNode; owner: PSym): bool =
var n = n
var hasDeref = false
while true:
case n.kind
of nkDerefExpr, nkHiddenDeref:
if n[0].typ.kind != tyVar:
hasDeref = true
n = n[0]
of PathKinds0 - {nkDerefExpr, nkHiddenDeref}:
n = n[0]
of PathKinds1:
n = n[1]
of nkCallKinds:
if n.len > 1:
if (n.typ != nil and classifyViewType(n.typ) != noView) or getMagic(n) == mSlice:
# borrow from first parameter:
n = n[1]
else:
break
else:
break
else:
break
if n.kind == nkSym:
# dangerous if contains a pointer deref or if it doesn't belong to us:
result = hasDeref or n.sym.owner != owner
when false:
# store to something that belongs to a `var` parameter is fine:
let s = n.sym
if s.kind == skParam:
# dangerous unless a `var T` parameter:
result = s.typ.kind != tyVar
else:
# dangerous if contains a pointer deref or if it doesn't belong to us:
result = hasDeref or s.owner != owner
else:
# dangerous if it contains a pointer deref
result = hasDeref

View File

@@ -691,7 +691,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
elif not comesFromShadowscope:
if {sfTemplateRedefinition, sfGenSym} * s.flags == {}:
#wrongRedefinition(c, n.info, proto.name.s, proto.info)
message(c.config, n.info, warnTemplateRedefinition, s.name.s)
message(c.config, n.info, warnImplicitTemplateRedefinition, s.name.s)
symTabReplace(c.currentScope.symbols, proto, s)
if n[patternPos].kind != nkEmpty:
c.patterns.add(s)

View File

@@ -38,7 +38,7 @@ const
errInOutFlagNotExtern = "the '$1' modifier can be used only with imported types"
proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType =
if prev == nil:
if prev == nil or prev.kind == tyGenericBody:
result = newTypeS(kind, c)
else:
result = prev
@@ -777,9 +777,10 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
if n == nil: return
case n.kind
of nkRecWhen:
var a = copyTree(n)
var branch: PNode = nil # the branch to take
for i in 0..<n.len:
var it = n[i]
for i in 0..<a.len:
var it = a[i]
if it == nil: illFormedAst(n, c.config)
var idx = 1
case it.kind
@@ -805,7 +806,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
semRecordNodeAux(c, it[idx], newCheck, newPos, newf, rectype, hasCaseFields)
it[idx] = if newf.len == 1: newf[0] else: newf
if c.inGenericContext > 0:
father.add n
father.add a
elif branch != nil:
semRecordNodeAux(c, branch, check, pos, father, rectype, hasCaseFields)
elif father.kind in {nkElse, nkOfBranch}:
@@ -977,7 +978,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
let n = if n[0].kind == nkBracket: n[0] else: n
checkMinSonsLen(n, 1, c.config)
let body = n.lastSon
var t = if prev != nil and body.kind == nkObjectTy:
var t = if prev != nil and prev.kind != tyGenericBody and body.kind == nkObjectTy:
semObjectNode(c, body, nil, prev.flags)
else:
semTypeNode(c, body, nil)
@@ -1404,9 +1405,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
"' is only valid for macros and templates")
# 'auto' as a return type does not imply a generic:
elif r.kind == tyAnything:
# 'p(): auto' and 'p(): untyped' are equivalent, but the rest of the
# compiler is hardly aware of 'auto':
r = newTypeS(tyUntyped, c)
discard
elif r.kind == tyStatic:
# type allowed should forbid this type
discard
@@ -1575,21 +1574,23 @@ proc maybeAliasType(c: PContext; typeExpr, prev: PType): PType =
result = newTypeS(tyAlias, c)
result.rawAddSon typeExpr
result.sym = prev.sym
assignType(prev, result)
if prev.kind != tyGenericBody:
assignType(prev, result)
proc fixupTypeOf(c: PContext, prev: PType, typExpr: PNode) =
if prev != nil:
let result = newTypeS(tyAlias, c)
result.rawAddSon typExpr.typ
result.sym = prev.sym
assignType(prev, result)
if prev.kind != tyGenericBody:
assignType(prev, result)
proc semTypeExpr(c: PContext, n: PNode; prev: PType): PType =
var n = semExprWithType(c, n, {efDetermineType})
if n.typ.kind == tyTypeDesc:
result = n.typ.base
# fix types constructed by macros/template:
if prev != nil and prev.sym != nil:
if prev != nil and prev.kind != tyGenericBody and prev.sym != nil:
if result.sym.isNil:
# Behold! you're witnessing enormous power yielded
# by macros. Only macros can summon unnamed types
@@ -1610,7 +1611,7 @@ proc semTypeExpr(c: PContext, n: PNode; prev: PType): PType =
result = errorType(c)
proc freshType(c: PContext; res, prev: PType): PType {.inline.} =
if prev.isNil:
if prev.isNil or prev.kind == tyGenericBody:
result = copyType(res, nextTypeId c.idgen, res.owner)
copyTypeProps(c.graph, c.idgen.module, result, res)
else:
@@ -1988,6 +1989,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
let alias = maybeAliasType(c, s.typ, prev)
if alias != nil:
result = alias
elif prev.kind == tyGenericBody:
result = s.typ
else:
assignType(prev, s.typ)
# bugfix: keep the fresh id for aliases to integral types:
@@ -2007,7 +2010,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
let alias = maybeAliasType(c, t, prev)
if alias != nil:
result = alias
elif prev == nil:
elif prev == nil or prev.kind == tyGenericBody:
result = t
else:
assignType(prev, t)

View File

@@ -499,10 +499,20 @@ proc propagateFieldFlags(t: PType, n: PNode) =
proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
template bailout =
if t.sym != nil and sfGeneratedType in t.sym.flags:
# Only consider the recursion limit if the symbol is a type with generic
# parameters that have not been explicitly supplied, typechecking should
# terminate when generic parameters are explicitly supplied.
if (t.sym == nil) or (t.sym != nil and sfGeneratedType in t.sym.flags):
# In the first case 't.sym' can be 'nil' if the type is a ref/ptr, see
# issue https://github.com/nim-lang/Nim/issues/20416 for more details.
# Fortunately for us this works for now because partial ref/ptr types are
# not allowed in object construction, eg.
# type
# Container[T] = ...
# O = object
# val: ref Container
#
# In the second case only consider the recursion limit if the symbol is a
# type with generic parameters that have not been explicitly supplied,
# typechecking should terminate when generic parameters are explicitly
# supplied.
if cl.recursionLimit > 100:
# bail out, see bug #2509. But note this caching is in general wrong,
# look at this example where TwoVectors should not share the generic

View File

@@ -373,14 +373,16 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
else:
result = t # Note: empty is valid here
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
proc handleRange(c: PContext, f, a: PType, min, max: TTypeKind): TTypeRelation =
if a.kind == f.kind:
result = isEqual
else:
let ab = skipTypes(a, {tyRange})
let k = ab.kind
let nf = c.config.normalizeKind(f.kind)
let na = c.config.normalizeKind(k)
if k == f.kind: result = isSubrange
elif k == tyInt and f.kind in {tyRange, tyInt8..tyInt64,
elif k == tyInt and f.kind in {tyRange, tyInt..tyInt64,
tyUInt..tyUInt64} and
isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and
getInt(ab.n) <= lastOrd(nil, f):
@@ -389,9 +391,13 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
# integer literal in the proper range; we want ``i16 + 4`` to stay an
# ``int16`` operation so we declare the ``4`` pseudo-equal to int16
result = isFromIntLit
elif f.kind == tyInt and k in {tyInt8..tyInt32}:
elif a.kind == tyInt and nf == c.config.targetSizeSignedToKind:
result = isIntConv
elif f.kind == tyUInt and k in {tyUInt8..tyUInt32}:
elif a.kind == tyUInt and nf == c.config.targetSizeUnsignedToKind:
result = isIntConv
elif f.kind == tyInt and na in {tyInt8 .. pred(c.config.targetSizeSignedToKind)}:
result = isIntConv
elif f.kind == tyUInt and na in {tyUInt8 .. pred(c.config.targetSizeUnsignedToKind)}:
result = isIntConv
elif k >= min and k <= max:
result = isConvertible
@@ -405,7 +411,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
result = isConvertible
else: result = isNone
proc isConvertibleToRange(f, a: PType): bool =
proc isConvertibleToRange(c: PContext, f, a: PType): bool =
if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and
a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}:
case f.kind
@@ -413,13 +419,14 @@ proc isConvertibleToRange(f, a: PType): bool =
of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16}
of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32}
# This is wrong, but seems like there's a lot of code that relies on it :(
of tyInt, tyUInt, tyUInt64: result = true
of tyInt, tyUInt: result = true
# of tyInt: result = isIntLit(a) or a.kind in {tyInt8 .. c.config.targetSizeSignedToKind}
of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8}
of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16}
of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32}
#of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
#of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64}
# of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8 .. c.config.targetSizeUnsignedToKind}
of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt64}
else: result = false
elif f.kind in {tyFloat..tyFloat128}:
# `isIntLit` is correct and should be used above as well, see PR:
@@ -1148,18 +1155,18 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
let f = skipTypes(f, {tyRange})
if f.kind == a.kind and (f.kind != tyEnum or sameEnumTypes(f, a)):
result = isIntConv
elif isConvertibleToRange(f, a):
elif isConvertibleToRange(c.c, f, a):
result = isConvertible # a convertible to f
of tyInt: result = handleRange(f, a, tyInt8, tyInt32)
of tyInt8: result = handleRange(f, a, tyInt8, tyInt8)
of tyInt16: result = handleRange(f, a, tyInt8, tyInt16)
of tyInt32: result = handleRange(f, a, tyInt8, tyInt32)
of tyInt64: result = handleRange(f, a, tyInt, tyInt64)
of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32)
of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8)
of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16)
of tyUInt32: result = handleRange(f, a, tyUInt8, tyUInt32)
of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64)
of tyInt: result = handleRange(c.c, f, a, tyInt8, c.c.config.targetSizeSignedToKind)
of tyInt8: result = handleRange(c.c, f, a, tyInt8, tyInt8)
of tyInt16: result = handleRange(c.c, f, a, tyInt8, tyInt16)
of tyInt32: result = handleRange(c.c, f, a, tyInt8, tyInt32)
of tyInt64: result = handleRange(c.c, f, a, tyInt, tyInt64)
of tyUInt: result = handleRange(c.c, f, a, tyUInt8, c.c.config.targetSizeUnsignedToKind)
of tyUInt8: result = handleRange(c.c, f, a, tyUInt8, tyUInt8)
of tyUInt16: result = handleRange(c.c, f, a, tyUInt8, tyUInt16)
of tyUInt32: result = handleRange(c.c, f, a, tyUInt8, tyUInt32)
of tyUInt64: result = handleRange(c.c, f, a, tyUInt, tyUInt64)
of tyFloat: result = handleFloatRange(f, a)
of tyFloat32: result = handleFloatRange(f, a)
of tyFloat64: result = handleFloatRange(f, a)
@@ -1912,13 +1919,16 @@ proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate,
result.add c.graph.emptyNode
result.add arg
proc isLValue(c: PContext; n: PNode): bool {.inline.} =
proc isLValue(c: PContext; n: PNode, isOutParam = false): bool {.inline.} =
let aa = isAssignable(nil, n)
case aa
of arLValue, arLocalLValue, arStrange:
result = true
of arDiscriminant:
result = c.inUncheckedAssignSection > 0
of arAddressableConst:
let sym = getRoot(n)
result = strictDefs in c.features and sym != nil and sym.kind == skLet and isOutParam
else:
result = false
@@ -2109,11 +2119,15 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
case r
of isConvertible:
if f.skipTypes({tyRange}).kind in {tyInt, tyUInt}:
inc(m.convMatches)
inc(m.convMatches)
result = implicitConv(nkHiddenStdConv, f, arg, m, c)
of isIntConv:
# I'm too lazy to introduce another ``*matches`` field, so we conflate
# ``isIntConv`` and ``isIntLit`` here:
if f.skipTypes({tyRange}).kind notin {tyInt, tyUInt}:
inc(m.intConvMatches)
inc(m.intConvMatches)
result = implicitConv(nkHiddenStdConv, f, arg, m, c)
of isSubtype:
@@ -2178,6 +2192,8 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
return arg
elif a.kind == tyVoid and f.matchesVoidProc and argOrig.kind == nkStmtList:
# lift do blocks without params to lambdas
# now deprecated
message(c.config, argOrig.info, warnStmtListLambda)
let p = c.graph
let lifted = c.semExpr(c, newProcNode(nkDo, argOrig.info, body = argOrig,
params = nkFormalParams.newTree(p.emptyNode), name = p.emptyNode, pattern = p.emptyNode,
@@ -2383,7 +2399,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var Int
if argConverter.typ.kind notin {tyVar}:
m.firstMismatch.kind = kVarNeeded
noMatch()
elif not isLValue(c, n):
elif not (isLValue(c, n, isOutParam(formal.typ))):
m.firstMismatch.kind = kVarNeeded
noMatch()

View File

@@ -19,7 +19,6 @@ proc checkForSink*(config: ConfigRef; idgen: IdGenerator; owner: PSym; arg: PNod
var local = p # sink parameter?
passToSink(local)
]#
if optSinkInference notin config.options: return
case arg.kind
of nkSym:
if arg.sym.kind == skParam and

View File

@@ -1,383 +1,207 @@
import os, strformat, strutils, tables, sets, ropes, json, algorithm
import std/[strutils, strscans, parseutils, assertions]
type
SourceNode* = ref object
line*: int
column*: int
source*: string
name*: string
children*: seq[Child]
Segment = object
## Segment refers to a block of something in the JS output.
## This could be a token or an entire line
original: int # Column in the Nim source
generated: int # Column in the generated JS
name: int # Index into names list (-1 for no name)
C = enum cSourceNode, cSourceString
Mapping = object
## Mapping refers to a line in the JS output.
## It is made up of segments which refer to the tokens in the line
case inSource: bool # Whether the line in JS has Nim equivilant
of true:
file: int # Index into files list
line: int # 0 indexed line of code in the Nim source
segments: seq[Segment]
else: discard
Child* = ref object
case kind*: C:
of cSourceNode:
node*: SourceNode
of cSourceString:
s*: string
SourceInfo = object
mappings: seq[Mapping]
names, files: seq[string]
SourceMap* = ref object
SourceMap* = object
version*: int
sources*: seq[string]
names*: seq[string]
mappings*: string
file*: string
# sourceRoot*: string
# sourcesContent*: string
SourceMapGenerator = ref object
file: string
sourceRoot: string
skipValidation: bool
sources: seq[string]
names: seq[string]
mappings: seq[Mapping]
func addSegment(info: var SourceInfo, original, generated: int, name: string = "") {.raises: [].} =
## Adds a new segment into the current line
assert info.mappings.len > 0, "No lines have been added yet"
var segment = Segment(original: original, generated: generated, name: -1)
if name != "":
# Make name be index into names list
segment.name = info.names.find(name)
if segment.name == -1:
segment.name = info.names.len
info.names &= name
Mapping* = ref object
source*: string
original*: tuple[line: int, column: int]
generated*: tuple[line: int, column: int]
name*: string
noSource*: bool
noName*: bool
assert info.mappings[^1].inSource, "Current line isn't in Nim source"
info.mappings[^1].segments &= segment
func newLine(info: var SourceInfo) {.raises: [].} =
## Add new mapping which doesn't appear in the Nim source
info.mappings &= Mapping(inSource: false)
proc child*(s: string): Child =
Child(kind: cSourceString, s: s)
proc child*(node: SourceNode): Child =
Child(kind: cSourceNode, node: node)
proc newSourceNode(line: int, column: int, path: string, node: SourceNode, name: string = ""): SourceNode =
SourceNode(line: line, column: column, source: path, name: name, children: @[child(node)])
proc newSourceNode(line: int, column: int, path: string, s: string, name: string = ""): SourceNode =
SourceNode(line: line, column: column, source: path, name: name, children: @[child(s)])
proc newSourceNode(line: int, column: int, path: string, children: seq[Child], name: string = ""): SourceNode =
SourceNode(line: line, column: column, source: path, name: name, children: children)
# debugging
proc text*(sourceNode: SourceNode, depth: int): string =
let empty = " "
result = &"{repeat(empty, depth)}SourceNode({sourceNode.source}:{sourceNode.line}:{sourceNode.column}):\n"
for child in sourceNode.children:
if child.kind == cSourceString:
result.add(&"{repeat(empty, depth + 1)}{child.s}\n")
else:
result.add(child.node.text(depth + 1))
proc `$`*(sourceNode: SourceNode): string = text(sourceNode, 0)
func newLine(info: var SourceInfo, file: string, line: int) {.raises: [].} =
## Starts a new line in the mappings. Call addSegment after this to add
## segments into the line
var mapping = Mapping(inSource: true, line: line)
# Set file to file position. Add in if needed
mapping.file = info.files.find(file)
if mapping.file == -1:
mapping.file = info.files.len
info.files &= file
info.mappings &= mapping
# base64_VLQ
func encode*(values: seq[int]): string {.raises: [].} =
## Encodes a series of integers into a VLQ base64 encoded string
# References:
# - https://www.lucidchart.com/techblog/2019/08/22/decode-encoding-base64-vlqs-source-maps/
# - https://github.com/rails/sprockets/blob/main/guides/source_maps.md#source-map-file
const
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
shift = 5
continueBit = 1 shl 5
mask = continueBit - 1
for val in values:
# Sign is stored in first bit
var newVal = abs(val) shl 1
if val < 0:
newVal = newVal or 1
# Now comes the variable length part
# This is how we are able to store large numbers
while true:
# We only encode 5 bits.
var masked = newVal and mask
newVal = newVal shr shift
# If there is still something left
# then signify with the continue bit that the
# decoder should keep decoding
if newVal > 0:
masked = masked or continueBit
result &= alphabet[masked]
# If the value is zero then we have nothing left to encode
if newVal == 0:
break
iterator tokenize*(line: string): (int, string) =
## Goes through a line and splits it into Nim identifiers and
## normal JS code. This allows us to map mangled names back to Nim names.
## Yields (column, name). Doesn't yield anything but identifiers.
## See mangleName in compiler/jsgen.nim for how name mangling is done
var
col = 0
token = ""
while col < line.len:
var
token: string
name: string
# First we find the next identifier
col += line.skipWhitespace(col)
col += line.skipUntil(IdentStartChars, col)
let identStart = col
col += line.parseIdent(token, col)
# Idents will either be originalName_randomInt or HEXhexCode_randomInt
if token.startsWith("HEX"):
var hex: int
# 3 = "HEX".len and we only want to parse the two integers after it
discard token[3 ..< 5].parseHex(hex)
name = $chr(hex)
elif not token.endsWith("_Idx"): # Ignore address indexes
# It might be in the form originalName_randomInt
let lastUnderscore = token.rfind('_')
if lastUnderscore != -1:
name = token[0..<lastUnderscore]
if name != "":
yield (identStart, name)
let integers = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
proc encode*(i: int): string =
result = ""
var n = i
if n < 0:
n = (-n shl 1) or 1
else:
n = n shl 1
var z = 0
while z == 0 or n > 0:
var e = n and 31
n = n shr 5
if n > 0:
e = e or 32
result.add(integers[e])
z += 1
type TokenState = enum Normal, String, Ident, Mangled
iterator tokenize*(line: string): (bool, string) =
# result = @[]
var state = Normal
var token = ""
var isMangled = false
for z, ch in line:
if ch.isAlphaAscii:
if state == Normal:
state = Ident
if token.len > 0:
yield (isMangled, token)
token = $ch
isMangled = false
else:
token.add(ch)
elif ch == '_':
if state == Ident:
state = Mangled
isMangled = true
token.add($ch)
elif ch != '"' and not ch.isAlphaNumeric:
if state in {Ident, Mangled}:
state = Normal
if token.len > 0:
yield (isMangled, token)
token = $ch
isMangled = false
else:
token.add($ch)
elif ch == '"':
if state != String:
state = String
if token.len > 0:
yield (isMangled, token)
token = $ch
isMangled = false
else:
state = Normal
token.add($ch)
if token.len > 0:
yield (isMangled, token)
isMangled = false
token = ""
func parse*(source: string): SourceInfo =
## Parses the JS output for embedded line info
## So it can convert those into a series of mappings
var
skipFirstLine = true
currColumn = 0
currLine = 0
currFile = ""
# Add each line as a node into the output
for line in source.splitLines():
var
lineNumber: int
linePath: string
column: int
if line.strip().scanf("/* line $i:$i \"$+\" */", lineNumber, column, linePath):
# When we reach the first line mappinsegmentg then we can assume
# we can map the rest of the JS lines to Nim lines
currColumn = column # Column is already zero indexed
currLine = lineNumber - 1
currFile = linePath
# Lines are zero indexed
result.newLine(currFile, currLine)
# Skip whitespace to find the starting column
result.addSegment(currColumn, line.skipWhitespace())
elif currFile != "":
result.newLine(currFile, currLine)
# There mightn't be any tokens so add a starting segment
result.addSegment(currColumn, line.skipWhitespace())
for jsColumn, token in line.tokenize:
result.addSegment(currColumn, jsColumn, token)
else:
token.add($ch)
if token.len > 0:
yield (isMangled, token)
result.newLine()
proc parse*(source: string, path: string): SourceNode =
let lines = source.splitLines()
var lastLocation: SourceNode = nil
result = newSourceNode(0, 0, path, @[])
# we just use one single parent and add all nim lines
# as its children, I guess in typical codegen
# that happens recursively on ast level
# we also don't have column info, but I doubt more one nim lines can compile to one js
# maybe in macros?
func toSourceMap*(info: SourceInfo, file: string): SourceMap {.raises: [].} =
## Convert from high level SourceInfo into the required SourceMap object
# Add basic info
result.version = 3
result.file = file
result.sources = info.files
result.names = info.names
# Convert nodes into mappings.
# Mappings are split into blocks where each block referes to a line in the outputted JS.
# Blocks can be seperated into statements which refere to tokens on the line.
# Since the mappings depend on previous values we need to
# keep track of previous file, name, etc
var
prevFile = 0
prevLine = 0
prevName = 0
prevNimCol = 0
for i, originalLine in lines:
let line = originalLine.strip
if line.len == 0:
continue
# this shouldn't be a problem:
# jsgen doesn't generate comments
# and if you emit // line you probably know what you're doing
if line.startsWith("// line"):
if result.children.len > 0:
result.children[^1].node.children.add(child(line & "\n"))
let pos = line.find(" ", 8)
let lineNumber = line[8 .. pos - 1].parseInt
let linePath = line[pos + 2 .. ^2] # quotes
lastLocation = newSourceNode(
lineNumber,
0,
linePath,
@[])
result.children.add(child(lastLocation))
else:
var last: SourceNode
for token in line.tokenize():
var name = ""
if token[0]:
name = token[1].split('_', 1)[0]
if result.children.len > 0:
result.children[^1].node.children.add(
child(
newSourceNode(
result.children[^1].node.line,
0,
result.children[^1].node.source,
token[1],
name)))
last = result.children[^1].node.children[^1].node
else:
result.children.add(
child(
newSourceNode(i + 1, 0, path, token[1], name)))
last = result.children[^1].node
let nl = "\n"
if not last.isNil:
last.source.add(nl)
for mapping in info.mappings:
# We know need to encode segments with the following fields
# All these fields are relative to their previous values
# - 0: Column in generated code
# - 1: Index of Nim file in source list
# - 2: Line in Nim source
# - 3: Column in Nim source
# - 4: Index in names list
if mapping.inSource:
# JS Column is special in that it is reset after every line
var prevJSCol = 0
for segment in mapping.segments:
var values = @[segment.generated - prevJSCol, mapping.file - prevFile, mapping.line - prevLine, segment.original - prevNimCol]
# Add name field if needed
if segment.name != -1:
values &= segment.name - prevName
prevName = segment.name
prevJSCol = segment.generated
prevNimCol = segment.original
prevFile = mapping.file
prevLine = mapping.line
result.mappings &= encode(values) & ","
# Remove trailing ,
if mapping.segments.len > 0:
result.mappings.setLen(result.mappings.len - 1)
proc cmp(a: Mapping, b: Mapping): int =
var c = cmp(a.generated, b.generated)
if c != 0:
return c
result.mappings &= ";"
c = cmp(a.source, b.source)
if c != 0:
return c
c = cmp(a.original, b.original)
if c != 0:
return c
return cmp(a.name, b.name)
proc index*[T](elements: seq[T], element: T): int =
for z in 0 ..< elements.len:
if elements[z] == element:
return z
return -1
proc serializeMappings(map: SourceMapGenerator, mappings: seq[Mapping]): string =
var previous = Mapping(generated: (line: 1, column: 0), original: (line: 0, column: 0), name: "", source: "")
var previousSourceId = 0
var previousNameId = 0
var next = ""
var nameId = 0
var sourceId = 0
result = ""
for z, mapping in mappings:
next = ""
if mapping.generated.line != previous.generated.line:
previous.generated.column = 0
while mapping.generated.line != previous.generated.line:
next.add(";")
previous.generated.line += 1
else:
if z > 0:
if cmp(mapping, mappings[z - 1]) == 0:
continue
next.add(",")
next.add(encode(mapping.generated.column - previous.generated.column))
previous.generated.column = mapping.generated.column
if not mapping.noSource and mapping.source.len > 0:
sourceId = map.sources.index(mapping.source)
next.add(encode(sourceId - previousSourceId))
previousSourceId = sourceId
next.add(encode(mapping.original.line - 1 - previous.original.line))
previous.original.line = mapping.original.line - 1
next.add(encode(mapping.original.column - previous.original.column))
previous.original.column = mapping.original.column
if not mapping.noName and mapping.name.len > 0:
nameId = map.names.index(mapping.name)
next.add(encode(nameId - previousNameId))
previousNameId = nameId
result.add(next)
proc gen*(map: SourceMapGenerator): SourceMap =
var mappings = map.mappings.sorted do (a: Mapping, b: Mapping) -> int:
cmp(a, b)
result = SourceMap(
file: map.file,
version: 3,
sources: map.sources[0..^1],
names: map.names[0..^1],
mappings: map.serializeMappings(mappings))
proc addMapping*(map: SourceMapGenerator, mapping: Mapping) =
if not mapping.noSource and mapping.source notin map.sources:
map.sources.add(mapping.source)
if not mapping.noName and mapping.name.len > 0 and mapping.name notin map.names:
map.names.add(mapping.name)
# echo "map ", mapping.source, " ", mapping.original, " ", mapping.generated, " ", mapping.name
map.mappings.add(mapping)
proc walk*(node: SourceNode, fn: proc(line: string, original: SourceNode)) =
for child in node.children:
if child.kind == cSourceString and child.s.len > 0:
fn(child.s, node)
else:
child.node.walk(fn)
proc toSourceMap*(node: SourceNode, file: string): SourceMapGenerator =
var map = SourceMapGenerator(file: file, sources: @[], names: @[], mappings: @[])
var generated = (line: 1, column: 0)
var sourceMappingActive = false
var lastOriginal = SourceNode(source: "", line: -1, column: 0, name: "", children: @[])
node.walk do (line: string, original: SourceNode):
if original.source.endsWith(".js"):
# ignore it
discard
else:
if original.line != -1:
if lastOriginal.source != original.source or
lastOriginal.line != original.line or
lastOriginal.column != original.column or
lastOriginal.name != original.name:
map.addMapping(
Mapping(
source: original.source,
original: (line: original.line, column: original.column),
generated: (line: generated.line, column: generated.column),
name: original.name))
lastOriginal = SourceNode(
source: original.source,
line: original.line,
column: original.column,
name: original.name,
children: lastOriginal.children)
sourceMappingActive = true
elif sourceMappingActive:
map.addMapping(
Mapping(
noSource: true,
noName: true,
generated: (line: generated.line, column: generated.column),
original: (line: -1, column: -1)))
lastOriginal.line = -1
sourceMappingActive = false
for z in 0 ..< line.len:
if line[z] in Newlines:
generated.line += 1
generated.column = 0
if z == line.len - 1:
lastOriginal.line = -1
sourceMappingActive = false
elif sourceMappingActive:
map.addMapping(
Mapping(
source: original.source,
original: (line: original.line, column: original.column),
generated: (line: generated.line, column: generated.column),
name: original.name))
else:
generated.column += 1
map
proc genSourceMap*(source: string, outFile: string): (Rope, SourceMap) =
let node = parse(source, outFile)
let map = node.toSourceMap(file = outFile)
((&"{source}\n//# sourceMappingURL={outFile}.map").rope, map.gen)
proc genSourceMap*(source: string, outFile: string): SourceMap =
let node = parse(source)
result = node.toSourceMap(outFile)

View File

@@ -68,7 +68,6 @@ proc newTransNode(kind: TNodeKind, n: PNode,
sons: int): PNode {.inline.} =
var x = newNodeIT(kind, n.info, n.typ)
newSeq(x.sons, sons)
x.typ = n.typ
# x.flags = n.flags
result = x

View File

@@ -753,8 +753,13 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 =
assert(t.n.kind == nkRange)
result = getOrdValue(t.n[0])
of tyInt:
if conf != nil and conf.target.intSize == 4:
result = toInt128(-2147483648)
if conf != nil:
case conf.target.intSize
of 8: result = toInt128(0x8000000000000000'i64)
of 4: result = toInt128(-2147483648)
of 2: result = toInt128(-32768)
of 1: result = toInt128(-128)
else: discard
else:
result = toInt128(0x8000000000000000'i64)
of tyInt8: result = toInt128(-128)
@@ -797,6 +802,29 @@ proc firstFloat*(t: PType): BiggestFloat =
internalError(newPartialConfigRef(), "invalid kind for firstFloat(" & $t.kind & ')')
NaN
proc targetSizeSignedToKind*(conf: ConfigRef): TTypeKind =
case conf.target.intSize
of 8: result = tyInt64
of 4: result = tyInt32
of 2: result = tyInt16
else: discard
proc targetSizeUnsignedToKind*(conf: ConfigRef): TTypeKind =
case conf.target.intSize
of 8: result = tyUInt64
of 4: result = tyUInt32
of 2: result = tyUInt16
else: discard
proc normalizeKind*(conf: ConfigRef, k: TTypeKind): TTypeKind =
case k
of tyInt:
result = conf.targetSizeSignedToKind()
of tyUInt:
result = conf.targetSizeUnsignedToKind()
else:
result = k
proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
case t.kind
of tyBool: result = toInt128(1'u)
@@ -808,7 +836,13 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
assert(t.n.kind == nkRange)
result = getOrdValue(t.n[1])
of tyInt:
if conf != nil and conf.target.intSize == 4: result = toInt128(0x7FFFFFFF)
if conf != nil:
case conf.target.intSize
of 8: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
of 4: result = toInt128(0x7FFFFFFF)
of 2: result = toInt128(0x00007FFF)
of 1: result = toInt128(0x0000007F)
else: discard
else: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
of tyInt8: result = toInt128(0x0000007F)
of tyInt16: result = toInt128(0x00007FFF)

View File

@@ -1,4 +1,6 @@
import ast
import ast, idents, lineinfos, astalgo
import vmdef
import std/times
template elementType*(T: typedesc): typedesc =
typeof(block:
@@ -43,3 +45,12 @@ proc toLit*[T](a: T): PNode =
else:
static: doAssert false, "not yet supported: " & $T # add as needed
proc toTimeLit*(a: Time, c: PCtx, obj: PNode, info: TLineInfo): PNode =
# probably refactor it into `toLit` in the future
result = newTree(nkObjConstr)
result.add(newNode(nkEmpty)) # can be changed to a symbol according to PType
for k, ai in fieldPairs(a):
let reti = newNode(nkExprColonExpr)
reti.add newSymNode(lookupInRecord(obj, getIdent(c.cache, k)), info)
reti.add ai.toLit
result.add reti

View File

@@ -328,8 +328,9 @@ proc registerAdditionalOps*(c: PCtx) =
registerCallback c, "stdlib.osproc.execCmdEx", proc (a: VmArgs) {.nimcall.} =
let options = getNode(a, 1).fromLit(set[osproc.ProcessOption])
a.setResult osproc.execCmdEx(getString(a, 0), options).toLit
registerCallback c, "stdlib.times.getTime", proc (a: VmArgs) {.nimcall.} =
setResult(a, times.getTime().toLit)
registerCallback c, "stdlib.times.getTimeImpl", proc (a: VmArgs) =
let obj = a.getNode(0).typ.n
setResult(a, times.getTime().toTimeLit(c, obj, a.currentLineInfo))
proc getEffectList(c: PCtx; a: VmArgs; effectIndex: int) =
let fn = getNode(a, 0)

View File

@@ -28,7 +28,9 @@ operatorB = OP0 | OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9 |
symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
| IDENT | KEYW
exprColonEqExpr = expr (':'|'=' expr)?
exprEqExpr = expr ('=' expr)?
exprList = expr ^+ comma
optionalExprList = expr ^* comma
exprColonEqExprList = exprColonEqExpr (comma exprColonEqExpr)* (comma)?
qualifiedIdent = symbol ('.' optInd symbol)?
setOrTableConstr = '{' ((exprColonEqExpr comma)* | ':' ) '}'
@@ -60,25 +62,26 @@ primarySuffix = '(' (exprColonEqExpr comma?)* ')'
| DOTLIKEOP optInd symbol generalizedLit?
| '[' optInd exprColonEqExprList optPar ']'
| '{' optInd exprColonEqExprList optPar '}'
| &( '`'|IDENT|literal|'cast'|'addr'|'type') expr (comma expr)* # command syntax
pragma = '{.' optInd (exprColonEqExpr comma?)* optPar ('.}' | '}')
identVis = symbol OPR? # postfix position
identVisDot = symbol '.' optInd symbol OPR?
identWithPragma = identVis pragma?
identWithPragmaDot = identVisDot pragma?
declColonEquals = identWithPragma (comma identWithPragma)* comma?
(':' optInd typeDesc)? ('=' optInd expr)?
(':' optInd typeDescExpr)? ('=' optInd expr)?
identColonEquals = IDENT (comma IDENT)* comma?
(':' optInd typeDesc)? ('=' optInd expr)?)
tupleDecl = 'tuple'
'[' optInd (identColonEquals (comma/semicolon)?)* optPar ']' |
COMMENT? (IND{>} identColonEquals (IND{=} identColonEquals)*)?
(':' optInd typeDescExpr)? ('=' optInd expr)?)
tupleTypeBracket = '[' optInd (identColonEquals (comma/semicolon)?)* optPar ']'
tupleType = 'tuple' tupleTypeBracket
tupleDecl = 'tuple' (tupleTypeBracket /
COMMENT? (IND{>} identColonEquals (IND{=} identColonEquals)*)?)
paramList = '(' declColonEquals ^* (comma/semicolon) ')'
paramListArrow = paramList? ('->' optInd typeDesc)?
paramListColon = paramList? (':' optInd typeDesc)?
doBlock = 'do' paramListArrow pragma? colcom stmt
routineExpr = ('proc' | 'func' | 'iterator') paramListColon pragma? ('=' COMMENT? stmt)?
forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt
routineType = ('proc' | 'iterator') paramListColon pragma?
forStmt = 'for' ((varTuple / identWithPragma) ^+ comma) 'in' expr colcom stmt
forExpr = forStmt
expr = (blockExpr
| ifExpr
@@ -87,25 +90,32 @@ expr = (blockExpr
| forExpr
| tryExpr)
/ simpleExpr
primary = operatorB primary primarySuffix* |
tupleDecl | routineExpr | enumDecl
objectDecl | conceptDecl | ('bind' primary)
('var' | 'out' | 'ref' | 'ptr' | 'distinct') primary
/ prefixOperator* identOrLiteral primarySuffix*
typeDesc = simpleExpr ('not' expr)?
typeDefAux = simpleExpr ('not' expr
| postExprBlocks)?
simplePrimary = SIGILLIKEOP? identOrLiteral primarySuffix*
commandStart = &('`'|IDENT|literal|'cast'|'addr'|'type'|'var'|'out'|
'static'|'enum'|'tuple'|'object'|'proc')
primary = simplePrimary (commandStart expr)
/ operatorB primary
/ routineExpr
/ rawTypeDesc
/ prefixOperator primary
rawTypeDesc = (tupleType | routineType | 'enum' | 'object' |
('var' | 'out' | 'ref' | 'ptr' | 'distinct') typeDesc?)
('not' expr)?
typeDescExpr = (routineType / simpleExpr) ('not' expr)?
typeDesc = rawTypeDesc / typeDescExpr
typeDefValue = ((tupleDecl | enumDecl | objectDecl | conceptDecl |
('ref' | 'ptr' | 'distinct') (tupleDecl | objectDecl))
/ (simpleExpr (exprEqExpr ^+ comma postExprBlocks)?))
('not' expr)?
postExprBlocks = ':' stmt? ( IND{=} doBlock
| IND{=} 'of' exprList ':' stmt
| IND{=} 'elif' expr ':' stmt
| IND{=} 'except' exprList ':' stmt
| IND{=} 'except' optionalExprList ':' stmt
| IND{=} 'finally' ':' stmt
| IND{=} 'else' ':' stmt )*
exprStmt = simpleExpr
(( '=' optInd expr colonBody? )
/ ( expr ^+ comma
postExprBlocks
))?
exprStmt = simpleExpr postExprBlocks?
/ simplePrimary (exprEqExpr ^+ comma) postExprBlocks?
/ simpleExpr '=' optInd (expr postExprBlocks?)
importStmt = 'import' optInd expr
((comma expr)*
/ 'except' optInd (expr ^+ comma))
@@ -139,10 +149,10 @@ caseStmt = 'case' expr ':'? COMMENT?
(IND{>} ofBranches DED
| IND{=} ofBranches)
tryStmt = 'try' colcom stmt &(IND{=}? 'except'|'finally')
(IND{=}? 'except' exprList colcom stmt)*
(IND{=}? 'except' optionalExprList colcom stmt)*
(IND{=}? 'finally' colcom stmt)?
tryExpr = 'try' colcom stmt &(optInd 'except'|'finally')
(optInd 'except' exprList colcom stmt)*
(optInd 'except' optionalExprList colcom stmt)*
(optInd 'finally' colcom stmt)?
blockStmt = 'block' symbol? colcom stmt
blockExpr = 'block' symbol? colcom stmt
@@ -175,7 +185,7 @@ objectDecl = 'object' ('of' typeDesc)? COMMENT? objectPart
conceptParam = ('var' | 'out')? symbol
conceptDecl = 'concept' conceptParam ^* ',' (pragma)? ('of' typeDesc ^* ',')?
&IND{>} stmt
typeDef = identVisDot genericParamList? pragma '=' optInd typeDefAux
typeDef = identVisDot genericParamList? pragma '=' optInd typeDefValue
indAndComment?
varTuple = '(' optInd identWithPragma ^+ comma optPar ')' '=' optInd expr
colonBody = colcom stmt postExprBlocks?

View File

@@ -46,15 +46,19 @@ Core
* [bitops](bitops.html)
Provides a series of low-level methods for bit manipulation.
* [compilesettings](compilesettings.html)
This module allows querying the compiler about diverse configuration settings.
* [cpuinfo](cpuinfo.html)
This module implements procs to determine the number of CPUs / cores.
* [effecttraits](effecttraits.html)
This module provides access to the inferred .raises effects
for Nim's macro system.
* [endians](endians.html)
This module contains helpers that deal with different byte orders.
* [lenientops](lenientops.html)
Provides binary operators for mixed integer/float expressions for convenience.
* [locks](locks.html)
Locks and condition variables for Nim.
@@ -122,9 +126,19 @@ Collections
* [packedsets](packedsets.html)
Efficient implementation of a set of ordinals as a sparse bit set.
* [ropes](ropes.html)
This module contains support for a *rope* data type.
Ropes can represent very long strings efficiently;
in particular, concatenation is done in O(1) instead of O(n).
* [sets](sets.html)
Nim hash set support.
* [strtabs](strtabs.html)
The `strtabs` module implements an efficient hash table that is a mapping
from strings to strings. Supports a case-sensitive, case-insensitive and
style-insensitive modes.
* [tables](tables.html)
Nim hash table support. Contains tables, ordered tables, and count tables.
@@ -143,20 +157,15 @@ String handling
Converts between different character encodings. On UNIX, this uses
the `iconv` library, on Windows the Windows API.
* [parseutils](parseutils.html)
This module contains helpers for parsing tokens, numbers, identifiers, etc.
* [formatfloat](formatfloat.html)
This module implements formatting floats as strings.
* [pegs](pegs.html)
This module contains procedures and operators for handling PEGs.
* [objectdollar](objectdollar.html)
This module implements a generic `$` operator to convert objects to strings.
* [punycode](punycode.html)
Implements a representation of Unicode with the limited ASCII character subset.
* [ropes](ropes.html)
This module contains support for a *rope* data type.
Ropes can represent very long strings efficiently;
in particular, concatenation is done in O(1) instead of O(n).
* [strbasics](strbasics.html)
This module provides some high performance string operations.
@@ -171,11 +180,6 @@ String handling
* [strscans](strscans.html)
This module contains a `scanf` macro for convenient parsing of mini languages.
* [strtabs](strtabs.html)
The `strtabs` module implements an efficient hash table that is a mapping
from strings to strings. Supports a case-sensitive, case-insensitive and
style-insensitive modes.
* [strutils](strutils.html)
This module contains common string handling operations like changing
case of a string, splitting a string into substrings, searching for
@@ -188,6 +192,9 @@ String handling
It provides a single proc that does Unicode to ASCII transliterations.
Based on Python's Unidecode module.
* [widestrs](widestrs.html)
Nim support for C/C++'s wide strings.
* [wordwrap](wordwrap.html)
This module contains an algorithm to wordwrap a Unicode string.
@@ -205,6 +212,16 @@ Time handling
Generic Operating System Services
---------------------------------
* [appdirs](appdirs.html)
This module implements helpers for determining special directories used by apps.
* [cmdline](cmdline.html)
This module contains system facilities for reading command
line parameters.
* [dirs](dirs.html)
This module implements directory handling.
* [distros](distros.html)
This module implements the basics for OS distribution ("distro") detection
and the OS's native package manager.
@@ -216,9 +233,14 @@ Generic Operating System Services
* [dynlib](dynlib.html)
This module implements the ability to access symbols from shared libraries.
* [marshal](marshal.html)
Contains procs for serialization and deserialization of arbitrary Nim
data structures.
* [envvars](envvars.html)
This module implements environment variable handling.
* [exitprocs](exitprocs.html)
This module allows adding hooks to program exit.
* [files](files.html)
This module implements file handling.
* [memfiles](memfiles.html)
This module provides support for memory-mapped files (Posix's `mmap`)
@@ -229,15 +251,31 @@ Generic Operating System Services
reading command line arguments, working with directories, running shell
commands, etc.
* [oserrors](oserrors.html)
This module implements OS error reporting.
* [osproc](osproc.html)
Module for process communication beyond `os.execShellCmd`.
* [paths](paths.html)
This module implements path handling.
* [reservedmem](reservedmem.html)
This module provides utilities for reserving portions of the
address space of a program without consuming physical memory.
* [streams](streams.html)
This module provides a stream interface and two implementations thereof:
the `FileStream` and the `StringStream` which implement the stream
interface for Nim file objects (`File`) and strings. Other modules
may provide other implementations for this standard stream interface.
* [symlinks](symlinks.html)
This module implements symlink handling.
* [syncio](syncio.html)
This module implements various synchronized I/O operations.
* [terminal](terminal.html)
This module contains a few procedures to control the *terminal*
(also called *console*). The implementation simply uses ANSI escape
@@ -258,6 +296,9 @@ Math libraries
Floating-point environment. Handling of floating-point rounding and
exceptions (overflow, zero-divide, etc.).
* [lenientops](lenientops.html)
Provides binary operators for mixed integer/float expressions for convenience.
* [math](math.html)
Mathematical operations like cosine, square root.
@@ -270,9 +311,6 @@ Math libraries
* [stats](stats.html)
Statistical analysis.
* [sums](sums.html)
Accurate summation functions.
* [sysrand](sysrand.html)
Cryptographically secure pseudorandom number generator.
@@ -280,6 +318,9 @@ Math libraries
Internet Protocols and Support
------------------------------
* [async](async.html)
Exports `asyncmacro` and `asyncfutures` for native backends, and `asyncjs` on the JS backend.
* [asyncdispatch](asyncdispatch.html)
This module implements an asynchronous dispatcher for IO operations.
@@ -295,6 +336,9 @@ Internet Protocols and Support
This module implements an asynchronous HTTP server using the `asyncnet`
module.
* [asyncmacro](asyncmacro.html)
Implements the `async` and `multisync` macros for `asyncdispatch`.
* [asyncnet](asyncnet.html)
This module implements asynchronous sockets based on the `asyncdispatch`
module.
@@ -326,6 +370,13 @@ Internet Protocols and Support
This module implements a selector API with backends specific to each OS.
Currently, epoll on Linux and select on other operating systems.
* [smtp](smtp.html)
This module implements a simple SMTP client.
* [socketstreams](socketstreams.html)
This module provides an implementation of the streams interface for sockets.
* [uri](uri.html)
This module provides functions for working with URIs.
@@ -333,12 +384,20 @@ Internet Protocols and Support
Threading
---------
* [threads](threads.html)
Basic Nim thread support.
* [isolation](isolation.html)
This module implements the `Isolated[T]` type for
safe construction of isolated subgraphs that can be
passed efficiently to different channels and threads.
* [tasks](tasks.html)
This module provides basic primitives for creating parallel programs.
* [threadpool](threadpool.html)
Implements Nim's [spawn](manual_experimental.html#parallel-amp-spawn).
* [typedthreads](typedthreads.html)
Basic Nim thread support.
Parsers
-------
@@ -349,9 +408,6 @@ Parsers
* [json](json.html)
High-performance JSON parser.
* [jsonutils](jsonutils.html)
This module implements a hookable (de)serialization for arbitrary types.
* [lexbase](lexbase.html)
This is a low-level module that implements an extremely efficient buffering
scheme for lexers and parsers. This is used by the diverse parsing modules.
@@ -375,12 +431,18 @@ Parsers
* [parsesql](parsesql.html)
The `parsesql` module implements a simple high-performance SQL parser.
* [parseutils](parseutils.html)
This module contains helpers for parsing tokens, numbers, identifiers, etc.
* [parsexml](parsexml.html)
The `parsexml` module implements a simple high performance XML/HTML parser.
The only encoding that is supported is UTF-8. The parser has been designed
to be somewhat error-correcting, so that even some "wild HTML" found on the
web can be parsed with it.
* [pegs](pegs.html)
This module contains procedures and operators for handling PEGs.
Docutils
--------
@@ -415,6 +477,9 @@ XML Processing
Generators
----------
* [genasts](genasts.html)
This module implements AST generation using captured variables for macros.
* [htmlgen](htmlgen.html)
This module implements a simple XML and HTML code
generator. Each commonly used HTML tag has a corresponding macro
@@ -443,9 +508,24 @@ Hashing
This module implements the SHA-1 checksum algorithm.
Serialization
-------------
* [jsonutils](jsonutils.html)
This module implements a hookable (de)serialization for arbitrary types
using JSON.
* [marshal](marshal.html)
Contains procs for serialization and deserialization of arbitrary Nim
data structures.
Miscellaneous
-------------
* [assertions](assertions.html)
This module implements assertion handling.
* [browsers](browsers.html)
This module implements procs for opening URLs with the user's default
browser.
@@ -456,9 +536,15 @@ Miscellaneous
* [coro](coro.html)
This module implements experimental coroutines in Nim.
* [decls](decls.html)
This module implements syntax sugar for some declarations.
* [enumerate](enumerate.html)
This module implements `enumerate` syntactic sugar based on Nim's macro system.
* [importutils](importutils.html)
Utilities related to import and symbol resolution.
* [logging](logging.html)
This module implements a simple logger.
@@ -477,9 +563,12 @@ Miscellaneous
* [with](with.html)
This module implements the `with` macro for easy function chaining.
* [wrapnils](wrapnils.html)
This module allows evaluating expressions safely against nil dereferences.
Modules for the JS backend
--------------------------
Modules for the JavaScript backend
----------------------------------
* [asyncjs](asyncjs.html)
Types and macros for writing asynchronous procedures in JavaScript.
@@ -497,9 +586,15 @@ Modules for the JS backend
The wrapper of core JavaScript functions. For most purposes, you should be using
the `math`, `json`, and `times` stdlib modules instead of this module.
* [jsfetch](jshttp.html)
Wrapper for `fetch`.
* [jsffi](jsffi.html)
Types and macros for easier interaction with JavaScript.
* [jsre](jsre.html)
Regular Expressions for the JavaScript target.
Impure libraries
================
@@ -511,18 +606,26 @@ Regular expressions
This module contains procedures and operators for handling regular
expressions. The current implementation uses PCRE.
* [nre](nre.html)
This module contains many help functions for handling regular expressions.
The current implementation uses PCRE.
Database support
----------------
* [db_postgres](db_postgres.html)
A higher level PostgreSQL database wrapper. The same interface is implemented
for other databases too.
* [db_mysql](db_mysql.html)
A higher level MySQL database wrapper. The same interface is implemented
for other databases too.
* [db_odbc](db_odbc.html)
A higher level ODBC database wrapper. The same interface is implemented
for other databases too.
* [db_postgres](db_postgres.html)
A higher level PostgreSQL database wrapper. The same interface is implemented
for other databases too.
* [db_sqlite](db_sqlite.html)
A higher level SQLite database wrapper. The same interface is implemented
for other databases too.
@@ -570,14 +673,14 @@ Regular expressions
Database support
----------------
* [postgres](postgres.html)
Contains a wrapper for the PostgreSQL API.
* [mysql](mysql.html)
Contains a wrapper for the mySQL API.
* [sqlite3](sqlite3.html)
Contains a wrapper for the SQLite 3 API.
* [odbcsql](odbcsql.html)
interface to the ODBC driver.
* [postgres](postgres.html)
Contains a wrapper for the PostgreSQL API.
* [sqlite3](sqlite3.html)
Contains a wrapper for the SQLite 3 API.
Network Programming and Internet Protocols

View File

@@ -8049,6 +8049,24 @@ used. To see if a value was provided, `defined(FooBar)` can be used.
The syntax `-d:flag`:option: is actually just a shortcut for
`-d:flag=true`:option:.
These pragmas also accept an optional string argument for qualified
define names.
```nim
const FooBar {.intdefine: "package.FooBar".}: int = 5
echo FooBar
```
```cmd
nim c -d:package.FooBar=42 foobar.nim
```
This helps disambiguate define names in different packages.
See also the [generic `define` pragma](manual_experimental.html#generic-define-pragma)
for a version of these pragmas that detects the type of the define based on
the constant value.
User-defined pragmas
====================
@@ -8424,23 +8442,12 @@ This is only useful if the program is compiled as a dynamic library via the
`--app:lib`:option: command-line option.
Threads
=======
To enable thread support the `--threads:on`:option: command-line switch needs to
be used. The [system module](system.html) module then contains several threading primitives.
See the [channels](channels_builtin.html) modules
for the low-level thread API. There are also high-level parallelism constructs
available. See [spawn](manual_experimental.html#parallel-amp-spawn) for
The `--threads:on`:option: command-line switch is enabled by default. The [typedthreads module](typedthreads.html) module then contains several threading primitives. See [spawn](manual_experimental.html#parallel-amp-spawn) for
further details.
Nim's memory model for threads is quite different than that of other common
programming languages (C, Pascal, Java): Each thread has its own (garbage
collected) heap, and sharing of memory is restricted to global variables. This
helps to prevent race conditions. GC efficiency is improved quite a lot,
because the GC never has to stop other threads and see what they reference.
The only way to create a thread is via `spawn` or
`createThread`. The invoked proc must not use `var` parameters nor must
any of its parameters contain a `ref` or `closure` type. This enforces

View File

@@ -65,6 +65,29 @@ However, a `void` type cannot be inferred in generic code:
The `void` type is only valid for parameters and return types; other symbols
cannot have the type `void`.
Generic `define` pragma
=======================
Aside the [typed define pragmas for constants](manual.html#implementation-specific-pragmas-compileminustime-define-pragmas),
there is a generic `{.define.}` pragma that interprets the value of the define
based on the type of the constant value.
```nim
const foo {.define: "package.foo".} = 123
const bar {.define: "package.bar".} = false
```
```cmd
nim c -d:package.foo=456 -d:package.bar foobar.nim
```
The following types are supported:
* `string` and `cstring`
* Signed and unsigned integer types
* `bool`
* Enums
Top-down type inference
=======================
@@ -519,8 +542,7 @@ Since version 1.4, a stricter definition of "side effect" is available.
In addition to the existing rule that a side effect is calling a function
with side effects, the following rule is also enforced:
Any mutation to an object does count as a side effect if that object is reachable
via a parameter that is not declared as a `var` parameter.
A store to the heap via a `ref` or `ptr` indirection is not allowed.
For example:
@@ -540,17 +562,14 @@ For example:
it = it.ri
func mut(n: Node) =
let m = n # is the statement that connected the mutation to the parameter
m.data = "yeah" # the mutation is here
# Error: 'mut' can have side effects
# an object reachable from 'n' is potentially mutated
var it = n
while it != nil:
it.data = "yeah" # forbidden mutation
it = it.ri
```
The algorithm behind this analysis is described in
the [view types algorithm][Algorithm].
View types
==========
@@ -1859,6 +1878,20 @@ before it is used. Thus the following is valid:
In this example every path does set `s` to a value before it is used.
```nim
{.experimental: "strictDefs".}
proc test(cond: bool) =
let s: seq[string]
if cond:
s = @["y"]
else:
s = @[]
```
With `experimental: "strictDefs"`, `let` statements are allowed to not have an initial value, but every path should set `s` to a value before it is used.
`out` parameters
----------------

View File

@@ -74,7 +74,9 @@ local turn on/off
---------------------
You can still turn off nil checking on function/module level by using a `{.strictNotNil: off.}` pragma.
Note: test that/TODO for code/manual.
..
Note: test that/TODO for code/manual.
nilability state
-----------------
@@ -101,7 +103,8 @@ Types are either nilable or non-nilable.
When you pass a param or a default value, we use the type : for nilable types we return `MaybeNil`
and for non-nilable `Safe`.
TODO: fix the manual here. (This is not great, as default values for non-nilables and nilables are usually actually `nil` , so we should think a bit more about this section.)
..
TODO: fix the manual here. (This is not great, as default values for non-nilables and nilables are usually actually `nil` , so we should think a bit more about this section.)
params rules
------------
@@ -236,11 +239,11 @@ e.g.
left = nil # moving out
```
..
initialization of non nilable and nilable values
-------------------------------------------------
initialization of non nilable and nilable values
-------------------------------------------------
TODO
TODO
warnings and errors
---------------------

View File

@@ -440,6 +440,7 @@ or setup a ``nim.cfg`` file like so:
#nim.cfg
--mm:orc
--d:nimAllocPagesViaMalloc
--define:nimInheritHandles
--passC="-I$DEVKITPRO/libnx/include"
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"

View File

@@ -76,7 +76,6 @@ At least the following standard library modules are available:
* [htmlgen](htmlgen.html)
* [httpcore](httpcore.html)
* [lenientops](lenientops.html)
* [mersenne](mersenne.html)
* [options](options.html)
* [parseutils](parseutils.html)
* [punycode](punycode.html)
@@ -89,7 +88,6 @@ At least the following standard library modules are available:
* [uri](uri.html)
* [std/editdistance](editdistance.html)
* [std/wordwrap](wordwrap.html)
* [std/sums](sums.html)
* [parsecsv](parsecsv.html)
* [parsecfg](parsecfg.html)
* [parsesql](parsesql.html)

View File

@@ -38,6 +38,14 @@ can also be used to include elements (and ranges of elements):
# from '0' to '9'
```
The module [`std/setutils`](https://nim-lang.org/docs/setutils.html) provides a way to initialize a set from an iterable:
```nim
import std/setutils
let uniqueChars = myString.toSet
```
These operations are supported by sets:
================== ========================================================

View File

@@ -10,7 +10,7 @@
#
const
NimbleStableCommit = "d13f3b8ce288b4dc8c34c219a4e050aaeaf43fc9" # master
NimbleStableCommit = "0777f33d1ddbd505b3aa7b714032125349323ceb" # master
# examples of possible values: #head, #ea82b54, 1.2.3
FusionStableHash = "#372ee4313827ef9f2ea388840f7d6b46c2b1b014"
HeadHash = "#head"

View File

@@ -1582,11 +1582,9 @@ proc customPragmaNode(n: NimNode): NimNode =
if n.kind in {nnkDotExpr, nnkCheckedFieldExpr}:
let name = $(if n.kind == nnkCheckedFieldExpr: n[0][1] else: n[1])
let typInst = getTypeInst(if n.kind == nnkCheckedFieldExpr or n[0].kind == nnkHiddenDeref: n[0][0] else: n[0])
var typDef = getImpl(
if typInst.kind in {nnkVarTy, nnkBracketExpr}: typInst[0]
else: typInst
)
var typInst = getTypeInst(if n.kind == nnkCheckedFieldExpr or n[0].kind == nnkHiddenDeref: n[0][0] else: n[0])
while typInst.kind in {nnkVarTy, nnkBracketExpr}: typInst = typInst[0]
var typDef = getImpl(typInst)
while typDef != nil:
typDef.expectKind(nnkTypeDef)
let typ = typDef[2].extractTypeImpl()

View File

@@ -29,7 +29,7 @@ const
CLONE_NEWPID* = 0x20000000'i32
CLONE_NEWNET* = 0x40000000'i32
CLONE_IO* = 0x80000000'i32
CLONE_STOPPED* {.deprecated.} = 0x02000000'i32
# fn should be of type proc (a2: pointer) {.cdecl.}
proc clone*(fn: pointer; child_stack: pointer; flags: cint;

View File

@@ -1,3 +1,6 @@
## Exports [asyncmacro](asyncmacro.html) and [asyncfutures](asyncfutures.html) for native backends,
## and [asyncjs](asyncjs.html) on the JS backend.
when defined(js):
import asyncjs
export asyncjs

View File

@@ -1983,7 +1983,8 @@ proc send*(socket: AsyncFD, data: string,
return retFuture
# -- Await Macro
include asyncmacro
import asyncmacro
export asyncmacro
proc readAll*(future: FutureStream[string]): owned(Future[string]) {.async.} =
## Returns a future that will complete when all the string data from the

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
## `asyncdispatch` module depends on the `asyncmacro` module to work properly.
## Implements the `async` and `multisync` macros for `asyncdispatch`.
import macros, strutils, asyncfutures
@@ -214,9 +214,18 @@ proc asyncSingleProc(prc: NimNode): NimNode =
# don't do anything with forward bodies (empty)
if procBody.kind != nnkEmpty:
# fix #13899, defer should not escape its original scope
procBody = newStmtList(newTree(nnkBlockStmt, newEmptyNode(), procBody))
procBody.add(createFutureVarCompletions(futureVarIdents, nil))
let blockStmt = newStmtList(newTree(nnkBlockStmt, newEmptyNode(), procBody))
procBody = newStmtList()
let resultIdent = ident"result"
procBody.add quote do:
template nimAsyncDispatchSetResult(x: `subRetType`) {.used.} =
# If the proc has implicit return then this will get called
`resultIdent` = x
template nimAsyncDispatchSetResult(x: untyped) {.used.} =
# If the proc doesn't have implicit return then this will get called
x
procBody.add newCall(ident"nimAsyncDispatchSetResult", blockStmt)
procBody.add(createFutureVarCompletions(futureVarIdents, nil))
procBody.insert(0): quote do:
{.push warning[resultshadowed]: off.}
when `subRetType` isnot void:
@@ -277,8 +286,8 @@ macro async*(prc: untyped): untyped =
proc splitParamType(paramType: NimNode, async: bool): NimNode =
result = paramType
if paramType.kind == nnkInfix and paramType[0].strVal in ["|", "or"]:
let firstAsync = "async" in paramType[1].strVal.normalize
let secondAsync = "async" in paramType[2].strVal.normalize
let firstAsync = "async" in paramType[1].toStrLit().strVal.normalize
let secondAsync = "async" in paramType[2].toStrLit().strVal.normalize
if firstAsync:
result = paramType[if async: 1 else: 2]

View File

@@ -38,16 +38,6 @@ proc slotsNeeded(count: Natural): int {.inline.} =
# Make sure to synchronize with `mustRehash` above
result = nextPowerOfTwo(count * 3 div 2 + 4)
proc rightSize*(count: Natural): int {.inline, deprecated: "Deprecated since 1.4.0".} =
## It is not needed anymore because
## picking the correct size is done internally.
##
## Returns the value of `initialSize` to support `count` items.
##
## If more items are expected to be added, simply add that
## expected extra amount to the parameter before calling this.
result = count
template rawGetKnownHCImpl() {.dirty.} =
if t.dataLen == 0:
return -1

View File

@@ -347,7 +347,7 @@ proc missingOrExcl*[A](s: var HashSet[A], key: A): bool =
proc pop*[A](s: var HashSet[A]): A =
## Removes and returns an arbitrary element from the set `s`.
##
## Raises KeyError if the set `s` is empty.
## Raises `KeyError` if the set `s` is empty.
##
## See also:
## * `clear proc <#clear,HashSet[A]>`_
@@ -425,7 +425,7 @@ proc intersection*[A](s1, s2: HashSet[A]): HashSet[A] =
assert c == toHashSet(["b"])
result = initHashSet[A](max(min(s1.data.len, s2.data.len), 2))
# iterate over the elements of the smaller set
if s1.data.len < s2.data.len:
for item in s1:
@@ -433,7 +433,7 @@ proc intersection*[A](s1, s2: HashSet[A]): HashSet[A] =
else:
for item in s2:
if item in s1: incl(result, item)
proc difference*[A](s1, s2: HashSet[A]): HashSet[A] =
## Returns the difference of the sets `s1` and `s2`.

View File

@@ -132,17 +132,13 @@ func toCaseInsensitive(headers: HttpHeaders, s: string): string {.inline.} =
func newHttpHeaders*(titleCase=false): HttpHeaders =
## Returns a new `HttpHeaders` object. if `titleCase` is set to true,
## headers are passed to the server in title case (e.g. "Content-Length")
new result
result.table = newTable[string, seq[string]]()
result.isTitleCase = titleCase
result = HttpHeaders(table: newTable[string, seq[string]](), isTitleCase: titleCase)
func newHttpHeaders*(keyValuePairs:
openArray[tuple[key: string, val: string]], titleCase=false): HttpHeaders =
## Returns a new `HttpHeaders` object from an array. if `titleCase` is set to true,
## headers are passed to the server in title case (e.g. "Content-Length")
new result
result.table = newTable[string, seq[string]]()
result.isTitleCase = titleCase
result = HttpHeaders(table: newTable[string, seq[string]](), isTitleCase: titleCase)
for pair in keyValuePairs:
let key = result.toCaseInsensitive(pair.key)

View File

@@ -47,7 +47,6 @@ runnableExamples:
## * `fenv module <fenv.html>`_ for handling of floating-point rounding
## and exceptions (overflow, zero-divide, etc.)
## * `random module <random.html>`_ for a fast and tiny random number generator
## * `mersenne module <mersenne.html>`_ for the Mersenne Twister random number generator
## * `stats module <stats.html>`_ for statistical analysis
## * `strformat module <strformat.html>`_ for formatting floats for printing
## * `system module <system.html>`_ for some very basic and trivial math operators

View File

@@ -168,8 +168,9 @@ func charSet*(s: set[char]): Peg {.rtl, extern: "npegs$1".} =
## constructs a PEG from a character set `s`
assert '\0' notin s
result = Peg(kind: pkCharChoice)
new(result.charChoice)
result.charChoice[] = s
{.cast(noSideEffect).}:
new(result.charChoice)
result.charChoice[] = s
func len(a: Peg): int {.inline.} = return a.sons.len
func add(d: var Peg, s: Peg) {.inline.} = add(d.sons, s)
@@ -1823,9 +1824,7 @@ type
skip: Peg
func pegError(p: PegParser, msg: string, line = -1, col = -1) =
var e: ref EInvalidPeg
new(e)
e.msg = errorStr(p, msg, line, col)
var e = (ref EInvalidPeg)(msg: errorStr(p, msg, line, col))
raise e
func getTok(p: var PegParser) =
@@ -1909,7 +1908,8 @@ func primary(p: var PegParser): Peg =
getTok(p)
elif not arrowIsNextTok(p):
var nt = getNonTerminal(p, p.tok.literal)
incl(nt.flags, ntUsed)
{.cast(noSideEffect).}:
incl(nt.flags, ntUsed)
result = nonterminal(nt).token(p)
getTok(p)
else:
@@ -2002,12 +2002,14 @@ func parseRule(p: var PegParser): NonTerminal =
result = getNonTerminal(p, p.tok.literal)
if ntDeclared in result.flags:
pegError(p, "attempt to redefine: " & result.name)
result.line = getLine(p)
result.col = getColumn(p)
{.cast(noSideEffect).}:
result.line = getLine(p)
result.col = getColumn(p)
getTok(p)
eat(p, tkArrow)
result.rule = parseExpr(p)
incl(result.flags, ntDeclared) # NOW inlining may be attempted
{.cast(noSideEffect).}:
result.rule = parseExpr(p)
incl(result.flags, ntDeclared) # NOW inlining may be attempted
else:
pegError(p, "rule expected, but found: " & p.tok.literal)

View File

@@ -14,7 +14,7 @@ when defined(nimdoc) and isMainModule:
runnableExamples:
include std/prelude
# same as:
# import std/[os, strutils, times, parseutils, hashes, tables, sets, sequtils, parseopt]
# import std/[os, strutils, times, parseutils, hashes, tables, sets, sequtils, parseopt, strformat]
let x = 1
assert "foo $# $#" % [$x, "bar"] == "foo 1 bar"
assert toSeq(1..3) == @[1, 2, 3]

View File

@@ -1,209 +0,0 @@
#
#
# Nim's Runtime Library
# (c) Copyright 2016 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Implements a representation of Unicode with the limited
## ASCII character subset.
import strutils
import unicode
# issue #3045
const
Base = 36
TMin = 1
TMax = 26
Skew = 38
Damp = 700
InitialBias = 72
InitialN = 128
Delimiter = '-'
type
PunyError* = object of ValueError
func decodeDigit(x: char): int {.raises: [PunyError].} =
if '0' <= x and x <= '9':
result = ord(x) - (ord('0') - 26)
elif 'A' <= x and x <= 'Z':
result = ord(x) - ord('A')
elif 'a' <= x and x <= 'z':
result = ord(x) - ord('a')
else:
raise newException(PunyError, "Bad input")
func encodeDigit(digit: int): Rune {.raises: [PunyError].} =
if 0 <= digit and digit < 26:
result = Rune(digit + ord('a'))
elif 26 <= digit and digit < 36:
result = Rune(digit + (ord('0') - 26))
else:
raise newException(PunyError, "internal error in punycode encoding")
func isBasic(c: char): bool = ord(c) < 0x80
func isBasic(r: Rune): bool = int(r) < 0x80
func adapt(delta, numPoints: int, first: bool): int =
var d = if first: delta div Damp else: delta div 2
d += d div numPoints
var k = 0
while d > ((Base-TMin)*TMax) div 2:
d = d div (Base - TMin)
k += Base
result = k + (Base - TMin + 1) * d div (d + Skew)
func encode*(prefix, s: string): string {.raises: [PunyError].} =
## Encode a string that may contain Unicode.
## Prepend `prefix` to the result
result = prefix
var (d, n, bias) = (0, InitialN, InitialBias)
var (b, remaining) = (0, 0)
for r in s.runes:
if r.isBasic:
# basic Ascii character
inc b
result.add($r)
else:
# special character
inc remaining
var h = b
if b > 0:
result.add(Delimiter) # we have some Ascii chars
while remaining != 0:
var m: int = high(int32)
for r in s.runes:
if m > int(r) and int(r) >= n:
m = int(r)
d += (m - n) * (h + 1)
if d < 0:
raise newException(PunyError, "invalid label " & s)
n = m
for r in s.runes:
if int(r) < n:
inc d
if d < 0:
raise newException(PunyError, "invalid label " & s)
continue
if int(r) > n:
continue
var q = d
var k = Base
while true:
var t = k - bias
if t < TMin:
t = TMin
elif t > TMax:
t = TMax
if q < t:
break
result.add($encodeDigit(t + (q - t) mod (Base - t)))
q = (q - t) div (Base - t)
k += Base
result.add($encodeDigit(q))
bias = adapt(d, h + 1, h == b)
d = 0
inc h
dec remaining
inc d
inc n
func encode*(s: string): string {.raises: [PunyError].} =
## Encode a string that may contain Unicode. Prefix is empty.
result = encode("", s)
func decode*(encoded: string): string {.raises: [PunyError].} =
## Decode a Punycode-encoded string
var
n = InitialN
i = 0
bias = InitialBias
var d = rfind(encoded, Delimiter)
var output: seq[Rune]
if d > 0:
# found Delimiter
for j in 0..<d:
var c = encoded[j] # char
if not c.isBasic:
raise newException(PunyError, "Encoded contains a non-basic char")
output.add(Rune(c)) # add the character
inc d
else:
d = 0 # set to first index
while (d < len(encoded)):
var oldi = i
var w = 1
var k = Base
while true:
if d == len(encoded):
raise newException(PunyError, "Bad input: " & encoded)
var c = encoded[d]; inc d
var digit = int(decodeDigit(c))
if digit > (high(int32) - i) div w:
raise newException(PunyError, "Too large a value: " & $digit)
i += digit * w
var t: int
if k <= bias:
t = TMin
elif k >= bias + TMax:
t = TMax
else:
t = k - bias
if digit < t:
break
w *= Base - t
k += Base
bias = adapt(i - oldi, len(output) + 1, oldi == 0)
if i div (len(output) + 1) > high(int32) - n:
raise newException(PunyError, "Value too large")
n += i div (len(output) + 1)
i = i mod (len(output) + 1)
insert(output, Rune(n), i)
inc i
result = $output
runnableExamples:
static:
block:
doAssert encode("") == ""
doAssert encode("a") == "a-"
doAssert encode("A") == "A-"
doAssert encode("3") == "3-"
doAssert encode("-") == "--"
doAssert encode("--") == "---"
doAssert encode("abc") == "abc-"
doAssert encode("London") == "London-"
doAssert encode("Lloyd-Atkinson") == "Lloyd-Atkinson-"
doAssert encode("This has spaces") == "This has spaces-"
doAssert encode("ü") == "tda"
doAssert encode("München") == "Mnchen-3ya"
doAssert encode("Mnchen-3ya") == "Mnchen-3ya-"
doAssert encode("München-Ost") == "Mnchen-Ost-9db"
doAssert encode("Bahnhof München-Ost") == "Bahnhof Mnchen-Ost-u6b"
block:
doAssert decode("") == ""
doAssert decode("a-") == "a"
doAssert decode("A-") == "A"
doAssert decode("3-") == "3"
doAssert decode("--") == "-"
doAssert decode("---") == "--"
doAssert decode("abc-") == "abc"
doAssert decode("London-") == "London"
doAssert decode("Lloyd-Atkinson-") == "Lloyd-Atkinson"
doAssert decode("This has spaces-") == "This has spaces"
doAssert decode("tda") == "ü"
doAssert decode("Mnchen-3ya") == "München"
doAssert decode("Mnchen-3ya-") == "Mnchen-3ya"
doAssert decode("Mnchen-Ost-9db") == "München-Ost"
doAssert decode("Bahnhof Mnchen-Ost-u6b") == "Bahnhof München-Ost"

View File

@@ -66,7 +66,6 @@ runnableExamples:
## See also
## ========
## * `std/sysrand module <sysrand.html>`_ for a cryptographically secure pseudorandom number generator
## * `mersenne module <mersenne.html>`_ for the Mersenne Twister random number generator
## * `math module <math.html>`_ for basic math routines
## * `stats module <stats.html>`_ for statistical analysis
## * `list of cryptographic and hashing modules <lib.html#pure-libraries-hashing>`_

View File

@@ -9,7 +9,7 @@
## :Authors: Zahary Karadjov
##
## This module provides utilities for reserving a portions of the
## This module provides utilities for reserving portions of the
## address space of a program without consuming physical memory.
## It can be used to implement a dynamically resizable buffer that
## is guaranteed to remain in the same memory location. The buffer

View File

@@ -261,10 +261,7 @@ proc newStringTable*(mode: StringTableMode): owned(StringTableRef) {.
## See also:
## * `newStringTable(keyValuePairs) proc
## <#newStringTable,varargs[tuple[string,string]],StringTableMode>`_
new(result)
result.mode = mode
result.counter = 0
newSeq(result.data, startSize)
result = StringTableRef(mode: mode, counter: 0, data: newSeq[KeyValuePair](startSize))
proc newStringTable*(keyValuePairs: varargs[string],
mode: StringTableMode): owned(StringTableRef) {.

View File

@@ -624,7 +624,7 @@ iterator splitLines*(s: string, keepEol = false): string =
##
## Every `character literal <manual.html#lexical-analysis-character-literals>`_
## newline combination (CR, LF, CR-LF) is supported. The result strings
## contain no trailing end of line characters unless parameter `keepEol`
## contain no trailing end of line characters unless the parameter `keepEol`
## is set to `true`.
##
## Example:

View File

@@ -953,27 +953,33 @@ proc toWinTime*(t: Time): int64 =
## since `1601-01-01T00:00:00Z`).
result = t.seconds * rateDiff + epochDiff + t.nanosecond div 100
proc getTimeImpl(typ: typedesc[Time]): Time =
discard "implemented in the vm"
proc getTime*(): Time {.tags: [TimeEffect], benign.} =
## Gets the current time as a `Time` with up to nanosecond resolution.
when defined(js):
let millis = newDate().getTime()
let seconds = convert(Milliseconds, Seconds, millis)
let nanos = convert(Milliseconds, Nanoseconds,
millis mod convert(Seconds, Milliseconds, 1).int)
result = initTime(seconds, nanos)
elif defined(macosx):
var a {.noinit.}: Timeval
gettimeofday(a)
result = initTime(a.tv_sec.int64,
convert(Microseconds, Nanoseconds, a.tv_usec.int))
elif defined(posix):
var ts {.noinit.}: Timespec
discard clock_gettime(CLOCK_REALTIME, ts)
result = initTime(ts.tv_sec.int64, ts.tv_nsec.int)
elif defined(windows):
var f {.noinit.}: FILETIME
getSystemTimeAsFileTime(f)
result = fromWinTime(rdFileTime(f))
when nimvm:
result = getTimeImpl(Time)
else:
when defined(js):
let millis = newDate().getTime()
let seconds = convert(Milliseconds, Seconds, millis)
let nanos = convert(Milliseconds, Nanoseconds,
millis mod convert(Seconds, Milliseconds, 1).int)
result = initTime(seconds, nanos)
elif defined(macosx):
var a {.noinit.}: Timeval
gettimeofday(a)
result = initTime(a.tv_sec.int64,
convert(Microseconds, Nanoseconds, a.tv_usec.int))
elif defined(posix):
var ts {.noinit.}: Timespec
discard clock_gettime(CLOCK_REALTIME, ts)
result = initTime(ts.tv_sec.int64, ts.tv_nsec.int)
elif defined(windows):
var f {.noinit.}: FILETIME
getSystemTimeAsFileTime(f)
result = fromWinTime(rdFileTime(f))
proc `-`*(a, b: Time): Duration {.operator, extern: "ntDiffTime".} =
## Computes the duration between two points in time.

View File

@@ -433,8 +433,6 @@ proc matchFilter(suiteName, testName, filter: string): bool =
return glob(suiteName, suiteAndTestFilters[0]) and
glob(testName, suiteAndTestFilters[1])
when defined(testing): export matchFilter
proc shouldRun(currentSuiteName, testName: string): bool =
## Check if a test should be run by matching suiteName and testName against
## test filters.

View File

@@ -1,3 +1,5 @@
## This module implements helpers for determining special directories used by apps.
from std/private/osappdirs import nil
import std/paths
import std/envvars

View File

@@ -34,7 +34,7 @@ elif defined(windows):
elif defined(posix):
import posix
else:
{.error: "cmdparam module not ported to your operating system!".}
{.error: "The cmdline module has not been implemented for the target platform.".}
# Needed by windows in order to obtain the command line for targets
@@ -310,4 +310,4 @@ when declared(paramCount) or defined(nimdoc):
else:
proc commandLineParams*(): seq[string] {.error:
"commandLineParams() unsupported by dynamic libraries".} =
discard
discard

View File

@@ -1,5 +1,4 @@
# see `semLowerLetVarCustomPragma` for compiler support that enables these
# lowerings
## This module implements syntax sugar for some declarations.
import macros

View File

@@ -1,3 +1,5 @@
## This module implements directory handling.
from paths import Path, ReadDirEffect, WriteDirEffect
from std/private/osdirs import dirExists, createDir, existsOrCreateDir, removeDir,

View File

@@ -8,7 +8,7 @@
#
## The `std/envvars` module implements environment variables handling.
## The `std/envvars` module implements environment variable handling.
import std/oserrors
type

View File

@@ -7,6 +7,8 @@
# distribution, for details about the copyright.
#
## This module allows adding hooks to program exit.
import locks
type

View File

@@ -1,3 +1,5 @@
## This module implements file handling.
from paths import Path, ReadDirEffect, WriteDirEffect
from std/private/osfiles import fileExists, removeFile,

View File

@@ -7,6 +7,8 @@
# distribution, for details about the copyright.
#
## This module implements formatting floats as strings.
when defined(nimPreviewSlimSystem):
import std/assertions
else:
@@ -28,11 +30,11 @@ proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: BiggestFloat)
##
## returns the amount of bytes written to `buf` not counting the
## terminating '\0' character.
result = toChars(buf, value, forceTrailingDotZero=true)
result = toChars(buf, value, forceTrailingDotZero=true).int
buf[result] = '\0'
proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: float32): int =
result = float32ToChars(buf, value, forceTrailingDotZero=true)
result = float32ToChars(buf, value, forceTrailingDotZero=true).int
buf[result] = '\0'
proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
@@ -49,7 +51,7 @@ proc writeFloatToBufferSprintf*(buf: var array[65, char]; value: BiggestFloat):
##
## returns the amount of bytes written to `buf` not counting the
## terminating '\0' character.
var n: int = c_sprintf(cast[cstring](addr buf), "%.16g", value)
var n = c_sprintf(cast[cstring](addr buf), "%.16g", value).int
var hasDot = false
for i in 0..n-1:
if buf[i] == ',':

View File

@@ -1,3 +1,5 @@
## This module implements AST generation using captured variables for macros.
import macros
type GenAstOpt* = enum

View File

@@ -2,7 +2,8 @@
when not defined(js):
{.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".}
import std/[asyncjs, jsheaders, jsformdata]
import std/[asyncjs, jsformdata, jsheaders]
export jsformdata, jsheaders
from std/httpcore import HttpMethod
from std/jsffi import JsObject
@@ -116,7 +117,7 @@ func `$`*(self: Request | Response | FetchOptions): string = $toCstring(self)
runnableExamples("-r:off"):
import std/[asyncjs, jsconsole, jsheaders, jsformdata]
import std/[asyncjs, jsconsole, jsformdata, jsheaders]
from std/httpcore import HttpMethod
from std/jsffi import JsObject
from std/sugar import `=>`

View File

@@ -1,5 +1,5 @@
##[
This module implements a hookable (de)serialization for arbitrary types.
This module implements a hookable (de)serialization for arbitrary types using JSON.
Design goal: avoid importing modules where a custom serialization is needed;
see strtabs.fromJsonHook,toJsonHook for an example.
]##

View File

@@ -1,3 +1,5 @@
## This module implements a generic `$` operator to convert objects to strings.
import std/private/miscdollars
proc `$`*[T: object](x: T): string =

View File

@@ -1,3 +1,5 @@
## This module implements path handling.
import std/private/osseps
export osseps

View File

@@ -34,7 +34,7 @@ proc utoa2Digits*(buf: var openArray[char]; pos: int; digits: uint32) {.inline.}
#copyMem(buf, unsafeAddr(digits100[2 * digits]), 2 * sizeof((char)))
proc trailingZeros2Digits*(digits: uint32): int32 {.inline.} =
return trailingZeros100[digits]
return trailingZeros100[digits.int8]
when defined(js):
proc numToString(a: SomeInteger): cstring {.importjs: "((#) + \"\")".}
@@ -63,14 +63,14 @@ func addIntImpl(result: var string, x: uint64) {.inline.} =
while num >= nbatch:
let originNum = num
num = num div nbatch
let index = (originNum - num * nbatch) shl 1
let index = int16((originNum - num * nbatch) shl 1)
tmp[next] = digits100[index + 1]
tmp[next - 1] = digits100[index]
dec(next, 2)
# process last 1-2 digits
if num < 10:
tmp[next] = chr(ord('0') + num)
tmp[next] = chr(ord('0') + num.uint8)
else:
let index = num * 2
tmp[next] = digits100[index + 1]

View File

@@ -1146,7 +1146,7 @@ proc printDecimalDigitsBackwards*(buf: var openArray[char]; pos: int; output64:
buf[pos] = chr(ord('0') + q)
return tz
proc decimalLength*(v: uint64): int32 {.inline.} =
proc decimalLength*(v: uint64): int {.inline.} =
dragonbox_Assert(v >= 1)
dragonbox_Assert(v <= 99999999999999999'u64)
if cast[uint32](v shr 32) != 0:
@@ -1166,48 +1166,48 @@ proc decimalLength*(v: uint64): int32 {.inline.} =
return 11
return 10
let v32: uint32 = cast[uint32](v)
if v32 >= 1000000000'u:
if v32 >= 1000000000'u32:
return 10
if v32 >= 100000000'u:
if v32 >= 100000000'u32:
return 9
if v32 >= 10000000'u:
if v32 >= 10000000'u32:
return 8
if v32 >= 1000000'u:
if v32 >= 1000000'u32:
return 7
if v32 >= 100000'u:
if v32 >= 100000'u32:
return 6
if v32 >= 10000'u:
if v32 >= 10000'u32:
return 5
if v32 >= 1000'u:
if v32 >= 1000'u32:
return 4
if v32 >= 100'u:
if v32 >= 100'u32:
return 3
if v32 >= 10'u:
if v32 >= 10'u32:
return 2
return 1
proc formatDigits*(buffer: var openArray[char]; pos: int; digits: uint64; decimalExponent: int32;
proc formatDigits*[T: Ordinal](buffer: var openArray[char]; pos: T; digits: uint64; decimalExponent: int;
forceTrailingDotZero = false): int {.inline.} =
const
minFixedDecimalPoint: int32 = -6
minFixedDecimalPoint = -6
const
maxFixedDecimalPoint: int32 = 17
var pos = pos
maxFixedDecimalPoint = 17
var pos:int = pos.int
assert(minFixedDecimalPoint <= -1, "internal error")
assert(maxFixedDecimalPoint >= 17, "internal error")
dragonbox_Assert(digits >= 1)
dragonbox_Assert(digits <= 99999999999999999'u64)
dragonbox_Assert(decimalExponent >= -999)
dragonbox_Assert(decimalExponent <= 999)
var numDigits: int32 = decimalLength(digits)
let decimalPoint: int32 = numDigits + decimalExponent
var numDigits = decimalLength(digits)
let decimalPoint = numDigits + decimalExponent
let useFixed: bool = minFixedDecimalPoint <= decimalPoint and
decimalPoint <= maxFixedDecimalPoint
## Prepare the buffer.
for i in 0..<32: buffer[pos+i] = '0'
assert(minFixedDecimalPoint >= -30, "internal error")
assert(maxFixedDecimalPoint <= 32, "internal error")
var decimalDigitsPosition: int32
var decimalDigitsPosition: int
if useFixed:
if decimalPoint <= 0:
## 0.[000]digits
@@ -1258,7 +1258,7 @@ proc formatDigits*(buffer: var openArray[char]; pos: int; digits: uint64; decima
## d.igitsE+123
buffer[pos+1] = '.'
pos = digitsEnd
let scientificExponent: int32 = decimalPoint - 1
let scientificExponent: int = decimalPoint - 1
## SF_ASSERT(scientific_exponent != 0);
buffer[pos] = 'e'
buffer[pos+1] = if scientificExponent < 0: '-' else: '+'
@@ -1291,7 +1291,7 @@ proc toChars*(buffer: var openArray[char]; v: float; forceTrailingDotZero = fals
if exponent != 0 or significand != 0:
## != 0
let dec = toDecimal64(significand, exponent)
return formatDigits(buffer, pos, dec.significand, dec.exponent,
return formatDigits(buffer, pos, dec.significand, dec.exponent.int,
forceTrailingDotZero)
else:
buffer[pos] = '0'

View File

@@ -244,7 +244,7 @@ proc toDecimal32(ieeeSignificand: uint32; ieeeExponent: uint32): FloatingDecimal
## ToChars
## ==================================================================================================
proc printDecimalDigitsBackwards(buf: var openArray[char]; pos: int; output: uint32): int32 {.inline.} =
proc printDecimalDigitsBackwards[T: Ordinal](buf: var openArray[char]; pos: T; output: uint32): int32 {.inline.} =
var output = output
var pos = pos
var tz: int32 = 0
@@ -300,7 +300,7 @@ proc printDecimalDigitsBackwards(buf: var openArray[char]; pos: int; output: uin
buf[pos] = chr(uint32('0') + q)
return tz
proc decimalLength(v: uint32): int32 {.inline.} =
proc decimalLength(v: uint32): int {.inline.} =
sf_Assert(v >= 1)
sf_Assert(v <= 999999999'u)
if v >= 100000000'u:
@@ -321,7 +321,7 @@ proc decimalLength(v: uint32): int32 {.inline.} =
return 2
return 1
proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimalExponent: int32;
proc formatDigits[T: Ordinal](buffer: var openArray[char]; pos: T; digits: uint32; decimalExponent: int;
forceTrailingDotZero: bool = false): int {.inline.} =
const
minFixedDecimalPoint: int32 = -4
@@ -333,8 +333,8 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
sf_Assert(digits <= 999999999'u)
sf_Assert(decimalExponent >= -99)
sf_Assert(decimalExponent <= 99)
var numDigits: int32 = decimalLength(digits)
let decimalPoint: int32 = numDigits + decimalExponent
var numDigits = decimalLength(digits)
let decimalPoint = numDigits + decimalExponent
let useFixed: bool = minFixedDecimalPoint <= decimalPoint and
decimalPoint <= maxFixedDecimalPoint
## Prepare the buffer.
@@ -342,7 +342,7 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
for i in 0..<32: buffer[pos+i] = '0'
assert(minFixedDecimalPoint >= -30, "internal error")
assert(maxFixedDecimalPoint <= 32, "internal error")
var decimalDigitsPosition: int32
var decimalDigitsPosition: int
if useFixed:
if decimalPoint <= 0:
## 0.[000]digits
@@ -386,7 +386,7 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
## d.igitsE+123
buffer[pos+1] = '.'
pos = digitsEnd
let scientificExponent: int32 = decimalPoint - 1
let scientificExponent = decimalPoint - 1
## SF_ASSERT(scientific_exponent != 0);
buffer[pos] = 'e'
buffer[pos+1] = if scientificExponent < 0: '-' else: '+'
@@ -412,7 +412,7 @@ proc float32ToChars*(buffer: var openArray[char]; v: float32; forceTrailingDotZe
if exponent != 0 or significand != 0:
## != 0
let dec: auto = toDecimal32(significand, exponent)
return formatDigits(buffer, pos, dec.digits, dec.exponent, forceTrailingDotZero)
return formatDigits(buffer, pos, dec.digits, dec.exponent.int, forceTrailingDotZero)
else:
buffer[pos] = '0'
buffer[pos+1] = '.'

View File

@@ -1,3 +1,5 @@
## This module implements symlink (symbolic link) handling.
from paths import Path, ReadDirEffect
from std/private/ossymlinks import symlinkExists, createSymlink, expandSymlink

View File

@@ -376,7 +376,7 @@ when defined(nimdoc) or (defined(posix) and not defined(nimscript)) or defined(w
flags = if inheritable: flags and not FD_CLOEXEC else: flags or FD_CLOEXEC
result = c_fcntl(f, F_SETFD, flags) != -1
else:
result = setHandleInformation(cast[IoHandle](f), HANDLE_FLAG_INHERIT,
result = setHandleInformation(cast[IoHandle](getOsfhandle(f)), HANDLE_FLAG_INHERIT,
inheritable.WinDWORD) != 0
proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
@@ -391,7 +391,7 @@ proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
importc: "memchr", header: "<string.h>".}
when defined(windows) and not defined(useWinAnsi):
proc readConsole(hConsoleInput: FileHandle, lpBuffer: pointer,
proc readConsole(hConsoleInput: IoHandle, lpBuffer: pointer,
nNumberOfCharsToRead: int32,
lpNumberOfCharsRead: ptr int32,
pInputControl: pointer): int32 {.
@@ -423,7 +423,7 @@ proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
const numberOfCharsToRead = 2048
var numberOfCharsRead = 0'i32
var buffer = newWideCString("", numberOfCharsToRead)
if readConsole(getOsFileHandle(f), addr(buffer[0]),
if readConsole(cast[IoHandle](getOsfhandle(getFileHandle(f))), addr(buffer[0]),
numberOfCharsToRead, addr(numberOfCharsRead), nil) == 0:
var error = getLastError()
var errorMsg: string
@@ -573,7 +573,7 @@ proc readAllFile(file: File, len: int64): string =
result = newString(len)
let bytes = readBuffer(file, addr(result[0]), len)
if endOfFile(file):
if bytes < len:
if bytes.int64 < len:
result.setLen(bytes)
else:
# We read all the bytes but did not reach the EOF
@@ -711,13 +711,13 @@ proc open*(f: var File, filename: string,
return false
when not defined(nimInheritHandles) and declared(setInheritable) and
NoInheritFlag.len == 0:
if not setInheritable(getOsFileHandle(f2), false):
if not setInheritable(getFileHandle(f2), false):
close(f2)
return false
result = true
f = cast[File](p)
if bufSize > 0 and bufSize <= high(cint).int:
if bufSize > 0 and bufSize.uint <= high(uint):
discard c_setvbuf(f, nil, IOFBF, cast[csize_t](bufSize))
elif bufSize == 0:
discard c_setvbuf(f, nil, IONBF, 0)
@@ -734,7 +734,7 @@ proc reopen*(f: File, filename: string, mode: FileMode = fmRead): bool {.
if freopen(filename.cstring, FormatOpen[mode], f) != nil:
when not defined(nimInheritHandles) and declared(setInheritable) and
NoInheritFlag.len == 0:
if not setInheritable(getOsFileHandle(f), false):
if not setInheritable(getFileHandle(f), false):
close(f)
return false
result = true
@@ -747,9 +747,7 @@ proc open*(f: var File, filehandle: FileHandle,
##
## The passed file handle will no longer be inheritable.
when not defined(nimInheritHandles) and declared(setInheritable):
let oshandle = when defined(windows): FileHandle getOsfhandle(
filehandle) else: filehandle
if not setInheritable(oshandle, false):
if not setInheritable(filehandle, false):
return false
f = c_fdopen(filehandle, FormatOpen[mode])
result = f != nil
@@ -821,7 +819,7 @@ when defined(windows) and appType == "console" and
proc getConsoleCP(): cuint {.stdcall, dynlib: "kernel32",
importc: "GetConsoleCP".}
const Utf8codepage = 65001
const Utf8codepage = 65001'u32
let
consoleOutputCP = getConsoleOutputCP()

View File

@@ -9,12 +9,6 @@
## Thread support for Nim.
##
## Nim's memory model for threads is quite different from other common
## programming languages (C, Pascal): Each thread has its own
## (garbage collected) heap and sharing of memory is restricted. This helps
## to prevent race conditions and improves efficiency. See `the manual for
## details of this memory model <manual.html#threads>`_.
##
## Examples
## ========
##
@@ -52,7 +46,7 @@ when defined(genode):
import genode/env
when hasAllocStack or defined(zephyr) or defined(freertos):
when hasAllocStack or defined(zephyr) or defined(freertos) or defined(cpu16) or defined(cpu8):
const
nimThreadStackSize {.intdefine.} = 8192
nimThreadStackGuard {.intdefine.} = 128

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
# Nim support for C/C++'s `wide strings`:idx:.
## Nim support for C/C++'s `wide strings`:idx:.
#when not declared(ThisIsSystem):
# {.error: "You must not import this module explicitly".}
@@ -15,214 +15,215 @@
type
Utf16Char* = distinct int16
when defined(nimv2):
when not (defined(cpu16) or defined(cpu8)):
when defined(nimv2):
type
WideCString* = ptr UncheckedArray[Utf16Char]
type
WideCString* = ptr UncheckedArray[Utf16Char]
WideCStringObj* = object
bytes: int
data: WideCString
WideCStringObj* = object
bytes: int
data: WideCString
proc `=destroy`(a: var WideCStringObj) =
if a.data != nil:
proc `=destroy`(a: var WideCStringObj) =
if a.data != nil:
when compileOption("threads"):
deallocShared(a.data)
else:
dealloc(a.data)
proc `=copy`(a: var WideCStringObj; b: WideCStringObj) {.error.}
proc `=sink`(a: var WideCStringObj; b: WideCStringObj) =
a.bytes = b.bytes
a.data = b.data
proc createWide(a: var WideCStringObj; bytes: int) =
a.bytes = bytes
when compileOption("threads"):
deallocShared(a.data)
a.data = cast[typeof(a.data)](allocShared0(bytes))
else:
dealloc(a.data)
a.data = cast[typeof(a.data)](alloc0(bytes))
proc `=copy`(a: var WideCStringObj; b: WideCStringObj) {.error.}
template `[]`*(a: WideCStringObj; idx: int): Utf16Char = a.data[idx]
template `[]=`*(a: WideCStringObj; idx: int; val: Utf16Char) = a.data[idx] = val
proc `=sink`(a: var WideCStringObj; b: WideCStringObj) =
a.bytes = b.bytes
a.data = b.data
template nullWide(): untyped = WideCStringObj(bytes: 0, data: nil)
proc createWide(a: var WideCStringObj; bytes: int) =
a.bytes = bytes
when compileOption("threads"):
a.data = cast[typeof(a.data)](allocShared0(bytes))
else:
a.data = cast[typeof(a.data)](alloc0(bytes))
converter toWideCString*(x: WideCStringObj): WideCString {.inline.} =
result = x.data
template `[]`*(a: WideCStringObj; idx: int): Utf16Char = a.data[idx]
template `[]=`*(a: WideCStringObj; idx: int; val: Utf16Char) = a.data[idx] = val
template nullWide(): untyped = WideCStringObj(bytes: 0, data: nil)
converter toWideCString*(x: WideCStringObj): WideCString {.inline.} =
result = x.data
else:
template nullWide(): untyped = nil
type
WideCString* = ref UncheckedArray[Utf16Char]
WideCStringObj* = WideCString
template createWide(a; L) =
unsafeNew(a, L)
proc ord(arg: Utf16Char): int = int(cast[uint16](arg))
proc len*(w: WideCString): int =
## returns the length of a widestring. This traverses the whole string to
## find the binary zero end marker!
result = 0
while int16(w[result]) != 0'i16: inc result
const
UNI_REPLACEMENT_CHAR = Utf16Char(0xFFFD'i16)
UNI_MAX_BMP = 0x0000FFFF
UNI_MAX_UTF16 = 0x0010FFFF
# UNI_MAX_UTF32 = 0x7FFFFFFF
# UNI_MAX_LEGAL_UTF32 = 0x0010FFFF
halfShift = 10
halfBase = 0x0010000
halfMask = 0x3FF
UNI_SUR_HIGH_START = 0xD800
UNI_SUR_HIGH_END = 0xDBFF
UNI_SUR_LOW_START = 0xDC00
UNI_SUR_LOW_END = 0xDFFF
UNI_REPL = 0xFFFD
template ones(n: untyped): untyped = ((1 shl n)-1)
template fastRuneAt(s: cstring, i, L: int, result: untyped, doInc = true) =
## Returns the unicode character `s[i]` in `result`. If `doInc == true`
## `i` is incremented by the number of bytes that have been processed.
bind ones
if ord(s[i]) <= 127:
result = ord(s[i])
when doInc: inc(i)
elif ord(s[i]) shr 5 == 0b110:
#assert(ord(s[i+1]) shr 6 == 0b10)
if i <= L - 2:
result = (ord(s[i]) and (ones(5))) shl 6 or (ord(s[i+1]) and ones(6))
when doInc: inc(i, 2)
else:
result = UNI_REPL
when doInc: inc(i)
elif ord(s[i]) shr 4 == 0b1110:
if i <= L - 3:
#assert(ord(s[i+1]) shr 6 == 0b10)
#assert(ord(s[i+2]) shr 6 == 0b10)
result = (ord(s[i]) and ones(4)) shl 12 or
(ord(s[i+1]) and ones(6)) shl 6 or
(ord(s[i+2]) and ones(6))
when doInc: inc(i, 3)
else:
result = UNI_REPL
when doInc: inc(i)
elif ord(s[i]) shr 3 == 0b11110:
if i <= L - 4:
#assert(ord(s[i+1]) shr 6 == 0b10)
#assert(ord(s[i+2]) shr 6 == 0b10)
#assert(ord(s[i+3]) shr 6 == 0b10)
result = (ord(s[i]) and ones(3)) shl 18 or
(ord(s[i+1]) and ones(6)) shl 12 or
(ord(s[i+2]) and ones(6)) shl 6 or
(ord(s[i+3]) and ones(6))
when doInc: inc(i, 4)
else:
result = UNI_REPL
when doInc: inc(i)
else:
result = 0xFFFD
when doInc: inc(i)
template nullWide(): untyped = nil
iterator runes(s: cstring, L: int): int =
var
i = 0
result: int
while i < L:
fastRuneAt(s, i, L, result, true)
yield result
type
WideCString* = ref UncheckedArray[Utf16Char]
WideCStringObj* = WideCString
proc newWideCString*(size: int): WideCStringObj =
createWide(result, size * 2 + 2)
template createWide(a; L) =
unsafeNew(a, L)
proc newWideCString*(source: cstring, L: int): WideCStringObj =
createWide(result, L * 2 + 2)
var d = 0
for ch in runes(source, L):
proc ord(arg: Utf16Char): int = int(cast[uint16](arg))
if ch <= UNI_MAX_BMP:
if ch >= UNI_SUR_HIGH_START and ch <= UNI_SUR_LOW_END:
proc len*(w: WideCString): int =
## returns the length of a widestring. This traverses the whole string to
## find the binary zero end marker!
result = 0
while int16(w[result]) != 0'i16: inc result
const
UNI_REPLACEMENT_CHAR = Utf16Char(0xFFFD'i16)
UNI_MAX_BMP = 0x0000FFFF
UNI_MAX_UTF16 = 0x0010FFFF
# UNI_MAX_UTF32 = 0x7FFFFFFF
# UNI_MAX_LEGAL_UTF32 = 0x0010FFFF
halfShift = 10
halfBase = 0x0010000
halfMask = 0x3FF
UNI_SUR_HIGH_START = 0xD800
UNI_SUR_HIGH_END = 0xDBFF
UNI_SUR_LOW_START = 0xDC00
UNI_SUR_LOW_END = 0xDFFF
UNI_REPL = 0xFFFD
template ones(n: untyped): untyped = ((1 shl n)-1)
template fastRuneAt(s: cstring, i, L: int, result: untyped, doInc = true) =
## Returns the unicode character `s[i]` in `result`. If `doInc == true`
## `i` is incremented by the number of bytes that have been processed.
bind ones
if ord(s[i]) <= 127:
result = ord(s[i])
when doInc: inc(i)
elif ord(s[i]) shr 5 == 0b110:
#assert(ord(s[i+1]) shr 6 == 0b10)
if i <= L - 2:
result = (ord(s[i]) and (ones(5))) shl 6 or (ord(s[i+1]) and ones(6))
when doInc: inc(i, 2)
else:
result = UNI_REPL
when doInc: inc(i)
elif ord(s[i]) shr 4 == 0b1110:
if i <= L - 3:
#assert(ord(s[i+1]) shr 6 == 0b10)
#assert(ord(s[i+2]) shr 6 == 0b10)
result = (ord(s[i]) and ones(4)) shl 12 or
(ord(s[i+1]) and ones(6)) shl 6 or
(ord(s[i+2]) and ones(6))
when doInc: inc(i, 3)
else:
result = UNI_REPL
when doInc: inc(i)
elif ord(s[i]) shr 3 == 0b11110:
if i <= L - 4:
#assert(ord(s[i+1]) shr 6 == 0b10)
#assert(ord(s[i+2]) shr 6 == 0b10)
#assert(ord(s[i+3]) shr 6 == 0b10)
result = (ord(s[i]) and ones(3)) shl 18 or
(ord(s[i+1]) and ones(6)) shl 12 or
(ord(s[i+2]) and ones(6)) shl 6 or
(ord(s[i+3]) and ones(6))
when doInc: inc(i, 4)
else:
result = UNI_REPL
when doInc: inc(i)
else:
result = 0xFFFD
when doInc: inc(i)
iterator runes(s: cstring, L: int): int =
var
i = 0
result: int
while i < L:
fastRuneAt(s, i, L, result, true)
yield result
proc newWideCString*(size: int): WideCStringObj =
createWide(result, size * 2 + 2)
proc newWideCString*(source: cstring, L: int): WideCStringObj =
createWide(result, L * 2 + 2)
var d = 0
for ch in runes(source, L):
if ch <= UNI_MAX_BMP:
if ch >= UNI_SUR_HIGH_START and ch <= UNI_SUR_LOW_END:
result[d] = UNI_REPLACEMENT_CHAR
else:
result[d] = cast[Utf16Char](uint16(ch))
elif ch > UNI_MAX_UTF16:
result[d] = UNI_REPLACEMENT_CHAR
else:
result[d] = cast[Utf16Char](uint16(ch))
elif ch > UNI_MAX_UTF16:
result[d] = UNI_REPLACEMENT_CHAR
else:
let ch = ch - halfBase
result[d] = cast[Utf16Char](uint16((ch shr halfShift) + UNI_SUR_HIGH_START))
let ch = ch - halfBase
result[d] = cast[Utf16Char](uint16((ch shr halfShift) + UNI_SUR_HIGH_START))
inc d
result[d] = cast[Utf16Char](uint16((ch and halfMask) + UNI_SUR_LOW_START))
inc d
result[d] = cast[Utf16Char](uint16((ch and halfMask) + UNI_SUR_LOW_START))
inc d
result[d] = Utf16Char(0)
result[d] = Utf16Char(0)
proc newWideCString*(s: cstring): WideCStringObj =
if s.isNil: return nullWide
proc newWideCString*(s: cstring): WideCStringObj =
if s.isNil: return nullWide
result = newWideCString(s, s.len)
result = newWideCString(s, s.len)
proc newWideCString*(s: string): WideCStringObj =
result = newWideCString(cstring s, s.len)
proc newWideCString*(s: string): WideCStringObj =
result = newWideCString(cstring s, s.len)
proc `$`*(w: WideCString, estimate: int, replacement: int = 0xFFFD): string =
result = newStringOfCap(estimate + estimate shr 2)
proc `$`*(w: WideCString, estimate: int, replacement: int = 0xFFFD): string =
result = newStringOfCap(estimate + estimate shr 2)
var i = 0
while w[i].int16 != 0'i16:
var ch = ord(w[i])
inc i
if ch >= UNI_SUR_HIGH_START and ch <= UNI_SUR_HIGH_END:
# If the 16 bits following the high surrogate are in the source buffer...
let ch2 = ord(w[i])
var i = 0
while w[i].int16 != 0'i16:
var ch = ord(w[i])
inc i
if ch >= UNI_SUR_HIGH_START and ch <= UNI_SUR_HIGH_END:
# If the 16 bits following the high surrogate are in the source buffer...
let ch2 = ord(w[i])
# If it's a low surrogate, convert to UTF32:
if ch2 >= UNI_SUR_LOW_START and ch2 <= UNI_SUR_LOW_END:
ch = (((ch and halfMask) shl halfShift) + (ch2 and halfMask)) + halfBase
inc i
else:
# If it's a low surrogate, convert to UTF32:
if ch2 >= UNI_SUR_LOW_START and ch2 <= UNI_SUR_LOW_END:
ch = (((ch and halfMask) shl halfShift) + (ch2 and halfMask)) + halfBase
inc i
else:
#invalid UTF-16
ch = replacement
elif ch >= UNI_SUR_LOW_START and ch <= UNI_SUR_LOW_END:
#invalid UTF-16
ch = replacement
elif ch >= UNI_SUR_LOW_START and ch <= UNI_SUR_LOW_END:
#invalid UTF-16
ch = replacement
if ch < 0x80:
result.add chr(ch)
elif ch < 0x800:
result.add chr((ch shr 6) or 0xc0)
result.add chr((ch and 0x3f) or 0x80)
elif ch < 0x10000:
result.add chr((ch shr 12) or 0xe0)
result.add chr(((ch shr 6) and 0x3f) or 0x80)
result.add chr((ch and 0x3f) or 0x80)
elif ch <= 0x10FFFF:
result.add chr((ch shr 18) or 0xf0)
result.add chr(((ch shr 12) and 0x3f) or 0x80)
result.add chr(((ch shr 6) and 0x3f) or 0x80)
result.add chr((ch and 0x3f) or 0x80)
else:
# replacement char(in case user give very large number):
result.add chr(0xFFFD shr 12 or 0b1110_0000)
result.add chr(0xFFFD shr 6 and ones(6) or 0b10_0000_00)
result.add chr(0xFFFD and ones(6) or 0b10_0000_00)
if ch < 0x80:
result.add chr(ch)
elif ch < 0x800:
result.add chr((ch shr 6) or 0xc0)
result.add chr((ch and 0x3f) or 0x80)
elif ch < 0x10000:
result.add chr((ch shr 12) or 0xe0)
result.add chr(((ch shr 6) and 0x3f) or 0x80)
result.add chr((ch and 0x3f) or 0x80)
elif ch <= 0x10FFFF:
result.add chr((ch shr 18) or 0xf0)
result.add chr(((ch shr 12) and 0x3f) or 0x80)
result.add chr(((ch shr 6) and 0x3f) or 0x80)
result.add chr((ch and 0x3f) or 0x80)
else:
# replacement char(in case user give very large number):
result.add chr(0xFFFD shr 12 or 0b1110_0000)
result.add chr(0xFFFD shr 6 and ones(6) or 0b10_0000_00)
result.add chr(0xFFFD and ones(6) or 0b10_0000_00)
proc `$`*(s: WideCString): string =
result = s $ 80
proc `$`*(s: WideCString): string =
result = s $ 80
when defined(nimv2):
proc `$`*(s: WideCStringObj, estimate: int, replacement: int = 0xFFFD): string =
`$`(s.data, estimate, replacement)
when defined(nimv2):
proc `$`*(s: WideCStringObj, estimate: int, replacement: int = 0xFFFD): string =
`$`(s.data, estimate, replacement)
proc `$`*(s: WideCStringObj): string =
$(s.data)
proc `$`*(s: WideCStringObj): string =
$(s.data)
proc len*(w: WideCStringObj): int {.inline.} =
len(w.data)
proc len*(w: WideCStringObj): int {.inline.} =
len(w.data)

View File

@@ -1664,6 +1664,8 @@ proc contains*[T](a: openArray[T], item: T): bool {.inline.}=
proc pop*[T](s: var seq[T]): T {.inline, noSideEffect.} =
## Returns the last item of `s` and decreases `s.len` by one. This treats
## `s` as a stack and implements the common *pop* operation.
##
## Raises `IndexDefect` if `s` is empty.
runnableExamples:
var a = @[1, 3, 5, 7]
let b = pop(a)
@@ -2001,7 +2003,7 @@ when notJSnotNims:
proc equalMem(a, b: pointer, size: Natural): bool =
nimCmpMem(a, b, size) == 0
proc cmpMem(a, b: pointer, size: Natural): int =
nimCmpMem(a, b, size)
nimCmpMem(a, b, size).int
when not defined(js):
proc cmp(x, y: string): int =
@@ -2300,11 +2302,13 @@ else:
type ExitCodeRange = int8
else: # win32 uses low 32 bits
type ExitCodeRange = cint
if errorcode < low(ExitCodeRange):
rawQuit(low(ExitCodeRange).cint)
elif errorcode > high(ExitCodeRange):
rawQuit(high(ExitCodeRange).cint)
when sizeof(errorcode) > sizeof(ExitCodeRange):
if errorcode < low(ExitCodeRange):
rawQuit(low(ExitCodeRange).cint)
elif errorcode > high(ExitCodeRange):
rawQuit(high(ExitCodeRange).cint)
else:
rawQuit(errorcode.cint)
else:
rawQuit(errorcode.cint)
@@ -2356,7 +2360,8 @@ when not defined(gcArc) and not defined(gcOrc):
if s.len == 0: return
when not defined(js) and not defined(nimscript) and not defined(nimSeqsV2):
var s = cast[PGenericSeq](s)
s.reserved = s.reserved or seqShallowFlag
{.noSideEffect.}:
s.reserved = s.reserved or seqShallowFlag
proc shallow*(s: var string) {.noSideEffect, inline.} =
## Marks a string `s` as `shallow`:idx:. Subsequent assignments will not
@@ -2369,7 +2374,8 @@ when not defined(gcArc) and not defined(gcOrc):
s = cast[PGenericSeq](newString(0))
# string literals cannot become 'shallow':
if (s.reserved and strlitFlag) == 0:
s.reserved = s.reserved or seqShallowFlag
{.noSideEffect.}:
s.reserved = s.reserved or seqShallowFlag
type
NimNodeObj = object
@@ -2796,7 +2802,7 @@ when notJSnotNims and not defined(nimSeqsV2):
assert y == "abcgh"
discard
proc arrayWith*[T](y: T, size: static int): array[size, T] {.noinit.} = # ? exempt from default value for result
proc nimArrayWith[T](y: T, size: static int): array[size, T] {.compilerRtl, raises: [].} =
## Creates a new array filled with `y`.
for i in 0..size-1:
result[i] = y

View File

@@ -24,7 +24,7 @@ template track(op, address, size) =
const
nimMinHeapPages {.intdefine.} = 128 # 0.5 MB
SmallChunkSize = PageSize
MaxFli = 30
MaxFli = when sizeof(int) > 2: 30 else: 14
MaxLog2Sli = 5 # 32, this cannot be increased without changing 'uint32'
# everywhere!
MaxSli = 1 shl MaxLog2Sli
@@ -32,7 +32,7 @@ const
RealFli = MaxFli - FliOffset
# size of chunks in last matrix bin
MaxBigChunkSize = 1 shl MaxFli - 1 shl (MaxFli-MaxLog2Sli-1)
MaxBigChunkSize = int(1'i32 shl MaxFli - 1'i32 shl (MaxFli-MaxLog2Sli-1))
HugeChunkSize = MaxBigChunkSize + 1
type
@@ -115,7 +115,7 @@ type
MemRegion = object
when not defined(gcDestructors):
minLargeObj, maxLargeObj: int
freeSmallChunks: array[0..SmallChunkSize div MemAlign-1, PSmallChunk]
freeSmallChunks: array[0..max(1,SmallChunkSize div MemAlign-1), PSmallChunk]
flBitmap: uint32
slBitmap: array[RealFli, uint32]
matrix: array[RealFli, array[MaxSli, PBigChunk]]
@@ -196,7 +196,7 @@ proc mappingSearch(r, fl, sl: var int) {.inline.} =
let t = roundup((1 shl (msbit(uint32 r) - MaxLog2Sli)), PageSize) - 1
r = r + t
r = r and not t
r = min(r, MaxBigChunkSize)
r = min(r, MaxBigChunkSize).int
fl = msbit(uint32 r)
sl = (r shr (fl - MaxLog2Sli)) - MaxSli
dec fl, FliOffset
@@ -472,7 +472,7 @@ proc requestOsChunks(a: var MemRegion, size: int): PBigChunk =
a.nextChunkSize = PageSize*4
else:
a.nextChunkSize = min(roundup(usedMem shr 2, PageSize), a.nextChunkSize * 2)
a.nextChunkSize = min(a.nextChunkSize, MaxBigChunkSize)
a.nextChunkSize = min(a.nextChunkSize, MaxBigChunkSize).int
var size = size
if size > a.nextChunkSize:
@@ -787,8 +787,9 @@ when defined(gcDestructors):
while it != nil:
if maxIters == 0:
let rest = it.next.loada
it.next.storea nil
addToSharedFreeList(c, rest)
if rest != nil:
it.next.storea nil
addToSharedFreeList(c, rest)
break
inc x, size
it = it.next.loada

View File

@@ -1,4 +1,4 @@
proc succ*[T: Ordinal](x: T, y = 1): T {.magic: "Succ", noSideEffect.} =
proc succ*[T, V: Ordinal](x: T, y: V = 1): T {.magic: "Succ", noSideEffect.} =
## Returns the `y`-th successor (default: 1) of the value `x`.
##
## If such a value does not exist, `OverflowDefect` is raised
@@ -7,7 +7,7 @@ proc succ*[T: Ordinal](x: T, y = 1): T {.magic: "Succ", noSideEffect.} =
assert succ(5) == 6
assert succ(5, 3) == 8
proc pred*[T: Ordinal](x: T, y = 1): T {.magic: "Pred", noSideEffect.} =
proc pred*[T, V: Ordinal](x: T, y: V = 1): T {.magic: "Pred", noSideEffect.} =
## Returns the `y`-th predecessor (default: 1) of the value `x`.
##
## If such a value does not exist, `OverflowDefect` is raised
@@ -16,7 +16,7 @@ proc pred*[T: Ordinal](x: T, y = 1): T {.magic: "Pred", noSideEffect.} =
assert pred(5) == 4
assert pred(5, 3) == 2
proc inc*[T: Ordinal](x: var T, y = 1) {.magic: "Inc", noSideEffect.} =
proc inc*[T, V: Ordinal](x: var T, y: V = 1) {.magic: "Inc", noSideEffect.} =
## Increments the ordinal `x` by `y`.
##
## If such a value does not exist, `OverflowDefect` is raised or a compile
@@ -28,7 +28,7 @@ proc inc*[T: Ordinal](x: var T, y = 1) {.magic: "Inc", noSideEffect.} =
inc(i, 3)
assert i == 6
proc dec*[T: Ordinal](x: var T, y = 1) {.magic: "Dec", noSideEffect.} =
proc dec*[T, V: Ordinal](x: var T, y: V = 1) {.magic: "Dec", noSideEffect.} =
## Decrements the ordinal `x` by `y`.
##
## If such a value does not exist, `OverflowDefect` is raised or a compile

View File

@@ -10,7 +10,7 @@
# Page size of the system; in most cases 4096 bytes. For exotic OS or
# CPU this needs to be changed:
const
PageShift = when defined(nimPage256) or defined(cpu16): 8
PageShift = when defined(nimPage256) or defined(cpu16): 3
elif defined(nimPage512): 9
elif defined(nimPage1k): 10
else: 12 # \ # my tests showed no improvements for using larger page sizes.

View File

@@ -103,16 +103,17 @@ proc add*[T](x: var seq[T]; value: sink T) {.magic: "AppendSeqElem", noSideEffec
## containers should also call their adding proc `add` for consistency.
## Generic code becomes much easier to write if the Nim naming scheme is
## respected.
let oldLen = x.len
var xu = cast[ptr NimSeqV2[T]](addr x)
if xu.p == nil or xu.p.cap < oldLen+1:
xu.p = cast[typeof(xu.p)](prepareSeqAdd(oldLen, xu.p, 1, sizeof(T), alignof(T)))
xu.len = oldLen+1
# .nodestroy means `xu.p.data[oldLen] = value` is compiled into a
# copyMem(). This is fine as know by construction that
# in `xu.p.data[oldLen]` there is nothing to destroy.
# We also save the `wasMoved + destroy` pair for the sink parameter.
xu.p.data[oldLen] = value
{.cast(noSideEffect).}:
let oldLen = x.len
var xu = cast[ptr NimSeqV2[T]](addr x)
if xu.p == nil or xu.p.cap < oldLen+1:
xu.p = cast[typeof(xu.p)](prepareSeqAdd(oldLen, xu.p, 1, sizeof(T), alignof(T)))
xu.len = oldLen+1
# .nodestroy means `xu.p.data[oldLen] = value` is compiled into a
# copyMem(). This is fine as know by construction that
# in `xu.p.data[oldLen]` there is nothing to destroy.
# We also save the `wasMoved + destroy` pair for the sink parameter.
xu.p.data[oldLen] = value
proc setLen[T](s: var seq[T], newlen: Natural) =
{.noSideEffect.}:

View File

@@ -17,7 +17,7 @@ proc cmpStrings(a, b: string): int {.inline, compilerproc.} =
let blen = b.len
let minlen = min(alen, blen)
if minlen > 0:
result = c_memcmp(unsafeAddr a[0], unsafeAddr b[0], cast[csize_t](minlen))
result = c_memcmp(unsafeAddr a[0], unsafeAddr b[0], cast[csize_t](minlen)).int
if result == 0:
result = alen - blen
else:

View File

@@ -36,7 +36,7 @@ template frees(s) =
proc resize(old: int): int {.inline.} =
if old <= 0: result = 4
elif old < 65536: result = old * 2
elif old <= high(int16): result = old * 2
else: result = old * 3 div 2 # for large arrays * 3/2 is better
proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} =

File diff suppressed because it is too large Load Diff

View File

@@ -1,844 +0,0 @@
#
#
# Nim's Runtime Library
# (c) Copyright 2015 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
when defined(nimPreviewSlimSystem):
import std/widestrs
when not defined(ODBCVER):
const
ODBCVER = 0x0351 ## define ODBC version 3.51 by default
when defined(windows):
{.push callconv: stdcall.}
const odbclib = "odbc32.dll"
else:
{.push callconv: cdecl.}
const odbclib = "libodbc.so"
when defined(nimHasStyleChecks):
{.push styleChecks: off.}
# DATA TYPES CORRESPONDENCE
# BDE fields ODBC types
# ---------- ------------------
# ftBlob SQL_BINARY
# ftBoolean SQL_BIT
# ftDate SQL_TYPE_DATE
# ftTime SQL_TYPE_TIME
# ftDateTime SQL_TYPE_TIMESTAMP
# ftInteger SQL_INTEGER
# ftSmallint SQL_SMALLINT
# ftFloat SQL_DOUBLE
# ftString SQL_CHAR
# ftMemo SQL_BINARY // SQL_VARCHAR
#
type
TSqlChar* = char
TSqlSmallInt* = int16
SqlUSmallInt* = int16
SqlHandle* = pointer
SqlHEnv* = SqlHandle
SqlHDBC* = SqlHandle
SqlHStmt* = SqlHandle
SqlHDesc* = SqlHandle
TSqlInteger* = int32
SqlUInteger* = int32
TSqlLen* = int
TSqlULen* = uint
SqlPointer* = pointer
TSqlReal* = cfloat
TSqlDouble* = cdouble
TSqlFloat* = cdouble
SqlHWND* = pointer
PSQLCHAR* = cstring
PSQLINTEGER* = ptr TSqlInteger
PSQLUINTEGER* = ptr SqlUInteger
PSQLSMALLINT* = ptr TSqlSmallInt
PSQLUSMALLINT* = ptr SqlUSmallInt
PSQLREAL* = ptr TSqlReal
PSQLDOUBLE* = ptr TSqlDouble
PSQLFLOAT* = ptr TSqlFloat
PSQLHANDLE* = ptr SqlHandle
const # SQL data type codes
SQL_UNKNOWN_TYPE* = 0
SQL_LONGVARCHAR* = (- 1)
SQL_BINARY* = (- 2)
SQL_VARBINARY* = (- 3)
SQL_LONGVARBINARY* = (- 4)
SQL_BIGINT* = (- 5)
SQL_TINYINT* = (- 6)
SQL_BIT* = (- 7)
SQL_WCHAR* = (- 8)
SQL_WVARCHAR* = (- 9)
SQL_WLONGVARCHAR* = (- 10)
SQL_CHAR* = 1
SQL_NUMERIC* = 2
SQL_DECIMAL* = 3
SQL_INTEGER* = 4
SQL_SMALLINT* = 5
SQL_FLOAT* = 6
SQL_REAL* = 7
SQL_DOUBLE* = 8
SQL_DATETIME* = 9
SQL_VARCHAR* = 12
SQL_TYPE_DATE* = 91
SQL_TYPE_TIME* = 92
SQL_TYPE_TIMESTAMP* = 93
SQL_DATE* = 9
SQL_TIME* = 10
SQL_TIMESTAMP* = 11
SQL_INTERVAL* = 10
SQL_GUID* = - 11 # interval codes
when ODBCVER >= 0x0300:
const
SQL_CODE_YEAR* = 1
SQL_CODE_MONTH* = 2
SQL_CODE_DAY* = 3
SQL_CODE_HOUR* = 4
SQL_CODE_MINUTE* = 5
SQL_CODE_SECOND* = 6
SQL_CODE_YEAR_TO_MONTH* = 7
SQL_CODE_DAY_TO_HOUR* = 8
SQL_CODE_DAY_TO_MINUTE* = 9
SQL_CODE_DAY_TO_SECOND* = 10
SQL_CODE_HOUR_TO_MINUTE* = 11
SQL_CODE_HOUR_TO_SECOND* = 12
SQL_CODE_MINUTE_TO_SECOND* = 13
SQL_INTERVAL_YEAR* = 100 + SQL_CODE_YEAR
SQL_INTERVAL_MONTH* = 100 + SQL_CODE_MONTH
SQL_INTERVAL_DAY* = 100 + SQL_CODE_DAY
SQL_INTERVAL_HOUR* = 100 + SQL_CODE_HOUR
SQL_INTERVAL_MINUTE* = 100 + SQL_CODE_MINUTE
SQL_INTERVAL_SECOND* = 100 + SQL_CODE_SECOND
SQL_INTERVAL_YEAR_TO_MONTH* = 100 + SQL_CODE_YEAR_TO_MONTH
SQL_INTERVAL_DAY_TO_HOUR* = 100 + SQL_CODE_DAY_TO_HOUR
SQL_INTERVAL_DAY_TO_MINUTE* = 100 + SQL_CODE_DAY_TO_MINUTE
SQL_INTERVAL_DAY_TO_SECOND* = 100 + SQL_CODE_DAY_TO_SECOND
SQL_INTERVAL_HOUR_TO_MINUTE* = 100 + SQL_CODE_HOUR_TO_MINUTE
SQL_INTERVAL_HOUR_TO_SECOND* = 100 + SQL_CODE_HOUR_TO_SECOND
SQL_INTERVAL_MINUTE_TO_SECOND* = 100 + SQL_CODE_MINUTE_TO_SECOND
else:
const
SQL_INTERVAL_YEAR* = - 80
SQL_INTERVAL_MONTH* = - 81
SQL_INTERVAL_YEAR_TO_MONTH* = - 82
SQL_INTERVAL_DAY* = - 83
SQL_INTERVAL_HOUR* = - 84
SQL_INTERVAL_MINUTE* = - 85
SQL_INTERVAL_SECOND* = - 86
SQL_INTERVAL_DAY_TO_HOUR* = - 87
SQL_INTERVAL_DAY_TO_MINUTE* = - 88
SQL_INTERVAL_DAY_TO_SECOND* = - 89
SQL_INTERVAL_HOUR_TO_MINUTE* = - 90
SQL_INTERVAL_HOUR_TO_SECOND* = - 91
SQL_INTERVAL_MINUTE_TO_SECOND* = - 92
when ODBCVER < 0x0300:
const
SQL_UNICODE* = - 95
SQL_UNICODE_VARCHAR* = - 96
SQL_UNICODE_LONGVARCHAR* = - 97
SQL_UNICODE_CHAR* = SQL_UNICODE
else:
# The previous definitions for SQL_UNICODE_ are historical and obsolete
const
SQL_UNICODE* = SQL_WCHAR
SQL_UNICODE_VARCHAR* = SQL_WVARCHAR
SQL_UNICODE_LONGVARCHAR* = SQL_WLONGVARCHAR
SQL_UNICODE_CHAR* = SQL_WCHAR
const # C datatype to SQL datatype mapping
SQL_C_CHAR* = SQL_CHAR
SQL_C_LONG* = SQL_INTEGER
SQL_C_SHORT* = SQL_SMALLINT
SQL_C_FLOAT* = SQL_REAL
SQL_C_DOUBLE* = SQL_DOUBLE
SQL_C_NUMERIC* = SQL_NUMERIC
SQL_C_DEFAULT* = 99
SQL_SIGNED_OFFSET* = - 20
SQL_UNSIGNED_OFFSET* = - 22
SQL_C_DATE* = SQL_DATE
SQL_C_TIME* = SQL_TIME
SQL_C_TIMESTAMP* = SQL_TIMESTAMP
SQL_C_TYPE_DATE* = SQL_TYPE_DATE
SQL_C_TYPE_TIME* = SQL_TYPE_TIME
SQL_C_TYPE_TIMESTAMP* = SQL_TYPE_TIMESTAMP
SQL_C_INTERVAL_YEAR* = SQL_INTERVAL_YEAR
SQL_C_INTERVAL_MONTH* = SQL_INTERVAL_MONTH
SQL_C_INTERVAL_DAY* = SQL_INTERVAL_DAY
SQL_C_INTERVAL_HOUR* = SQL_INTERVAL_HOUR
SQL_C_INTERVAL_MINUTE* = SQL_INTERVAL_MINUTE
SQL_C_INTERVAL_SECOND* = SQL_INTERVAL_SECOND
SQL_C_INTERVAL_YEAR_TO_MONTH* = SQL_INTERVAL_YEAR_TO_MONTH
SQL_C_INTERVAL_DAY_TO_HOUR* = SQL_INTERVAL_DAY_TO_HOUR
SQL_C_INTERVAL_DAY_TO_MINUTE* = SQL_INTERVAL_DAY_TO_MINUTE
SQL_C_INTERVAL_DAY_TO_SECOND* = SQL_INTERVAL_DAY_TO_SECOND
SQL_C_INTERVAL_HOUR_TO_MINUTE* = SQL_INTERVAL_HOUR_TO_MINUTE
SQL_C_INTERVAL_HOUR_TO_SECOND* = SQL_INTERVAL_HOUR_TO_SECOND
SQL_C_INTERVAL_MINUTE_TO_SECOND* = SQL_INTERVAL_MINUTE_TO_SECOND
SQL_C_BINARY* = SQL_BINARY
SQL_C_BIT* = SQL_BIT
SQL_C_SBIGINT* = SQL_BIGINT + SQL_SIGNED_OFFSET # SIGNED BIGINT
SQL_C_UBIGINT* = SQL_BIGINT + SQL_UNSIGNED_OFFSET # UNSIGNED BIGINT
SQL_C_TINYINT* = SQL_TINYINT
SQL_C_SLONG* = SQL_C_LONG + SQL_SIGNED_OFFSET # SIGNED INTEGER
SQL_C_SSHORT* = SQL_C_SHORT + SQL_SIGNED_OFFSET # SIGNED SMALLINT
SQL_C_STINYINT* = SQL_TINYINT + SQL_SIGNED_OFFSET # SIGNED TINYINT
SQL_C_ULONG* = SQL_C_LONG + SQL_UNSIGNED_OFFSET # UNSIGNED INTEGER
SQL_C_USHORT* = SQL_C_SHORT + SQL_UNSIGNED_OFFSET # UNSIGNED SMALLINT
SQL_C_UTINYINT* = SQL_TINYINT + SQL_UNSIGNED_OFFSET # UNSIGNED TINYINT
SQL_C_BOOKMARK* = SQL_C_ULONG # BOOKMARK
SQL_C_GUID* = SQL_GUID
SQL_TYPE_NULL* = 0
when ODBCVER < 0x0300:
const
SQL_TYPE_MIN* = SQL_BIT
SQL_TYPE_MAX* = SQL_VARCHAR
const
SQL_C_VARBOOKMARK* = SQL_C_BINARY
SQL_API_SQLDESCRIBEPARAM* = 58
SQL_NO_TOTAL* = - 4
type
SQL_DATE_STRUCT* {.final, pure.} = object
Year*: TSqlSmallInt
Month*: SqlUSmallInt
Day*: SqlUSmallInt
PSQL_DATE_STRUCT* = ptr SQL_DATE_STRUCT
SQL_TIME_STRUCT* {.final, pure.} = object
Hour*: SqlUSmallInt
Minute*: SqlUSmallInt
Second*: SqlUSmallInt
PSQL_TIME_STRUCT* = ptr SQL_TIME_STRUCT
SQL_TIMESTAMP_STRUCT* {.final, pure.} = object
Year*: SqlUSmallInt
Month*: SqlUSmallInt
Day*: SqlUSmallInt
Hour*: SqlUSmallInt
Minute*: SqlUSmallInt
Second*: SqlUSmallInt
Fraction*: SqlUInteger
PSQL_TIMESTAMP_STRUCT* = ptr SQL_TIMESTAMP_STRUCT
const
SQL_NAME_LEN* = 128
SQL_OV_ODBC3* = 3
SQL_OV_ODBC2* = 2
SQL_ATTR_ODBC_VERSION* = 200 # Options for SQLDriverConnect
SQL_DRIVER_NOPROMPT* = 0
SQL_DRIVER_COMPLETE* = 1
SQL_DRIVER_PROMPT* = 2
SQL_DRIVER_COMPLETE_REQUIRED* = 3
SQL_IS_POINTER* = (- 4) # whether an attribute is a pointer or not
SQL_IS_UINTEGER* = (- 5)
SQL_IS_INTEGER* = (- 6)
SQL_IS_USMALLINT* = (- 7)
SQL_IS_SMALLINT* = (- 8) # SQLExtendedFetch "fFetchType" values
SQL_FETCH_BOOKMARK* = 8
SQL_SCROLL_OPTIONS* = 44 # SQL_USE_BOOKMARKS options
SQL_UB_OFF* = 0
SQL_UB_ON* = 1
SQL_UB_DEFAULT* = SQL_UB_OFF
SQL_UB_FIXED* = SQL_UB_ON
SQL_UB_VARIABLE* = 2 # SQL_SCROLL_OPTIONS masks
SQL_SO_FORWARD_ONLY* = 0x00000001
SQL_SO_KEYSET_DRIVEN* = 0x00000002
SQL_SO_DYNAMIC* = 0x00000004
SQL_SO_MIXED* = 0x00000008
SQL_SO_STATIC* = 0x00000010
SQL_BOOKMARK_PERSISTENCE* = 82
SQL_STATIC_SENSITIVITY* = 83 # SQL_BOOKMARK_PERSISTENCE values
SQL_BP_CLOSE* = 0x00000001
SQL_BP_DELETE* = 0x00000002
SQL_BP_DROP* = 0x00000004
SQL_BP_TRANSACTION* = 0x00000008
SQL_BP_UPDATE* = 0x00000010
SQL_BP_OTHER_HSTMT* = 0x00000020
SQL_BP_SCROLL* = 0x00000040
SQL_DYNAMIC_CURSOR_ATTRIBUTES1* = 144
SQL_DYNAMIC_CURSOR_ATTRIBUTES2* = 145
SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1* = 146
SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2* = 147
SQL_INDEX_KEYWORDS* = 148
SQL_INFO_SCHEMA_VIEWS* = 149
SQL_KEYSET_CURSOR_ATTRIBUTES1* = 150
SQL_KEYSET_CURSOR_ATTRIBUTES2* = 151
SQL_STATIC_CURSOR_ATTRIBUTES1* = 167
SQL_STATIC_CURSOR_ATTRIBUTES2* = 168 # supported SQLFetchScroll FetchOrientation's
SQL_CA1_NEXT* = 1
SQL_CA1_ABSOLUTE* = 2
SQL_CA1_RELATIVE* = 4
SQL_CA1_BOOKMARK* = 8 # supported SQLSetPos LockType's
SQL_CA1_LOCK_NO_CHANGE* = 0x00000040
SQL_CA1_LOCK_EXCLUSIVE* = 0x00000080
SQL_CA1_LOCK_UNLOCK* = 0x00000100 # supported SQLSetPos Operations
SQL_CA1_POS_POSITION* = 0x00000200
SQL_CA1_POS_UPDATE* = 0x00000400
SQL_CA1_POS_DELETE* = 0x00000800
SQL_CA1_POS_REFRESH* = 0x00001000 # positioned updates and deletes
SQL_CA1_POSITIONED_UPDATE* = 0x00002000
SQL_CA1_POSITIONED_DELETE* = 0x00004000
SQL_CA1_SELECT_FOR_UPDATE* = 0x00008000 # supported SQLBulkOperations operations
SQL_CA1_BULK_ADD* = 0x00010000
SQL_CA1_BULK_UPDATE_BY_BOOKMARK* = 0x00020000
SQL_CA1_BULK_DELETE_BY_BOOKMARK* = 0x00040000
SQL_CA1_BULK_FETCH_BY_BOOKMARK* = 0x00080000 # supported values for SQL_ATTR_SCROLL_CONCURRENCY
SQL_CA2_READ_ONLY_CONCURRENCY* = 1
SQL_CA2_LOCK_CONCURRENCY* = 2
SQL_CA2_OPT_ROWVER_CONCURRENCY* = 4
SQL_CA2_OPT_VALUES_CONCURRENCY* = 8 # sensitivity of the cursor to its own inserts, deletes, and updates
SQL_CA2_SENSITIVITY_ADDITIONS* = 0x00000010
SQL_CA2_SENSITIVITY_DELETIONS* = 0x00000020
SQL_CA2_SENSITIVITY_UPDATES* = 0x00000040 # semantics of SQL_ATTR_MAX_ROWS
SQL_CA2_MAX_ROWS_SELECT* = 0x00000080
SQL_CA2_MAX_ROWS_INSERT* = 0x00000100
SQL_CA2_MAX_ROWS_DELETE* = 0x00000200
SQL_CA2_MAX_ROWS_UPDATE* = 0x00000400
SQL_CA2_MAX_ROWS_CATALOG* = 0x00000800
SQL_CA2_MAX_ROWS_AFFECTS_ALL* = (SQL_CA2_MAX_ROWS_SELECT or
SQL_CA2_MAX_ROWS_INSERT or SQL_CA2_MAX_ROWS_DELETE or
SQL_CA2_MAX_ROWS_UPDATE or SQL_CA2_MAX_ROWS_CATALOG) # semantics of
# SQL_DIAG_CURSOR_ROW_COUNT
SQL_CA2_CRC_EXACT* = 0x00001000
SQL_CA2_CRC_APPROXIMATE* = 0x00002000 # the kinds of positioned statements that can be simulated
SQL_CA2_SIMULATE_NON_UNIQUE* = 0x00004000
SQL_CA2_SIMULATE_TRY_UNIQUE* = 0x00008000
SQL_CA2_SIMULATE_UNIQUE* = 0x00010000 # Operations in SQLBulkOperations
SQL_ADD* = 4
SQL_SETPOS_MAX_OPTION_VALUE* = SQL_ADD
SQL_UPDATE_BY_BOOKMARK* = 5
SQL_DELETE_BY_BOOKMARK* = 6
SQL_FETCH_BY_BOOKMARK* = 7 # Operations in SQLSetPos
SQL_POSITION* = 0
SQL_REFRESH* = 1
SQL_UPDATE* = 2
SQL_DELETE* = 3 # Lock options in SQLSetPos
SQL_LOCK_NO_CHANGE* = 0
SQL_LOCK_EXCLUSIVE* = 1
SQL_LOCK_UNLOCK* = 2 # SQLExtendedFetch "rgfRowStatus" element values
SQL_ROW_SUCCESS* = 0
SQL_ROW_DELETED* = 1
SQL_ROW_UPDATED* = 2
SQL_ROW_NOROW* = 3
SQL_ROW_ADDED* = 4
SQL_ROW_ERROR* = 5
SQL_ROW_SUCCESS_WITH_INFO* = 6
SQL_ROW_PROCEED* = 0
SQL_ROW_IGNORE* = 1
SQL_MAX_DSN_LENGTH* = 32 # maximum data source name size
SQL_MAX_OPTION_STRING_LENGTH* = 256
SQL_ODBC_CURSORS* = 110
SQL_ATTR_ODBC_CURSORS* = SQL_ODBC_CURSORS # SQL_ODBC_CURSORS options
SQL_CUR_USE_IF_NEEDED* = 0
SQL_CUR_USE_ODBC* = 1
SQL_CUR_USE_DRIVER* = 2
SQL_CUR_DEFAULT* = SQL_CUR_USE_DRIVER
SQL_PARAM_TYPE_UNKNOWN* = 0
SQL_PARAM_INPUT* = 1
SQL_PARAM_INPUT_OUTPUT* = 2
SQL_RESULT_COL* = 3
SQL_PARAM_OUTPUT* = 4
SQL_RETURN_VALUE* = 5 # special length/indicator values
SQL_NULL_DATA* = (- 1)
SQL_DATA_AT_EXEC* = (- 2)
SQL_SUCCESS* = 0
SQL_SUCCESS_WITH_INFO* = 1
SQL_NO_DATA* = 100
SQL_ERROR* = (- 1)
SQL_INVALID_HANDLE* = (- 2)
SQL_STILL_EXECUTING* = 2
SQL_NEED_DATA* = 99 # flags for null-terminated string
SQL_NTS* = (- 3) # maximum message length
SQL_MAX_MESSAGE_LENGTH* = 512 # date/time length constants
SQL_DATE_LEN* = 10
SQL_TIME_LEN* = 8 # add P+1 if precision is nonzero
SQL_TIMESTAMP_LEN* = 19 # add P+1 if precision is nonzero
# handle type identifiers
SQL_HANDLE_ENV* = 1
SQL_HANDLE_DBC* = 2
SQL_HANDLE_STMT* = 3
SQL_HANDLE_DESC* = 4 # environment attribute
SQL_ATTR_OUTPUT_NTS* = 10001 # connection attributes
SQL_ATTR_AUTO_IPD* = 10001
SQL_ATTR_METADATA_ID* = 10014 # statement attributes
SQL_ATTR_APP_ROW_DESC* = 10010
SQL_ATTR_APP_PARAM_DESC* = 10011
SQL_ATTR_IMP_ROW_DESC* = 10012
SQL_ATTR_IMP_PARAM_DESC* = 10013
SQL_ATTR_CURSOR_SCROLLABLE* = (- 1)
SQL_ATTR_CURSOR_SENSITIVITY* = (- 2)
SQL_QUERY_TIMEOUT* = 0
SQL_MAX_ROWS* = 1
SQL_NOSCAN* = 2
SQL_MAX_LENGTH* = 3
SQL_ASYNC_ENABLE* = 4 # same as SQL_ATTR_ASYNC_ENABLE */
SQL_BIND_TYPE* = 5
SQL_CURSOR_TYPE* = 6
SQL_CONCURRENCY* = 7
SQL_KEYSET_SIZE* = 8
SQL_ROWSET_SIZE* = 9
SQL_SIMULATE_CURSOR* = 10
SQL_RETRIEVE_DATA* = 11
SQL_USE_BOOKMARKS* = 12
SQL_GET_BOOKMARK* = 13 # GetStmtOption Only */
SQL_ROW_NUMBER* = 14 # GetStmtOption Only */
SQL_ATTR_CURSOR_TYPE* = SQL_CURSOR_TYPE
SQL_ATTR_CONCURRENCY* = SQL_CONCURRENCY
SQL_ATTR_FETCH_BOOKMARK_PTR* = 16
SQL_ATTR_ROW_STATUS_PTR* = 25
SQL_ATTR_ROWS_FETCHED_PTR* = 26
SQL_AUTOCOMMIT* = 102
SQL_ATTR_AUTOCOMMIT* = SQL_AUTOCOMMIT
SQL_ATTR_ROW_NUMBER* = SQL_ROW_NUMBER
SQL_TXN_ISOLATION* = 108
SQL_ATTR_TXN_ISOLATION* = SQL_TXN_ISOLATION
SQL_ATTR_MAX_ROWS* = SQL_MAX_ROWS
SQL_ATTR_USE_BOOKMARKS* = SQL_USE_BOOKMARKS #* connection attributes */
SQL_ACCESS_MODE* = 101 # SQL_AUTOCOMMIT =102;
SQL_LOGIN_TIMEOUT* = 103
SQL_OPT_TRACE* = 104
SQL_OPT_TRACEFILE* = 105
SQL_TRANSLATE_DLL* = 106
SQL_TRANSLATE_OPTION* = 107 # SQL_TXN_ISOLATION =108;
SQL_CURRENT_QUALIFIER* = 109 # SQL_ODBC_CURSORS =110;
SQL_QUIET_MODE* = 111
SQL_PACKET_SIZE* = 112 #* connection attributes with new names */
SQL_ATTR_ACCESS_MODE* = SQL_ACCESS_MODE # SQL_ATTR_AUTOCOMMIT =SQL_AUTOCOMMIT;
SQL_ATTR_CONNECTION_DEAD* = 1209 #* GetConnectAttr only */
SQL_ATTR_CONNECTION_TIMEOUT* = 113
SQL_ATTR_CURRENT_CATALOG* = SQL_CURRENT_QUALIFIER
SQL_ATTR_DISCONNECT_BEHAVIOR* = 114
SQL_ATTR_ENLIST_IN_DTC* = 1207
SQL_ATTR_ENLIST_IN_XA* = 1208
SQL_ATTR_LOGIN_TIMEOUT* = SQL_LOGIN_TIMEOUT # SQL_ATTR_ODBC_CURSORS =SQL_ODBC_CURSORS;
SQL_ATTR_PACKET_SIZE* = SQL_PACKET_SIZE
SQL_ATTR_QUIET_MODE* = SQL_QUIET_MODE
SQL_ATTR_TRACE* = SQL_OPT_TRACE
SQL_ATTR_TRACEFILE* = SQL_OPT_TRACEFILE
SQL_ATTR_TRANSLATE_LIB* = SQL_TRANSLATE_DLL
SQL_ATTR_TRANSLATE_OPTION* = SQL_TRANSLATE_OPTION # SQL_ATTR_TXN_ISOLATION =SQL_TXN_ISOLATION;
#* SQL_ACCESS_MODE options */
SQL_MODE_READ_WRITE* = 0
SQL_MODE_READ_ONLY* = 1
SQL_MODE_DEFAULT* = SQL_MODE_READ_WRITE #* SQL_AUTOCOMMIT options */
SQL_AUTOCOMMIT_OFF* = 0
SQL_AUTOCOMMIT_ON* = 1
SQL_AUTOCOMMIT_DEFAULT* = SQL_AUTOCOMMIT_ON # SQL_ATTR_CURSOR_SCROLLABLE values
SQL_NONSCROLLABLE* = 0
SQL_SCROLLABLE* = 1 # SQL_CURSOR_TYPE options
SQL_CURSOR_FORWARD_ONLY* = 0
SQL_CURSOR_KEYSET_DRIVEN* = 1
SQL_CURSOR_DYNAMIC* = 2
SQL_CURSOR_STATIC* = 3
SQL_CURSOR_TYPE_DEFAULT* = SQL_CURSOR_FORWARD_ONLY # Default value
# SQL_CONCURRENCY options
SQL_CONCUR_READ_ONLY* = 1
SQL_CONCUR_LOCK* = 2
SQL_CONCUR_ROWVER* = 3
SQL_CONCUR_VALUES* = 4
SQL_CONCUR_DEFAULT* = SQL_CONCUR_READ_ONLY # Default value
# identifiers of fields in the SQL descriptor
SQL_DESC_COUNT* = 1001
SQL_DESC_TYPE* = 1002
SQL_DESC_LENGTH* = 1003
SQL_DESC_OCTET_LENGTH_PTR* = 1004
SQL_DESC_PRECISION* = 1005
SQL_DESC_SCALE* = 1006
SQL_DESC_DATETIME_INTERVAL_CODE* = 1007
SQL_DESC_NULLABLE* = 1008
SQL_DESC_INDICATOR_PTR* = 1009
SQL_DESC_DATA_PTR* = 1010
SQL_DESC_NAME* = 1011
SQL_DESC_UNNAMED* = 1012
SQL_DESC_OCTET_LENGTH* = 1013
SQL_DESC_ALLOC_TYPE* = 1099 # identifiers of fields in the diagnostics area
SQL_DIAG_RETURNCODE* = 1
SQL_DIAG_NUMBER* = 2
SQL_DIAG_ROW_COUNT* = 3
SQL_DIAG_SQLSTATE* = 4
SQL_DIAG_NATIVE* = 5
SQL_DIAG_MESSAGE_TEXT* = 6
SQL_DIAG_DYNAMIC_FUNCTION* = 7
SQL_DIAG_CLASS_ORIGIN* = 8
SQL_DIAG_SUBCLASS_ORIGIN* = 9
SQL_DIAG_CONNECTION_NAME* = 10
SQL_DIAG_SERVER_NAME* = 11
SQL_DIAG_DYNAMIC_FUNCTION_CODE* = 12 # dynamic function codes
SQL_DIAG_ALTER_TABLE* = 4
SQL_DIAG_CREATE_INDEX* = (- 1)
SQL_DIAG_CREATE_TABLE* = 77
SQL_DIAG_CREATE_VIEW* = 84
SQL_DIAG_DELETE_WHERE* = 19
SQL_DIAG_DROP_INDEX* = (- 2)
SQL_DIAG_DROP_TABLE* = 32
SQL_DIAG_DROP_VIEW* = 36
SQL_DIAG_DYNAMIC_DELETE_CURSOR* = 38
SQL_DIAG_DYNAMIC_UPDATE_CURSOR* = 81
SQL_DIAG_GRANT* = 48
SQL_DIAG_INSERT* = 50
SQL_DIAG_REVOKE* = 59
SQL_DIAG_SELECT_CURSOR* = 85
SQL_DIAG_UNKNOWN_STATEMENT* = 0
SQL_DIAG_UPDATE_WHERE* = 82 # Statement attribute values for cursor sensitivity
SQL_UNSPECIFIED* = 0
SQL_INSENSITIVE* = 1
SQL_SENSITIVE* = 2 # GetTypeInfo() request for all data types
SQL_ALL_TYPES* = 0 # Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData()
SQL_DEFAULT* = 99 # SQLGetData() code indicating that the application row descriptor
# specifies the data type
SQL_ARD_TYPE* = (- 99) # SQL date/time type subcodes
SQL_CODE_DATE* = 1
SQL_CODE_TIME* = 2
SQL_CODE_TIMESTAMP* = 3 # CLI option values
SQL_FALSE* = 0
SQL_TRUE* = 1 # values of NULLABLE field in descriptor
SQL_NO_NULLS* = 0
SQL_NULLABLE* = 1 # Value returned by SQLGetTypeInfo() to denote that it is
# not known whether or not a data type supports null values.
SQL_NULLABLE_UNKNOWN* = 2
SQL_CLOSE* = 0
SQL_DROP* = 1
SQL_UNBIND* = 2
SQL_RESET_PARAMS* = 3 # Codes used for FetchOrientation in SQLFetchScroll(),
# and in SQLDataSources()
SQL_FETCH_NEXT* = 1
SQL_FETCH_FIRST* = 2
SQL_FETCH_FIRST_USER* = 31
SQL_FETCH_FIRST_SYSTEM* = 32 # Other codes used for FetchOrientation in SQLFetchScroll()
SQL_FETCH_LAST* = 3
SQL_FETCH_PRIOR* = 4
SQL_FETCH_ABSOLUTE* = 5
SQL_FETCH_RELATIVE* = 6
SQL_NULL_HENV* = SqlHEnv(nil)
SQL_NULL_HDBC* = SqlHDBC(nil)
SQL_NULL_HSTMT* = SqlHStmt(nil)
SQL_NULL_HDESC* = SqlHDesc(nil) #* null handle used in place of parent handle when allocating HENV */
SQL_NULL_HANDLE* = SqlHandle(nil) #* Values that may appear in the result set of SQLSpecialColumns() */
SQL_SCOPE_CURROW* = 0
SQL_SCOPE_TRANSACTION* = 1
SQL_SCOPE_SESSION* = 2 #* Column types and scopes in SQLSpecialColumns. */
SQL_BEST_ROWID* = 1
SQL_ROWVER* = 2
SQL_ROW_IDENTIFIER* = 1 #* Reserved values for UNIQUE argument of SQLStatistics() */
SQL_INDEX_UNIQUE* = 0
SQL_INDEX_ALL* = 1 #* Reserved values for RESERVED argument of SQLStatistics() */
SQL_QUICK* = 0
SQL_ENSURE* = 1 #* Values that may appear in the result set of SQLStatistics() */
SQL_TABLE_STAT* = 0
SQL_INDEX_CLUSTERED* = 1
SQL_INDEX_HASHED* = 2
SQL_INDEX_OTHER* = 3
SQL_SCROLL_CONCURRENCY* = 43
SQL_TXN_CAPABLE* = 46
SQL_TRANSACTION_CAPABLE* = SQL_TXN_CAPABLE
SQL_USER_NAME* = 47
SQL_TXN_ISOLATION_OPTION* = 72
SQL_TRANSACTION_ISOLATION_OPTION* = SQL_TXN_ISOLATION_OPTION
SQL_OJ_CAPABILITIES* = 115
SQL_OUTER_JOIN_CAPABILITIES* = SQL_OJ_CAPABILITIES
SQL_XOPEN_CLI_YEAR* = 10000
SQL_CURSOR_SENSITIVITY* = 10001
SQL_DESCRIBE_PARAMETER* = 10002
SQL_CATALOG_NAME* = 10003
SQL_COLLATION_SEQ* = 10004
SQL_MAX_IDENTIFIER_LEN* = 10005
SQL_MAXIMUM_IDENTIFIER_LENGTH* = SQL_MAX_IDENTIFIER_LEN
SQL_SCCO_READ_ONLY* = 1
SQL_SCCO_LOCK* = 2
SQL_SCCO_OPT_ROWVER* = 4
SQL_SCCO_OPT_VALUES* = 8 #* SQL_TXN_CAPABLE values */
SQL_TC_NONE* = 0
SQL_TC_DML* = 1
SQL_TC_ALL* = 2
SQL_TC_DDL_COMMIT* = 3
SQL_TC_DDL_IGNORE* = 4 #* SQL_TXN_ISOLATION_OPTION bitmasks */
SQL_TXN_READ_UNCOMMITTED* = 1
SQL_TRANSACTION_READ_UNCOMMITTED* = SQL_TXN_READ_UNCOMMITTED
SQL_TXN_READ_COMMITTED* = 2
SQL_TRANSACTION_READ_COMMITTED* = SQL_TXN_READ_COMMITTED
SQL_TXN_REPEATABLE_READ* = 4
SQL_TRANSACTION_REPEATABLE_READ* = SQL_TXN_REPEATABLE_READ
SQL_TXN_SERIALIZABLE* = 8
SQL_TRANSACTION_SERIALIZABLE* = SQL_TXN_SERIALIZABLE
SQL_SS_ADDITIONS* = 1
SQL_SS_DELETIONS* = 2
SQL_SS_UPDATES* = 4 # SQLColAttributes defines
SQL_COLUMN_COUNT* = 0
SQL_COLUMN_NAME* = 1
SQL_COLUMN_TYPE* = 2
SQL_COLUMN_LENGTH* = 3
SQL_COLUMN_PRECISION* = 4
SQL_COLUMN_SCALE* = 5
SQL_COLUMN_DISPLAY_SIZE* = 6
SQL_COLUMN_NULLABLE* = 7
SQL_COLUMN_UNSIGNED* = 8
SQL_COLUMN_MONEY* = 9
SQL_COLUMN_UPDATABLE* = 10
SQL_COLUMN_AUTO_INCREMENT* = 11
SQL_COLUMN_CASE_SENSITIVE* = 12
SQL_COLUMN_SEARCHABLE* = 13
SQL_COLUMN_TYPE_NAME* = 14
SQL_COLUMN_TABLE_NAME* = 15
SQL_COLUMN_OWNER_NAME* = 16
SQL_COLUMN_QUALIFIER_NAME* = 17
SQL_COLUMN_LABEL* = 18
SQL_COLATT_OPT_MAX* = SQL_COLUMN_LABEL
SQL_COLUMN_DRIVER_START* = 1000
SQL_DESC_ARRAY_SIZE* = 20
SQL_DESC_ARRAY_STATUS_PTR* = 21
SQL_DESC_AUTO_UNIQUE_VALUE* = SQL_COLUMN_AUTO_INCREMENT
SQL_DESC_BASE_COLUMN_NAME* = 22
SQL_DESC_BASE_TABLE_NAME* = 23
SQL_DESC_BIND_OFFSET_PTR* = 24
SQL_DESC_BIND_TYPE* = 25
SQL_DESC_CASE_SENSITIVE* = SQL_COLUMN_CASE_SENSITIVE
SQL_DESC_CATALOG_NAME* = SQL_COLUMN_QUALIFIER_NAME
SQL_DESC_CONCISE_TYPE* = SQL_COLUMN_TYPE
SQL_DESC_DATETIME_INTERVAL_PRECISION* = 26
SQL_DESC_DISPLAY_SIZE* = SQL_COLUMN_DISPLAY_SIZE
SQL_DESC_FIXED_PREC_SCALE* = SQL_COLUMN_MONEY
SQL_DESC_LABEL* = SQL_COLUMN_LABEL
SQL_DESC_LITERAL_PREFIX* = 27
SQL_DESC_LITERAL_SUFFIX* = 28
SQL_DESC_LOCAL_TYPE_NAME* = 29
SQL_DESC_MAXIMUM_SCALE* = 30
SQL_DESC_MINIMUM_SCALE* = 31
SQL_DESC_NUM_PREC_RADIX* = 32
SQL_DESC_PARAMETER_TYPE* = 33
SQL_DESC_ROWS_PROCESSED_PTR* = 34
SQL_DESC_SCHEMA_NAME* = SQL_COLUMN_OWNER_NAME
SQL_DESC_SEARCHABLE* = SQL_COLUMN_SEARCHABLE
SQL_DESC_TYPE_NAME* = SQL_COLUMN_TYPE_NAME
SQL_DESC_TABLE_NAME* = SQL_COLUMN_TABLE_NAME
SQL_DESC_UNSIGNED* = SQL_COLUMN_UNSIGNED
SQL_DESC_UPDATABLE* = SQL_COLUMN_UPDATABLE #* SQLEndTran() options */
SQL_COMMIT* = 0
SQL_ROLLBACK* = 1
SQL_ATTR_ROW_ARRAY_SIZE* = 27 #* SQLConfigDataSource() options */
ODBC_ADD_DSN* = 1
ODBC_CONFIG_DSN* = 2
ODBC_REMOVE_DSN* = 3
ODBC_ADD_SYS_DSN* = 4
ODBC_CONFIG_SYS_DSN* = 5
ODBC_REMOVE_SYS_DSN* = 6
SQL_ACTIVE_CONNECTIONS* = 0 # SQLGetInfo
SQL_DATA_SOURCE_NAME* = 2
SQL_DATA_SOURCE_READ_ONLY* = 25
SQL_DATABASE_NAME* = 2
SQL_DBMS_NAME* = 17
SQL_DBMS_VERSION* = 18
SQL_DRIVER_HDBC* = 3
SQL_DRIVER_HENV* = 4
SQL_DRIVER_HSTMT* = 5
SQL_DRIVER_NAME* = 6
SQL_DRIVER_VER* = 7
SQL_FETCH_DIRECTION* = 8
SQL_ODBC_VER* = 10
SQL_DRIVER_ODBC_VER* = 77
SQL_SERVER_NAME* = 13
SQL_ACTIVE_ENVIRONMENTS* = 116
SQL_ACTIVE_STATEMENTS* = 1
SQL_SQL_CONFORMANCE* = 118
SQL_DATETIME_LITERALS* = 119
SQL_ASYNC_MODE* = 10021
SQL_BATCH_ROW_COUNT* = 120
SQL_BATCH_SUPPORT* = 121
SQL_CATALOG_LOCATION* = 114
#SQL_CATALOG_NAME* = 10003
SQL_CATALOG_NAME_SEPARATOR* = 41
SQL_CATALOG_TERM* = 42
SQL_CATALOG_USAGE* = 92
#SQL_COLLATION_SEQ* = 10004
SQL_COLUMN_ALIAS* = 87
#SQL_USER_NAME* = 47
proc SQLAllocHandle*(HandleType: TSqlSmallInt, InputHandle: SqlHandle,
OutputHandlePtr: var SqlHandle): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLSetEnvAttr*(EnvironmentHandle: SqlHEnv, Attribute: TSqlInteger,
Value: SqlPointer, StringLength: TSqlInteger): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLGetEnvAttr*(EnvironmentHandle: SqlHEnv, Attribute: TSqlInteger,
Value: SqlPointer, BufferLength: TSqlInteger,
StringLength: PSQLINTEGER): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLFreeHandle*(HandleType: TSqlSmallInt, Handle: SqlHandle): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLGetDiagRec*(HandleType: TSqlSmallInt, Handle: SqlHandle,
RecNumber: TSqlSmallInt, Sqlstate: PSQLCHAR,
NativeError: var TSqlInteger, MessageText: PSQLCHAR,
BufferLength: TSqlSmallInt, TextLength: var TSqlSmallInt): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLGetDiagField*(HandleType: TSqlSmallInt, Handle: SqlHandle,
RecNumber: TSqlSmallInt, DiagIdentifier: TSqlSmallInt,
DiagInfoPtr: SqlPointer, BufferLength: TSqlSmallInt,
StringLengthPtr: var TSqlSmallInt): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLConnect*(ConnectionHandle: SqlHDBC, ServerName: PSQLCHAR,
NameLength1: TSqlSmallInt, UserName: PSQLCHAR,
NameLength2: TSqlSmallInt, Authentication: PSQLCHAR,
NameLength3: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLDisconnect*(ConnectionHandle: SqlHDBC): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLDriverConnect*(hdbc: SqlHDBC, hwnd: SqlHWND, szCsin: cstring,
szCLen: TSqlSmallInt, szCsout: cstring,
cbCSMax: TSqlSmallInt, cbCsOut: var TSqlSmallInt,
f: SqlUSmallInt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLBrowseConnect*(hdbc: SqlHDBC, szConnStrIn: PSQLCHAR,
cbConnStrIn: TSqlSmallInt, szConnStrOut: PSQLCHAR,
cbConnStrOutMax: TSqlSmallInt,
cbConnStrOut: var TSqlSmallInt): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLExecDirect*(StatementHandle: SqlHStmt, StatementText: PSQLCHAR,
TextLength: TSqlInteger): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLExecDirectW*(StatementHandle: SqlHStmt, StatementText: WideCString,
TextLength: TSqlInteger): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLPrepare*(StatementHandle: SqlHStmt, StatementText: PSQLCHAR,
TextLength: TSqlInteger): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLPrepareW*(StatementHandle: SqlHStmt, StatementText: WideCString,
TextLength: TSqlInteger): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLCloseCursor*(StatementHandle: SqlHStmt): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLExecute*(StatementHandle: SqlHStmt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLFetch*(StatementHandle: SqlHStmt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLNumResultCols*(StatementHandle: SqlHStmt, ColumnCount: var TSqlSmallInt): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLDescribeCol*(StatementHandle: SqlHStmt, ColumnNumber: SqlUSmallInt,
ColumnName: PSQLCHAR, BufferLength: TSqlSmallInt,
NameLength: var TSqlSmallInt, DataType: var TSqlSmallInt,
ColumnSize: var TSqlULen,
DecimalDigits: var TSqlSmallInt, Nullable: var TSqlSmallInt): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLFetchScroll*(StatementHandle: SqlHStmt, FetchOrientation: TSqlSmallInt,
FetchOffset: TSqlLen): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLExtendedFetch*(hstmt: SqlHStmt, fFetchType: SqlUSmallInt,
irow: TSqlLen, pcrow: var TSqlULen,
rgfRowStatus: PSQLUSMALLINT): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLGetData*(StatementHandle: SqlHStmt, ColumnNumber: SqlUSmallInt,
TargetType: TSqlSmallInt, TargetValue: SqlPointer,
BufferLength: TSqlLen, StrLen_or_Ind: ptr TSqlLen): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLSetStmtAttr*(StatementHandle: SqlHStmt, Attribute: TSqlInteger,
Value: SqlPointer, StringLength: TSqlInteger): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLGetStmtAttr*(StatementHandle: SqlHStmt, Attribute: TSqlInteger,
Value: SqlPointer, BufferLength: TSqlInteger,
StringLength: PSQLINTEGER): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLGetInfo*(ConnectionHandle: SqlHDBC, InfoType: SqlUSmallInt,
InfoValue: SqlPointer, BufferLength: TSqlSmallInt,
StringLength: PSQLSMALLINT): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLBulkOperations*(StatementHandle: SqlHStmt, Operation: SqlUSmallInt): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLPutData*(StatementHandle: SqlHStmt, Data: SqlPointer,
StrLen_or_Ind: TSQLLEN): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLBindCol*(StatementHandle: SqlHStmt, ColumnNumber: SqlUSmallInt,
TargetType: TSqlSmallInt, TargetValue: SqlPointer,
BufferLength: TSqlLEN, StrLen_or_Ind: PSQLINTEGER): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLSetPos*(hstmt: SqlHStmt, irow: SqlUSmallInt, fOption: SqlUSmallInt,
fLock: SqlUSmallInt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLDataSources*(EnvironmentHandle: SqlHEnv, Direction: SqlUSmallInt,
ServerName: PSQLCHAR, BufferLength1: TSqlSmallInt,
NameLength1: PSQLSMALLINT, Description: PSQLCHAR,
BufferLength2: TSqlSmallInt, NameLength2: PSQLSMALLINT): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLDrivers*(EnvironmentHandle: SqlHEnv, Direction: SqlUSmallInt,
DriverDescription: PSQLCHAR, BufferLength1: TSqlSmallInt,
DescriptionLength1: PSQLSMALLINT, DriverAttributes: PSQLCHAR,
BufferLength2: TSqlSmallInt, AttributesLength2: PSQLSMALLINT): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLSetConnectAttr*(ConnectionHandle: SqlHDBC, Attribute: TSqlInteger,
Value: SqlPointer, StringLength: TSqlInteger): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLGetCursorName*(StatementHandle: SqlHStmt, CursorName: PSQLCHAR,
BufferLength: TSqlSmallInt, NameLength: PSQLSMALLINT): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLSetCursorName*(StatementHandle: SqlHStmt, CursorName: PSQLCHAR,
NameLength: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLRowCount*(StatementHandle: SqlHStmt, RowCount: var TSQLLEN): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLBindParameter*(hstmt: SqlHStmt, ipar: SqlUSmallInt,
fParamType: TSqlSmallInt, fCType: TSqlSmallInt,
fSqlType: TSqlSmallInt, cbColDef: TSQLULEN,
ibScale: TSqlSmallInt, rgbValue: SqlPointer,
cbValueMax: TSQLLEN, pcbValue: var TSQLLEN): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLFreeStmt*(StatementHandle: SqlHStmt, Option: SqlUSmallInt): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLColAttribute*(StatementHandle: SqlHStmt, ColumnNumber: SqlUSmallInt,
FieldIdentifier: SqlUSmallInt,
CharacterAttribute: PSQLCHAR, BufferLength: TSqlSmallInt,
StringLength: PSQLSMALLINT,
NumericAttribute: TSQLLEN): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLEndTran*(HandleType: TSqlSmallInt, Handle: SqlHandle,
CompletionType: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLTables*(hstmt: SqlHStmt, szTableQualifier: PSQLCHAR,
cbTableQualifier: TSqlSmallInt, szTableOwner: PSQLCHAR,
cbTableOwner: TSqlSmallInt, szTableName: PSQLCHAR,
cbTableName: TSqlSmallInt, szTableType: PSQLCHAR,
cbTableType: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLColumns*(hstmt: SqlHStmt, szTableQualifier: PSQLCHAR,
cbTableQualifier: TSqlSmallInt, szTableOwner: PSQLCHAR,
cbTableOwner: TSqlSmallInt, szTableName: PSQLCHAR,
cbTableName: TSqlSmallInt, szColumnName: PSQLCHAR,
cbColumnName: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLSpecialColumns*(StatementHandle: SqlHStmt, IdentifierType: SqlUSmallInt,
CatalogName: PSQLCHAR, NameLength1: TSqlSmallInt,
SchemaName: PSQLCHAR, NameLength2: TSqlSmallInt,
TableName: PSQLCHAR, NameLength3: TSqlSmallInt,
Scope: SqlUSmallInt,
Nullable: SqlUSmallInt): TSqlSmallInt{.
dynlib: odbclib, importc.}
proc SQLProcedures*(hstmt: SqlHStmt, szTableQualifier: PSQLCHAR,
cbTableQualifier: TSqlSmallInt, szTableOwner: PSQLCHAR,
cbTableOwner: TSqlSmallInt, szTableName: PSQLCHAR,
cbTableName: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLPrimaryKeys*(hstmt: SqlHStmt, CatalogName: PSQLCHAR,
NameLength1: TSqlSmallInt, SchemaName: PSQLCHAR,
NameLength2: TSqlSmallInt, TableName: PSQLCHAR,
NameLength3: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLProcedureColumns*(hstmt: SqlHStmt, CatalogName: PSQLCHAR,
NameLength1: TSqlSmallInt, SchemaName: PSQLCHAR,
NameLength2: TSqlSmallInt, ProcName: PSQLCHAR,
NameLength3: TSqlSmallInt, ColumnName: PSQLCHAR,
NameLength4: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib,
importc.}
proc SQLStatistics*(hstmt: SqlHStmt, CatalogName: PSQLCHAR,
NameLength1: TSqlSmallInt, SchemaName: PSQLCHAR,
NameLength2: TSqlSmallInt, TableName: PSQLCHAR,
NameLength3: TSqlSmallInt, Unique: SqlUSmallInt,
Reserved: SqlUSmallInt): TSqlSmallInt {.
dynlib: odbclib, importc.}
proc SQLErr*(henv: SqlHEnv, hdbc: SqlHDBC, hstmt: SqlHStmt,
szSqlState, pfNativeError, szErrorMsg: PSQLCHAR,
cbErrorMsgMax: TSqlSmallInt,
pcbErrorMsg: PSQLSMALLINT): TSqlSmallInt {.
dynlib: odbclib, importc: "SQLError".}
{.pop.}
when defined(nimHasStyleChecks):
{.pop.}

View File

@@ -1,378 +0,0 @@
#
#
# Nim's Runtime Library
# (c) Copyright 2015 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
# This module contains the definitions for structures and externs for
# functions used by frontend postgres applications. It is based on
# Postgresql's libpq-fe.h.
#
# It is for postgreSQL version 7.4 and higher with support for the v3.0
# connection-protocol.
#
when defined(nimHasStyleChecks):
{.push styleChecks: off.}
when defined(windows):
const
dllName = "libpq.dll"
elif defined(macosx):
const
dllName = "libpq.dylib"
else:
const
dllName = "libpq.so(.5|)"
when defined(nimPreviewSlimSystem):
import std/syncio
type
POid* = ptr Oid
Oid* = int32
const
ERROR_MSG_LENGTH* = 4096
CMDSTATUS_LEN* = 40
type
SockAddr* = array[1..112, int8]
PGresAttDesc*{.pure, final.} = object
name*: cstring
adtid*: Oid
adtsize*: int
PPGresAttDesc* = ptr PGresAttDesc
PPPGresAttDesc* = ptr PPGresAttDesc
PGresAttValue*{.pure, final.} = object
length*: int32
value*: cstring
PPGresAttValue* = ptr PGresAttValue
PPPGresAttValue* = ptr PPGresAttValue
PExecStatusType* = ptr ExecStatusType
ExecStatusType* = enum
PGRES_EMPTY_QUERY = 0, PGRES_COMMAND_OK, PGRES_TUPLES_OK, PGRES_COPY_OUT,
PGRES_COPY_IN, PGRES_BAD_RESPONSE, PGRES_NONFATAL_ERROR, PGRES_FATAL_ERROR,
PGRES_COPY_BOTH, PGRES_SINGLE_TUPLE
PGlobjfuncs*{.pure, final.} = object
fn_lo_open*: Oid
fn_lo_close*: Oid
fn_lo_creat*: Oid
fn_lo_unlink*: Oid
fn_lo_lseek*: Oid
fn_lo_tell*: Oid
fn_lo_read*: Oid
fn_lo_write*: Oid
PPGlobjfuncs* = ptr PGlobjfuncs
PConnStatusType* = ptr ConnStatusType
ConnStatusType* = enum
CONNECTION_OK, CONNECTION_BAD, CONNECTION_STARTED, CONNECTION_MADE,
CONNECTION_AWAITING_RESPONSE, CONNECTION_AUTH_OK, CONNECTION_SETENV,
CONNECTION_SSL_STARTUP, CONNECTION_NEEDED, CONNECTION_CHECK_WRITABLE,
CONNECTION_CONSUME, CONNECTION_GSS_STARTUP, CONNECTION_CHECK_TARGET
PGconn*{.pure, final.} = object
pghost*: cstring
pgtty*: cstring
pgport*: cstring
pgoptions*: cstring
dbName*: cstring
status*: ConnStatusType
errorMessage*: array[0..(ERROR_MSG_LENGTH) - 1, char]
Pfin*: File
Pfout*: File
Pfdebug*: File
sock*: int32
laddr*: SockAddr
raddr*: SockAddr
salt*: array[0..(2) - 1, char]
asyncNotifyWaiting*: int32
notifyList*: pointer
pguser*: cstring
pgpass*: cstring
lobjfuncs*: PPGlobjfuncs
PPGconn* = ptr PGconn
PGresult*{.pure, final.} = object
ntups*: int32
numAttributes*: int32
attDescs*: PPGresAttDesc
tuples*: PPPGresAttValue
tupArrSize*: int32
resultStatus*: ExecStatusType
cmdStatus*: array[0..(CMDSTATUS_LEN) - 1, char]
binary*: int32
conn*: PPGconn
PPGresult* = ptr PGresult
PPostgresPollingStatusType* = ptr PostgresPollingStatusType
PostgresPollingStatusType* = enum
PGRES_POLLING_FAILED = 0, PGRES_POLLING_READING, PGRES_POLLING_WRITING,
PGRES_POLLING_OK, PGRES_POLLING_ACTIVE
PPGTransactionStatusType* = ptr PGTransactionStatusType
PGTransactionStatusType* = enum
PQTRANS_IDLE, PQTRANS_ACTIVE, PQTRANS_INTRANS, PQTRANS_INERROR,
PQTRANS_UNKNOWN
PPGVerbosity* = ptr PGVerbosity
PGVerbosity* = enum
PQERRORS_TERSE, PQERRORS_DEFAULT, PQERRORS_VERBOSE, PQERRORS_SQLSTATE
PPGNotify* = ptr pgNotify
pgNotify*{.pure, final.} = object
relname*: cstring
be_pid*: int32
extra*: cstring
PQnoticeReceiver* = proc (arg: pointer, res: PPGresult){.cdecl.}
PQnoticeProcessor* = proc (arg: pointer, message: cstring){.cdecl.}
Ppqbool* = ptr pqbool
pqbool* = char
PPQprintOpt* = ptr PQprintOpt
PQprintOpt*{.pure, final.} = object
header*: pqbool
align*: pqbool
standard*: pqbool
html3*: pqbool
expanded*: pqbool
pager*: pqbool
fieldSep*: cstring
tableOpt*: cstring
caption*: cstring
fieldName*: ptr cstring
PPQconninfoOption* = ptr PQconninfoOption
PQconninfoOption*{.pure, final.} = object
keyword*: cstring
envvar*: cstring
compiled*: cstring
val*: cstring
label*: cstring
dispchar*: cstring
dispsize*: int32
PPQArgBlock* = ptr PQArgBlock
PQArgBlock*{.pure, final.} = object
length*: int32
isint*: int32
p*: pointer
proc pqinitOpenSSL*(do_ssl: int32, do_crypto: int32) {.cdecl, dynlib: dllName,
importc: "PQinitOpenSSL".}
proc pqconnectStart*(conninfo: cstring): PPGconn{.cdecl, dynlib: dllName,
importc: "PQconnectStart".}
proc pqconnectPoll*(conn: PPGconn): PostgresPollingStatusType{.cdecl,
dynlib: dllName, importc: "PQconnectPoll".}
proc pqconnectdb*(conninfo: cstring): PPGconn{.cdecl, dynlib: dllName,
importc: "PQconnectdb".}
proc pqsetdbLogin*(pghost: cstring, pgport: cstring, pgoptions: cstring,
pgtty: cstring, dbName: cstring, login: cstring, pwd: cstring): PPGconn{.
cdecl, dynlib: dllName, importc: "PQsetdbLogin".}
proc pqsetdb*(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME: cstring): PPGconn
proc pqfinish*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQfinish".}
proc pqconndefaults*(): PPQconninfoOption{.cdecl, dynlib: dllName,
importc: "PQconndefaults".}
proc pqconninfoFree*(connOptions: PPQconninfoOption){.cdecl, dynlib: dllName,
importc: "PQconninfoFree".}
proc pqresetStart*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQresetStart".}
proc pqresetPoll*(conn: PPGconn): PostgresPollingStatusType{.cdecl,
dynlib: dllName, importc: "PQresetPoll".}
proc pqreset*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQreset".}
proc pqrequestCancel*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQrequestCancel".}
proc pqdb*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQdb".}
proc pquser*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQuser".}
proc pqpass*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQpass".}
proc pqhost*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQhost".}
proc pqport*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQport".}
proc pqtty*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQtty".}
proc pqoptions*(conn: PPGconn): cstring{.cdecl, dynlib: dllName,
importc: "PQoptions".}
proc pqstatus*(conn: PPGconn): ConnStatusType{.cdecl, dynlib: dllName,
importc: "PQstatus".}
proc pqtransactionStatus*(conn: PPGconn): PGTransactionStatusType{.cdecl,
dynlib: dllName, importc: "PQtransactionStatus".}
proc pqparameterStatus*(conn: PPGconn, paramName: cstring): cstring{.cdecl,
dynlib: dllName, importc: "PQparameterStatus".}
proc pqserverVersion*(conn: PPGconn): int32{.cdecl,
dynlib: dllName, importc: "PQserverVersion".}
proc pqprotocolVersion*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQprotocolVersion".}
proc pqerrorMessage*(conn: PPGconn): cstring{.cdecl, dynlib: dllName,
importc: "PQerrorMessage".}
proc pqsocket*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQsocket".}
proc pqbackendPID*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQbackendPID".}
proc pqconnectionNeedsPassword*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQconnectionNeedsPassword".}
proc pqconnectionUsedPassword*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQconnectionUsedPassword".}
proc pqclientEncoding*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQclientEncoding".}
proc pqsetClientEncoding*(conn: PPGconn, encoding: cstring): int32{.cdecl,
dynlib: dllName, importc: "PQsetClientEncoding".}
proc pqsetErrorVerbosity*(conn: PPGconn, verbosity: PGVerbosity): PGVerbosity{.
cdecl, dynlib: dllName, importc: "PQsetErrorVerbosity".}
proc pqtrace*(conn: PPGconn, debug_port: File){.cdecl, dynlib: dllName,
importc: "PQtrace".}
proc pquntrace*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQuntrace".}
proc pqsetNoticeReceiver*(conn: PPGconn, theProc: PQnoticeReceiver, arg: pointer): PQnoticeReceiver{.
cdecl, dynlib: dllName, importc: "PQsetNoticeReceiver".}
proc pqsetNoticeProcessor*(conn: PPGconn, theProc: PQnoticeProcessor,
arg: pointer): PQnoticeProcessor{.cdecl,
dynlib: dllName, importc: "PQsetNoticeProcessor".}
proc pqexec*(conn: PPGconn, query: cstring): PPGresult{.cdecl, dynlib: dllName,
importc: "PQexec".}
proc pqexecParams*(conn: PPGconn, command: cstring, nParams: int32,
paramTypes: POid, paramValues: cstringArray,
paramLengths, paramFormats: ptr int32, resultFormat: int32): PPGresult{.
cdecl, dynlib: dllName, importc: "PQexecParams".}
proc pqprepare*(conn: PPGconn, stmtName, query: cstring, nParams: int32,
paramTypes: POid): PPGresult{.cdecl, dynlib: dllName, importc: "PQprepare".}
proc pqexecPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32,
paramValues: cstringArray,
paramLengths, paramFormats: ptr int32, resultFormat: int32): PPGresult{.
cdecl, dynlib: dllName, importc: "PQexecPrepared".}
proc pqsendQuery*(conn: PPGconn, query: cstring): int32{.cdecl, dynlib: dllName,
importc: "PQsendQuery".}
## See also https://www.postgresql.org/docs/current/libpq-async.html
proc pqsendQueryParams*(conn: PPGconn, command: cstring, nParams: int32,
paramTypes: POid, paramValues: cstringArray,
paramLengths, paramFormats: ptr int32,
resultFormat: int32): int32{.cdecl, dynlib: dllName,
importc: "PQsendQueryParams".}
proc pqsendQueryPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32,
paramValues: cstringArray,
paramLengths, paramFormats: ptr int32,
resultFormat: int32): int32{.cdecl, dynlib: dllName,
importc: "PQsendQueryPrepared".}
proc pqSetSingleRowMode*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQsetSingleRowMode".}
## See also https://www.postgresql.org/docs/current/libpq-single-row-mode.html
proc pqgetResult*(conn: PPGconn): PPGresult{.cdecl, dynlib: dllName,
importc: "PQgetResult".}
proc pqisBusy*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQisBusy".}
proc pqconsumeInput*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQconsumeInput".}
proc pqnotifies*(conn: PPGconn): PPGNotify{.cdecl, dynlib: dllName,
importc: "PQnotifies".}
proc pqputCopyData*(conn: PPGconn, buffer: cstring, nbytes: int32): int32{.
cdecl, dynlib: dllName, importc: "PQputCopyData".}
proc pqputCopyEnd*(conn: PPGconn, errormsg: cstring): int32{.cdecl,
dynlib: dllName, importc: "PQputCopyEnd".}
proc pqgetCopyData*(conn: PPGconn, buffer: cstringArray, async: int32): int32{.
cdecl, dynlib: dllName, importc: "PQgetCopyData".}
proc pqgetline*(conn: PPGconn, str: cstring, len: int32): int32{.cdecl,
dynlib: dllName, importc: "PQgetline".}
proc pqputline*(conn: PPGconn, str: cstring): int32{.cdecl, dynlib: dllName,
importc: "PQputline".}
proc pqgetlineAsync*(conn: PPGconn, buffer: cstring, bufsize: int32): int32{.
cdecl, dynlib: dllName, importc: "PQgetlineAsync".}
proc pqputnbytes*(conn: PPGconn, buffer: cstring, nbytes: int32): int32{.cdecl,
dynlib: dllName, importc: "PQputnbytes".}
proc pqendcopy*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQendcopy".}
proc pqsetnonblocking*(conn: PPGconn, arg: int32): int32{.cdecl,
dynlib: dllName, importc: "PQsetnonblocking".}
proc pqisnonblocking*(conn: PPGconn): int32{.cdecl, dynlib: dllName,
importc: "PQisnonblocking".}
proc pqflush*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQflush".}
proc pqfn*(conn: PPGconn, fnid: int32, result_buf, result_len: ptr int32,
result_is_int: int32, args: PPQArgBlock, nargs: int32): PPGresult{.
cdecl, dynlib: dllName, importc: "PQfn".}
proc pqresultStatus*(res: PPGresult): ExecStatusType{.cdecl, dynlib: dllName,
importc: "PQresultStatus".}
proc pqresStatus*(status: ExecStatusType): cstring{.cdecl, dynlib: dllName,
importc: "PQresStatus".}
proc pqresultErrorMessage*(res: PPGresult): cstring{.cdecl, dynlib: dllName,
importc: "PQresultErrorMessage".}
proc pqresultErrorField*(res: PPGresult, fieldcode: int32): cstring{.cdecl,
dynlib: dllName, importc: "PQresultErrorField".}
proc pqntuples*(res: PPGresult): int32{.cdecl, dynlib: dllName,
importc: "PQntuples".}
proc pqnfields*(res: PPGresult): int32{.cdecl, dynlib: dllName,
importc: "PQnfields".}
proc pqbinaryTuples*(res: PPGresult): int32{.cdecl, dynlib: dllName,
importc: "PQbinaryTuples".}
proc pqfname*(res: PPGresult, field_num: int32): cstring{.cdecl,
dynlib: dllName, importc: "PQfname".}
proc pqfnumber*(res: PPGresult, field_name: cstring): int32{.cdecl,
dynlib: dllName, importc: "PQfnumber".}
proc pqftable*(res: PPGresult, field_num: int32): Oid{.cdecl, dynlib: dllName,
importc: "PQftable".}
proc pqftablecol*(res: PPGresult, field_num: int32): int32{.cdecl,
dynlib: dllName, importc: "PQftablecol".}
proc pqfformat*(res: PPGresult, field_num: int32): int32{.cdecl,
dynlib: dllName, importc: "PQfformat".}
proc pqftype*(res: PPGresult, field_num: int32): Oid{.cdecl, dynlib: dllName,
importc: "PQftype".}
proc pqfsize*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName,
importc: "PQfsize".}
proc pqfmod*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName,
importc: "PQfmod".}
proc pqcmdStatus*(res: PPGresult): cstring{.cdecl, dynlib: dllName,
importc: "PQcmdStatus".}
proc pqoidStatus*(res: PPGresult): cstring{.cdecl, dynlib: dllName,
importc: "PQoidStatus".}
proc pqoidValue*(res: PPGresult): Oid{.cdecl, dynlib: dllName,
importc: "PQoidValue".}
proc pqcmdTuples*(res: PPGresult): cstring{.cdecl, dynlib: dllName,
importc: "PQcmdTuples".}
proc pqgetvalue*(res: PPGresult, tup_num: int32, field_num: int32): cstring{.
cdecl, dynlib: dllName, importc: "PQgetvalue".}
proc pqgetlength*(res: PPGresult, tup_num: int32, field_num: int32): int32{.
cdecl, dynlib: dllName, importc: "PQgetlength".}
proc pqgetisnull*(res: PPGresult, tup_num: int32, field_num: int32): int32{.
cdecl, dynlib: dllName, importc: "PQgetisnull".}
proc pqclear*(res: PPGresult){.cdecl, dynlib: dllName, importc: "PQclear".}
proc pqfreemem*(p: pointer){.cdecl, dynlib: dllName, importc: "PQfreemem".}
proc pqmakeEmptyPGresult*(conn: PPGconn, status: ExecStatusType): PPGresult{.
cdecl, dynlib: dllName, importc: "PQmakeEmptyPGresult".}
proc pqescapeString*(till, `from`: cstring, len: int): int{.cdecl,
dynlib: dllName, importc: "PQescapeString".}
proc pqescapeBytea*(bintext: cstring, binlen: int, bytealen: var int): cstring{.
cdecl, dynlib: dllName, importc: "PQescapeBytea".}
proc pqunescapeBytea*(strtext: cstring, retbuflen: var int): cstring{.cdecl,
dynlib: dllName, importc: "PQunescapeBytea".}
proc pqprint*(fout: File, res: PPGresult, ps: PPQprintOpt){.cdecl,
dynlib: dllName, importc: "PQprint".}
proc pqdisplayTuples*(res: PPGresult, fp: File, fillAlign: int32,
fieldSep: cstring, printHeader: int32, quiet: int32){.
cdecl, dynlib: dllName, importc: "PQdisplayTuples".}
proc pqprintTuples*(res: PPGresult, fout: File, printAttName: int32,
terseOutput: int32, width: int32){.cdecl, dynlib: dllName,
importc: "PQprintTuples".}
proc lo_open*(conn: PPGconn, lobjId: Oid, mode: int32): int32{.cdecl,
dynlib: dllName, importc: "lo_open".}
proc lo_close*(conn: PPGconn, fd: int32): int32{.cdecl, dynlib: dllName,
importc: "lo_close".}
proc lo_read*(conn: PPGconn, fd: int32, buf: cstring, length: int): int32{.
cdecl, dynlib: dllName, importc: "lo_read".}
proc lo_write*(conn: PPGconn, fd: int32, buf: cstring, length: int): int32{.
cdecl, dynlib: dllName, importc: "lo_write".}
proc lo_lseek*(conn: PPGconn, fd: int32, offset: int32, whence: int32): int32{.
cdecl, dynlib: dllName, importc: "lo_lseek".}
proc lo_creat*(conn: PPGconn, mode: int32): Oid{.cdecl, dynlib: dllName,
importc: "lo_creat".}
proc lo_tell*(conn: PPGconn, fd: int32): int32{.cdecl, dynlib: dllName,
importc: "lo_tell".}
proc lo_unlink*(conn: PPGconn, lobjId: Oid): int32{.cdecl, dynlib: dllName,
importc: "lo_unlink".}
proc lo_import*(conn: PPGconn, filename: cstring): Oid{.cdecl, dynlib: dllName,
importc: "lo_import".}
proc lo_export*(conn: PPGconn, lobjId: Oid, filename: cstring): int32{.cdecl,
dynlib: dllName, importc: "lo_export".}
proc pqmblen*(s: cstring, encoding: int32): int32{.cdecl, dynlib: dllName,
importc: "PQmblen".}
proc pqenv2encoding*(): int32{.cdecl, dynlib: dllName, importc: "PQenv2encoding".}
proc pqsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME: cstring): PPGconn =
result = pqsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, "", "")
when defined(nimHasStyleChecks):
{.pop.}

View File

@@ -1,392 +0,0 @@
#
#
# Nim's Runtime Library
# (c) Copyright 2012 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
when defined(nimHasStyleChecks):
{.push styleChecks: off.}
when defined(windows):
when defined(nimOldDlls):
const Lib = "sqlite3.dll"
elif defined(cpu64):
const Lib = "sqlite3_64.dll"
else:
const Lib = "sqlite3_32.dll"
elif defined(macosx):
const
Lib = "libsqlite3(|.0).dylib"
else:
const
Lib = "libsqlite3.so(|.0)"
when defined(staticSqlite):
{.pragma: mylib.}
{.compile("sqlite3.c", "-O3").}
else:
{.pragma: mylib, dynlib: Lib.}
const
SQLITE_INTEGER* = 1
SQLITE_FLOAT* = 2
SQLITE_BLOB* = 4
SQLITE_NULL* = 5
SQLITE_TEXT* = 3
SQLITE_UTF8* = 1
SQLITE_UTF16LE* = 2
SQLITE_UTF16BE* = 3 # Use native byte order
SQLITE_UTF16* = 4 # sqlite3_create_function only
SQLITE_ANY* = 5 #sqlite_exec return values
SQLITE_OK* = 0
SQLITE_ERROR* = 1 # SQL error or missing database
SQLITE_INTERNAL* = 2 # An internal logic error in SQLite
SQLITE_PERM* = 3 # Access permission denied
SQLITE_ABORT* = 4 # Callback routine requested an abort
SQLITE_BUSY* = 5 # The database file is locked
SQLITE_LOCKED* = 6 # A table in the database is locked
SQLITE_NOMEM* = 7 # A malloc() failed
SQLITE_READONLY* = 8 # Attempt to write a readonly database
SQLITE_INTERRUPT* = 9 # Operation terminated by sqlite3_interrupt()
SQLITE_IOERR* = 10 # Some kind of disk I/O error occurred
SQLITE_CORRUPT* = 11 # The database disk image is malformed
SQLITE_NOTFOUND* = 12 # (Internal Only) Table or record not found
SQLITE_FULL* = 13 # Insertion failed because database is full
SQLITE_CANTOPEN* = 14 # Unable to open the database file
SQLITE_PROTOCOL* = 15 # Database lock protocol error
SQLITE_EMPTY* = 16 # Database is empty
SQLITE_SCHEMA* = 17 # The database schema changed
SQLITE_TOOBIG* = 18 # Too much data for one row of a table
SQLITE_CONSTRAINT* = 19 # Abort due to constraint violation
SQLITE_MISMATCH* = 20 # Data type mismatch
SQLITE_MISUSE* = 21 # Library used incorrectly
SQLITE_NOLFS* = 22 # Uses OS features not supported on host
SQLITE_AUTH* = 23 # Authorization denied
SQLITE_FORMAT* = 24 # Auxiliary database format error
SQLITE_RANGE* = 25 # 2nd parameter to sqlite3_bind out of range
SQLITE_NOTADB* = 26 # File opened that is not a database file
SQLITE_ROW* = 100 # sqlite3_step() has another row ready
SQLITE_DONE* = 101 # sqlite3_step() has finished executing
SQLITE_COPY* = 0
SQLITE_CREATE_INDEX* = 1
SQLITE_CREATE_TABLE* = 2
SQLITE_CREATE_TEMP_INDEX* = 3
SQLITE_CREATE_TEMP_TABLE* = 4
SQLITE_CREATE_TEMP_TRIGGER* = 5
SQLITE_CREATE_TEMP_VIEW* = 6
SQLITE_CREATE_TRIGGER* = 7
SQLITE_CREATE_VIEW* = 8
SQLITE_DELETE* = 9
SQLITE_DROP_INDEX* = 10
SQLITE_DROP_TABLE* = 11
SQLITE_DROP_TEMP_INDEX* = 12
SQLITE_DROP_TEMP_TABLE* = 13
SQLITE_DROP_TEMP_TRIGGER* = 14
SQLITE_DROP_TEMP_VIEW* = 15
SQLITE_DROP_TRIGGER* = 16
SQLITE_DROP_VIEW* = 17
SQLITE_INSERT* = 18
SQLITE_PRAGMA* = 19
SQLITE_READ* = 20
SQLITE_SELECT* = 21
SQLITE_TRANSACTION* = 22
SQLITE_UPDATE* = 23
SQLITE_ATTACH* = 24
SQLITE_DETACH* = 25
SQLITE_ALTER_TABLE* = 26
SQLITE_REINDEX* = 27
SQLITE_DENY* = 1
SQLITE_IGNORE* = 2 # Original from sqlite3.h:
#define SQLITE_STATIC ((void(*)(void *))0)
#define SQLITE_TRANSIENT ((void(*)(void *))-1)
SQLITE_DETERMINISTIC* = 0x800
type
Sqlite3 {.pure, final.} = object
PSqlite3* = ptr Sqlite3
PPSqlite3* = ptr PSqlite3
Sqlite3_Backup {.pure, final.} = object
PSqlite3_Backup* = ptr Sqlite3_Backup
PPSqlite3_Backup* = ptr PSqlite3_Backup
Context{.pure, final.} = object
Pcontext* = ptr Context
TStmt{.pure, final.} = object
PStmt* = ptr TStmt
Value{.pure, final.} = object
PValue* = ptr Value
PValueArg* = array[0..127, PValue]
Callback* = proc (para1: pointer, para2: int32, para3,
para4: cstringArray): int32{.cdecl.}
Tbind_destructor_func* = proc (para1: pointer){.cdecl, tags: [], gcsafe.}
Create_function_step_func* = proc (para1: Pcontext, para2: int32,
para3: PValueArg){.cdecl.}
Create_function_func_func* = proc (para1: Pcontext, para2: int32,
para3: PValueArg){.cdecl.}
Create_function_final_func* = proc (para1: Pcontext){.cdecl.}
Result_func* = proc (para1: pointer){.cdecl.}
Create_collation_func* = proc (para1: pointer, para2: int32, para3: pointer,
para4: int32, para5: pointer): int32{.cdecl.}
Collation_needed_func* = proc (para1: pointer, para2: PSqlite3, eTextRep: int32,
para4: cstring){.cdecl.}
const
SQLITE_STATIC* = nil
SQLITE_TRANSIENT* = cast[Tbind_destructor_func](-1)
proc close*(para1: PSqlite3): int32{.cdecl, mylib, importc: "sqlite3_close".}
proc exec*(para1: PSqlite3, sql: cstring, para3: Callback, para4: pointer,
errmsg: var cstring): int32{.cdecl, mylib,
importc: "sqlite3_exec".}
proc last_insert_rowid*(para1: PSqlite3): int64{.cdecl, mylib,
importc: "sqlite3_last_insert_rowid".}
proc changes*(para1: PSqlite3): int32{.cdecl, mylib, importc: "sqlite3_changes".}
proc total_changes*(para1: PSqlite3): int32{.cdecl, mylib,
importc: "sqlite3_total_changes".}
proc interrupt*(para1: PSqlite3){.cdecl, mylib, importc: "sqlite3_interrupt".}
proc complete*(sql: cstring): int32{.cdecl, mylib,
importc: "sqlite3_complete".}
proc complete16*(sql: pointer): int32{.cdecl, mylib,
importc: "sqlite3_complete16".}
proc busy_handler*(para1: PSqlite3,
para2: proc (para1: pointer, para2: int32): int32{.cdecl.},
para3: pointer): int32{.cdecl, mylib,
importc: "sqlite3_busy_handler".}
proc busy_timeout*(para1: PSqlite3, ms: int32): int32{.cdecl, mylib,
importc: "sqlite3_busy_timeout".}
proc get_table*(para1: PSqlite3, sql: cstring, resultp: var cstringArray,
nrow, ncolumn: var cint, errmsg: ptr cstring): int32{.cdecl,
mylib, importc: "sqlite3_get_table".}
proc free_table*(result: cstringArray){.cdecl, mylib,
importc: "sqlite3_free_table".}
# Todo: see how translate sqlite3_mprintf, sqlite3_vmprintf, sqlite3_snprintf
# function sqlite3_mprintf(_para1:Pchar; args:array of const):Pchar;cdecl; external Sqlite3Lib name 'sqlite3_mprintf';
proc mprintf*(para1: cstring): cstring{.cdecl, varargs, mylib,
importc: "sqlite3_mprintf".}
#function sqlite3_vmprintf(_para1:Pchar; _para2:va_list):Pchar;cdecl; external Sqlite3Lib name 'sqlite3_vmprintf';
proc free*(z: cstring){.cdecl, mylib, importc: "sqlite3_free".}
#function sqlite3_snprintf(_para1:longint; _para2:Pchar; _para3:Pchar; args:array of const):Pchar;cdecl; external Sqlite3Lib name 'sqlite3_snprintf';
proc snprintf*(para1: int32, para2: cstring, para3: cstring): cstring{.cdecl,
mylib, varargs, importc: "sqlite3_snprintf".}
proc set_authorizer*(para1: PSqlite3, xAuth: proc (para1: pointer, para2: int32,
para3: cstring, para4: cstring, para5: cstring, para6: cstring): int32{.
cdecl.}, pUserData: pointer): int32{.cdecl, mylib,
importc: "sqlite3_set_authorizer".}
proc trace*(para1: PSqlite3, xTrace: proc (para1: pointer, para2: cstring){.cdecl.},
para3: pointer): pointer{.cdecl, mylib,
importc: "sqlite3_trace".}
proc progress_handler*(para1: PSqlite3, para2: int32,
para3: proc (para1: pointer): int32{.cdecl.},
para4: pointer){.cdecl, mylib,
importc: "sqlite3_progress_handler".}
proc commit_hook*(para1: PSqlite3, para2: proc (para1: pointer): int32{.cdecl.},
para3: pointer): pointer{.cdecl, mylib,
importc: "sqlite3_commit_hook".}
proc open*(filename: cstring, ppDb: var PSqlite3): int32{.cdecl, mylib,
importc: "sqlite3_open".}
proc open16*(filename: pointer, ppDb: var PSqlite3): int32{.cdecl, mylib,
importc: "sqlite3_open16".}
proc errcode*(db: PSqlite3): int32{.cdecl, mylib, importc: "sqlite3_errcode".}
proc errmsg*(para1: PSqlite3): cstring{.cdecl, mylib, importc: "sqlite3_errmsg".}
proc errmsg16*(para1: PSqlite3): pointer{.cdecl, mylib,
importc: "sqlite3_errmsg16".}
proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: var PStmt,
pzTail: ptr cstring): int32{.cdecl, mylib,
importc: "sqlite3_prepare".}
proc prepare_v2*(db: PSqlite3, zSql: cstring, nByte: cint, ppStmt: var PStmt,
pzTail: ptr cstring): cint {.
importc: "sqlite3_prepare_v2", cdecl, mylib.}
proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: var PStmt,
pzTail: var pointer): int32{.cdecl, mylib,
importc: "sqlite3_prepare16".}
proc bind_blob*(para1: PStmt, para2: int32, para3: pointer, n: int32,
para5: Tbind_destructor_func): int32{.cdecl, mylib,
importc: "sqlite3_bind_blob".}
proc bind_double*(para1: PStmt, para2: int32, para3: float64): int32{.cdecl,
mylib, importc: "sqlite3_bind_double".}
proc bind_int*(para1: PStmt, para2: int32, para3: int32): int32{.cdecl,
mylib, importc: "sqlite3_bind_int".}
proc bind_int64*(para1: PStmt, para2: int32, para3: int64): int32{.cdecl,
mylib, importc: "sqlite3_bind_int64".}
proc bind_null*(para1: PStmt, para2: int32): int32{.cdecl, mylib,
importc: "sqlite3_bind_null".}
proc bind_text*(para1: PStmt, para2: int32, para3: cstring, n: int32,
para5: Tbind_destructor_func): int32{.cdecl, mylib,
importc: "sqlite3_bind_text".}
proc bind_text16*(para1: PStmt, para2: int32, para3: pointer, para4: int32,
para5: Tbind_destructor_func): int32{.cdecl, mylib,
importc: "sqlite3_bind_text16".}
#function sqlite3_bind_value(_para1:Psqlite3_stmt; _para2:longint; _para3:Psqlite3_value):longint;cdecl; external Sqlite3Lib name 'sqlite3_bind_value';
#These overloaded functions were introduced to allow the use of SQLITE_STATIC and SQLITE_TRANSIENT
#It's the c world man ;-)
proc bind_blob*(para1: PStmt, para2: int32, para3: pointer, n: int32,
para5: int32): int32{.cdecl, mylib,
importc: "sqlite3_bind_blob".}
proc bind_text*(para1: PStmt, para2: int32, para3: cstring, n: int32,
para5: int32): int32{.cdecl, mylib,
importc: "sqlite3_bind_text".}
proc bind_text16*(para1: PStmt, para2: int32, para3: pointer, para4: int32,
para5: int32): int32{.cdecl, mylib,
importc: "sqlite3_bind_text16".}
proc bind_parameter_count*(para1: PStmt): int32{.cdecl, mylib,
importc: "sqlite3_bind_parameter_count".}
proc bind_parameter_name*(para1: PStmt, para2: int32): cstring{.cdecl,
mylib, importc: "sqlite3_bind_parameter_name".}
proc bind_parameter_index*(para1: PStmt, zName: cstring): int32{.cdecl,
mylib, importc: "sqlite3_bind_parameter_index".}
proc clear_bindings*(para1: PStmt): int32 {.cdecl,
mylib, importc: "sqlite3_clear_bindings".}
proc column_count*(PStmt: PStmt): int32{.cdecl, mylib,
importc: "sqlite3_column_count".}
proc column_name*(para1: PStmt, para2: int32): cstring{.cdecl, mylib,
importc: "sqlite3_column_name".}
proc column_table_name*(para1: PStmt; para2: int32): cstring{.cdecl, mylib,
importc: "sqlite3_column_table_name".}
proc column_name16*(para1: PStmt, para2: int32): pointer{.cdecl, mylib,
importc: "sqlite3_column_name16".}
proc column_decltype*(para1: PStmt, i: int32): cstring{.cdecl, mylib,
importc: "sqlite3_column_decltype".}
proc column_decltype16*(para1: PStmt, para2: int32): pointer{.cdecl,
mylib, importc: "sqlite3_column_decltype16".}
proc step*(para1: PStmt): int32{.cdecl, mylib, importc: "sqlite3_step".}
proc data_count*(PStmt: PStmt): int32{.cdecl, mylib,
importc: "sqlite3_data_count".}
proc column_blob*(para1: PStmt, iCol: int32): pointer{.cdecl, mylib,
importc: "sqlite3_column_blob".}
proc column_bytes*(para1: PStmt, iCol: int32): int32{.cdecl, mylib,
importc: "sqlite3_column_bytes".}
proc column_bytes16*(para1: PStmt, iCol: int32): int32{.cdecl, mylib,
importc: "sqlite3_column_bytes16".}
proc column_double*(para1: PStmt, iCol: int32): float64{.cdecl, mylib,
importc: "sqlite3_column_double".}
proc column_int*(para1: PStmt, iCol: int32): int32{.cdecl, mylib,
importc: "sqlite3_column_int".}
proc column_int64*(para1: PStmt, iCol: int32): int64{.cdecl, mylib,
importc: "sqlite3_column_int64".}
proc column_text*(para1: PStmt, iCol: int32): cstring{.cdecl, mylib,
importc: "sqlite3_column_text".}
proc column_text16*(para1: PStmt, iCol: int32): pointer{.cdecl, mylib,
importc: "sqlite3_column_text16".}
proc column_type*(para1: PStmt, iCol: int32): int32{.cdecl, mylib,
importc: "sqlite3_column_type".}
proc finalize*(PStmt: PStmt): int32{.cdecl, mylib,
importc: "sqlite3_finalize".}
proc reset*(PStmt: PStmt): int32{.cdecl, mylib, importc: "sqlite3_reset".}
proc create_function*(para1: PSqlite3, zFunctionName: cstring, nArg: int32,
eTextRep: int32, para5: pointer,
xFunc: Create_function_func_func,
xStep: Create_function_step_func,
xFinal: Create_function_final_func): int32{.cdecl,
mylib, importc: "sqlite3_create_function".}
proc create_function16*(para1: PSqlite3, zFunctionName: pointer, nArg: int32,
eTextRep: int32, para5: pointer,
xFunc: Create_function_func_func,
xStep: Create_function_step_func,
xFinal: Create_function_final_func): int32{.cdecl,
mylib, importc: "sqlite3_create_function16".}
proc aggregate_count*(para1: Pcontext): int32{.cdecl, mylib,
importc: "sqlite3_aggregate_count".}
proc value_blob*(para1: PValue): pointer{.cdecl, mylib,
importc: "sqlite3_value_blob".}
proc value_bytes*(para1: PValue): int32{.cdecl, mylib,
importc: "sqlite3_value_bytes".}
proc value_bytes16*(para1: PValue): int32{.cdecl, mylib,
importc: "sqlite3_value_bytes16".}
proc value_double*(para1: PValue): float64{.cdecl, mylib,
importc: "sqlite3_value_double".}
proc value_int*(para1: PValue): int32{.cdecl, mylib,
importc: "sqlite3_value_int".}
proc value_int64*(para1: PValue): int64{.cdecl, mylib,
importc: "sqlite3_value_int64".}
proc value_text*(para1: PValue): cstring{.cdecl, mylib,
importc: "sqlite3_value_text".}
proc value_text16*(para1: PValue): pointer{.cdecl, mylib,
importc: "sqlite3_value_text16".}
proc value_text16le*(para1: PValue): pointer{.cdecl, mylib,
importc: "sqlite3_value_text16le".}
proc value_text16be*(para1: PValue): pointer{.cdecl, mylib,
importc: "sqlite3_value_text16be".}
proc value_type*(para1: PValue): int32{.cdecl, mylib,
importc: "sqlite3_value_type".}
proc aggregate_context*(para1: Pcontext, nBytes: int32): pointer{.cdecl,
mylib, importc: "sqlite3_aggregate_context".}
proc user_data*(para1: Pcontext): pointer{.cdecl, mylib,
importc: "sqlite3_user_data".}
proc get_auxdata*(para1: Pcontext, para2: int32): pointer{.cdecl, mylib,
importc: "sqlite3_get_auxdata".}
proc set_auxdata*(para1: Pcontext, para2: int32, para3: pointer,
para4: proc (para1: pointer){.cdecl.}){.cdecl, mylib,
importc: "sqlite3_set_auxdata".}
proc result_blob*(para1: Pcontext, para2: pointer, para3: int32,
para4: Result_func){.cdecl, mylib,
importc: "sqlite3_result_blob".}
proc result_double*(para1: Pcontext, para2: float64){.cdecl, mylib,
importc: "sqlite3_result_double".}
proc result_error*(para1: Pcontext, para2: cstring, para3: int32){.cdecl,
mylib, importc: "sqlite3_result_error".}
proc result_error16*(para1: Pcontext, para2: pointer, para3: int32){.cdecl,
mylib, importc: "sqlite3_result_error16".}
proc result_int*(para1: Pcontext, para2: int32){.cdecl, mylib,
importc: "sqlite3_result_int".}
proc result_int64*(para1: Pcontext, para2: int64){.cdecl, mylib,
importc: "sqlite3_result_int64".}
proc result_null*(para1: Pcontext){.cdecl, mylib,
importc: "sqlite3_result_null".}
proc result_text*(para1: Pcontext, para2: cstring, para3: int32,
para4: Result_func){.cdecl, mylib,
importc: "sqlite3_result_text".}
proc result_text16*(para1: Pcontext, para2: pointer, para3: int32,
para4: Result_func){.cdecl, mylib,
importc: "sqlite3_result_text16".}
proc result_text16le*(para1: Pcontext, para2: pointer, para3: int32,
para4: Result_func){.cdecl, mylib,
importc: "sqlite3_result_text16le".}
proc result_text16be*(para1: Pcontext, para2: pointer, para3: int32,
para4: Result_func){.cdecl, mylib,
importc: "sqlite3_result_text16be".}
proc result_value*(para1: Pcontext, para2: PValue){.cdecl, mylib,
importc: "sqlite3_result_value".}
proc create_collation*(para1: PSqlite3, zName: cstring, eTextRep: int32,
para4: pointer, xCompare: Create_collation_func): int32{.
cdecl, mylib, importc: "sqlite3_create_collation".}
proc create_collation16*(para1: PSqlite3, zName: cstring, eTextRep: int32,
para4: pointer, xCompare: Create_collation_func): int32{.
cdecl, mylib, importc: "sqlite3_create_collation16".}
proc collation_needed*(para1: PSqlite3, para2: pointer, para3: Collation_needed_func): int32{.
cdecl, mylib, importc: "sqlite3_collation_needed".}
proc collation_needed16*(para1: PSqlite3, para2: pointer, para3: Collation_needed_func): int32{.
cdecl, mylib, importc: "sqlite3_collation_needed16".}
proc libversion*(): cstring{.cdecl, mylib, importc: "sqlite3_libversion".}
#Alias for allowing better code portability (win32 is not working with external variables)
proc version*(): cstring{.cdecl, mylib, importc: "sqlite3_libversion".}
# Not published functions
proc libversion_number*(): int32{.cdecl, mylib,
importc: "sqlite3_libversion_number".}
proc backup_init*(pDest: PSqlite3, zDestName: cstring, pSource: PSqlite3, zSourceName: cstring): PSqlite3_Backup {.
cdecl, mylib, importc: "sqlite3_backup_init".}
proc backup_step*(pBackup: PSqlite3_Backup, nPage: int32): int32 {.cdecl, mylib, importc: "sqlite3_backup_step".}
proc backup_finish*(pBackup: PSqlite3_Backup): int32 {.cdecl, mylib, importc: "sqlite3_backup_finish".}
proc backup_pagecount*(pBackup: PSqlite3_Backup): int32 {.cdecl, mylib, importc: "sqlite3_backup_pagecount".}
proc backup_remaining*(pBackup: PSqlite3_Backup): int32 {.cdecl, mylib, importc: "sqlite3_backup_remaining".}
proc sqlite3_sleep*(t: int64): int64 {.cdecl, mylib, importc: "sqlite3_sleep".}
#function sqlite3_key(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; external Sqlite3Lib name 'sqlite3_key';
#function sqlite3_rekey(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; external Sqlite3Lib name 'sqlite3_rekey';
#function sqlite3_sleep(_para1:longint):longint;cdecl; external Sqlite3Lib name 'sqlite3_sleep';
#function sqlite3_expired(_para1:Psqlite3_stmt):longint;cdecl; external Sqlite3Lib name 'sqlite3_expired';
#function sqlite3_global_recover:longint;cdecl; external Sqlite3Lib name 'sqlite3_global_recover';
# implementation
when defined(nimHasStyleChecks):
{.pop.}

View File

@@ -116,7 +116,8 @@
</ul>
<ul class="simple nested-toc-section">bar
<li><a class="reference" href="#bar%2CT%2CT" title="bar[T](a, b: T): T">bar[T](a, b: T): T</a></li>
<li><a class="reference" href="#bar" title="bar(f: FooBuzz)">bar(f: FooBuzz)</a></li>
<li><a class="reference" href="#bar%2CT%2CT" title="bar[T](a, b: T): T">bar[T](a, b: T): T</a></li>
</ul>
<ul class="simple nested-toc-section">baz
@@ -539,7 +540,15 @@
</div>
<div id="bar-procs-all">
<div id="bar,T,T">
<div id="bar">
<dt><pre><span class="Keyword">proc</span> <a href="#bar"><span class="Identifier">bar</span></a><span class="Other">(</span><span class="Identifier">f</span><span class="Other">:</span> <a href="testproject.html#FooBuzz"><span class="Identifier">FooBuzz</span></a><span class="Other">)</span> {.<span><span class="Other pragmadots">...</span></span><span class="pragmawrap"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">forbids</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span>.}</pre></dt>
<dd>
</dd>
</div>
<div id="bar,T,T">
<dt><pre><span class="Keyword">proc</span> <a href="#bar%2CT%2CT"><span class="Identifier">bar</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">a</span><span class="Other">,</span> <span class="Identifier">b</span><span class="Other">:</span> <span class="Identifier">T</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">T</span></pre></dt>
<dd>

View File

@@ -7,6 +7,7 @@ bar testproject.html#bar,T,T testproject: bar[T](a, b: T): T
baz testproject.html#baz,T,T testproject: baz[T](a, b: T): T
buzz testproject.html#buzz,T,T testproject: buzz[T](a, b: T): T
FooBuzz testproject.html#FooBuzz testproject: FooBuzz
bar testproject.html#bar testproject: bar(f: FooBuzz)
aVariable testproject.html#aVariable testproject: aVariable
A testproject.html#A testproject: A
B testproject.html#B testproject: B

View File

@@ -78,6 +78,8 @@
</ul></dd>
<dt><a name="bar" href="#bar"><span>bar:</span></a></dt><dd><ul class="simple">
<li><a class="reference external"
data-doc-search-tag="testproject: bar(f: FooBuzz)" href="testproject.html#bar">testproject: bar(f: FooBuzz)</a></li>
<li><a class="reference external"
data-doc-search-tag="testproject: bar[T](a, b: T): T" href="testproject.html#bar%2CT%2CT">testproject: bar[T](a, b: T): T</a></li>
<li><a class="reference external"
data-doc-search-tag="testproject: bar(): untyped" href="testproject.html#bar.m">testproject: bar(): untyped</a></li>

View File

@@ -42,6 +42,11 @@ proc buzz*[T](a, b: T): T {.deprecated: "since v0.20".} =
type
FooBuzz* {.deprecated: "FooBuzz msg".} = int
using f: FooBuzz
proc bar*(f) = # `f` should be expanded to `f: FooBuzz`
discard
import std/macros
var aVariable*: array[1, int]

View File

@@ -27,7 +27,7 @@ import compiler / [options, commands, modules, sem,
passes, passaux, msgs,
sigmatch, ast,
idents, modulegraphs, prefixmatches, lineinfos, cmdlinehelper,
pathutils]
pathutils, condsyms]
when defined(nimPreviewSlimSystem):
import std/typedthreads
@@ -553,6 +553,7 @@ proc mainCommand(graph: ModuleGraph) =
registerPass graph, verbosePass
registerPass graph, semPass
conf.setCmd cmdIdeTools
defineSymbol(conf.symbols, $conf.backend)
wantMainModule(conf)
if not fileExists(conf.projectFull):
@@ -952,10 +953,12 @@ else:
proc mockCommand(graph: ModuleGraph) =
retval = graph
let conf = graph.config
conf.setCmd cmdIdeTools
defineSymbol(conf.symbols, $conf.backend)
clearPasses(graph)
registerPass graph, verbosePass
registerPass graph, semPass
conf.setCmd cmdIdeTools
wantMainModule(conf)
if not fileExists(conf.projectFull):

View File

@@ -0,0 +1,7 @@
when not defined(js):
{.fatal: "Crash".}
echo 4
discard """
$nimsuggest --v3 --tester $file
"""

Some files were not shown because too many files have changed in this diff Show More