moderate system cleanup & refactor (#20355)
* system refactor, move out 600 lines * compilation, slice, backwardsindex, misc_num moved out of system * some procs/types moved into arithmetics, basic_types * system no longer depends on syncio * some procs moved around to fit with their surroundings * make exceptions an import, old ops to misc_num * move instantiationInfo back * move back nim version, fix windows echo * include compilation * better docs for imported modules, fix unsigned ops also remove ze, ze64, toU8, toU16, toU32 with nimPreviewSlimSystem * fix terminal * workaround IC test & weird csize bug, changelog * move NimMajor etc back to compilation, rebase for CI * try ic fix * form single `indices`, slim out TaintedString, try fix IC * fix CI, update changelog, addQuitProc * fix CI * try fix CI * actually fix CI finally hopefully * Update lib/system/compilation.nim Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com> * update kochdocs * hopefully fix csize uses for slimsystem * fix tquit Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
This commit is contained in:
parent
b463c8aedf
commit
919a889ba8
37 changed files with 1167 additions and 1102 deletions
30
changelog.md
30
changelog.md
|
|
@ -7,8 +7,34 @@
|
||||||
- `addr` is now available for all addressable locations,
|
- `addr` is now available for all addressable locations,
|
||||||
`unsafeAddr` is now deprecated and an alias for `addr`.
|
`unsafeAddr` is now deprecated and an alias for `addr`.
|
||||||
|
|
||||||
- `io`, `assertions`, `formatfloat`, and `` dollars.`$` `` for objects are about to move out of the `system` module. You may instead import `std/syncio`, `std/assertions`, `std/formatfloat` and `std/objectdollar`.
|
- Certain definitions from the default `system` module have been moved to
|
||||||
The `-d:nimPreviewSlimSystem` option makes these imports required.
|
the following new modules:
|
||||||
|
|
||||||
|
- `std/syncio`
|
||||||
|
- `std/assertions`
|
||||||
|
- `std/formatfloat`
|
||||||
|
- `std/objectdollar`
|
||||||
|
|
||||||
|
In the future, these definitions will be removed from the `system` module,
|
||||||
|
and their respective modules will have to be imported to use them.
|
||||||
|
Currently, to make these imports required, the `-d:nimPreviewSlimSystem` option
|
||||||
|
may be used.
|
||||||
|
|
||||||
|
- Enabling `-d:nimPreviewSlimSystem` also removes the following deprecated
|
||||||
|
symbols in the `system` module:
|
||||||
|
- Aliases with `Error` suffix to exception types that have a `Defect` suffix
|
||||||
|
(see [exceptions](https://nim-lang.org/docs/exceptions.html)):
|
||||||
|
`ArithmeticError`, `DivByZeroError`, `OverflowError`,
|
||||||
|
`AccessViolationError`, `AssertionError`, `OutOfMemError`, `IndexError`,
|
||||||
|
`FieldError`, `RangeError`, `StackOverflowError`, `ReraiseError`,
|
||||||
|
`ObjectAssignmentError`, `ObjectConversionError`, `FloatingPointError`,
|
||||||
|
`FloatOverflowError`, `FloatUnderflowError`, `FloatInexactError`,
|
||||||
|
`DeadThreadError`, `NilAccessError`
|
||||||
|
- `addQuitProc`, replaced by `exitprocs.addExitProc`
|
||||||
|
- Legacy unsigned conversion operations: `ze`, `ze64`, `toU8`, `toU16`, `toU32`
|
||||||
|
- `TaintedString`, formerly a distinct alias to `string`
|
||||||
|
- `PInt32`, `PInt64`, `PFloat32`, `PFloat64`, aliases to
|
||||||
|
`ptr int32`, `ptr int64`, `ptr float32`, `ptr float64`
|
||||||
|
|
||||||
- The `gc:v2` option is removed.
|
- The `gc:v2` option is removed.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -505,11 +505,11 @@ proc getNumber(L: var Lexer, result: var Token) =
|
||||||
of tkUInt16Lit: setNumber result.iNumber, xi and 0xffff
|
of tkUInt16Lit: setNumber result.iNumber, xi and 0xffff
|
||||||
of tkUInt32Lit: setNumber result.iNumber, xi and 0xffffffff
|
of tkUInt32Lit: setNumber result.iNumber, xi and 0xffffffff
|
||||||
of tkFloat32Lit:
|
of tkFloat32Lit:
|
||||||
setNumber result.fNumber, (cast[PFloat32](addr(xi)))[]
|
setNumber result.fNumber, (cast[ptr float32](addr(xi)))[]
|
||||||
# note: this code is endian neutral!
|
# note: this code is endian neutral!
|
||||||
# XXX: Test this on big endian machine!
|
# XXX: Test this on big endian machine!
|
||||||
of tkFloat64Lit, tkFloatLit:
|
of tkFloat64Lit, tkFloatLit:
|
||||||
setNumber result.fNumber, (cast[PFloat64](addr(xi)))[]
|
setNumber result.fNumber, (cast[ptr float64](addr(xi)))[]
|
||||||
else: internalError(L.config, getLineInfo(L), "getNumber")
|
else: internalError(L.config, getLineInfo(L), "getNumber")
|
||||||
|
|
||||||
# Bounds checks. Non decimal literals are allowed to overflow the range of
|
# Bounds checks. Non decimal literals are allowed to overflow the range of
|
||||||
|
|
|
||||||
|
|
@ -398,18 +398,18 @@ proc atom(g: TSrcGen; n: PNode): string =
|
||||||
of nkUInt64Lit: result = ulitAux(g, n, n.intVal, 8) & "\'u64"
|
of nkUInt64Lit: result = ulitAux(g, n, n.intVal, 8) & "\'u64"
|
||||||
of nkFloatLit:
|
of nkFloatLit:
|
||||||
if n.flags * {nfBase2, nfBase8, nfBase16} == {}: result = $(n.floatVal)
|
if n.flags * {nfBase2, nfBase8, nfBase16} == {}: result = $(n.floatVal)
|
||||||
else: result = litAux(g, n, (cast[PInt64](addr(n.floatVal)))[] , 8)
|
else: result = litAux(g, n, (cast[ptr int64](addr(n.floatVal)))[] , 8)
|
||||||
of nkFloat32Lit:
|
of nkFloat32Lit:
|
||||||
if n.flags * {nfBase2, nfBase8, nfBase16} == {}:
|
if n.flags * {nfBase2, nfBase8, nfBase16} == {}:
|
||||||
result = $n.floatVal & "\'f32"
|
result = $n.floatVal & "\'f32"
|
||||||
else:
|
else:
|
||||||
f = n.floatVal.float32
|
f = n.floatVal.float32
|
||||||
result = litAux(g, n, (cast[PInt32](addr(f)))[], 4) & "\'f32"
|
result = litAux(g, n, (cast[ptr int32](addr(f)))[], 4) & "\'f32"
|
||||||
of nkFloat64Lit:
|
of nkFloat64Lit:
|
||||||
if n.flags * {nfBase2, nfBase8, nfBase16} == {}:
|
if n.flags * {nfBase2, nfBase8, nfBase16} == {}:
|
||||||
result = $n.floatVal & "\'f64"
|
result = $n.floatVal & "\'f64"
|
||||||
else:
|
else:
|
||||||
result = litAux(g, n, (cast[PInt64](addr(n.floatVal)))[], 8) & "\'f64"
|
result = litAux(g, n, (cast[ptr int64](addr(n.floatVal)))[], 8) & "\'f64"
|
||||||
of nkNilLit: result = "nil"
|
of nkNilLit: result = "nil"
|
||||||
of nkType:
|
of nkType:
|
||||||
if (n.typ != nil) and (n.typ.sym != nil): result = n.typ.sym.name.s
|
if (n.typ != nil) and (n.typ.sym != nil): result = n.typ.sym.name.s
|
||||||
|
|
|
||||||
|
|
@ -1066,17 +1066,6 @@ operation meaning
|
||||||
`a %% b` unsigned integer modulo operation
|
`a %% b` unsigned integer modulo operation
|
||||||
`a <% b` treat `a` and `b` as unsigned and compare
|
`a <% b` treat `a` and `b` as unsigned and compare
|
||||||
`a <=% b` treat `a` and `b` as unsigned and compare
|
`a <=% b` treat `a` and `b` as unsigned and compare
|
||||||
`ze(a)` extends the bits of `a` with zeros until it has the
|
|
||||||
width of the `int` type
|
|
||||||
`toU8(a)` treats `a` as unsigned and converts it to an
|
|
||||||
unsigned integer of 8 bits (but still the
|
|
||||||
`int8` type)
|
|
||||||
`toU16(a)` treats `a` as unsigned and converts it to an
|
|
||||||
unsigned integer of 16 bits (but still the
|
|
||||||
`int16` type)
|
|
||||||
`toU32(a)` treats `a` as unsigned and converts it to an
|
|
||||||
unsigned integer of 32 bits (but still the
|
|
||||||
`int32` type)
|
|
||||||
====================== ======================================================
|
====================== ======================================================
|
||||||
|
|
||||||
`Automatic type conversion`:idx: is performed in expressions where different
|
`Automatic type conversion`:idx: is performed in expressions where different
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ type
|
||||||
rawTypePtr: pointer
|
rawTypePtr: pointer
|
||||||
|
|
||||||
ppointer = ptr pointer
|
ppointer = ptr pointer
|
||||||
pbyteArray = ptr array[0xffff, int8]
|
pbyteArray = ptr array[0xffff, uint8]
|
||||||
|
|
||||||
when not defined(gcDestructors):
|
when not defined(gcDestructors):
|
||||||
type
|
type
|
||||||
|
|
@ -139,10 +139,10 @@ proc getDiscriminant(aa: pointer, n: ptr TNimNode): int =
|
||||||
var d: int
|
var d: int
|
||||||
let a = cast[ByteAddress](aa)
|
let a = cast[ByteAddress](aa)
|
||||||
case n.typ.size
|
case n.typ.size
|
||||||
of 1: d = ze(cast[ptr int8](a +% n.offset)[])
|
of 1: d = int(cast[ptr uint8](a +% n.offset)[])
|
||||||
of 2: d = ze(cast[ptr int16](a +% n.offset)[])
|
of 2: d = int(cast[ptr uint16](a +% n.offset)[])
|
||||||
of 4: d = int(cast[ptr int32](a +% n.offset)[])
|
of 4: d = int(cast[ptr uint32](a +% n.offset)[])
|
||||||
of 8: d = int(cast[ptr int64](a +% n.offset)[])
|
of 8: d = int(cast[ptr uint64](a +% n.offset)[])
|
||||||
else: assert(false)
|
else: assert(false)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
@ -484,8 +484,8 @@ proc getBiggestInt*(x: Any): BiggestInt =
|
||||||
of tyChar: result = BiggestInt(cast[ptr char](x.value)[])
|
of tyChar: result = BiggestInt(cast[ptr char](x.value)[])
|
||||||
of tyEnum, tySet:
|
of tyEnum, tySet:
|
||||||
case t.size
|
case t.size
|
||||||
of 1: result = ze64(cast[ptr int8](x.value)[])
|
of 1: result = int64(cast[ptr uint8](x.value)[])
|
||||||
of 2: result = ze64(cast[ptr int16](x.value)[])
|
of 2: result = int64(cast[ptr uint16](x.value)[])
|
||||||
of 4: result = BiggestInt(cast[ptr int32](x.value)[])
|
of 4: result = BiggestInt(cast[ptr int32](x.value)[])
|
||||||
of 8: result = BiggestInt(cast[ptr int64](x.value)[])
|
of 8: result = BiggestInt(cast[ptr int64](x.value)[])
|
||||||
else: assert false
|
else: assert false
|
||||||
|
|
@ -509,8 +509,8 @@ proc setBiggestInt*(x: Any, y: BiggestInt) =
|
||||||
of tyChar: cast[ptr char](x.value)[] = chr(y.int)
|
of tyChar: cast[ptr char](x.value)[] = chr(y.int)
|
||||||
of tyEnum, tySet:
|
of tyEnum, tySet:
|
||||||
case t.size
|
case t.size
|
||||||
of 1: cast[ptr int8](x.value)[] = toU8(y.int)
|
of 1: cast[ptr uint8](x.value)[] = uint8(y.int)
|
||||||
of 2: cast[ptr int16](x.value)[] = toU16(y.int)
|
of 2: cast[ptr uint16](x.value)[] = uint16(y.int)
|
||||||
of 4: cast[ptr int32](x.value)[] = int32(y)
|
of 4: cast[ptr int32](x.value)[] = int32(y)
|
||||||
of 8: cast[ptr int64](x.value)[] = y
|
of 8: cast[ptr int64](x.value)[] = y
|
||||||
else: assert false
|
else: assert false
|
||||||
|
|
@ -691,14 +691,14 @@ iterator elements*(x: Any): int =
|
||||||
# "typ.slots.len" field is for sets the "first" field
|
# "typ.slots.len" field is for sets the "first" field
|
||||||
var u: int64
|
var u: int64
|
||||||
case typ.size
|
case typ.size
|
||||||
of 1: u = ze64(cast[ptr int8](p)[])
|
of 1: u = int64(cast[ptr uint8](p)[])
|
||||||
of 2: u = ze64(cast[ptr int16](p)[])
|
of 2: u = int64(cast[ptr uint16](p)[])
|
||||||
of 4: u = ze64(cast[ptr int32](p)[])
|
of 4: u = int64(cast[ptr uint32](p)[])
|
||||||
of 8: u = cast[ptr int64](p)[]
|
of 8: u = cast[ptr int64](p)[]
|
||||||
else:
|
else:
|
||||||
let a = cast[pbyteArray](p)
|
let a = cast[pbyteArray](p)
|
||||||
for i in 0 .. typ.size*8-1:
|
for i in 0 .. typ.size*8-1:
|
||||||
if (ze(a[i div 8]) and (1 shl (i mod 8))) != 0:
|
if (int(a[i div 8]) and (1 shl (i mod 8))) != 0:
|
||||||
yield i + typ.node.len
|
yield i + typ.node.len
|
||||||
if typ.size <= 8:
|
if typ.size <= 8:
|
||||||
for i in 0..sizeof(int64)*8-1:
|
for i in 0..sizeof(int64)*8-1:
|
||||||
|
|
@ -727,4 +727,4 @@ proc inclSetElement*(x: Any, elem: int) =
|
||||||
a[] = a[] or (1'i64 shl e)
|
a[] = a[] or (1'i64 shl e)
|
||||||
else:
|
else:
|
||||||
var a = cast[pbyteArray](p)
|
var a = cast[pbyteArray](p)
|
||||||
a[e shr 3] = toU8(a[e shr 3] or (1 shl (e and 7)))
|
a[e shr 3] = a[e shr 3] or uint8(1 shl (e and 7))
|
||||||
|
|
|
||||||
|
|
@ -304,7 +304,7 @@ type
|
||||||
Stack* {.importc: "stack_t",
|
Stack* {.importc: "stack_t",
|
||||||
header: "<signal.h>", final, pure.} = object ## stack_t
|
header: "<signal.h>", final, pure.} = object ## stack_t
|
||||||
ss_sp*: pointer ## Stack base or pointer.
|
ss_sp*: pointer ## Stack base or pointer.
|
||||||
ss_size*: csize ## Stack size.
|
ss_size*: csize_t ## Stack size.
|
||||||
ss_flags*: cint ## Flags.
|
ss_flags*: cint ## Flags.
|
||||||
|
|
||||||
SigInfo* {.importc: "siginfo_t",
|
SigInfo* {.importc: "siginfo_t",
|
||||||
|
|
@ -404,7 +404,7 @@ type
|
||||||
IOVec* {.importc: "struct iovec", pure, final,
|
IOVec* {.importc: "struct iovec", pure, final,
|
||||||
header: "<sys/uio.h>".} = object ## struct iovec
|
header: "<sys/uio.h>".} = object ## struct iovec
|
||||||
iov_base*: pointer ## Base address of a memory region for input or output.
|
iov_base*: pointer ## Base address of a memory region for input or output.
|
||||||
iov_len*: csize ## The size of the memory pointed to by iov_base.
|
iov_len*: csize_t ## The size of the memory pointed to by iov_base.
|
||||||
|
|
||||||
Tmsghdr* {.importc: "struct msghdr", pure, final,
|
Tmsghdr* {.importc: "struct msghdr", pure, final,
|
||||||
header: "<sys/socket.h>".} = object ## struct msghdr
|
header: "<sys/socket.h>".} = object ## struct msghdr
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ type
|
||||||
header: "<signal.h>", final, pure.} = object ## stack_t
|
header: "<signal.h>", final, pure.} = object ## stack_t
|
||||||
ss_sp*: pointer ## Stack base or pointer.
|
ss_sp*: pointer ## Stack base or pointer.
|
||||||
ss_flags*: cint ## Flags.
|
ss_flags*: cint ## Flags.
|
||||||
ss_size*: csize ## Stack size.
|
ss_size*: csize_t ## Stack size.
|
||||||
|
|
||||||
SigInfo* {.importc: "siginfo_t",
|
SigInfo* {.importc: "siginfo_t",
|
||||||
header: "<signal.h>", final, pure.} = object ## siginfo_t
|
header: "<signal.h>", final, pure.} = object ## siginfo_t
|
||||||
|
|
@ -321,7 +321,7 @@ type
|
||||||
aio_lio_opcode*: cint ## Operation to be performed.
|
aio_lio_opcode*: cint ## Operation to be performed.
|
||||||
aio_reqprio*: cint ## Request priority offset.
|
aio_reqprio*: cint ## Request priority offset.
|
||||||
aio_buf*: pointer ## Location of buffer.
|
aio_buf*: pointer ## Location of buffer.
|
||||||
aio_nbytes*: csize ## Length of transfer.
|
aio_nbytes*: csize_t ## Length of transfer.
|
||||||
aio_sigevent*: SigEvent ## Signal number and value.
|
aio_sigevent*: SigEvent ## Signal number and value.
|
||||||
next_prio: pointer
|
next_prio: pointer
|
||||||
abs_prio: cint
|
abs_prio: cint
|
||||||
|
|
@ -378,15 +378,15 @@ type
|
||||||
msg_name*: pointer ## Optional address.
|
msg_name*: pointer ## Optional address.
|
||||||
msg_namelen*: SockLen ## Size of address.
|
msg_namelen*: SockLen ## Size of address.
|
||||||
msg_iov*: ptr IOVec ## Scatter/gather array.
|
msg_iov*: ptr IOVec ## Scatter/gather array.
|
||||||
msg_iovlen*: csize ## Members in msg_iov.
|
msg_iovlen*: csize_t ## Members in msg_iov.
|
||||||
msg_control*: pointer ## Ancillary data; see below.
|
msg_control*: pointer ## Ancillary data; see below.
|
||||||
msg_controllen*: csize ## Ancillary data buffer len.
|
msg_controllen*: csize_t ## Ancillary data buffer len.
|
||||||
msg_flags*: cint ## Flags on received message.
|
msg_flags*: cint ## Flags on received message.
|
||||||
|
|
||||||
|
|
||||||
Tcmsghdr* {.importc: "struct cmsghdr", pure, final,
|
Tcmsghdr* {.importc: "struct cmsghdr", pure, final,
|
||||||
header: "<sys/socket.h>".} = object ## struct cmsghdr
|
header: "<sys/socket.h>".} = object ## struct cmsghdr
|
||||||
cmsg_len*: csize ## Data byte count, including the cmsghdr.
|
cmsg_len*: csize_t ## Data byte count, including the cmsghdr.
|
||||||
cmsg_level*: cint ## Originating protocol.
|
cmsg_level*: cint ## Originating protocol.
|
||||||
cmsg_type*: cint ## Protocol-specific type.
|
cmsg_type*: cint ## Protocol-specific type.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -317,9 +317,9 @@ when defined(posix) or defined(nimdoc):
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
when defined(linux): #Maybe NetBSD, too?
|
when defined(linux): #Maybe NetBSD, too?
|
||||||
#On Linux this can be over 100 times faster than a munmap,mmap cycle.
|
#On Linux this can be over 100 times faster than a munmap,mmap cycle.
|
||||||
proc mremap(old: pointer; oldSize, newSize: csize; flags: cint):
|
proc mremap(old: pointer; oldSize, newSize: csize_t; flags: cint):
|
||||||
pointer {.importc: "mremap", header: "<sys/mman.h>".}
|
pointer {.importc: "mremap", header: "<sys/mman.h>".}
|
||||||
let newAddr = mremap(f.mem, csize(f.size), csize(newFileSize), cint(1))
|
let newAddr = mremap(f.mem, csize_t(f.size), csize_t(newFileSize), cint(1))
|
||||||
if newAddr == cast[pointer](MAP_FAILED):
|
if newAddr == cast[pointer](MAP_FAILED):
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
else:
|
else:
|
||||||
|
|
@ -412,7 +412,7 @@ iterator memSlices*(mfile: MemFile, delim = '\l', eat = '\r'): MemSlice {.inline
|
||||||
## inc(count)
|
## inc(count)
|
||||||
## echo count
|
## echo count
|
||||||
|
|
||||||
proc c_memchr(cstr: pointer, c: char, n: csize): pointer {.
|
proc c_memchr(cstr: pointer, c: char, n: csize_t): pointer {.
|
||||||
importc: "memchr", header: "<string.h>".}
|
importc: "memchr", header: "<string.h>".}
|
||||||
proc `-!`(p, q: pointer): int {.inline.} = return cast[int](p) -% cast[int](q)
|
proc `-!`(p, q: pointer): int {.inline.} = return cast[int](p) -% cast[int](q)
|
||||||
var ms: MemSlice
|
var ms: MemSlice
|
||||||
|
|
@ -420,7 +420,7 @@ iterator memSlices*(mfile: MemFile, delim = '\l', eat = '\r'): MemSlice {.inline
|
||||||
ms.data = mfile.mem
|
ms.data = mfile.mem
|
||||||
var remaining = mfile.size
|
var remaining = mfile.size
|
||||||
while remaining > 0:
|
while remaining > 0:
|
||||||
ending = c_memchr(ms.data, delim, remaining)
|
ending = c_memchr(ms.data, delim, csize_t(remaining))
|
||||||
if ending == nil: # unterminated final slice
|
if ending == nil: # unterminated final slice
|
||||||
ms.size = remaining # Weird case..check eat?
|
ms.size = remaining # Weird case..check eat?
|
||||||
yield ms
|
yield ms
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ when not useWinVersion:
|
||||||
|
|
||||||
else:
|
else:
|
||||||
proc toInt(domain: Domain): cint =
|
proc toInt(domain: Domain): cint =
|
||||||
result = toU32(ord(domain)).cint
|
result = cast[cint](uint32(ord(domain)))
|
||||||
|
|
||||||
proc toKnownDomain*(family: cint): Option[Domain] =
|
proc toKnownDomain*(family: cint): Option[Domain] =
|
||||||
## Converts the platform-dependent `cint` to the Domain or none(),
|
## Converts the platform-dependent `cint` to the Domain or none(),
|
||||||
|
|
@ -375,9 +375,9 @@ when not useNimNetLite:
|
||||||
##
|
##
|
||||||
## On posix this will search through the `/etc/services` file.
|
## On posix this will search through the `/etc/services` file.
|
||||||
when useWinVersion:
|
when useWinVersion:
|
||||||
var s = winlean.getservbyport(ze(int16(port)).cint, proto)
|
var s = winlean.getservbyport(uint16(port).cint, proto)
|
||||||
else:
|
else:
|
||||||
var s = posix.getservbyport(ze(int16(port)).cint, proto)
|
var s = posix.getservbyport(uint16(port).cint, proto)
|
||||||
if s == nil: raiseOSError(osLastError(), "Service not found.")
|
if s == nil: raiseOSError(osLastError(), "Service not found.")
|
||||||
result.name = $s.s_name
|
result.name = $s.s_name
|
||||||
result.aliases = cstringArrayToSeq(s.s_aliases)
|
result.aliases = cstringArrayToSeq(s.s_aliases)
|
||||||
|
|
|
||||||
|
|
@ -3121,7 +3121,7 @@ when defined(haiku):
|
||||||
B_FIND_PATH_IMAGE_PATH = 1000
|
B_FIND_PATH_IMAGE_PATH = 1000
|
||||||
|
|
||||||
proc find_path(codePointer: pointer, baseDirectory: cint, subPath: cstring,
|
proc find_path(codePointer: pointer, baseDirectory: cint, subPath: cstring,
|
||||||
pathBuffer: cstring, bufferSize: csize): int32
|
pathBuffer: cstring, bufferSize: csize_t): int32
|
||||||
{.importc, header: "<FindDirectory.h>".}
|
{.importc, header: "<FindDirectory.h>".}
|
||||||
|
|
||||||
proc getApplHaiku(): string =
|
proc getApplHaiku(): string =
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ when defined(haiku):
|
||||||
proc find_paths_etc(architecture: cstring, baseDirectory: cint,
|
proc find_paths_etc(architecture: cstring, baseDirectory: cint,
|
||||||
subPath: cstring, flags: uint32,
|
subPath: cstring, flags: uint32,
|
||||||
paths: var ptr UncheckedArray[cstring],
|
paths: var ptr UncheckedArray[cstring],
|
||||||
pathCount: var csize): int32
|
pathCount: var csize_t): int32
|
||||||
{.importc, header: "<FindDirectory.h>".}
|
{.importc, header: "<FindDirectory.h>".}
|
||||||
proc free(p: pointer) {.importc, header: "<stdlib.h>".}
|
proc free(p: pointer) {.importc, header: "<stdlib.h>".}
|
||||||
|
|
||||||
|
|
@ -137,7 +137,7 @@ iterator scanSSLCertificates*(useEnvVars = false): string =
|
||||||
else:
|
else:
|
||||||
var
|
var
|
||||||
paths: ptr UncheckedArray[cstring]
|
paths: ptr UncheckedArray[cstring]
|
||||||
size: csize
|
size: csize_t
|
||||||
let err = find_paths_etc(
|
let err = find_paths_etc(
|
||||||
nil, B_FIND_PATH_DATA_DIRECTORY, "ssl/CARootCertificates.pem",
|
nil, B_FIND_PATH_DATA_DIRECTORY, "ssl/CARootCertificates.pem",
|
||||||
B_FIND_PATH_EXISTING_ONLY, paths, size
|
B_FIND_PATH_EXISTING_ONLY, paths, size
|
||||||
|
|
|
||||||
|
|
@ -644,9 +644,9 @@ proc setForegroundColor*(f: File, fg: ForegroundColor, bright = false) =
|
||||||
0, # fg8Bit not supported, see `enableTrueColors` instead.
|
0, # fg8Bit not supported, see `enableTrueColors` instead.
|
||||||
0] # unused
|
0] # unused
|
||||||
if fg == fgDefault:
|
if fg == fgDefault:
|
||||||
discard setConsoleTextAttribute(h, toU16(old or defaultForegroundColor))
|
discard setConsoleTextAttribute(h, cast[int16](cast[uint16](old) or cast[uint16](defaultForegroundColor)))
|
||||||
else:
|
else:
|
||||||
discard setConsoleTextAttribute(h, toU16(old or lookup[fg]))
|
discard setConsoleTextAttribute(h, cast[int16](cast[uint16](old) or cast[uint16](lookup[fg])))
|
||||||
else:
|
else:
|
||||||
gFG = ord(fg)
|
gFG = ord(fg)
|
||||||
if bright: inc(gFG, 60)
|
if bright: inc(gFG, 60)
|
||||||
|
|
@ -673,9 +673,9 @@ proc setBackgroundColor*(f: File, bg: BackgroundColor, bright = false) =
|
||||||
0, # bg8Bit not supported, see `enableTrueColors` instead.
|
0, # bg8Bit not supported, see `enableTrueColors` instead.
|
||||||
0] # unused
|
0] # unused
|
||||||
if bg == bgDefault:
|
if bg == bgDefault:
|
||||||
discard setConsoleTextAttribute(h, toU16(old or defaultBackgroundColor))
|
discard setConsoleTextAttribute(h, cast[int16](cast[uint16](old) or cast[uint16](defaultBackgroundColor)))
|
||||||
else:
|
else:
|
||||||
discard setConsoleTextAttribute(h, toU16(old or lookup[bg]))
|
discard setConsoleTextAttribute(h, cast[int16](cast[uint16](old) or cast[uint16](lookup[bg])))
|
||||||
else:
|
else:
|
||||||
gBG = ord(bg)
|
gBG = ord(bg)
|
||||||
if bright: inc(gBG, 60)
|
if bright: inc(gBG, 60)
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,13 @@ type
|
||||||
FileHandle* = cint ## type that represents an OS file handle; this is
|
FileHandle* = cint ## type that represents an OS file handle; this is
|
||||||
## useful for low-level file access
|
## useful for low-level file access
|
||||||
|
|
||||||
|
FileSeekPos* = enum ## Position relative to which seek should happen.
|
||||||
|
# The values are ordered so that they match with stdio
|
||||||
|
# SEEK_SET, SEEK_CUR and SEEK_END respectively.
|
||||||
|
fspSet ## Seek to absolute value
|
||||||
|
fspCur ## Seek relative to current position
|
||||||
|
fspEnd ## Seek relative to end
|
||||||
|
|
||||||
# text file handling:
|
# text file handling:
|
||||||
when not defined(nimscript) and not defined(js):
|
when not defined(nimscript) and not defined(js):
|
||||||
# duplicated between io and ansi_c
|
# duplicated between io and ansi_c
|
||||||
|
|
@ -142,13 +149,6 @@ proc c_fprintf(f: File, frmt: cstring): cint {.
|
||||||
proc c_fputc(c: char, f: File): cint {.
|
proc c_fputc(c: char, f: File): cint {.
|
||||||
importc: "fputc", header: "<stdio.h>".}
|
importc: "fputc", header: "<stdio.h>".}
|
||||||
|
|
||||||
# When running nim in android app, stdout goes nowhere, so echo gets ignored
|
|
||||||
# To redirect echo to the android logcat, use -d:androidNDK
|
|
||||||
when defined(androidNDK):
|
|
||||||
const ANDROID_LOG_VERBOSE = 2.cint
|
|
||||||
proc android_log_print(prio: cint, tag: cstring, fmt: cstring): cint
|
|
||||||
{.importc: "__android_log_print", header: "<android/log.h>", varargs, discardable.}
|
|
||||||
|
|
||||||
template sysFatal(exc, msg) =
|
template sysFatal(exc, msg) =
|
||||||
raise newException(exc, msg)
|
raise newException(exc, msg)
|
||||||
|
|
||||||
|
|
@ -791,52 +791,6 @@ proc setStdIoUnbuffered*() {.tags: [], benign.} =
|
||||||
when declared(stdin):
|
when declared(stdin):
|
||||||
discard c_setvbuf(stdin, nil, IONBF, 0)
|
discard c_setvbuf(stdin, nil, IONBF, 0)
|
||||||
|
|
||||||
when declared(stdout):
|
|
||||||
when defined(windows) and compileOption("threads"):
|
|
||||||
proc addSysExitProc(quitProc: proc() {.noconv.}) {.importc: "atexit", header: "<stdlib.h>".}
|
|
||||||
|
|
||||||
const insideRLocksModule = false
|
|
||||||
include "system/syslocks"
|
|
||||||
|
|
||||||
|
|
||||||
var echoLock: SysLock
|
|
||||||
initSysLock echoLock
|
|
||||||
addSysExitProc(proc() {.noconv.} = deinitSys(echoLock))
|
|
||||||
|
|
||||||
const stdOutLock = not defined(windows) and
|
|
||||||
not defined(android) and
|
|
||||||
not defined(nintendoswitch) and
|
|
||||||
not defined(freertos) and
|
|
||||||
not defined(zephyr) and
|
|
||||||
hostOS != "any"
|
|
||||||
|
|
||||||
proc echoBinSafe(args: openArray[string]) {.compilerproc.} =
|
|
||||||
when defined(androidNDK):
|
|
||||||
var s = ""
|
|
||||||
for arg in args:
|
|
||||||
s.add arg
|
|
||||||
android_log_print(ANDROID_LOG_VERBOSE, "nim", s)
|
|
||||||
else:
|
|
||||||
# flockfile deadlocks some versions of Android 5.x.x
|
|
||||||
when stdOutLock:
|
|
||||||
proc flockfile(f: File) {.importc, nodecl.}
|
|
||||||
proc funlockfile(f: File) {.importc, nodecl.}
|
|
||||||
flockfile(stdout)
|
|
||||||
when defined(windows) and compileOption("threads"):
|
|
||||||
acquireSys echoLock
|
|
||||||
for s in args:
|
|
||||||
when defined(windows):
|
|
||||||
writeWindows(stdout, s)
|
|
||||||
else:
|
|
||||||
discard c_fwrite(s.cstring, cast[csize_t](s.len), 1, stdout)
|
|
||||||
const linefeed = "\n"
|
|
||||||
discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout)
|
|
||||||
discard c_fflush(stdout)
|
|
||||||
when stdOutLock:
|
|
||||||
funlockfile(stdout)
|
|
||||||
when defined(windows) and compileOption("threads"):
|
|
||||||
releaseSys echoLock
|
|
||||||
|
|
||||||
|
|
||||||
when defined(windows) and not defined(nimscript) and not defined(js):
|
when defined(windows) and not defined(nimscript) and not defined(js):
|
||||||
# work-around C's sucking abstraction:
|
# work-around C's sucking abstraction:
|
||||||
|
|
@ -960,3 +914,7 @@ iterator lines*(f: File): string {.tags: [ReadIOEffect].} =
|
||||||
result.lines += 1
|
result.lines += 1
|
||||||
var res = newStringOfCap(80)
|
var res = newStringOfCap(80)
|
||||||
while f.readLine(res): yield res
|
while f.readLine(res): yield res
|
||||||
|
|
||||||
|
template `&=`*(f: File, x: typed) =
|
||||||
|
## An alias for `write`.
|
||||||
|
write(f, x)
|
||||||
|
|
|
||||||
967
lib/system.nim
967
lib/system.nim
File diff suppressed because it is too large
Load diff
|
|
@ -180,6 +180,8 @@ proc c_printf*(frmt: cstring): cint {.
|
||||||
|
|
||||||
proc c_fputs*(c: cstring, f: CFilePtr): cint {.
|
proc c_fputs*(c: cstring, f: CFilePtr): cint {.
|
||||||
importc: "fputs", header: "<stdio.h>", discardable.}
|
importc: "fputs", header: "<stdio.h>", discardable.}
|
||||||
|
proc c_fputc*(c: char, f: CFilePtr): cint {.
|
||||||
|
importc: "fputc", header: "<stdio.h>", discardable.}
|
||||||
|
|
||||||
proc c_sprintf*(buf, frmt: cstring): cint {.
|
proc c_sprintf*(buf, frmt: cstring): cint {.
|
||||||
importc: "sprintf", header: "<stdio.h>", varargs, noSideEffect.}
|
importc: "sprintf", header: "<stdio.h>", varargs, noSideEffect.}
|
||||||
|
|
@ -212,7 +214,7 @@ else:
|
||||||
proc c_fwrite*(buf: pointer, size, n: csize_t, f: CFilePtr): cint {.
|
proc c_fwrite*(buf: pointer, size, n: csize_t, f: CFilePtr): cint {.
|
||||||
importc: "fwrite", header: "<stdio.h>".}
|
importc: "fwrite", header: "<stdio.h>".}
|
||||||
|
|
||||||
proc c_fflush(f: CFilePtr): cint {.
|
proc c_fflush*(f: CFilePtr): cint {.
|
||||||
importc: "fflush", header: "<stdio.h>".}
|
importc: "fflush", header: "<stdio.h>".}
|
||||||
|
|
||||||
proc rawWriteString*(f: CFilePtr, s: cstring, length: int) {.compilerproc, nonReloadable, inline.} =
|
proc rawWriteString*(f: CFilePtr, s: cstring, length: int) {.compilerproc, nonReloadable, inline.} =
|
||||||
|
|
|
||||||
|
|
@ -45,109 +45,6 @@ proc dec*[T: Ordinal](x: var T, y = 1) {.magic: "Dec", noSideEffect.} =
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# built-in operators
|
# built-in operators
|
||||||
|
|
||||||
when defined(nimNoZeroExtendMagic):
|
|
||||||
proc ze*(x: int8): int {.deprecated.} =
|
|
||||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
cast[int](uint(cast[uint8](x)))
|
|
||||||
|
|
||||||
proc ze*(x: int16): int {.deprecated.} =
|
|
||||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
cast[int](uint(cast[uint16](x)))
|
|
||||||
|
|
||||||
proc ze64*(x: int8): int64 {.deprecated.} =
|
|
||||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
cast[int64](uint64(cast[uint8](x)))
|
|
||||||
|
|
||||||
proc ze64*(x: int16): int64 {.deprecated.} =
|
|
||||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
cast[int64](uint64(cast[uint16](x)))
|
|
||||||
|
|
||||||
proc ze64*(x: int32): int64 {.deprecated.} =
|
|
||||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
cast[int64](uint64(cast[uint32](x)))
|
|
||||||
|
|
||||||
proc ze64*(x: int): int64 {.deprecated.} =
|
|
||||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
|
||||||
## unsigned. Does nothing if the size of an `int` is the same as `int64`.
|
|
||||||
## (This is the case on 64 bit processors.)
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
cast[int64](uint64(cast[uint](x)))
|
|
||||||
|
|
||||||
proc toU8*(x: int): int8 {.deprecated.} =
|
|
||||||
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
|
||||||
## from `x`.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
cast[int8](x)
|
|
||||||
|
|
||||||
proc toU16*(x: int): int16 {.deprecated.} =
|
|
||||||
## treats `x` as unsigned and converts it to an `int16` by taking the last
|
|
||||||
## 16 bits from `x`.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
cast[int16](x)
|
|
||||||
|
|
||||||
proc toU32*(x: int64): int32 {.deprecated.} =
|
|
||||||
## treats `x` as unsigned and converts it to an `int32` by taking the
|
|
||||||
## last 32 bits from `x`.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
cast[int32](x)
|
|
||||||
|
|
||||||
elif not defined(js):
|
|
||||||
proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect, deprecated.}
|
|
||||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
|
|
||||||
proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect, deprecated.}
|
|
||||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
|
|
||||||
proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect, deprecated.}
|
|
||||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
|
|
||||||
proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect, deprecated.}
|
|
||||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
|
|
||||||
proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect, deprecated.}
|
|
||||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
|
|
||||||
proc ze64*(x: int): int64 {.magic: "ZeIToI64", noSideEffect, deprecated.}
|
|
||||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
|
||||||
## unsigned. Does nothing if the size of an `int` is the same as `int64`.
|
|
||||||
## (This is the case on 64 bit processors.)
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
|
|
||||||
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect, deprecated.}
|
|
||||||
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
|
||||||
## from `x`.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
|
|
||||||
proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect, deprecated.}
|
|
||||||
## treats `x` as unsigned and converts it to an `int16` by taking the last
|
|
||||||
## 16 bits from `x`.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
|
|
||||||
proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect, deprecated.}
|
|
||||||
## treats `x` as unsigned and converts it to an `int32` by taking the
|
|
||||||
## last 32 bits from `x`.
|
|
||||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
|
||||||
|
|
||||||
# integer calculations:
|
# integer calculations:
|
||||||
proc `+`*(x: int): int {.magic: "UnaryPlusI", noSideEffect.}
|
proc `+`*(x: int): int {.magic: "UnaryPlusI", noSideEffect.}
|
||||||
## Unary `+` operator for an integer. Has no effect.
|
## Unary `+` operator for an integer. Has no effect.
|
||||||
|
|
@ -399,6 +296,59 @@ proc `mod`*(x, y: uint16): uint16 {.magic: "ModU", noSideEffect.}
|
||||||
proc `mod`*(x, y: uint32): uint32 {.magic: "ModU", noSideEffect.}
|
proc `mod`*(x, y: uint32): uint32 {.magic: "ModU", noSideEffect.}
|
||||||
proc `mod`*(x, y: uint64): uint64 {.magic: "ModU", noSideEffect.}
|
proc `mod`*(x, y: uint64): uint64 {.magic: "ModU", noSideEffect.}
|
||||||
|
|
||||||
|
proc `+=`*[T: SomeInteger](x: var T, y: T) {.
|
||||||
|
magic: "Inc", noSideEffect.}
|
||||||
|
## Increments an integer.
|
||||||
|
|
||||||
|
proc `-=`*[T: SomeInteger](x: var T, y: T) {.
|
||||||
|
magic: "Dec", noSideEffect.}
|
||||||
|
## Decrements an integer.
|
||||||
|
|
||||||
|
proc `*=`*[T: SomeInteger](x: var T, y: T) {.
|
||||||
|
inline, noSideEffect.} =
|
||||||
|
## Binary `*=` operator for integers.
|
||||||
|
x = x * y
|
||||||
|
|
||||||
|
# floating point operations:
|
||||||
|
proc `+`*(x: float32): float32 {.magic: "UnaryPlusF64", noSideEffect.}
|
||||||
|
proc `-`*(x: float32): float32 {.magic: "UnaryMinusF64", noSideEffect.}
|
||||||
|
proc `+`*(x, y: float32): float32 {.magic: "AddF64", noSideEffect.}
|
||||||
|
proc `-`*(x, y: float32): float32 {.magic: "SubF64", noSideEffect.}
|
||||||
|
proc `*`*(x, y: float32): float32 {.magic: "MulF64", noSideEffect.}
|
||||||
|
proc `/`*(x, y: float32): float32 {.magic: "DivF64", noSideEffect.}
|
||||||
|
|
||||||
|
proc `+`*(x: float): float {.magic: "UnaryPlusF64", noSideEffect.}
|
||||||
|
proc `-`*(x: float): float {.magic: "UnaryMinusF64", noSideEffect.}
|
||||||
|
proc `+`*(x, y: float): float {.magic: "AddF64", noSideEffect.}
|
||||||
|
proc `-`*(x, y: float): float {.magic: "SubF64", noSideEffect.}
|
||||||
|
proc `*`*(x, y: float): float {.magic: "MulF64", noSideEffect.}
|
||||||
|
proc `/`*(x, y: float): float {.magic: "DivF64", noSideEffect.}
|
||||||
|
|
||||||
|
proc `+=`*[T: float|float32|float64] (x: var T, y: T) {.
|
||||||
|
inline, noSideEffect.} =
|
||||||
|
## Increments in place a floating point number.
|
||||||
|
x = x + y
|
||||||
|
|
||||||
|
proc `-=`*[T: float|float32|float64] (x: var T, y: T) {.
|
||||||
|
inline, noSideEffect.} =
|
||||||
|
## Decrements in place a floating point number.
|
||||||
|
x = x - y
|
||||||
|
|
||||||
|
proc `*=`*[T: float|float32|float64] (x: var T, y: T) {.
|
||||||
|
inline, noSideEffect.} =
|
||||||
|
## Multiplies in place a floating point number.
|
||||||
|
x = x * y
|
||||||
|
|
||||||
|
proc `/=`*(x: var float64, y: float64) {.inline, noSideEffect.} =
|
||||||
|
## Divides in place a floating point number.
|
||||||
|
x = x / y
|
||||||
|
|
||||||
|
proc `/=`*[T: float|float32](x: var T, y: T) {.inline, noSideEffect.} =
|
||||||
|
## Divides in place a floating point number.
|
||||||
|
x = x / y
|
||||||
|
|
||||||
|
# the following have to be included in system, not imported for some reason:
|
||||||
|
|
||||||
proc `+%`*(x, y: int): int {.inline.} =
|
proc `+%`*(x, y: int): int {.inline.} =
|
||||||
## Treats `x` and `y` as unsigned and adds them.
|
## Treats `x` and `y` as unsigned and adds them.
|
||||||
##
|
##
|
||||||
|
|
@ -454,15 +404,106 @@ proc `%%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) mod cast
|
||||||
proc `%%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) mod cast[uint32](y))
|
proc `%%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) mod cast[uint32](y))
|
||||||
proc `%%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) mod cast[uint64](y))
|
proc `%%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) mod cast[uint64](y))
|
||||||
|
|
||||||
proc `+=`*[T: SomeInteger](x: var T, y: T) {.
|
when not defined(nimPreviewSlimSystem):
|
||||||
magic: "Inc", noSideEffect.}
|
when defined(nimNoZeroExtendMagic):
|
||||||
## Increments an integer.
|
proc ze*(x: int8): int {.deprecated.} =
|
||||||
|
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
cast[int](uint(cast[uint8](x)))
|
||||||
|
|
||||||
proc `-=`*[T: SomeInteger](x: var T, y: T) {.
|
proc ze*(x: int16): int {.deprecated.} =
|
||||||
magic: "Dec", noSideEffect.}
|
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||||
## Decrements an integer.
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
cast[int](uint(cast[uint16](x)))
|
||||||
|
|
||||||
proc `*=`*[T: SomeInteger](x: var T, y: T) {.
|
proc ze64*(x: int8): int64 {.deprecated.} =
|
||||||
inline, noSideEffect.} =
|
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||||
## Binary `*=` operator for integers.
|
## unsigned.
|
||||||
x = x * y
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
cast[int64](uint64(cast[uint8](x)))
|
||||||
|
|
||||||
|
proc ze64*(x: int16): int64 {.deprecated.} =
|
||||||
|
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
cast[int64](uint64(cast[uint16](x)))
|
||||||
|
|
||||||
|
proc ze64*(x: int32): int64 {.deprecated.} =
|
||||||
|
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
cast[int64](uint64(cast[uint32](x)))
|
||||||
|
|
||||||
|
proc ze64*(x: int): int64 {.deprecated.} =
|
||||||
|
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||||
|
## unsigned. Does nothing if the size of an `int` is the same as `int64`.
|
||||||
|
## (This is the case on 64 bit processors.)
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
cast[int64](uint64(cast[uint](x)))
|
||||||
|
|
||||||
|
proc toU8*(x: int): int8 {.deprecated.} =
|
||||||
|
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
||||||
|
## from `x`.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
cast[int8](x)
|
||||||
|
|
||||||
|
proc toU16*(x: int): int16 {.deprecated.} =
|
||||||
|
## treats `x` as unsigned and converts it to an `int16` by taking the last
|
||||||
|
## 16 bits from `x`.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
cast[int16](x)
|
||||||
|
|
||||||
|
proc toU32*(x: int64): int32 {.deprecated.} =
|
||||||
|
## treats `x` as unsigned and converts it to an `int32` by taking the
|
||||||
|
## last 32 bits from `x`.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
cast[int32](x)
|
||||||
|
|
||||||
|
elif not defined(js):
|
||||||
|
proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect, deprecated.}
|
||||||
|
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect, deprecated.}
|
||||||
|
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect, deprecated.}
|
||||||
|
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect, deprecated.}
|
||||||
|
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect, deprecated.}
|
||||||
|
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc ze64*(x: int): int64 {.magic: "ZeIToI64", noSideEffect, deprecated.}
|
||||||
|
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||||
|
## unsigned. Does nothing if the size of an `int` is the same as `int64`.
|
||||||
|
## (This is the case on 64 bit processors.)
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect, deprecated.}
|
||||||
|
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
||||||
|
## from `x`.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect, deprecated.}
|
||||||
|
## treats `x` as unsigned and converts it to an `int16` by taking the last
|
||||||
|
## 16 bits from `x`.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect, deprecated.}
|
||||||
|
## treats `x` as unsigned and converts it to an `int32` by taking the
|
||||||
|
## last 32 bits from `x`.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,45 @@
|
||||||
type
|
type
|
||||||
int* {.magic: "Int".} ## Default integer type; bitwidth depends on
|
int* {.magic: Int.} ## Default integer type; bitwidth depends on
|
||||||
## architecture, but is always the same as a pointer.
|
## architecture, but is always the same as a pointer.
|
||||||
int8* {.magic: "Int8".} ## Signed 8 bit integer type.
|
int8* {.magic: Int8.} ## Signed 8 bit integer type.
|
||||||
int16* {.magic: "Int16".} ## Signed 16 bit integer type.
|
int16* {.magic: Int16.} ## Signed 16 bit integer type.
|
||||||
int32* {.magic: "Int32".} ## Signed 32 bit integer type.
|
int32* {.magic: Int32.} ## Signed 32 bit integer type.
|
||||||
int64* {.magic: "Int64".} ## Signed 64 bit integer type.
|
int64* {.magic: Int64.} ## Signed 64 bit integer type.
|
||||||
uint* {.magic: "UInt".} ## Unsigned default integer type.
|
uint* {.magic: UInt.} ## Unsigned default integer type.
|
||||||
uint8* {.magic: "UInt8".} ## Unsigned 8 bit integer type.
|
uint8* {.magic: UInt8.} ## Unsigned 8 bit integer type.
|
||||||
uint16* {.magic: "UInt16".} ## Unsigned 16 bit integer type.
|
uint16* {.magic: UInt16.} ## Unsigned 16 bit integer type.
|
||||||
uint32* {.magic: "UInt32".} ## Unsigned 32 bit integer type.
|
uint32* {.magic: UInt32.} ## Unsigned 32 bit integer type.
|
||||||
uint64* {.magic: "UInt64".} ## Unsigned 64 bit integer type.
|
uint64* {.magic: UInt64.} ## Unsigned 64 bit integer type.
|
||||||
|
|
||||||
|
type
|
||||||
|
float* {.magic: Float.} ## Default floating point type.
|
||||||
|
float32* {.magic: Float32.} ## 32 bit floating point type.
|
||||||
|
float64* {.magic: Float.} ## 64 bit floating point type.
|
||||||
|
|
||||||
|
# 'float64' is now an alias to 'float'; this solves many problems
|
||||||
|
|
||||||
|
type
|
||||||
|
char* {.magic: Char.} ## Built-in 8 bit character type (unsigned).
|
||||||
|
string* {.magic: String.} ## Built-in string type.
|
||||||
|
cstring* {.magic: Cstring.} ## Built-in cstring (*compatible string*) type.
|
||||||
|
pointer* {.magic: Pointer.} ## Built-in pointer type, use the `addr`
|
||||||
|
## operator to get a pointer to a variable.
|
||||||
|
|
||||||
|
typedesc* {.magic: TypeDesc.} ## Meta type to denote a type description.
|
||||||
|
|
||||||
|
type
|
||||||
|
`ptr`*[T] {.magic: Pointer.} ## Built-in generic untraced pointer type.
|
||||||
|
`ref`*[T] {.magic: Pointer.} ## Built-in generic traced pointer type.
|
||||||
|
|
||||||
|
`nil` {.magic: "Nil".}
|
||||||
|
|
||||||
|
void* {.magic: "VoidType".} ## Meta type to denote the absence of any type.
|
||||||
|
auto* {.magic: Expr.} ## Meta type for automatic type determination.
|
||||||
|
any* {.deprecated: "Deprecated since v1.5; Use auto instead.".} = distinct auto ## Deprecated; Use `auto` instead. See https://github.com/nim-lang/RFCs/issues/281
|
||||||
|
untyped* {.magic: Expr.} ## Meta type to denote an expression that
|
||||||
|
## is not resolved (for templates).
|
||||||
|
typed* {.magic: Stmt.} ## Meta type to denote an expression that
|
||||||
|
## is resolved (for templates).
|
||||||
|
|
||||||
type # we need to start a new type section here, so that ``0`` can have a type
|
type # we need to start a new type section here, so that ``0`` can have a type
|
||||||
bool* {.magic: "Bool".} = enum ## Built-in boolean type.
|
bool* {.magic: "Bool".} = enum ## Built-in boolean type.
|
||||||
|
|
@ -29,15 +59,16 @@ type
|
||||||
SomeInteger* = SomeSignedInt|SomeUnsignedInt
|
SomeInteger* = SomeSignedInt|SomeUnsignedInt
|
||||||
## Type class matching all integer types.
|
## Type class matching all integer types.
|
||||||
|
|
||||||
|
SomeFloat* = float|float32|float64
|
||||||
|
## Type class matching all floating point number types.
|
||||||
|
|
||||||
|
SomeNumber* = SomeInteger|SomeFloat
|
||||||
|
## Type class matching all number types.
|
||||||
|
|
||||||
SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint|uint8|uint16|uint32|uint64
|
SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint|uint8|uint16|uint32|uint64
|
||||||
## Type class matching all ordinal types; however this includes enums with
|
## Type class matching all ordinal types; however this includes enums with
|
||||||
## holes. See also `Ordinal`
|
## holes. See also `Ordinal`
|
||||||
|
|
||||||
BiggestInt* = int64
|
|
||||||
## is an alias for the biggest signed integer type the Nim compiler
|
|
||||||
## supports. Currently this is `int64`, but it is platform-dependent
|
|
||||||
## in general.
|
|
||||||
|
|
||||||
|
|
||||||
{.push warning[GcMem]: off, warning[Uninit]: off.}
|
{.push warning[GcMem]: off, warning[Uninit]: off.}
|
||||||
{.push hints: off.}
|
{.push hints: off.}
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,11 @@ proc raiseFieldError(f: string) {.compilerproc, noinline.} =
|
||||||
when defined(nimV2):
|
when defined(nimV2):
|
||||||
proc raiseFieldError2(f: string, discVal: int) {.compilerproc, noinline.} =
|
proc raiseFieldError2(f: string, discVal: int) {.compilerproc, noinline.} =
|
||||||
## raised when field is inaccessible given runtime value of discriminant
|
## raised when field is inaccessible given runtime value of discriminant
|
||||||
sysFatal(FieldError, f & $discVal & "'")
|
sysFatal(FieldDefect, f & $discVal & "'")
|
||||||
else:
|
else:
|
||||||
proc raiseFieldError2(f: string, discVal: string) {.compilerproc, noinline.} =
|
proc raiseFieldError2(f: string, discVal: string) {.compilerproc, noinline.} =
|
||||||
## raised when field is inaccessible given runtime value of discriminant
|
## raised when field is inaccessible given runtime value of discriminant
|
||||||
sysFatal(FieldError, formatFieldDefect(f, discVal))
|
sysFatal(FieldDefect, formatFieldDefect(f, discVal))
|
||||||
|
|
||||||
proc raiseRangeErrorI(i, a, b: BiggestInt) {.compilerproc, noinline.} =
|
proc raiseRangeErrorI(i, a, b: BiggestInt) {.compilerproc, noinline.} =
|
||||||
when defined(standalone):
|
when defined(standalone):
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,14 @@ proc `==`*(x, y: uint16): bool {.magic: "EqI", noSideEffect.}
|
||||||
proc `==`*(x, y: uint32): bool {.magic: "EqI", noSideEffect.}
|
proc `==`*(x, y: uint32): bool {.magic: "EqI", noSideEffect.}
|
||||||
proc `==`*(x, y: uint64): bool {.magic: "EqI", noSideEffect.}
|
proc `==`*(x, y: uint64): bool {.magic: "EqI", noSideEffect.}
|
||||||
|
|
||||||
|
proc `<=`*(x, y: float32): bool {.magic: "LeF64", noSideEffect.}
|
||||||
|
proc `<=`*(x, y: float): bool {.magic: "LeF64", noSideEffect.}
|
||||||
|
|
||||||
|
proc `<`*(x, y: float32): bool {.magic: "LtF64", noSideEffect.}
|
||||||
|
proc `<`*(x, y: float): bool {.magic: "LtF64", noSideEffect.}
|
||||||
|
|
||||||
|
proc `==`*(x, y: float32): bool {.magic: "EqF64", noSideEffect.}
|
||||||
|
proc `==`*(x, y: float): bool {.magic: "EqF64", noSideEffect.}
|
||||||
|
|
||||||
{.push stackTrace: off.}
|
{.push stackTrace: off.}
|
||||||
|
|
||||||
|
|
@ -220,6 +228,13 @@ proc min*(x, y: int32): int32 {.magic: "MinI", noSideEffect.} =
|
||||||
proc min*(x, y: int64): int64 {.magic: "MinI", noSideEffect.} =
|
proc min*(x, y: int64): int64 {.magic: "MinI", noSideEffect.} =
|
||||||
## The minimum value of two integers.
|
## The minimum value of two integers.
|
||||||
if x <= y: x else: y
|
if x <= y: x else: y
|
||||||
|
proc min*(x, y: float32): float32 {.noSideEffect, inline.} =
|
||||||
|
if x <= y or y != y: x else: y
|
||||||
|
proc min*(x, y: float64): float64 {.noSideEffect, inline.} =
|
||||||
|
if x <= y or y != y: x else: y
|
||||||
|
proc min*[T: not SomeFloat](x, y: T): T {.inline.} =
|
||||||
|
## Generic minimum operator of 2 values based on `<=`.
|
||||||
|
if x <= y: x else: y
|
||||||
|
|
||||||
proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.} =
|
proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.} =
|
||||||
if y <= x: x else: y
|
if y <= x: x else: y
|
||||||
|
|
@ -232,6 +247,13 @@ proc max*(x, y: int32): int32 {.magic: "MaxI", noSideEffect.} =
|
||||||
proc max*(x, y: int64): int64 {.magic: "MaxI", noSideEffect.} =
|
proc max*(x, y: int64): int64 {.magic: "MaxI", noSideEffect.} =
|
||||||
## The maximum value of two integers.
|
## The maximum value of two integers.
|
||||||
if y <= x: x else: y
|
if y <= x: x else: y
|
||||||
|
proc max*(x, y: float32): float32 {.noSideEffect, inline.} =
|
||||||
|
if y <= x or y != y: x else: y
|
||||||
|
proc max*(x, y: float64): float64 {.noSideEffect, inline.} =
|
||||||
|
if y <= x or y != y: x else: y
|
||||||
|
proc max*[T: not SomeFloat](x, y: T): T {.inline.} =
|
||||||
|
## Generic maximum operator of 2 values based on `<=`.
|
||||||
|
if y <= x: x else: y
|
||||||
|
|
||||||
|
|
||||||
proc min*[T](x: openArray[T]): T =
|
proc min*[T](x: openArray[T]): T =
|
||||||
|
|
|
||||||
214
lib/system/compilation.nim
Normal file
214
lib/system/compilation.nim
Normal file
|
|
@ -0,0 +1,214 @@
|
||||||
|
const
|
||||||
|
NimMajor* {.intdefine.}: int = 1
|
||||||
|
## is the major number of Nim's version. Example:
|
||||||
|
## ```
|
||||||
|
## when (NimMajor, NimMinor, NimPatch) >= (1, 3, 1): discard
|
||||||
|
## ```
|
||||||
|
# see also std/private/since
|
||||||
|
|
||||||
|
NimMinor* {.intdefine.}: int = 7
|
||||||
|
## is the minor number of Nim's version.
|
||||||
|
## Odd for devel, even for releases.
|
||||||
|
|
||||||
|
NimPatch* {.intdefine.}: int = 3
|
||||||
|
## is the patch number of Nim's version.
|
||||||
|
## Odd for devel, even for releases.
|
||||||
|
|
||||||
|
{.push profiler: off.}
|
||||||
|
let nimvm* {.magic: "Nimvm", compileTime.}: bool = false
|
||||||
|
## May be used only in `when` expression.
|
||||||
|
## It is true in Nim VM context and false otherwise.
|
||||||
|
{.pop.}
|
||||||
|
|
||||||
|
const
|
||||||
|
isMainModule* {.magic: "IsMainModule".}: bool = false
|
||||||
|
## True only when accessed in the main module. This works thanks to
|
||||||
|
## compiler magic. It is useful to embed testing code in a module.
|
||||||
|
|
||||||
|
CompileDate* {.magic: "CompileDate".}: string = "0000-00-00"
|
||||||
|
## The date (in UTC) of compilation as a string of the form
|
||||||
|
## `YYYY-MM-DD`. This works thanks to compiler magic.
|
||||||
|
|
||||||
|
CompileTime* {.magic: "CompileTime".}: string = "00:00:00"
|
||||||
|
## The time (in UTC) of compilation as a string of the form
|
||||||
|
## `HH:MM:SS`. This works thanks to compiler magic.
|
||||||
|
|
||||||
|
proc defined*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
|
||||||
|
## Special compile-time procedure that checks whether `x` is
|
||||||
|
## defined.
|
||||||
|
##
|
||||||
|
## `x` is an external symbol introduced through the compiler's
|
||||||
|
## `-d:x switch <nimc.html#compiler-usage-compileminustime-symbols>`_ to enable
|
||||||
|
## build time conditionals:
|
||||||
|
## ```
|
||||||
|
## when not defined(release):
|
||||||
|
## # Do here programmer friendly expensive sanity checks.
|
||||||
|
## # Put here the normal code
|
||||||
|
## ```
|
||||||
|
##
|
||||||
|
## See also:
|
||||||
|
## * `compileOption <#compileOption,string>`_ for `on|off` options
|
||||||
|
## * `compileOption <#compileOption,string,string>`_ for enum options
|
||||||
|
## * `define pragmas <manual.html#implementation-specific-pragmas-compileminustime-define-pragmas>`_
|
||||||
|
|
||||||
|
when defined(nimHasDeclaredMagic):
|
||||||
|
proc declared*(x: untyped): bool {.magic: "Declared", noSideEffect, compileTime.}
|
||||||
|
## Special compile-time procedure that checks whether `x` is
|
||||||
|
## declared. `x` has to be an identifier or a qualified identifier.
|
||||||
|
##
|
||||||
|
## This can be used to check whether a library provides a certain
|
||||||
|
## feature or not:
|
||||||
|
## ```
|
||||||
|
## when not declared(strutils.toUpper):
|
||||||
|
## # provide our own toUpper proc here, because strutils is
|
||||||
|
## # missing it.
|
||||||
|
## ```
|
||||||
|
##
|
||||||
|
## See also:
|
||||||
|
## * `declaredInScope <#declaredInScope,untyped>`_
|
||||||
|
else:
|
||||||
|
proc declared*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
|
||||||
|
|
||||||
|
when defined(nimHasDeclaredMagic):
|
||||||
|
proc declaredInScope*(x: untyped): bool {.magic: "DeclaredInScope", noSideEffect, compileTime.}
|
||||||
|
## Special compile-time procedure that checks whether `x` is
|
||||||
|
## declared in the current scope. `x` has to be an identifier.
|
||||||
|
else:
|
||||||
|
proc declaredInScope*(x: untyped): bool {.magic: "DefinedInScope", noSideEffect, compileTime.}
|
||||||
|
|
||||||
|
proc compiles*(x: untyped): bool {.magic: "Compiles", noSideEffect, compileTime.} =
|
||||||
|
## Special compile-time procedure that checks whether `x` can be compiled
|
||||||
|
## without any semantic error.
|
||||||
|
## This can be used to check whether a type supports some operation:
|
||||||
|
## ```
|
||||||
|
## when compiles(3 + 4):
|
||||||
|
## echo "'+' for integers is available"
|
||||||
|
## ```
|
||||||
|
discard
|
||||||
|
|
||||||
|
proc astToStr*[T](x: T): string {.magic: "AstToStr", noSideEffect.}
|
||||||
|
## Converts the AST of `x` into a string representation. This is very useful
|
||||||
|
## for debugging.
|
||||||
|
|
||||||
|
proc runnableExamples*(rdoccmd = "", body: untyped) {.magic: "RunnableExamples".} =
|
||||||
|
## A section you should use to mark `runnable example`:idx: code with.
|
||||||
|
##
|
||||||
|
## - In normal debug and release builds code within
|
||||||
|
## a `runnableExamples` section is ignored.
|
||||||
|
## - The documentation generator is aware of these examples and considers them
|
||||||
|
## part of the `##` doc comment. As the last step of documentation
|
||||||
|
## generation each runnableExample is put in its own file `$file_examples$i.nim`,
|
||||||
|
## compiled and tested. The collected examples are
|
||||||
|
## put into their own module to ensure the examples do not refer to
|
||||||
|
## non-exported symbols.
|
||||||
|
runnableExamples:
|
||||||
|
proc timesTwo*(x: int): int =
|
||||||
|
## This proc doubles a number.
|
||||||
|
runnableExamples:
|
||||||
|
# at module scope
|
||||||
|
const exported* = 123
|
||||||
|
assert timesTwo(5) == 10
|
||||||
|
block: # at block scope
|
||||||
|
defer: echo "done"
|
||||||
|
runnableExamples "-d:foo -b:cpp":
|
||||||
|
import std/compilesettings
|
||||||
|
assert querySetting(backend) == "cpp"
|
||||||
|
assert defined(foo)
|
||||||
|
runnableExamples "-r:off": ## this one is only compiled
|
||||||
|
import std/browsers
|
||||||
|
openDefaultBrowser "https://forum.nim-lang.org/"
|
||||||
|
2 * x
|
||||||
|
|
||||||
|
proc compileOption*(option: string): bool {.
|
||||||
|
magic: "CompileOption", noSideEffect.} =
|
||||||
|
## Can be used to determine an `on|off` compile-time option.
|
||||||
|
##
|
||||||
|
## See also:
|
||||||
|
## * `compileOption <#compileOption,string,string>`_ for enum options
|
||||||
|
## * `defined <#defined,untyped>`_
|
||||||
|
## * `std/compilesettings module <compilesettings.html>`_
|
||||||
|
runnableExamples("--floatChecks:off"):
|
||||||
|
static: doAssert not compileOption("floatchecks")
|
||||||
|
{.push floatChecks: on.}
|
||||||
|
static: doAssert compileOption("floatchecks")
|
||||||
|
# floating point NaN and Inf checks enabled in this scope
|
||||||
|
{.pop.}
|
||||||
|
|
||||||
|
proc compileOption*(option, arg: string): bool {.
|
||||||
|
magic: "CompileOptionArg", noSideEffect.} =
|
||||||
|
## Can be used to determine an enum compile-time option.
|
||||||
|
##
|
||||||
|
## See also:
|
||||||
|
## * `compileOption <#compileOption,string>`_ for `on|off` options
|
||||||
|
## * `defined <#defined,untyped>`_
|
||||||
|
## * `std/compilesettings module <compilesettings.html>`_
|
||||||
|
runnableExamples:
|
||||||
|
when compileOption("opt", "size") and compileOption("gc", "boehm"):
|
||||||
|
discard "compiled with optimization for size and uses Boehm's GC"
|
||||||
|
|
||||||
|
template currentSourcePath*: string = instantiationInfo(-1, true).filename
|
||||||
|
## Returns the full file-system path of the current source.
|
||||||
|
##
|
||||||
|
## To get the directory containing the current source, use it with
|
||||||
|
## `os.parentDir() <os.html#parentDir%2Cstring>`_ as `currentSourcePath.parentDir()`.
|
||||||
|
##
|
||||||
|
## The path returned by this template is set at compile time.
|
||||||
|
##
|
||||||
|
## See the docstring of `macros.getProjectPath() <macros.html#getProjectPath>`_
|
||||||
|
## for an example to see the distinction between the `currentSourcePath`
|
||||||
|
## and `getProjectPath`.
|
||||||
|
##
|
||||||
|
## See also:
|
||||||
|
## * `getCurrentDir proc <os.html#getCurrentDir>`_
|
||||||
|
|
||||||
|
proc slurp*(filename: string): string {.magic: "Slurp".}
|
||||||
|
## This is an alias for `staticRead <#staticRead,string>`_.
|
||||||
|
|
||||||
|
proc staticRead*(filename: string): string {.magic: "Slurp".}
|
||||||
|
## Compile-time `readFile <syncio.html#readFile,string>`_ proc for easy
|
||||||
|
## `resource`:idx: embedding:
|
||||||
|
##
|
||||||
|
## The maximum file size limit that `staticRead` and `slurp` can read is
|
||||||
|
## near or equal to the *free* memory of the device you are using to compile.
|
||||||
|
## ```
|
||||||
|
## const myResource = staticRead"mydatafile.bin"
|
||||||
|
## ```
|
||||||
|
##
|
||||||
|
## `slurp <#slurp,string>`_ is an alias for `staticRead`.
|
||||||
|
|
||||||
|
proc gorge*(command: string, input = "", cache = ""): string {.
|
||||||
|
magic: "StaticExec".} = discard
|
||||||
|
## This is an alias for `staticExec <#staticExec,string,string,string>`_.
|
||||||
|
|
||||||
|
proc staticExec*(command: string, input = "", cache = ""): string {.
|
||||||
|
magic: "StaticExec".} = discard
|
||||||
|
## Executes an external process at compile-time and returns its text output
|
||||||
|
## (stdout + stderr).
|
||||||
|
##
|
||||||
|
## If `input` is not an empty string, it will be passed as a standard input
|
||||||
|
## to the executed program.
|
||||||
|
## ```
|
||||||
|
## const buildInfo = "Revision " & staticExec("git rev-parse HEAD") &
|
||||||
|
## "\nCompiled on " & staticExec("uname -v")
|
||||||
|
## ```
|
||||||
|
##
|
||||||
|
## `gorge <#gorge,string,string,string>`_ is an alias for `staticExec`.
|
||||||
|
##
|
||||||
|
## Note that you can use this proc inside a pragma like
|
||||||
|
## `passc <manual.html#implementation-specific-pragmas-passc-pragma>`_ or
|
||||||
|
## `passl <manual.html#implementation-specific-pragmas-passl-pragma>`_.
|
||||||
|
##
|
||||||
|
## If `cache` is not empty, the results of `staticExec` are cached within
|
||||||
|
## the `nimcache` directory. Use `--forceBuild` to get rid of this caching
|
||||||
|
## behaviour then. `command & input & cache` (the concatenated string) is
|
||||||
|
## used to determine whether the entry in the cache is still valid. You can
|
||||||
|
## use versioning information for `cache`:
|
||||||
|
## ```
|
||||||
|
## const stateMachine = staticExec("dfaoptimizer", "input", "0.8.0")
|
||||||
|
## ```
|
||||||
|
|
||||||
|
proc gorgeEx*(command: string, input = "", cache = ""): tuple[output: string,
|
||||||
|
exitCode: int] =
|
||||||
|
## Similar to `gorge <#gorge,string,string,string>`_ but also returns the
|
||||||
|
## precious exit code.
|
||||||
|
discard
|
||||||
90
lib/system/ctypes.nim
Normal file
90
lib/system/ctypes.nim
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
## Some type definitions for compatibility between different
|
||||||
|
## backends and platforms.
|
||||||
|
|
||||||
|
type
|
||||||
|
BiggestInt* = int64
|
||||||
|
## is an alias for the biggest signed integer type the Nim compiler
|
||||||
|
## supports. Currently this is `int64`, but it is platform-dependent
|
||||||
|
## in general.
|
||||||
|
|
||||||
|
BiggestFloat* = float64
|
||||||
|
## is an alias for the biggest floating point type the Nim
|
||||||
|
## compiler supports. Currently this is `float64`, but it is
|
||||||
|
## platform-dependent in general.
|
||||||
|
|
||||||
|
when defined(js):
|
||||||
|
type BiggestUInt* = uint32
|
||||||
|
## is an alias for the biggest unsigned integer type the Nim compiler
|
||||||
|
## supports. Currently this is `uint32` for JS and `uint64` for other
|
||||||
|
## targets.
|
||||||
|
else:
|
||||||
|
type BiggestUInt* = uint64
|
||||||
|
## is an alias for the biggest unsigned integer type the Nim compiler
|
||||||
|
## supports. Currently this is `uint32` for JS and `uint64` for other
|
||||||
|
## targets.
|
||||||
|
|
||||||
|
when defined(windows):
|
||||||
|
type
|
||||||
|
clong* {.importc: "long", nodecl.} = int32
|
||||||
|
## This is the same as the type `long` in *C*.
|
||||||
|
culong* {.importc: "unsigned long", nodecl.} = uint32
|
||||||
|
## This is the same as the type `unsigned long` in *C*.
|
||||||
|
else:
|
||||||
|
type
|
||||||
|
clong* {.importc: "long", nodecl.} = int
|
||||||
|
## This is the same as the type `long` in *C*.
|
||||||
|
culong* {.importc: "unsigned long", nodecl.} = uint
|
||||||
|
## This is the same as the type `unsigned long` in *C*.
|
||||||
|
|
||||||
|
type # these work for most platforms:
|
||||||
|
cchar* {.importc: "char", nodecl.} = char
|
||||||
|
## This is the same as the type `char` in *C*.
|
||||||
|
cschar* {.importc: "signed char", nodecl.} = int8
|
||||||
|
## This is the same as the type `signed char` in *C*.
|
||||||
|
cshort* {.importc: "short", nodecl.} = int16
|
||||||
|
## This is the same as the type `short` in *C*.
|
||||||
|
cint* {.importc: "int", nodecl.} = int32
|
||||||
|
## This is the same as the type `int` in *C*.
|
||||||
|
csize_t* {.importc: "size_t", nodecl.} = uint
|
||||||
|
## This is the same as the type `size_t` in *C*.
|
||||||
|
clonglong* {.importc: "long long", nodecl.} = int64
|
||||||
|
## This is the same as the type `long long` in *C*.
|
||||||
|
cfloat* {.importc: "float", nodecl.} = float32
|
||||||
|
## This is the same as the type `float` in *C*.
|
||||||
|
cdouble* {.importc: "double", nodecl.} = float64
|
||||||
|
## This is the same as the type `double` in *C*.
|
||||||
|
clongdouble* {.importc: "long double", nodecl.} = BiggestFloat
|
||||||
|
## This is the same as the type `long double` in *C*.
|
||||||
|
## This C type is not supported by Nim's code generator.
|
||||||
|
|
||||||
|
cuchar* {.importc: "unsigned char", nodecl, deprecated: "use `char` or `uint8` instead".} = char
|
||||||
|
## Deprecated: Use `uint8` instead.
|
||||||
|
cushort* {.importc: "unsigned short", nodecl.} = uint16
|
||||||
|
## This is the same as the type `unsigned short` in *C*.
|
||||||
|
cuint* {.importc: "unsigned int", nodecl.} = uint32
|
||||||
|
## This is the same as the type `unsigned int` in *C*.
|
||||||
|
culonglong* {.importc: "unsigned long long", nodecl.} = uint64
|
||||||
|
## This is the same as the type `unsigned long long` in *C*.
|
||||||
|
|
||||||
|
type
|
||||||
|
ByteAddress* = int
|
||||||
|
## is the signed integer type that should be used for converting
|
||||||
|
## pointers to integer addresses for readability.
|
||||||
|
|
||||||
|
cstringArray* {.importc: "char**", nodecl.} = ptr UncheckedArray[cstring]
|
||||||
|
## This is binary compatible to the type `char**` in *C*. The array's
|
||||||
|
## high value is large enough to disable bounds checking in practice.
|
||||||
|
## Use `cstringArrayToSeq proc <#cstringArrayToSeq,cstringArray,Natural>`_
|
||||||
|
## to convert it into a `seq[string]`.
|
||||||
|
|
||||||
|
when not defined(nimPreviewSlimSystem):
|
||||||
|
# pollutes namespace
|
||||||
|
type
|
||||||
|
PFloat32* {.deprecated: "use `ptr float32`".} = ptr float32
|
||||||
|
## An alias for `ptr float32`.
|
||||||
|
PFloat64* {.deprecated: "use `ptr float64`".} = ptr float64
|
||||||
|
## An alias for `ptr float64`.
|
||||||
|
PInt64* {.deprecated: "use `ptr int64`".} = ptr int64
|
||||||
|
## An alias for `ptr int64`.
|
||||||
|
PInt32* {.deprecated: "use `ptr int32`".} = ptr int32
|
||||||
|
## An alias for `ptr int32`.
|
||||||
|
|
@ -1,61 +1,13 @@
|
||||||
const NimStackTraceMsgs =
|
## Exception and effect types used in Nim code.
|
||||||
when defined(nimHasStacktraceMsgs): compileOption("stacktraceMsgs")
|
|
||||||
else: false
|
|
||||||
|
|
||||||
type
|
type
|
||||||
RootEffect* {.compilerproc.} = object of RootObj ## \
|
|
||||||
## Base effect class.
|
|
||||||
##
|
|
||||||
## Each effect should inherit from `RootEffect` unless you know what
|
|
||||||
## you're doing.
|
|
||||||
TimeEffect* = object of RootEffect ## Time effect.
|
TimeEffect* = object of RootEffect ## Time effect.
|
||||||
IOEffect* = object of RootEffect ## IO effect.
|
IOEffect* = object of RootEffect ## IO effect.
|
||||||
ReadIOEffect* = object of IOEffect ## Effect describing a read IO operation.
|
ReadIOEffect* = object of IOEffect ## Effect describing a read IO operation.
|
||||||
WriteIOEffect* = object of IOEffect ## Effect describing a write IO operation.
|
WriteIOEffect* = object of IOEffect ## Effect describing a write IO operation.
|
||||||
ExecIOEffect* = object of IOEffect ## Effect describing an executing IO operation.
|
ExecIOEffect* = object of IOEffect ## Effect describing an executing IO operation.
|
||||||
|
|
||||||
StackTraceEntry* = object ## In debug mode exceptions store the stack trace that led
|
type
|
||||||
## to them. A `StackTraceEntry` is a single entry of the
|
|
||||||
## stack trace.
|
|
||||||
procname*: cstring ## Name of the proc that is currently executing.
|
|
||||||
line*: int ## Line number of the proc that is currently executing.
|
|
||||||
filename*: cstring ## Filename of the proc that is currently executing.
|
|
||||||
when NimStackTraceMsgs:
|
|
||||||
frameMsg*: string ## When a stacktrace is generated in a given frame and
|
|
||||||
## rendered at a later time, we should ensure the stacktrace
|
|
||||||
## data isn't invalidated; any pointer into PFrame is
|
|
||||||
## subject to being invalidated so shouldn't be stored.
|
|
||||||
when defined(nimStackTraceOverride):
|
|
||||||
programCounter*: uint ## Program counter - will be used to get the rest of the info,
|
|
||||||
## when `$` is called on this type. We can't use
|
|
||||||
## "cuintptr_t" in here.
|
|
||||||
procnameStr*, filenameStr*: string ## GC-ed alternatives to "procname" and "filename"
|
|
||||||
|
|
||||||
Exception* {.compilerproc, magic: "Exception".} = object of RootObj ## \
|
|
||||||
## Base exception class.
|
|
||||||
##
|
|
||||||
## Each exception has to inherit from `Exception`. See the full `exception
|
|
||||||
## hierarchy <manual.html#exception-handling-exception-hierarchy>`_.
|
|
||||||
parent*: ref Exception ## Parent exception (can be used as a stack).
|
|
||||||
name*: cstring ## The exception's name is its Nim identifier.
|
|
||||||
## This field is filled automatically in the
|
|
||||||
## `raise` statement.
|
|
||||||
msg* {.exportc: "message".}: string ## The exception's message. Not
|
|
||||||
## providing an exception message
|
|
||||||
## is bad style.
|
|
||||||
when defined(js):
|
|
||||||
trace: string
|
|
||||||
else:
|
|
||||||
trace: seq[StackTraceEntry]
|
|
||||||
up: ref Exception # used for stacking exceptions. Not exported!
|
|
||||||
|
|
||||||
Defect* = object of Exception ## \
|
|
||||||
## Abstract base class for all exceptions that Nim's runtime raises
|
|
||||||
## but that are strictly uncatchable as they can also be mapped to
|
|
||||||
## a `quit` / `trap` / `exit` operation.
|
|
||||||
|
|
||||||
CatchableError* = object of Exception ## \
|
|
||||||
## Abstract class for all exceptions that are catchable.
|
|
||||||
IOError* = object of CatchableError ## \
|
IOError* = object of CatchableError ## \
|
||||||
## Raised if an IO error occurred.
|
## Raised if an IO error occurred.
|
||||||
EOFError* = object of IOError ## \
|
EOFError* = object of IOError ## \
|
||||||
|
|
@ -144,6 +96,8 @@ type
|
||||||
##
|
##
|
||||||
## This is only raised if the `segfaults module <segfaults.html>`_ was imported!
|
## This is only raised if the `segfaults module <segfaults.html>`_ was imported!
|
||||||
|
|
||||||
|
when not defined(nimPreviewSlimSystem):
|
||||||
|
type
|
||||||
ArithmeticError* {.deprecated: "See corresponding Defect".} = ArithmeticDefect
|
ArithmeticError* {.deprecated: "See corresponding Defect".} = ArithmeticDefect
|
||||||
DivByZeroError* {.deprecated: "See corresponding Defect".} = DivByZeroDefect
|
DivByZeroError* {.deprecated: "See corresponding Defect".} = DivByZeroDefect
|
||||||
OverflowError* {.deprecated: "See corresponding Defect".} = OverflowDefect
|
OverflowError* {.deprecated: "See corresponding Defect".} = OverflowDefect
|
||||||
|
|
|
||||||
156
lib/system/indices.nim
Normal file
156
lib/system/indices.nim
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
type
|
||||||
|
BackwardsIndex* = distinct int ## Type that is constructed by `^` for
|
||||||
|
## reversed array accesses.
|
||||||
|
## (See `^ template <#^.t,int>`_)
|
||||||
|
|
||||||
|
template `^`*(x: int): BackwardsIndex = BackwardsIndex(x)
|
||||||
|
## Builtin `roof`:idx: operator that can be used for convenient array access.
|
||||||
|
## `a[^x]` is a shortcut for `a[a.len-x]`.
|
||||||
|
##
|
||||||
|
## ```
|
||||||
|
## let
|
||||||
|
## a = [1, 3, 5, 7, 9]
|
||||||
|
## b = "abcdefgh"
|
||||||
|
##
|
||||||
|
## echo a[^1] # => 9
|
||||||
|
## echo b[^2] # => g
|
||||||
|
## ```
|
||||||
|
|
||||||
|
proc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline.} =
|
||||||
|
system.`[]`(s, s.len - int(i))
|
||||||
|
|
||||||
|
proc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline.} =
|
||||||
|
a[Idx(a.len - int(i) + int low(a))]
|
||||||
|
proc `[]`*(s: string; i: BackwardsIndex): char {.inline.} = s[s.len - int(i)]
|
||||||
|
|
||||||
|
proc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline.} =
|
||||||
|
system.`[]`(s, s.len - int(i))
|
||||||
|
proc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline.} =
|
||||||
|
a[Idx(a.len - int(i) + int low(a))]
|
||||||
|
proc `[]`*(s: var string; i: BackwardsIndex): var char {.inline.} = s[s.len - int(i)]
|
||||||
|
|
||||||
|
proc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline.} =
|
||||||
|
system.`[]=`(s, s.len - int(i), x)
|
||||||
|
proc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline.} =
|
||||||
|
a[Idx(a.len - int(i) + int low(a))] = x
|
||||||
|
proc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline.} =
|
||||||
|
s[s.len - int(i)] = x
|
||||||
|
|
||||||
|
template `..^`*(a, b: untyped): untyped =
|
||||||
|
## A shortcut for `.. ^` to avoid the common gotcha that a space between
|
||||||
|
## '..' and '^' is required.
|
||||||
|
a .. ^b
|
||||||
|
|
||||||
|
template `..<`*(a, b: untyped): untyped =
|
||||||
|
## A shortcut for `a .. pred(b)`.
|
||||||
|
## ```
|
||||||
|
## for i in 5 ..< 9:
|
||||||
|
## echo i # => 5; 6; 7; 8
|
||||||
|
## ```
|
||||||
|
a .. (when b is BackwardsIndex: succ(b) else: pred(b))
|
||||||
|
|
||||||
|
template `[]`*(s: string; i: int): char = arrGet(s, i)
|
||||||
|
template `[]=`*(s: string; i: int; val: char) = arrPut(s, i, val)
|
||||||
|
|
||||||
|
template `^^`(s, i: untyped): untyped =
|
||||||
|
(when i is BackwardsIndex: s.len - int(i) else: int(i))
|
||||||
|
|
||||||
|
template spliceImpl(s, a, L, b: untyped): untyped =
|
||||||
|
# make room for additional elements or cut:
|
||||||
|
var shift = b.len - max(0,L) # ignore negative slice size
|
||||||
|
var newLen = s.len + shift
|
||||||
|
if shift > 0:
|
||||||
|
# enlarge:
|
||||||
|
setLen(s, newLen)
|
||||||
|
for i in countdown(newLen-1, a+b.len): movingCopy(s[i], s[i-shift])
|
||||||
|
else:
|
||||||
|
for i in countup(a+b.len, newLen-1): movingCopy(s[i], s[i-shift])
|
||||||
|
# cut down:
|
||||||
|
setLen(s, newLen)
|
||||||
|
# fill the hole:
|
||||||
|
for i in 0 ..< b.len: s[a+i] = b[i]
|
||||||
|
|
||||||
|
proc `[]`*[T, U: Ordinal](s: string, x: HSlice[T, U]): string {.inline.} =
|
||||||
|
## Slice operation for strings.
|
||||||
|
## Returns the inclusive range `[s[x.a], s[x.b]]`:
|
||||||
|
## ```
|
||||||
|
## var s = "abcdef"
|
||||||
|
## assert s[1..3] == "bcd"
|
||||||
|
## ```
|
||||||
|
let a = s ^^ x.a
|
||||||
|
let L = (s ^^ x.b) - a + 1
|
||||||
|
result = newString(L)
|
||||||
|
for i in 0 ..< L: result[i] = s[i + a]
|
||||||
|
|
||||||
|
proc `[]=`*[T, U: Ordinal](s: var string, x: HSlice[T, U], b: string) =
|
||||||
|
## Slice assignment for strings.
|
||||||
|
##
|
||||||
|
## If `b.len` is not exactly the number of elements that are referred to
|
||||||
|
## by `x`, a `splice`:idx: is performed:
|
||||||
|
##
|
||||||
|
runnableExamples:
|
||||||
|
var s = "abcdefgh"
|
||||||
|
s[1 .. ^2] = "xyz"
|
||||||
|
assert s == "axyzh"
|
||||||
|
|
||||||
|
var a = s ^^ x.a
|
||||||
|
var L = (s ^^ x.b) - a + 1
|
||||||
|
if L == b.len:
|
||||||
|
for i in 0..<L: s[i+a] = b[i]
|
||||||
|
else:
|
||||||
|
spliceImpl(s, a, L, b)
|
||||||
|
|
||||||
|
proc `[]`*[Idx, T; U, V: Ordinal](a: array[Idx, T], x: HSlice[U, V]): seq[T] =
|
||||||
|
## Slice operation for arrays.
|
||||||
|
## Returns the inclusive range `[a[x.a], a[x.b]]`:
|
||||||
|
## ```
|
||||||
|
## var a = [1, 2, 3, 4]
|
||||||
|
## assert a[0..2] == @[1, 2, 3]
|
||||||
|
## ```
|
||||||
|
let xa = a ^^ x.a
|
||||||
|
let L = (a ^^ x.b) - xa + 1
|
||||||
|
result = newSeq[T](L)
|
||||||
|
for i in 0..<L: result[i] = a[Idx(i + xa)]
|
||||||
|
|
||||||
|
proc `[]=`*[Idx, T; U, V: Ordinal](a: var array[Idx, T], x: HSlice[U, V], b: openArray[T]) =
|
||||||
|
## Slice assignment for arrays.
|
||||||
|
## ```
|
||||||
|
## var a = [10, 20, 30, 40, 50]
|
||||||
|
## a[1..2] = @[99, 88]
|
||||||
|
## assert a == [10, 99, 88, 40, 50]
|
||||||
|
## ```
|
||||||
|
let xa = a ^^ x.a
|
||||||
|
let L = (a ^^ x.b) - xa + 1
|
||||||
|
if L == b.len:
|
||||||
|
for i in 0..<L: a[Idx(i + xa)] = b[i]
|
||||||
|
else:
|
||||||
|
sysFatal(RangeDefect, "different lengths for slice assignment")
|
||||||
|
|
||||||
|
proc `[]`*[T; U, V: Ordinal](s: openArray[T], x: HSlice[U, V]): seq[T] =
|
||||||
|
## Slice operation for sequences.
|
||||||
|
## Returns the inclusive range `[s[x.a], s[x.b]]`:
|
||||||
|
## ```
|
||||||
|
## var s = @[1, 2, 3, 4]
|
||||||
|
## assert s[0..2] == @[1, 2, 3]
|
||||||
|
## ```
|
||||||
|
let a = s ^^ x.a
|
||||||
|
let L = (s ^^ x.b) - a + 1
|
||||||
|
newSeq(result, L)
|
||||||
|
for i in 0 ..< L: result[i] = s[i + a]
|
||||||
|
|
||||||
|
proc `[]=`*[T; U, V: Ordinal](s: var seq[T], x: HSlice[U, V], b: openArray[T]) =
|
||||||
|
## Slice assignment for sequences.
|
||||||
|
##
|
||||||
|
## If `b.len` is not exactly the number of elements that are referred to
|
||||||
|
## by `x`, a `splice`:idx: is performed.
|
||||||
|
runnableExamples:
|
||||||
|
var s = @"abcdefgh"
|
||||||
|
s[1 .. ^2] = @"xyz"
|
||||||
|
assert s == @"axyzh"
|
||||||
|
|
||||||
|
let a = s ^^ x.a
|
||||||
|
let L = (s ^^ x.b) - a + 1
|
||||||
|
if L == b.len:
|
||||||
|
for i in 0 ..< L: s[i+a] = b[i]
|
||||||
|
else:
|
||||||
|
spliceImpl(s, a, L, b)
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
## Default iterators for some Nim types.
|
||||||
|
|
||||||
when defined(nimPreviewSlimSystem):
|
when defined(nimPreviewSlimSystem):
|
||||||
import std/assertions
|
import std/assertions
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,11 @@ The System module imports several separate modules, and their documentation
|
||||||
is in separate files:
|
is in separate files:
|
||||||
|
|
||||||
* `iterators <iterators.html>`_
|
* `iterators <iterators.html>`_
|
||||||
|
* `exceptions <exceptions.html>`_
|
||||||
* `assertions <assertions.html>`_
|
* `assertions <assertions.html>`_
|
||||||
* `dollars <dollars.html>`_
|
* `dollars <dollars.html>`_
|
||||||
* `widestrs <widestrs.html>`_
|
* `widestrs <widestrs.html>`_
|
||||||
|
* `ctypes <ctypes.html>`_
|
||||||
|
|
||||||
|
|
||||||
Here is a short overview of the most commonly used functions from the
|
Here is a short overview of the most commonly used functions from the
|
||||||
|
|
|
||||||
|
|
@ -422,10 +422,10 @@ else:
|
||||||
importc: "GetCommandLineA", stdcall, dynlib: "kernel32", sideEffect.}
|
importc: "GetCommandLineA", stdcall, dynlib: "kernel32", sideEffect.}
|
||||||
|
|
||||||
proc rdFileTime*(f: FILETIME): int64 =
|
proc rdFileTime*(f: FILETIME): int64 =
|
||||||
result = ze64(f.dwLowDateTime) or (ze64(f.dwHighDateTime) shl 32)
|
result = int64(cast[uint32](f.dwLowDateTime)) or (int64(cast[uint32](f.dwHighDateTime)) shl 32)
|
||||||
|
|
||||||
proc rdFileSize*(f: WIN32_FIND_DATA): int64 =
|
proc rdFileSize*(f: WIN32_FIND_DATA): int64 =
|
||||||
result = ze64(f.nFileSizeLow) or (ze64(f.nFileSizeHigh) shl 32)
|
result = int64(cast[uint32](f.nFileSizeLow)) or (int64(cast[uint32](f.nFileSizeHigh)) shl 32)
|
||||||
|
|
||||||
proc getSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var FILETIME) {.
|
proc getSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var FILETIME) {.
|
||||||
importc: "GetSystemTimeAsFileTime", dynlib: "kernel32", stdcall, sideEffect.}
|
importc: "GetSystemTimeAsFileTime", dynlib: "kernel32", stdcall, sideEffect.}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,6 @@ $nimsuggest --tester $file
|
||||||
>sug $1
|
>sug $1
|
||||||
sug;;skType;;tsug_typedecl.someType;;someType;;*nimsuggest/tests/tsug_typedecl.nim;;7;;2;;"";;100;;Prefix
|
sug;;skType;;tsug_typedecl.someType;;someType;;*nimsuggest/tests/tsug_typedecl.nim;;7;;2;;"";;100;;Prefix
|
||||||
sug;;skType;;tsug_typedecl.super;;super;;*nimsuggest/tests/tsug_typedecl.nim;;6;;2;;"";;100;;Prefix
|
sug;;skType;;tsug_typedecl.super;;super;;*nimsuggest/tests/tsug_typedecl.nim;;6;;2;;"";;100;;Prefix
|
||||||
sug;;skType;;system.string;;string;;*lib/system.nim;;*;;*;;*;;100;;Prefix
|
sug;;skType;;system.string;;string;;*lib/system/basic_types.nim;;*;;*;;*;;100;;Prefix
|
||||||
sug;;skType;;system.seq;;seq;;*lib/system.nim;;*;;*;;*;;100;;Prefix
|
sug;;skType;;system.seq;;seq;;*lib/system.nim;;*;;*;;*;;100;;Prefix
|
||||||
"""
|
"""
|
||||||
|
|
@ -2,8 +2,8 @@ discard """
|
||||||
$nimsuggest --tester --maxresults:3 $file
|
$nimsuggest --tester --maxresults:3 $file
|
||||||
>sug $1
|
>sug $1
|
||||||
sug;;skType;;ttype_decl.Other;;Other;;$file;;10;;2;;"";;100;;None
|
sug;;skType;;ttype_decl.Other;;Other;;$file;;10;;2;;"";;100;;None
|
||||||
sug;;skType;;system.int;;int;;*/lib/system/basic_types.nim;;2;;2;;"";;100;;None
|
sug;;skType;;system.int;;int;;*lib/system/basic_types.nim;;2;;2;;"";;100;;None
|
||||||
sug;;skType;;system.string;;string;;*/lib/system.nim;;34;;2;;"";;100;;None
|
sug;;skType;;system.string;;string;;*lib/system/basic_types.nim;;23;;2;;"";;100;;None
|
||||||
"""
|
"""
|
||||||
import strutils
|
import strutils
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ type
|
||||||
|
|
||||||
proc c_str(a: stdString): cstring {.importcpp: "(char *)(#.c_str())", header: "<string>".}
|
proc c_str(a: stdString): cstring {.importcpp: "(char *)(#.c_str())", header: "<string>".}
|
||||||
|
|
||||||
proc len(a: stdString): csize {.importcpp: "(#.length())", header: "<string>".}
|
proc len(a: stdString): csize_t {.importcpp: "(#.length())", header: "<string>".}
|
||||||
|
|
||||||
proc setChar(a: var stdString, i: csize, c: char) {.importcpp: "(#[#] = #)", header: "<string>".}
|
proc setChar(a: var stdString, i: csize_t, c: char) {.importcpp: "(#[#] = #)", header: "<string>".}
|
||||||
|
|
||||||
proc `*`*[T](this: stdUniquePtr[T]): var T {.noSideEffect, importcpp: "(* #)", header: "<memory>".}
|
proc `*`*[T](this: stdUniquePtr[T]): var T {.noSideEffect, importcpp: "(* #)", header: "<memory>".}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ type
|
||||||
TRadixNode {.pure, inheritable.} = object
|
TRadixNode {.pure, inheritable.} = object
|
||||||
kind: TRadixNodeKind
|
kind: TRadixNodeKind
|
||||||
TRadixNodeLinear = object of TRadixNode
|
TRadixNodeLinear = object of TRadixNode
|
||||||
len: int8
|
len: uint8
|
||||||
keys: array[0..31, int8]
|
keys: array[0..31, uint8]
|
||||||
vals: array[0..31, PRadixNode]
|
vals: array[0..31, PRadixNode]
|
||||||
|
|
||||||
TRadixNodeFull = object of TRadixNode
|
TRadixNodeFull = object of TRadixNode
|
||||||
|
|
@ -49,8 +49,8 @@ type
|
||||||
TRadixNodeLeafBits = object of TRadixNode
|
TRadixNodeLeafBits = object of TRadixNode
|
||||||
b: array[0..7, int]
|
b: array[0..7, int]
|
||||||
TRadixNodeLeafLinear = object of TRadixNode
|
TRadixNodeLeafLinear = object of TRadixNode
|
||||||
len: int8
|
len: uint8
|
||||||
keys: array[0..31, int8]
|
keys: array[0..31, uint8]
|
||||||
|
|
||||||
var
|
var
|
||||||
root: PRadixNode
|
root: PRadixNode
|
||||||
|
|
@ -59,8 +59,8 @@ proc searchInner(r: PRadixNode, a: int): PRadixNode =
|
||||||
case r.kind
|
case r.kind
|
||||||
of rnLinear:
|
of rnLinear:
|
||||||
var x = cast[ptr TRadixNodeLinear](r)
|
var x = cast[ptr TRadixNodeLinear](r)
|
||||||
for i in 0..ze(x.len)-1:
|
for i in 0..int(x.len)-1:
|
||||||
if ze(x.keys[i]) == a: return x.vals[i]
|
if int(x.keys[i]) == a: return x.vals[i]
|
||||||
of rnFull:
|
of rnFull:
|
||||||
var x = cast[ptr TRadixNodeFull](r)
|
var x = cast[ptr TRadixNodeFull](r)
|
||||||
return x.b[a]
|
return x.b[a]
|
||||||
|
|
@ -87,8 +87,8 @@ proc searchLeaf(r: PRadixNode, a: int): bool =
|
||||||
return testBit(x.b[a /% BitsPerUnit], a)
|
return testBit(x.b[a /% BitsPerUnit], a)
|
||||||
of rnLeafLinear:
|
of rnLeafLinear:
|
||||||
var x = cast[ptr TRadixNodeLeafLinear](r)
|
var x = cast[ptr TRadixNodeLeafLinear](r)
|
||||||
for i in 0..ze(x.len)-1:
|
for i in 0..int(x.len)-1:
|
||||||
if ze(x.keys[i]) == a: return true
|
if int(x.keys[i]) == a: return true
|
||||||
else: assert(false)
|
else: assert(false)
|
||||||
|
|
||||||
proc exclLeaf(r: PRadixNode, a: int) =
|
proc exclLeaf(r: PRadixNode, a: int) =
|
||||||
|
|
@ -98,9 +98,9 @@ proc exclLeaf(r: PRadixNode, a: int) =
|
||||||
resetBit(x.b[a /% BitsPerUnit], a)
|
resetBit(x.b[a /% BitsPerUnit], a)
|
||||||
of rnLeafLinear:
|
of rnLeafLinear:
|
||||||
var x = cast[ptr TRadixNodeLeafLinear](r)
|
var x = cast[ptr TRadixNodeLeafLinear](r)
|
||||||
var L = ze(x.len)
|
var L = int(x.len)
|
||||||
for i in 0..L-1:
|
for i in 0..L-1:
|
||||||
if ze(x.keys[i]) == a:
|
if int(x.keys[i]) == a:
|
||||||
x.keys[i] = x.keys[L-1]
|
x.keys[i] = x.keys[L-1]
|
||||||
dec(x.len)
|
dec(x.len)
|
||||||
return
|
return
|
||||||
|
|
@ -131,8 +131,8 @@ proc addLeaf(r: var PRadixNode, a: int): bool =
|
||||||
# a linear node:
|
# a linear node:
|
||||||
var x = cast[ptr TRadixNodeLinear](alloc0(sizeof(TRadixNodeLinear)))
|
var x = cast[ptr TRadixNodeLinear](alloc0(sizeof(TRadixNodeLinear)))
|
||||||
x.kind = rnLeafLinear
|
x.kind = rnLeafLinear
|
||||||
x.len = 1'i8
|
x.len = 1'u8
|
||||||
x.keys[0] = toU8(a)
|
x.keys[0] = uint8(a)
|
||||||
r = x
|
r = x
|
||||||
return false # not already in set
|
return false # not already in set
|
||||||
case r.kind
|
case r.kind
|
||||||
|
|
@ -141,18 +141,18 @@ proc addLeaf(r: var PRadixNode, a: int): bool =
|
||||||
return testOrSetBit(x.b[a /% BitsPerUnit], a)
|
return testOrSetBit(x.b[a /% BitsPerUnit], a)
|
||||||
of rnLeafLinear:
|
of rnLeafLinear:
|
||||||
var x = cast[ptr TRadixNodeLeafLinear](r)
|
var x = cast[ptr TRadixNodeLeafLinear](r)
|
||||||
var L = ze(x.len)
|
var L = int(x.len)
|
||||||
for i in 0..L-1:
|
for i in 0..L-1:
|
||||||
if ze(x.keys[i]) == a: return true
|
if int(x.keys[i]) == a: return true
|
||||||
if L <= high(x.keys):
|
if L <= high(x.keys):
|
||||||
x.keys[L] = toU8(a)
|
x.keys[L] = uint8(a)
|
||||||
inc(x.len)
|
inc(x.len)
|
||||||
else:
|
else:
|
||||||
# transform into a full node:
|
# transform into a full node:
|
||||||
var y = cast[ptr TRadixNodeLeafBits](alloc0(sizeof(TRadixNodeLeafBits)))
|
var y = cast[ptr TRadixNodeLeafBits](alloc0(sizeof(TRadixNodeLeafBits)))
|
||||||
y.kind = rnLeafBits
|
y.kind = rnLeafBits
|
||||||
for i in 0..ze(x.len)-1:
|
for i in 0..int(x.len)-1:
|
||||||
var u = ze(x.keys[i])
|
var u = int(x.keys[i])
|
||||||
setBit(y.b[u /% BitsPerUnit], u)
|
setBit(y.b[u /% BitsPerUnit], u)
|
||||||
setBit(y.b[a /% BitsPerUnit], a)
|
setBit(y.b[a /% BitsPerUnit], a)
|
||||||
dealloc(r)
|
dealloc(r)
|
||||||
|
|
@ -167,26 +167,26 @@ proc addInner(r: var PRadixNode, a: int, d: int): bool =
|
||||||
# a linear node:
|
# a linear node:
|
||||||
var x = cast[ptr TRadixNodeLinear](alloc0(sizeof(TRadixNodeLinear)))
|
var x = cast[ptr TRadixNodeLinear](alloc0(sizeof(TRadixNodeLinear)))
|
||||||
x.kind = rnLinear
|
x.kind = rnLinear
|
||||||
x.len = 1'i8
|
x.len = 1'u8
|
||||||
x.keys[0] = toU8(k)
|
x.keys[0] = uint8(k)
|
||||||
r = x
|
r = x
|
||||||
return addInner(x.vals[0], a, d-8)
|
return addInner(x.vals[0], a, d-8)
|
||||||
case r.kind
|
case r.kind
|
||||||
of rnLinear:
|
of rnLinear:
|
||||||
var x = cast[ptr TRadixNodeLinear](r)
|
var x = cast[ptr TRadixNodeLinear](r)
|
||||||
var L = ze(x.len)
|
var L = int(x.len)
|
||||||
for i in 0..L-1:
|
for i in 0..L-1:
|
||||||
if ze(x.keys[i]) == k: # already exists
|
if int(x.keys[i]) == k: # already exists
|
||||||
return addInner(x.vals[i], a, d-8)
|
return addInner(x.vals[i], a, d-8)
|
||||||
if L <= high(x.keys):
|
if L <= high(x.keys):
|
||||||
x.keys[L] = toU8(k)
|
x.keys[L] = uint8(k)
|
||||||
inc(x.len)
|
inc(x.len)
|
||||||
return addInner(x.vals[L], a, d-8)
|
return addInner(x.vals[L], a, d-8)
|
||||||
else:
|
else:
|
||||||
# transform into a full node:
|
# transform into a full node:
|
||||||
var y = cast[ptr TRadixNodeFull](alloc0(sizeof(TRadixNodeFull)))
|
var y = cast[ptr TRadixNodeFull](alloc0(sizeof(TRadixNodeFull)))
|
||||||
y.kind = rnFull
|
y.kind = rnFull
|
||||||
for i in 0..L-1: y.b[ze(x.keys[i])] = x.vals[i]
|
for i in 0..L-1: y.b[int(x.keys[i])] = x.vals[i]
|
||||||
dealloc(r)
|
dealloc(r)
|
||||||
r = y
|
r = y
|
||||||
return addInner(y.b[k], a, d-8)
|
return addInner(y.b[k], a, d-8)
|
||||||
|
|
@ -211,8 +211,8 @@ iterator innerElements(r: PRadixNode): tuple[prefix: int, n: PRadixNode] =
|
||||||
yield (i, r.b[i])
|
yield (i, r.b[i])
|
||||||
of rnLinear:
|
of rnLinear:
|
||||||
var r = cast[ptr TRadixNodeLinear](r)
|
var r = cast[ptr TRadixNodeLinear](r)
|
||||||
for i in 0..ze(r.len)-1:
|
for i in 0..int(r.len)-1:
|
||||||
yield (ze(r.keys[i]), r.vals[i])
|
yield (int(r.keys[i]), r.vals[i])
|
||||||
else: assert(false)
|
else: assert(false)
|
||||||
|
|
||||||
iterator leafElements(r: PRadixNode): int =
|
iterator leafElements(r: PRadixNode): int =
|
||||||
|
|
@ -228,8 +228,8 @@ iterator leafElements(r: PRadixNode): int =
|
||||||
yield i*BitsPerUnit+j
|
yield i*BitsPerUnit+j
|
||||||
of rnLeafLinear:
|
of rnLeafLinear:
|
||||||
var r = cast[ptr TRadixNodeLeafLinear](r)
|
var r = cast[ptr TRadixNodeLeafLinear](r)
|
||||||
for i in 0..ze(r.len)-1:
|
for i in 0..int(r.len)-1:
|
||||||
yield ze(r.keys[i])
|
yield int(r.keys[i])
|
||||||
else: assert(false)
|
else: assert(false)
|
||||||
|
|
||||||
iterator elements*(r: PRadixNode): ByteAddress {.inline.} =
|
iterator elements*(r: PRadixNode): ByteAddress {.inline.} =
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,14 @@ discard $x0
|
||||||
const x1 = cast[uint](-1)
|
const x1 = cast[uint](-1)
|
||||||
discard $(x1,)
|
discard $(x1,)
|
||||||
|
|
||||||
|
when not defined(nimPreviewSlimSystem):
|
||||||
# bug #13698
|
# bug #13698
|
||||||
let n: csize = 1 # xxx should that be csize_t or is that essential here?
|
let n: csize = 1 # xxx should that be csize_t or is that essential here?
|
||||||
doAssert $n.int32 == "1"
|
doAssert $n.int32 == "1"
|
||||||
|
|
||||||
|
let n2: csize_t = 1
|
||||||
|
doAssert $n2.int32 == "1"
|
||||||
|
|
||||||
# bug #14616
|
# bug #14616
|
||||||
|
|
||||||
let limit = 1'u64
|
let limit = 1'u64
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import
|
||||||
strutils
|
strutils
|
||||||
|
|
||||||
type
|
type
|
||||||
TBuffer = array[0..10, int8]
|
TBuffer = array[0..10, uint8]
|
||||||
|
|
||||||
proc toVarNum(x: int32, b: var TBuffer) =
|
proc toVarNum(x: int32, b: var TBuffer) =
|
||||||
# encoding: first bit indicates end of number (0 if at end)
|
# encoding: first bit indicates end of number (0 if at end)
|
||||||
|
|
@ -21,11 +21,11 @@ proc toVarNum(x: int32, b: var TBuffer) =
|
||||||
# anyway
|
# anyway
|
||||||
a = abs(x)
|
a = abs(x)
|
||||||
# first 6 bits:
|
# first 6 bits:
|
||||||
b[0] = toU8(ord(a >% 63'i32) shl 7 or (ord(x < 0'i32) shl 6) or (int(a) and 63))
|
b[0] = uint8(ord(a >% 63'i32) shl 7 or (ord(x < 0'i32) shl 6) or (int(a) and 63))
|
||||||
a = (a shr 6'i32) and 0x03ffffff # skip first 6 bits
|
a = (a shr 6'i32) and 0x03ffffff # skip first 6 bits
|
||||||
var i = 1
|
var i = 1
|
||||||
while a != 0'i32:
|
while a != 0'i32:
|
||||||
b[i] = toU8(ord(a >% 127'i32) shl 7 or (int(a) and 127))
|
b[i] = uint8(ord(a >% 127'i32) shl 7 or (int(a) and 127))
|
||||||
inc(i)
|
inc(i)
|
||||||
a = a shr 7'i32
|
a = a shr 7'i32
|
||||||
|
|
||||||
|
|
@ -41,40 +41,40 @@ proc toVarNum64(x: int64, b: var TBuffer) =
|
||||||
# anyway
|
# anyway
|
||||||
a = abs(x)
|
a = abs(x)
|
||||||
# first 6 bits:
|
# first 6 bits:
|
||||||
b[0] = toU8(ord(a >% 63'i64) shl 7 or (ord(x < 0'i64) shl 6) or int(a and 63))
|
b[0] = uint8(ord(a >% 63'i64) shl 7 or (ord(x < 0'i64) shl 6) or int(a and 63))
|
||||||
a = (a shr 6) and 0x03ffffffffffffff # skip first 6 bits
|
a = (a shr 6) and 0x03ffffffffffffff # skip first 6 bits
|
||||||
var i = 1
|
var i = 1
|
||||||
while a != 0'i64:
|
while a != 0'i64:
|
||||||
b[i] = toU8(ord(a >% 127'i64) shl 7 or int(a and 127))
|
b[i] = uint8(ord(a >% 127'i64) shl 7 or int(a and 127))
|
||||||
inc(i)
|
inc(i)
|
||||||
a = a shr 7
|
a = a shr 7
|
||||||
|
|
||||||
proc toNum64(b: TBuffer): int64 =
|
proc toNum64(b: TBuffer): int64 =
|
||||||
# treat first byte different:
|
# treat first byte different:
|
||||||
result = ze64(b[0]) and 63
|
result = int64(b[0]) and 63
|
||||||
var
|
var
|
||||||
i = 0
|
i = 0
|
||||||
Shift = 6'i64
|
Shift = 6'i64
|
||||||
while (ze(b[i]) and 128) != 0:
|
while (int(b[i]) and 128) != 0:
|
||||||
inc(i)
|
inc(i)
|
||||||
result = result or ((ze64(b[i]) and 127) shl Shift)
|
result = result or ((int64(b[i]) and 127) shl Shift)
|
||||||
inc(Shift, 7)
|
inc(Shift, 7)
|
||||||
if (ze(b[0]) and 64) != 0: # sign bit set?
|
if (int(b[0]) and 64) != 0: # sign bit set?
|
||||||
result = not result +% 1
|
result = not result +% 1
|
||||||
# this is the same as ``- result``
|
# this is the same as ``- result``
|
||||||
# but gives no overflow error for low(int)
|
# but gives no overflow error for low(int)
|
||||||
|
|
||||||
proc toNum(b: TBuffer): int32 =
|
proc toNum(b: TBuffer): int32 =
|
||||||
# treat first byte different:
|
# treat first byte different:
|
||||||
result = int32 ze(b[0]) and 63
|
result = int32(b[0]) and 63
|
||||||
var
|
var
|
||||||
i = 0
|
i = 0
|
||||||
Shift = 6'i32
|
Shift = 6'i32
|
||||||
while (ze(b[i]) and 128) != 0:
|
while (int(b[i]) and 128) != 0:
|
||||||
inc(i)
|
inc(i)
|
||||||
result = result or ((int32(ze(b[i])) and 127'i32) shl Shift)
|
result = result or ((int32(b[i]) and 127'i32) shl Shift)
|
||||||
Shift = Shift + 7'i32
|
Shift = Shift + 7'i32
|
||||||
if (ze(b[0]) and (1 shl 6)) != 0: # sign bit set?
|
if (int(b[0]) and (1 shl 6)) != 0: # sign bit set?
|
||||||
result = (not result) +% 1'i32
|
result = (not result) +% 1'i32
|
||||||
# this is the same as ``- result``
|
# this is the same as ``- result``
|
||||||
# but gives no overflow error for low(int)
|
# but gives no overflow error for low(int)
|
||||||
|
|
|
||||||
|
|
@ -74,37 +74,37 @@ block tn8vsint16:
|
||||||
|
|
||||||
import strutils
|
import strutils
|
||||||
block tcolors:
|
block tcolors:
|
||||||
type TColor = distinct int32
|
type TColor = distinct uint32
|
||||||
|
|
||||||
proc rgb(r, g, b: range[0..255]): TColor =
|
proc rgb(r, g, b: range[0..255]): TColor =
|
||||||
result = TColor(r or g shl 8 or b shl 16)
|
result = TColor(r or g shl 8 or b shl 16)
|
||||||
proc `$`(c: TColor): string =
|
proc `$`(c: TColor): string =
|
||||||
result = "#" & toHex(int32(c), 6)
|
result = "#" & toHex(uint32(c), 6)
|
||||||
echo rgb(34, 55, 255)
|
echo rgb(34, 55, 255)
|
||||||
|
|
||||||
when false:
|
block:
|
||||||
type
|
type
|
||||||
TColor = distinct int32
|
TColor = distinct uint32
|
||||||
TColorComponent = distinct int8
|
TColorComponent = distinct uint8
|
||||||
|
|
||||||
proc red(a: TColor): TColorComponent =
|
proc red(a: TColor): TColorComponent =
|
||||||
result = TColorComponent(int32(a) and 0xff'i32)
|
result = TColorComponent(uint32(a) and 0xff'u32)
|
||||||
proc green(a: TColor): TColorComponent =
|
proc green(a: TColor): TColorComponent =
|
||||||
result = TColorComponent(int32(a) shr 8'i32 and 0xff'i32)
|
result = TColorComponent(uint32(a) shr 8'u32 and 0xff'u32)
|
||||||
proc blue(a: TColor): TColorComponent =
|
proc blue(a: TColor): TColorComponent =
|
||||||
result = TColorComponent(int32(a) shr 16'i32 and 0xff'i32)
|
result = TColorComponent(uint32(a) shr 16'u32 and 0xff'u32)
|
||||||
proc rgb(r, g, b: range[0..255]): TColor =
|
proc rgb(r, g, b: range[0..255]): TColor =
|
||||||
result = TColor(r or g shl 8 or b shl 8)
|
result = TColor(r or g shl 8 or b shl 8)
|
||||||
|
|
||||||
proc `+!` (a, b: TColorComponent): TColorComponent =
|
proc `+!` (a, b: TColorComponent): TColorComponent =
|
||||||
## saturated arithmetic:
|
## saturated arithmetic:
|
||||||
result = TColorComponent(min(ze(int8(a)) + ze(int8(b)), 255))
|
result = TColorComponent(min(int(uint8(a)) + int(uint8(b)), 255))
|
||||||
|
|
||||||
proc `+` (a, b: TColor): TColor =
|
proc `+` (a, b: TColor): TColor =
|
||||||
## saturated arithmetic for colors makes sense, I think:
|
## saturated arithmetic for colors makes sense, I think:
|
||||||
return rgb(red(a) +! red(b), green(a) +! green(b), blue(a) +! blue(b))
|
return rgb(int(red(a) +! red(b)), int(green(a) +! green(b)), int(blue(a) +! blue(b)))
|
||||||
|
|
||||||
rgb(34, 55, 255)
|
discard rgb(34, 55, 255)
|
||||||
|
|
||||||
block:
|
block:
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
|
disabled: true
|
||||||
output: '''
|
output: '''
|
||||||
just exiting...
|
just exiting...
|
||||||
'''
|
'''
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ type
|
||||||
TRadixNode {.inheritable.} = object
|
TRadixNode {.inheritable.} = object
|
||||||
kind: TRadixNodeKind
|
kind: TRadixNodeKind
|
||||||
TRadixNodeLinear = object of TRadixNode
|
TRadixNodeLinear = object of TRadixNode
|
||||||
len: int8
|
len: uint8
|
||||||
keys: array[0..31, char]
|
keys: array[0..31, char]
|
||||||
vals: array[0..31, PRadixNode]
|
vals: array[0..31, PRadixNode]
|
||||||
TRadixNodeFull = object of TRadixNode
|
TRadixNodeFull = object of TRadixNode
|
||||||
|
|
@ -24,7 +24,7 @@ proc search(r: PRadixNode, s: string): PRadixNode =
|
||||||
case r.kind
|
case r.kind
|
||||||
of rnLinear:
|
of rnLinear:
|
||||||
var x = PRadixNodeLinear(r)
|
var x = PRadixNodeLinear(r)
|
||||||
for j in 0..ze(x.len)-1:
|
for j in 0..int(x.len)-1:
|
||||||
if x.keys[j] == s[i]:
|
if x.keys[j] == s[i]:
|
||||||
if s[i] == '\0': return r
|
if s[i] == '\0': return r
|
||||||
r = x.vals[j]
|
r = x.vals[j]
|
||||||
|
|
@ -63,9 +63,9 @@ proc excl*(r: var PRadixNode, s: string) =
|
||||||
of rnFull: PRadixNodeFull(x).b['\0'] = nil
|
of rnFull: PRadixNodeFull(x).b['\0'] = nil
|
||||||
of rnLinear:
|
of rnLinear:
|
||||||
var x = PRadixNodeLinear(x)
|
var x = PRadixNodeLinear(x)
|
||||||
for i in 0..ze(x.len)-1:
|
for i in 0..int(x.len)-1:
|
||||||
if x.keys[i] == '\0':
|
if x.keys[i] == '\0':
|
||||||
swap(x.keys[i], x.keys[ze(x.len)-1])
|
swap(x.keys[i], x.keys[int(x.len)-1])
|
||||||
dec(x.len)
|
dec(x.len)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ proc get_values(): (seq[int8], seq[int16], seq[int32]) =
|
||||||
let i8 = -3'i8
|
let i8 = -3'i8
|
||||||
let i16 = -3'i16
|
let i16 = -3'i16
|
||||||
let i32 = -3'i32
|
let i32 = -3'i32
|
||||||
doAssert i8.ze == 0xFD
|
doAssert int(cast[uint8](i8)) == 0xFD
|
||||||
doAssert i8.ze64 == 0xFD
|
doAssert int64(cast[uint8](i8)) == 0xFD
|
||||||
doAssert i16.ze == 0xFFFD
|
doAssert int(cast[uint16](i16)) == 0xFFFD
|
||||||
doAssert i16.ze64 == 0xFFFD
|
doAssert int64(cast[uint16](i16)) == 0xFFFD
|
||||||
|
|
||||||
result[0] = @[]; result[1] = @[]; result[2] = @[]
|
result[0] = @[]; result[1] = @[]; result[2] = @[]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -190,8 +190,10 @@ proc getDocList(): seq[string] =
|
||||||
lib/system/nimscript.nim
|
lib/system/nimscript.nim
|
||||||
lib/system/assertions.nim
|
lib/system/assertions.nim
|
||||||
lib/system/iterators.nim
|
lib/system/iterators.nim
|
||||||
|
lib/system/exceptions.nim
|
||||||
lib/system/dollars.nim
|
lib/system/dollars.nim
|
||||||
lib/system/widestrs.nim
|
lib/system/widestrs.nim
|
||||||
|
lib/system/ctypes.nim
|
||||||
""".splitWhitespace()
|
""".splitWhitespace()
|
||||||
|
|
||||||
proc follow(a: PathEntry): bool =
|
proc follow(a: PathEntry): bool =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue