diff options
Diffstat (limited to 'lib/system.nim')
-rw-r--r-- | lib/system.nim | 506 |
1 files changed, 275 insertions, 231 deletions
diff --git a/lib/system.nim b/lib/system.nim index 0df8849f5..da49386ed 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2013 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -77,44 +77,53 @@ type auto* = expr any* = distinct auto - TSignedInt* = int|int8|int16|int32|int64 + SomeSignedInt* = int|int8|int16|int32|int64 ## type class matching all signed integer types - TUnsignedInt* = uint|uint8|uint16|uint32|uint64 + SomeUnsignedInt* = uint|uint8|uint16|uint32|uint64 ## type class matching all unsigned integer types - TInteger* = TSignedInt|TUnsignedInt + SomeInteger* = SomeSignedInt|SomeUnsignedInt ## type class matching all integer types - TOrdinal* = int|int8|int16|int32|int64|bool|enum|uint8|uint16|uint32 + SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint8|uint16|uint32 ## type class matching all ordinal types; however this includes enums with ## holes. - TReal* = float|float32|float64 + SomeReal* = float|float32|float64 ## type class matching all floating point number types - TNumber* = TInteger|TReal + SomeNumber* = SomeInteger|SomeReal ## type class matching all number types proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.} ## Special compile-time procedure that checks whether `x` is ## defined. ## `x` is an external symbol introduced through the compiler's - ## `-d:x switch <nimrodc.html#compile-time-symbols>`_ to enable build time + ## `-d:x switch <nimc.html#compile-time-symbols>`_ to enable build time ## conditionals: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## when not defined(release): ## # Do here programmer friendly expensive sanity checks. ## # Put here the normal code +when defined(nimalias): + {.deprecated: [ + TSignedInt: SomeSignedInt, + TUnsignedInt: SomeUnsignedInt, + TInteger: SomeInteger, + TReal: SomeReal, + TNumber: SomeNumber, + TOrdinal: SomeOrdinal].} + proc declared*(x: expr): bool {.magic: "Defined", noSideEffect.} ## 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: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## when not defined(strutils.toUpper): ## # provide our own toUpper proc here, because strutils is ## # missing it. @@ -183,6 +192,7 @@ proc high*[T](x: T): T {.magic: "High", noSideEffect.} ## returns the highest possible index of an array, a sequence, a string or ## the highest possible value of an ordinal value `x`. As a special ## semantic rule, `x` may also be a type identifier. + ## ``high(int)`` is Nim's way of writing `INT_MAX`:idx: or `MAX_INT`:idx:. proc low*[T](x: T): T {.magic: "Low", noSideEffect.} ## returns the lowest possible index of an array, a sequence, a string or @@ -202,10 +212,13 @@ type set*{.magic: "Set".}[T] ## Generic type to construct bit sets. type - TSlice* {.final, pure.}[T] = object ## builtin slice type - a*, b*: T ## the bounds + Slice* {.final, pure.}[T] = object ## builtin slice type + a*, b*: T ## the bounds + +when defined(nimalias): + {.deprecated: [TSlice: Slice].} -proc `..`*[T](a, b: T): TSlice[T] {.noSideEffect, inline.} = +proc `..`*[T](a, b: T): Slice[T] {.noSideEffect, inline.} = ## `slice`:idx: operator that constructs an interval ``[a, b]``, both `a` ## and `b` are inclusive. Slices can also be used in the set constructor ## and in ordinal case statements, but then they are special-cased by the @@ -213,7 +226,7 @@ proc `..`*[T](a, b: T): TSlice[T] {.noSideEffect, inline.} = result.a = a result.b = b -proc `..`*[T](b: T): TSlice[T] {.noSideEffect, inline.} = +proc `..`*[T](b: T): Slice[T] {.noSideEffect, inline.} = ## `slice`:idx: operator that constructs an interval ``[default(T), b]`` result.b = b @@ -296,7 +309,7 @@ when not defined(JS) and not defined(NimrodVM): include "system/hti" type - Byte* = uint8 ## this is an alias for ``uint8``, that is an unsigned + byte* = uint8 ## this is an alias for ``uint8``, that is an unsigned ## int 8 bits wide. Natural* = range[0..high(int)] @@ -307,29 +320,29 @@ type ## is an int type ranging from one to the maximum value ## of an int. This type is often useful for documentation and debugging. - TObject* {.exportc: "TNimObject", inheritable.} = - object ## the root of Nimrod's object hierarchy. Objects should + RootObj* {.exportc: "TNimObject", inheritable.} = + object ## the root of Nim's object hierarchy. Objects should ## inherit from TObject or one of its descendants. However, ## objects that have no ancestor are allowed. - PObject* = ref TObject ## reference to TObject + RootRef* = ref RootObj ## reference to RootObj - TEffect* {.compilerproc.} = object of TObject ## \ + RootEffect* {.compilerproc.} = object of RootObj ## \ ## base effect class; each effect should ## inherit from `TEffect` unless you know what ## you doing. - FTime* = object of TEffect ## Time effect. - FIO* = object of TEffect ## IO effect. - FReadIO* = object of FIO ## Effect describing a read IO operation. - FWriteIO* = object of FIO ## Effect describing a write IO operation. - FExecIO* = object of FIO ## Effect describing an executing IO operation. + TimeEffect* = object of RootEffect ## Time effect. + IOEffect* = object of RootEffect ## IO effect. + ReadIOEffect* = object of IOEffect ## Effect describing a read IO operation. + WriteIOEffect* = object of IOEffect ## Effect describing a write IO operation. + ExecIOEffect* = object of IOEffect ## Effect describing an executing IO operation. - E_Base* {.compilerproc.} = object of TObject ## \ + Exception* {.compilerproc.} = object of RootObj ## \ ## Base exception class. ## - ## Each exception has to inherit from `E_Base`. See the full `exception + ## Each exception has to inherit from `Exception`. See the full `exception ## hierarchy`_. - parent: ref E_Base ## parent exception (can be used as a stack) - name: cstring ## The exception's name is its Nimrod identifier. + 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 @@ -337,143 +350,156 @@ type ## is bad style. trace: string - EAsynch* = object of E_Base ## \ - ## Abstract exception class for *asynchronous exceptions* (interrupts). - ## - ## This is rarely needed: most exception types inherit from `ESynch - ## <#ESynch>`_. See the full `exception hierarchy`_. - EControlC* = object of EAsynch ## \ - ## Raised for Ctrl+C key presses in console applications. - ## - ## See the full `exception hierarchy`_. - ESynch* = object of E_Base ## \ - ## Abstract exception class for *synchronous exceptions*. - ## - ## Most exceptions should be inherited (directly or indirectly) from - ## `ESynch` instead of from `EAsynch <#EAsynch>`_. See the full `exception - ## hierarchy`_. - ESystem* = object of ESynch ## \ + SystemError* = object of Exception ## \ ## Abstract class for exceptions that the runtime system raises. ## ## See the full `exception hierarchy`_. - EIO* = object of ESystem ## \ + IOError* = object of SystemError ## \ ## Raised if an IO error occured. ## ## See the full `exception hierarchy`_. - EOS* = object of ESystem ## \ + OSError* = object of SystemError ## \ ## Raised if an operating system service failed. ## ## See the full `exception hierarchy`_. errorCode*: int32 ## OS-defined error code describing this error. - EInvalidLibrary* = object of EOS ## \ + LibraryError* = object of OSError ## \ ## Raised if a dynamic library could not be loaded. ## ## See the full `exception hierarchy`_. - EResourceExhausted* = object of ESystem ## \ + ResourceExhaustedError* = object of SystemError ## \ ## Raised if a resource request could not be fullfilled. ## ## See the full `exception hierarchy`_. - EArithmetic* = object of ESynch ## \ + ArithmeticError* = object of Exception ## \ ## Raised if any kind of arithmetic error occured. ## ## See the full `exception hierarchy`_. - EDivByZero* {.compilerproc.} = object of EArithmetic ## \ + DivByZeroError* = object of ArithmeticError ## \ ## Raised for runtime integer divide-by-zero errors. ## ## See the full `exception hierarchy`_. - EOverflow* {.compilerproc.} = object of EArithmetic ## \ + + OverflowError* = object of ArithmeticError ## \ ## Raised for runtime integer overflows. ## ## This happens for calculations whose results are too large to fit in the ## provided bits. See the full `exception hierarchy`_. - EAccessViolation* {.compilerproc.} = object of ESynch ## \ + AccessViolationError* = object of Exception ## \ ## Raised for invalid memory access errors ## ## See the full `exception hierarchy`_. - EAssertionFailed* {.compilerproc.} = object of ESynch ## \ + AssertionError* = object of Exception ## \ ## Raised when assertion is proved wrong. ## ## Usually the result of using the `assert() template <#assert>`_. See the ## full `exception hierarchy`_. - EInvalidValue* = object of ESynch ## \ + ValueError* = object of Exception ## \ ## Raised for string and object conversion errors. - EInvalidKey* = object of EInvalidValue ## \ + KeyError* = object of ValueError ## \ ## Raised if a key cannot be found in a table. ## ## Mostly used by the `tables <tables.html>`_ module, it can also be raised ## by other collection modules like `sets <sets.html>`_ or `strtabs ## <strtabs.html>`_. See the full `exception hierarchy`_. - EOutOfMemory* = object of ESystem ## \ + OutOfMemError* = object of SystemError ## \ ## Raised for unsuccessful attempts to allocate memory. ## ## See the full `exception hierarchy`_. - EInvalidIndex* = object of ESynch ## \ + IndexError* = object of Exception ## \ ## Raised if an array index is out of bounds. ## ## See the full `exception hierarchy`_. - EInvalidField* = object of ESynch ## \ + + FieldError* = object of Exception ## \ ## Raised if a record field is not accessible because its dicriminant's ## value does not fit. ## ## See the full `exception hierarchy`_. - EOutOfRange* = object of ESynch ## \ + RangeError* = object of Exception ## \ ## Raised if a range check error occurred. ## ## See the full `exception hierarchy`_. - EStackOverflow* = object of ESystem ## \ + StackOverflowError* = object of SystemError ## \ ## Raised if the hardware stack used for subroutine calls overflowed. ## ## See the full `exception hierarchy`_. - ENoExceptionToReraise* = object of ESynch ## \ + ReraiseError* = object of Exception ## \ ## Raised if there is no exception to reraise. ## ## See the full `exception hierarchy`_. - EInvalidObjectAssignment* = object of ESynch ## \ + ObjectAssignmentError* = object of Exception ## \ ## Raised if an object gets assigned to its parent's object. ## ## See the full `exception hierarchy`_. - EInvalidObjectConversion* = object of ESynch ## \ + ObjectConversionError* = object of Exception ## \ ## Raised if an object is converted to an incompatible object type. ## ## See the full `exception hierarchy`_. - EFloatingPoint* = object of ESynch ## \ + FloatingPointError* = object of Exception ## \ ## Base class for floating point exceptions. ## ## See the full `exception hierarchy`_. - EFloatInvalidOp* {.compilerproc.} = object of EFloatingPoint ## \ + FloatInvalidOpError* = object of FloatingPointError ## \ ## Raised by invalid operations according to IEEE. ## ## Raised by ``0.0/0.0``, for example. See the full `exception ## hierarchy`_. - EFloatDivByZero* {.compilerproc.} = object of EFloatingPoint ## \ + FloatDivByZeroError* = object of FloatingPointError ## \ ## Raised by division by zero. ## ## Divisor is zero and dividend is a finite nonzero number. See the full ## `exception hierarchy`_. - EFloatOverflow* {.compilerproc.} = object of EFloatingPoint ## \ + FloatOverflowError* = object of FloatingPointError ## \ ## Raised for overflows. ## ## The operation produced a result that exceeds the range of the exponent. ## See the full `exception hierarchy`_. - EFloatUnderflow* {.compilerproc.} = object of EFloatingPoint ## \ + FloatUnderflowError* = object of FloatingPointError ## \ ## Raised for underflows. ## ## The operation produced a result that is too small to be represented as a ## normal number. See the full `exception hierarchy`_. - EFloatInexact* {.compilerproc.} = object of EFloatingPoint ## \ + FloatInexactError* = object of FloatingPointError ## \ ## Raised for inexact results. ## ## The operation produced a result that cannot be represented with infinite ## precision -- for example: ``2.0 / 3.0, log(1.1)`` ## - ## **NOTE**: Nimrod currently does not detect these! See the full + ## **NOTE**: Nim currently does not detect these! See the full ## `exception hierarchy`_. - EDeadThread* = object of ESynch ## \ + DeadThreadError* = object of Exception ## \ ## Raised if it is attempted to send a message to a dead thread. ## ## See the full `exception hierarchy`_. - TResult* = enum Failure, Success + TResult* {.deprecated.} = enum Failure, Success + +{.deprecated: [TObject: RootObj, PObject: RootRef, TEffect: RootEffect, + FTime: TimeEffect, FIO: IOEffect, FReadIO: ReadIOEffect, + FWriteIO: WriteIOEffect, FExecIO: ExecIOEffect, + + E_Base: Exception, ESystem: SystemError, EIO: IOError, + EOS: OSError, EInvalidLibrary: LibraryError, + EResourceExhausted: ResourceExhaustedError, + EArithmetic: ArithmeticError, EDivByZero: DivByZeroError, + EOverflow: OverflowError, EAccessViolation: AccessViolationError, + EAssertionFailed: AssertionError, EInvalidValue: ValueError, + EInvalidKey: KeyError, EOutOfMemory: OutOfMemError, + EInvalidIndex: IndexError, EInvalidField: FieldError, + EOutOfRange: RangeError, EStackOverflow: StackOverflowError, + ENoExceptionToReraise: ReraiseError, + EInvalidObjectAssignment: ObjectAssignmentError, + EInvalidObjectConversion: ObjectConversionError, + EDeadThread: DeadThreadError, + EFloatInexact: FloatInexactError, + EFloatUnderflow: FloatUnderflowError, + EFloatingPoint: FloatingPointError, + EFloatInvalidOp: FloatInvalidOpError, + EFloatDivByZero: FloatDivByZeroError, + EFloatOverflow: FloatOverflowError, + ESynch: Exception +].} proc sizeof*[T](x: T): Natural {.magic: "SizeOf", noSideEffect.} ## returns the size of ``x`` in bytes. Since this is a low-level proc, @@ -484,7 +510,7 @@ proc sizeof*[T](x: T): Natural {.magic: "SizeOf", noSideEffect.} proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect.} ## unary ``<`` that can be used for nice looking excluding ranges: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for i in 0 .. <10: echo i ## ## Semantically this is the same as ``pred``. @@ -519,7 +545,7 @@ proc newSeq*[T](s: var seq[T], len: int) {.magic: "NewSeq", noSideEffect.} ## ``nil``. After the creation of the sequence you should assign entries to ## the sequence instead of adding them. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var inputStrings : seq[string] ## newSeq(inputStrings, 3) ## inputStrings[0] = "The fourth" @@ -535,7 +561,7 @@ proc newSeq*[T](len = 0): seq[T] = ## ``nil``. After the creation of the sequence you should assign entries to ## the sequence instead of adding them. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var inputStrings = newSeq[string](3) ## inputStrings[0] = "The fourth" ## inputStrings[1] = "assignment" @@ -666,7 +692,7 @@ proc `div` *(x, y: int32): int32 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int64): int64 {.magic: "DivI64", noSideEffect.} ## computes the integer division. This is roughly the same as ## ``floor(x/y)``. - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## 1 div 2 == 0 ## 2 div 2 == 1 ## 3 div 2 == 1 @@ -685,7 +711,7 @@ proc `shr` *(x, y: int16): int16 {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int32): int32 {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int64): int64 {.magic: "ShrI64", noSideEffect.} ## computes the `shift right` operation of `x` and `y`. - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## 0b0001_0000'i8 shr 2 == 0b0100_0000'i8 ## 0b1000_0000'i8 shr 2 == 0b0000_0000'i8 ## 0b0000_0001'i8 shr 9 == 0b0000_0000'i8 @@ -824,12 +850,12 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} ## One should overload this proc if one wants to overload the ``in`` operator. ## The parameters are in reverse order! ``a in b`` is a template for ## ``contains(b, a)``. - ## This is because the unification algorithm that Nimrod uses for overload + ## This is because the unification algorithm that Nim uses for overload ## resolution works from left to right. ## But for the ``in`` operator that would be the wrong direction for this ## piece of code: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## var s: set[range['a'..'z']] = {'a'..'c'} ## writeln(stdout, 'b' in s) ## @@ -839,11 +865,11 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} ## is achieved by reversing the parameters for ``contains``; ``in`` then ## passes its arguments in reverse order. -proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} = +proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} = ## Checks if `value` is withing the range of `s`; returns true iff ## `value >= s.a and value <= s.b` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert((1..3).contains(1) == true) ## assert((1..3).contains(2) == true) ## assert((1..3).contains(4) == false) @@ -852,20 +878,20 @@ proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} = template `in` * (x, y: expr): expr {.immediate, dirty.} = contains(y, x) ## Sugar for contains ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(1 in (1..3) == true) ## assert(5 in (1..3) == false) template `notin` * (x, y: expr): expr {.immediate, dirty.} = not contains(y, x) ## Sugar for not containing ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(1 notin (1..3) == false) ## assert(5 notin (1..3) == true) proc `is` *[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.} ## Checks if T is of the same type as S ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## proc test[T](a: T): int = ## when (T is int): ## return a @@ -880,7 +906,7 @@ template `isnot` *(x, y: expr): expr {.immediate.} = not (x is y) proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.} ## Checks if `x` has a type of `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(EFloatingPoint of EBase) ## assert(EIO of ESystem) ## assert(EDivByZero of EBase) @@ -936,25 +962,25 @@ proc `&` * (x: string, y: char): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` with `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert("ab" & 'c' == "abc") proc `&` * (x: char, y: char): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` and `y` into a string ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert('a' & 'b' == "ab") proc `&` * (x, y: string): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` and `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert("ab" & "cd" == "abcd") proc `&` * (x: char, y: string): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` with `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert('a' & "bc" == "abc") # implementation note: These must all have the same magic value "ConStrStr" so @@ -963,7 +989,7 @@ proc `&` * (x: char, y: string): string {. proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.} ## Appends `y` to `x` in place ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## var tmp = "" ## tmp.add('a') ## tmp.add('b') @@ -971,14 +997,14 @@ proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.} proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.} ## Concatenates `x` and `y` in place ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## var tmp = "" ## tmp.add("ab") ## tmp.add("cd") ## assert(tmp == "abcd") type - TEndian* = enum ## is a type describing the endianness of a processor. + Endianness* = enum ## is a type describing the endianness of a processor. littleEndian, bigEndian const @@ -994,23 +1020,23 @@ const ## is the time of compilation as a string of the form ## ``HH:MM:SS``. This works thanks to compiler magic. - NimrodVersion* {.magic: "NimrodVersion"}: string = "0.0.0" - ## is the version of Nimrod as a string. + NimVersion* {.magic: "NimrodVersion"}: string = "0.0.0" + ## is the version of Nim as a string. ## This works thanks to compiler magic. - NimrodMajor* {.magic: "NimrodMajor"}: int = 0 - ## is the major number of Nimrod's version. + NimMajor* {.magic: "NimrodMajor"}: int = 0 + ## is the major number of Nim's version. ## This works thanks to compiler magic. - NimrodMinor* {.magic: "NimrodMinor"}: int = 0 - ## is the minor number of Nimrod's version. + NimMinor* {.magic: "NimrodMinor"}: int = 0 + ## is the minor number of Nim's version. ## This works thanks to compiler magic. - NimrodPatch* {.magic: "NimrodPatch"}: int = 0 - ## is the patch number of Nimrod's version. + NimPatch* {.magic: "NimrodPatch"}: int = 0 + ## is the patch number of Nim's version. ## This works thanks to compiler magic. - cpuEndian* {.magic: "CpuEndian"}: TEndian = littleEndian + cpuEndian* {.magic: "CpuEndian"}: Endianness = littleEndian ## is the endianness of the target CPU. This is a valuable piece of ## information for low-level code only. This works thanks to compiler ## magic. @@ -1025,12 +1051,15 @@ const ## "i386", "alpha", "powerpc", "sparc", "amd64", "mips", "arm". seqShallowFlag = low(int) - + +{.deprecated: [TEndian: Endianness, NimrodVersion: NimVersion, + NimrodMajor: NimMajor, NimrodMinor: NimMinor, NimrodPatch: NimPatch].} + proc compileOption*(option: string): bool {. magic: "CompileOption", noSideEffect.} ## can be used to determine an on|off compile-time option. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when compileOption("floatchecks"): ## echo "compiled with floating point NaN and Inf checks" @@ -1038,7 +1067,7 @@ proc compileOption*(option, arg: string): bool {. magic: "CompileOptionArg", noSideEffect.} ## can be used to determine an enum compile-time option. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when compileOption("opt", "size") and compileOption("gc", "boehm"): ## echo "compiled with optimization for size and uses Boehm's GC" @@ -1095,7 +1124,7 @@ proc quit*(errorcode: int = QuitSuccess) {. ## procedures. It does *not* call the garbage collector to free all the ## memory, unless a quit procedure calls ``GC_collect``. ## - ## The proc ``quit(QuitSuccess)`` is called implicitly when your nimrod + ## The proc ``quit(QuitSuccess)`` is called implicitly when your nim ## program finishes without incident. A raised unhandled exception is ## equivalent to calling ``quit(QuitFailure)``. ## @@ -1117,7 +1146,7 @@ proc add *[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} = ## Generic proc for adding a data item `y` to a container `x`. ## For containers that have an order, `add` means *append*. New generic ## containers should also call their adding proc `add` for consistency. - ## Generic code becomes much easier to write if the Nimrod naming scheme is + ## Generic code becomes much easier to write if the Nim naming scheme is ## respected. let xl = x.len setLen(x, xl + y.len) @@ -1155,25 +1184,27 @@ proc insert*[T](x: var seq[T], item: T, i = 0) {.noSideEffect.} = x[i] = item proc repr*[T](x: T): string {.magic: "Repr", noSideEffect.} - ## takes any Nimrod variable and returns its string representation. It + ## takes any Nim variable and returns its string representation. It ## works even for complex data graphs with cycles. This is a great ## debugging tool. type - TAddress* = int + ByteAddress* = int ## is the signed integer type that should be used for converting ## pointers to integer addresses for readability. BiggestInt* = int64 - ## is an alias for the biggest signed integer type the Nimrod compiler + ## is an alias for the biggest signed integer type the Nim compiler ## supports. Currently this is ``int64``, but it is platform-dependant ## in general. BiggestFloat* = float64 - ## is an alias for the biggest floating point type the Nimrod + ## is an alias for the biggest floating point type the Nim ## compiler supports. Currently this is ``float64``, but it is ## platform-dependant in general. +{.deprecated: [TAddress: ByteAddress].} + when defined(windows): type clong* {.importc: "long", nodecl.} = int32 @@ -1206,7 +1237,7 @@ type # these work for most platforms: ## 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 Nimrod's code generator + ## This C type is not supported by Nim's code generator cuchar* {.importc: "unsigned char", nodecl.} = char ## This is the same as the type ``unsigned char`` in *C*. @@ -1560,7 +1591,7 @@ iterator `||`*[S, T](a: S, b: T, annotation=""): T {. ## Note that the compiler maps that to ## the ``#pragma omp parallel for`` construct of `OpenMP`:idx: and as ## such isn't aware of the parallelism in your code! Be careful! Later - ## versions of ``||`` will get proper support by Nimrod's code generator + ## versions of ``||`` will get proper support by Nim's code generator ## and GC. discard @@ -1612,7 +1643,7 @@ proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.} = proc clamp*[T](x, a, b: T): T = ## limits the value ``x`` within the interval [a, b] ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert((1.4).clamp(0.0, 1.0) == 1.0) ## assert((0.5).clamp(0.0, 1.0) == 0.5) if x < a: return a @@ -1716,7 +1747,7 @@ proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect.} = ## Concatenates two sequences. ## Requires copying of the sequences. ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6]) newSeq(result, x.len + y.len) for i in 0..x.len-1: @@ -1728,7 +1759,7 @@ proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect.} = ## Appends element y to the end of the sequence. ## Requires copying of the sequence ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(@[1, 2, 3] & 4 == @[1, 2, 3, 4]) newSeq(result, x.len + 1) for i in 0..x.len-1: @@ -1739,7 +1770,7 @@ proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} = ## Prepends the element x to the beginning of the sequence. ## Requires copying of the sequence ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(1 & @[2, 3, 4] == @[1, 2, 3, 4]) newSeq(result, y.len + 1) result[0] = x @@ -1810,7 +1841,7 @@ proc map*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): seq[S] = ## Since the input is not modified you can use this version of ``map`` to ## transform the type of the elements in the input sequence. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let ## a = @[1, 2, 3, 4] ## b = map(a, proc(x: int): string = $x) @@ -1824,7 +1855,7 @@ proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) = ## Note that this version of ``map`` requires your input and output types to ## be the same, since they are modified in-place. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var a = @["1", "2", "3", "4"] ## echo repr(a) ## # --> ["1", "2", "3", "4"] @@ -1833,7 +1864,7 @@ proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) = ## # --> ["142", "242", "342", "442"] for i in 0..data.len-1: op(data[i]) -iterator fields*[T: tuple|object](x: T): TObject {. +iterator fields*[T: tuple|object](x: T): RootObj {. magic: "Fields", noSideEffect.} ## iterates over every field of `x`. Warning: This really transforms ## the 'for' and unrolls the loop. The current implementation also has a bug @@ -1844,7 +1875,7 @@ iterator fields*[S:tuple|object, T:tuple|object](x: S, y: T): tuple[a,b: expr] { ## Warning: This is really transforms the 'for' and unrolls the loop. ## The current implementation also has a bug that affects symbol binding ## in the loop body. -iterator fieldPairs*[T: tuple|object](x: T): TObject {. +iterator fieldPairs*[T: tuple|object](x: T): RootObj {. magic: "FieldPairs", noSideEffect.} ## Iterates over every field of `x` returning their name and value. ## @@ -1853,7 +1884,7 @@ iterator fieldPairs*[T: tuple|object](x: T): TObject {. ## you want to run for each type. To perform the comparison use the `is ## operator <manual.html#is-operator>`_. Example: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## ## type ## Custom = object @@ -1915,7 +1946,7 @@ proc `$`*[T: tuple|object](x: T): string = ## generic ``$`` operator for tuples that is lifted from the components ## of `x`. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## $(23, 45) == "(23, 45)" ## $() == "()" result = "(" @@ -1941,7 +1972,7 @@ proc `$`*[T](x: set[T]): string = ## generic ``$`` operator for sets that is lifted from the components ## of `x`. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ${23, 45} == "{23, 45}" collectionToString(x, "{", "}") @@ -1949,7 +1980,7 @@ proc `$`*[T](x: seq[T]): string = ## generic ``$`` operator for seqs that is lifted from the components ## of `x`. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## $(@[23, 45]) == "@[23, 45]" collectionToString(x, "@[", "]") @@ -1975,13 +2006,15 @@ when not defined(nimrodVM) and hostOS != "standalone": ## Ordinary code does not need to call this (and should not). type - TGC_Strategy* = enum ## the strategy the GC should use for the application + GC_Strategy* = enum ## the strategy the GC should use for the application gcThroughput, ## optimize for throughput gcResponsiveness, ## optimize for responsiveness (default) gcOptimizeTime, ## optimize for speed gcOptimizeSpace ## optimize for memory footprint - proc GC_setStrategy*(strategy: TGC_Strategy) {.rtl, deprecated.} + {.deprecated: [TGC_Strategy: GC_Strategy].} + + proc GC_setStrategy*(strategy: GC_Strategy) {.rtl, deprecated.} ## tells the GC the desired strategy for the application. ## **Deprecated** since version 0.8.14. This has always been a nop. @@ -2015,7 +2048,7 @@ template accumulateResult*(iter: expr) = for x in iter: add(result, x) # we have to compute this here before turning it off in except.nim anyway ... -const nimrodStackTrace = compileOption("stacktrace") +const NimStackTrace = compileOption("stacktrace") {.push checks: off.} # obviously we cannot generate checking operations here :-) @@ -2024,7 +2057,7 @@ const nimrodStackTrace = compileOption("stacktrace") # of the code var - globalRaiseHook*: proc (e: ref E_Base): bool {.nimcall, gcsafe.} + globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, gcsafe.} ## with this hook you can influence exception handling on a global level. ## If not nil, every 'raise' statement ends up calling this hook. Ordinary ## application code should never set this hook! You better know what you @@ -2032,7 +2065,7 @@ var ## exception is caught and does not propagate further through the call ## stack. - localRaiseHook* {.threadvar.}: proc (e: ref E_Base): bool {.nimcall, gcsafe.} + localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, gcsafe.} ## with this hook you can influence exception handling on a ## thread local level. ## If not nil, every 'raise' statement ends up calling this hook. Ordinary @@ -2046,7 +2079,7 @@ var ## writes an error message and terminates the program. `outOfMemHook` can ## be used to raise an exception in case of OOM like so: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## var gOutOfMem: ref EOutOfMemory ## new(gOutOfMem) # need to be allocated *before* OOM really happened! @@ -2092,7 +2125,7 @@ elif hostOS != "standalone": inc(i) {.pop.} -proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [FWriteIO], gcsafe.} +proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], gcsafe.} ## Writes and flushes the parameters to the standard output. ## ## Special built-in that takes a variable number of arguments. Each argument @@ -2224,9 +2257,9 @@ when not defined(JS): #and not defined(NimrodVM): type CFile {.importc: "FILE", header: "<stdio.h>", final, incompletestruct.} = object - TFile* = ptr CFile ## The type representing a file handle. + File* = ptr CFile ## The type representing a file handle. - TFileMode* = enum ## The file mode when opening a file. + FileMode* = enum ## The file mode when opening a file. fmRead, ## Open the file for read access only. fmWrite, ## Open the file for write access only. fmReadWrite, ## Open the file for read and write access. @@ -2238,49 +2271,51 @@ when not defined(JS): #and not defined(NimrodVM): fmAppend ## Open the file for writing only; append data ## at the end. - TFileHandle* = cint ## type that represents an OS file handle; this is - ## useful for low-level file access + FileHandle* = cint ## type that represents an OS file handle; this is + ## useful for low-level file access + + {.deprecated: [TFile: File, TFileHandle: FileHandle, TFileMode: FileMode].} # text file handling: var - stdin* {.importc: "stdin", header: "<stdio.h>".}: TFile + stdin* {.importc: "stdin", header: "<stdio.h>".}: File ## The standard input stream. - stdout* {.importc: "stdout", header: "<stdio.h>".}: TFile + stdout* {.importc: "stdout", header: "<stdio.h>".}: File ## The standard output stream. - stderr* {.importc: "stderr", header: "<stdio.h>".}: TFile + stderr* {.importc: "stderr", header: "<stdio.h>".}: File ## The standard error stream. when defined(useStdoutAsStdmsg): - template stdmsg*: TFile = stdout + template stdmsg*: File = stdout else: - template stdmsg*: TFile = stderr + template stdmsg*: File = stderr ## Template which expands to either stdout or stderr depending on ## `useStdoutAsStdmsg` compile-time switch. - proc open*(f: var TFile, filename: string, - mode: TFileMode = fmRead, bufSize: int = -1): bool {.tags: [], + proc open*(f: var File, filename: string, + mode: FileMode = fmRead, bufSize: int = -1): bool {.tags: [], gcsafe.} ## Opens a file named `filename` with given `mode`. ## ## Default mode is readonly. Returns true iff the file could be opened. ## This throws no exception if the file could not be opened. - proc open*(f: var TFile, filehandle: TFileHandle, - mode: TFileMode = fmRead): bool {.tags: [], gcsafe.} + proc open*(f: var File, filehandle: FileHandle, + mode: FileMode = fmRead): bool {.tags: [], gcsafe.} ## Creates a ``TFile`` from a `filehandle` with given `mode`. ## ## Default mode is readonly. Returns true iff the file could be opened. proc open*(filename: string, - mode: TFileMode = fmRead, bufSize: int = -1): TFile = + mode: FileMode = fmRead, bufSize: int = -1): File = ## Opens a file named `filename` with given `mode`. ## ## Default mode is readonly. Raises an ``IO`` exception if the file ## could not be opened. if not open(result, filename, mode, bufSize): - sysFatal(EIO, "cannot open: ", filename) + sysFatal(IOError, "cannot open: ", filename) - proc reopen*(f: TFile, filename: string, mode: TFileMode = fmRead): bool {. + proc reopen*(f: File, filename: string, mode: FileMode = fmRead): bool {. tags: [], gcsafe.} ## reopens the file `f` with given `filename` and `mode`. This ## is often used to redirect the `stdin`, `stdout` or `stderr` @@ -2288,52 +2323,52 @@ when not defined(JS): #and not defined(NimrodVM): ## ## Default mode is readonly. Returns true iff the file could be reopened. - proc close*(f: TFile) {.importc: "fclose", header: "<stdio.h>", tags: [].} + proc close*(f: File) {.importc: "fclose", header: "<stdio.h>", tags: [].} ## Closes the file. - proc endOfFile*(f: TFile): bool {.tags: [], gcsafe.} + proc endOfFile*(f: File): bool {.tags: [], gcsafe.} ## Returns true iff `f` is at the end. - proc readChar*(f: TFile): char {. - importc: "fgetc", header: "<stdio.h>", tags: [FReadIO].} + proc readChar*(f: File): char {. + importc: "fgetc", header: "<stdio.h>", tags: [ReadIOEffect].} ## Reads a single character from the stream `f`. - proc flushFile*(f: TFile) {. - importc: "fflush", header: "<stdio.h>", tags: [FWriteIO].} + proc flushFile*(f: File) {. + importc: "fflush", header: "<stdio.h>", tags: [WriteIOEffect].} ## Flushes `f`'s buffer. - proc readAll*(file: TFile): TaintedString {.tags: [FReadIO], gcsafe.} + proc readAll*(file: File): TaintedString {.tags: [ReadIOEffect], gcsafe.} ## Reads all data from the stream `file`. ## ## Raises an IO exception in case of an error. It is an error if the ## current file position is not at the beginning of the file. - proc readFile*(filename: string): TaintedString {.tags: [FReadIO], gcsafe.} + proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], gcsafe.} ## Opens a file named `filename` for reading. Then calls `readAll` ## and closes the file afterwards. Returns the string. ## Raises an IO exception in case of an error. - proc writeFile*(filename, content: string) {.tags: [FWriteIO], gcsafe.} + proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], gcsafe.} ## Opens a file named `filename` for writing. Then writes the ## `content` completely to the file and closes the file afterwards. ## Raises an IO exception in case of an error. - proc write*(f: TFile, r: float32) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, i: int) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, i: BiggestInt) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, r: BiggestFloat) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, s: string) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, b: bool) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, c: char) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, c: cstring) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, a: varargs[string, `$`]) {.tags: [FWriteIO], gcsafe.} + proc write*(f: File, r: float32) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, i: int) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, i: BiggestInt) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, s: string) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, b: bool) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, c: char) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, c: cstring) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, a: varargs[string, `$`]) {.tags: [WriteIOEffect], gcsafe.} ## Writes a value to the file `f`. May throw an IO exception. - proc readLine*(f: TFile): TaintedString {.tags: [FReadIO], gcsafe.} + proc readLine*(f: File): TaintedString {.tags: [ReadIOEffect], gcsafe.} ## reads a line of text from the file `f`. May throw an IO exception. ## A line of text may be delimited by ``CR``, ``LF`` or ## ``CRLF``. The newline character(s) are not part of the returned string. - proc readLine*(f: TFile, line: var TaintedString): bool {.tags: [FReadIO], + proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect], gcsafe.} ## reads a line of text from the file `f` into `line`. `line` must not be ## ``nil``! May throw an IO exception. @@ -2343,66 +2378,69 @@ when not defined(JS): #and not defined(NimrodVM): ## otherwise. If ``false`` is returned `line` contains no new data. when not defined(booting): - proc writeln*[Ty](f: TFile, x: varargs[Ty, `$`]) {.inline, - tags: [FWriteIO], gcsafe.} + proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, + tags: [WriteIOEffect], gcsafe.} ## writes the values `x` to `f` and then writes "\n". ## May throw an IO exception. else: - proc writeln*[Ty](f: TFile, x: varargs[Ty, `$`]) {.inline, - tags: [FWriteIO].} + proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, + tags: [WriteIOEffect].} - proc getFileSize*(f: TFile): int64 {.tags: [FReadIO], gcsafe.} + proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], gcsafe.} ## retrieves the file size (in bytes) of `f`. - proc readBytes*(f: TFile, a: var openArray[int8], start, len: int): int {. - tags: [FReadIO], gcsafe.} + proc readBytes*(f: File, a: var openArray[int8], start, len: int): int {. + tags: [ReadIOEffect], gcsafe.} ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc readChars*(f: TFile, a: var openArray[char], start, len: int): int {. - tags: [FReadIO], gcsafe.} + proc readChars*(f: File, a: var openArray[char], start, len: int): int {. + tags: [ReadIOEffect], gcsafe.} ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc readBuffer*(f: TFile, buffer: pointer, len: int): int {. - tags: [FReadIO], gcsafe.} + proc readBuffer*(f: File, buffer: pointer, len: int): int {. + tags: [ReadIOEffect], gcsafe.} ## reads `len` bytes into the buffer pointed to by `buffer`. Returns ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc writeBytes*(f: TFile, a: openArray[int8], start, len: int): int {. - tags: [FWriteIO], gcsafe.} + proc writeBytes*(f: File, a: openArray[int8], start, len: int): int {. + tags: [WriteIOEffect], gcsafe.} ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns ## the number of actual written bytes, which may be less than `len` in case ## of an error. - proc writeChars*(f: TFile, a: openArray[char], start, len: int): int {. - tags: [FWriteIO], gcsafe.} + proc writeChars*(f: File, a: openArray[char], start, len: int): int {. + tags: [WriteIOEffect], gcsafe.} ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns ## the number of actual written bytes, which may be less than `len` in case ## of an error. - proc writeBuffer*(f: TFile, buffer: pointer, len: int): int {. - tags: [FWriteIO], gcsafe.} + proc writeBuffer*(f: File, buffer: pointer, len: int): int {. + tags: [WriteIOEffect], gcsafe.} ## writes the bytes of buffer pointed to by the parameter `buffer` to the ## file `f`. Returns the number of actual written bytes, which may be less ## than `len` in case of an error. - proc setFilePos*(f: TFile, pos: int64) {.gcsafe.} + proc setFilePos*(f: File, pos: int64) {.gcsafe.} ## sets the position of the file pointer that is used for read/write ## operations. The file's first byte has the index zero. - proc getFilePos*(f: TFile): int64 {.gcsafe.} + proc getFilePos*(f: File): int64 {.gcsafe.} ## retrieves the current position of the file pointer that is used to ## read from the file `f`. The file's first byte has the index zero. - proc fileHandle*(f: TFile): TFileHandle {.importc: "fileno", - header: "<stdio.h>"} + proc getFileHandle*(f: File): FileHandle {.importc: "fileno", + header: "<stdio.h>"} ## returns the OS file handle of the file ``f``. This is only useful for ## platform specific programming. + when not defined(nimfix): + {.deprecated: [fileHandle: getFileHandle].} + proc cstringArrayToSeq*(a: cstringArray, len: int): seq[string] = ## converts a ``cstringArray`` to a ``seq[string]``. `a` is supposed to be ## of length ``len``. @@ -2454,7 +2492,7 @@ when not defined(JS): #and not defined(NimrodVM): status: int context: C_JmpBuf hasRaiseAction: bool - raiseAction: proc (e: ref E_Base): bool {.closure.} + raiseAction: proc (e: ref Exception): bool {.closure.} when declared(initAllocator): initAllocator() @@ -2470,14 +2508,14 @@ when not defined(JS): #and not defined(NimrodVM): ## allows you to override the behaviour of your application when CTRL+C ## is pressed. Only one such hook is supported. - proc writeStackTrace*() {.tags: [FWriteIO].} + proc writeStackTrace*() {.tags: [WriteIOEffect].} ## writes the current stack trace to ``stderr``. This is only works ## for debug builds. when hostOS != "standalone": proc getStackTrace*(): string ## gets the current stack trace. This only works for debug builds. - proc getStackTrace*(e: ref E_Base): string + proc getStackTrace*(e: ref Exception): string ## gets the stack trace associated with `e`, which is the stack that ## lead to the ``raise`` statement. This only works for debug builds. @@ -2505,7 +2543,7 @@ when not defined(JS): #and not defined(NimrodVM): proc getDiscriminant(aa: pointer, n: ptr TNimNode): int = sysAssert(n.kind == nkCase, "getDiscriminant: node != nkCase") var d: int - var a = cast[TAddress](aa) + var a = cast[ByteAddress](aa) case n.typ.size of 1: d = ze(cast[ptr int8](a +% n.offset)[]) of 2: d = ze(cast[ptr int16](a +% n.offset)[]) @@ -2534,13 +2572,13 @@ when not defined(JS): #and not defined(NimrodVM): include "system/sysio" when hostOS != "standalone": - iterator lines*(filename: string): TaintedString {.tags: [FReadIO].} = + iterator lines*(filename: string): TaintedString {.tags: [ReadIOEffect].} = ## Iterates over any line in the file named `filename`. ## ## If the file does not exist `EIO` is raised. The trailing newline ## character(s) are removed from the iterated lines. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## import strutils ## ## proc transformLetters(filename: string) = @@ -2553,14 +2591,14 @@ when not defined(JS): #and not defined(NimrodVM): while f.readLine(res): yield res close(f) - iterator lines*(f: TFile): TaintedString {.tags: [FReadIO].} = + iterator lines*(f: File): TaintedString {.tags: [ReadIOEffect].} = ## Iterate over any line in the file `f`. ## ## The trailing newline character(s) are removed from the iterated lines. ## Example: ## - ## .. code-block:: nimrod - ## proc countZeros(filename: TFile): tuple[lines, zeros: int] = + ## .. code-block:: nim + ## proc countZeros(filename: File): tuple[lines, zeros: int] = ## for line in filename.lines: ## for letter in line: ## if letter == '0': @@ -2573,7 +2611,7 @@ when not defined(JS): #and not defined(NimrodVM): include "system/assign" include "system/repr" - proc getCurrentException*(): ref E_Base {.compilerRtl, inl, gcsafe.} = + proc getCurrentException*(): ref Exception {.compilerRtl, inl, gcsafe.} = ## retrieves the current exception; if there is none, nil is returned. result = currException @@ -2583,7 +2621,7 @@ when not defined(JS): #and not defined(NimrodVM): var e = getCurrentException() return if e == nil: "" else: e.msg - proc onRaise*(action: proc(e: ref E_Base): bool{.closure.}) = + proc onRaise*(action: proc(e: ref Exception): bool{.closure.}) = ## can be used in a ``try`` statement to setup a Lisp-like ## `condition system`:idx:\: This prevents the 'raise' statement to ## raise an exception but instead calls ``action``. @@ -2593,6 +2631,12 @@ when not defined(JS): #and not defined(NimrodVM): excHandler.hasRaiseAction = true excHandler.raiseAction = action + proc setCurrentException*(exc: ref Exception) {.inline, gcsafe.} = + ## sets the current exception. + ## + ## **Warning**: Only use this if you know what you are doing. + currException = exc + {.push stack_trace: off, profiler:off.} when defined(endb) and not defined(NimrodVM): include "system/debugger" @@ -2609,7 +2653,7 @@ when not defined(JS): #and not defined(NimrodVM): ## platforms this can help the processor predict better which branch is ## going to be run. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for value in inputValues: ## if likely(value <= 100): ## process(value) @@ -2623,7 +2667,7 @@ when not defined(JS): #and not defined(NimrodVM): ## platforms this can help the processor predict better which branch is ## going to be run. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for value in inputValues: ## if unlikely(value > 100): ## echo "Value too big!" @@ -2657,7 +2701,7 @@ elif defined(JS): proc GC_disable() = discard proc GC_enable() = discard proc GC_fullCollect() = discard - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = discard proc GC_disableMarkAndSweep() = discard proc GC_getStatistics(): string = return "" @@ -2669,7 +2713,7 @@ elif defined(JS): proc dealloc(p: pointer) = discard proc alloc(size: int): pointer = discard proc alloc0(size: int): pointer = discard - proc realloc(p: Pointer, newsize: int): pointer = discard + proc realloc(p: pointer, newsize: int): pointer = discard proc allocShared(size: int): pointer = discard proc allocShared0(size: int): pointer = discard @@ -2721,16 +2765,16 @@ template spliceImpl(s, a, L, b: expr): stmt {.immediate.} = for i in 0 .. <b.len: s[i+a] = b[i] when hostOS != "standalone": - proc `[]`*(s: string, x: TSlice[int]): string {.inline.} = + proc `[]`*(s: string, x: Slice[int]): string {.inline.} = ## slice operation for strings. Negative indexes are supported. result = s.substr(x.a-|s, x.b-|s) - proc `[]=`*(s: var string, x: TSlice[int], b: string) = + proc `[]=`*(s: var string, x: Slice[int], b: string) = ## slice assignment for strings. Negative indexes are supported. If ## ``b.len`` is not exactly the number of elements that are referred to ## by `x`, a `splice`:idx: is performed: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var s = "abcdef" ## s[1 .. -2] = "xyz" ## assert s == "axyzf" @@ -2741,7 +2785,7 @@ when hostOS != "standalone": else: spliceImpl(s, a, L, b) -proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[int]): seq[T] = +proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[int]): seq[T] = ## slice operation for arrays. Negative indexes are **not** supported ## because the array might have negative bounds. when low(a) < 0: @@ -2750,7 +2794,7 @@ proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[int]): seq[T] = newSeq(result, L) for i in 0.. <L: result[i] = a[i + x.a] -proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[int], b: openArray[T]) = +proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[int], b: openArray[T]) = ## slice assignment for arrays. Negative indexes are **not** supported ## because the array might have negative bounds. when low(a) < 0: @@ -2759,9 +2803,9 @@ proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[int], b: openArray[T]) = if L == b.len: for i in 0 .. <L: a[i+x.a] = b[i] else: - sysFatal(EOutOfRange, "different lengths for slice assignment") + sysFatal(RangeError, "different lengths for slice assignment") -proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[Idx]): seq[T] = +proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[Idx]): seq[T] = ## slice operation for arrays. Negative indexes are **not** supported ## because the array might have negative bounds. var L = ord(x.b) - ord(x.a) + 1 @@ -2771,7 +2815,7 @@ proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[Idx]): seq[T] = result[i] = a[j] inc(j) -proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[Idx], b: openArray[T]) = +proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[Idx], b: openArray[T]) = ## slice assignment for arrays. Negative indexes are **not** supported ## because the array might have negative bounds. var L = ord(x.b) - ord(x.a) + 1 @@ -2781,16 +2825,16 @@ proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[Idx], b: openArray[T]) = a[j] = b[i] inc(j) else: - sysFatal(EOutOfRange, "different lengths for slice assignment") + sysFatal(RangeError, "different lengths for slice assignment") -proc `[]`*[T](s: seq[T], x: TSlice[int]): seq[T] = +proc `[]`*[T](s: seq[T], x: Slice[int]): seq[T] = ## slice operation for sequences. Negative indexes are supported. var a = x.a-|s var L = x.b-|s - a + 1 newSeq(result, L) for i in 0.. <L: result[i] = s[i + a] -proc `[]=`*[T](s: var seq[T], x: TSlice[int], b: openArray[T]) = +proc `[]=`*[T](s: var seq[T], x: Slice[int], b: openArray[T]) = ## slice assignment for sequences. Negative indexes are supported. If ## ``b.len`` is not exactly the number of elements that are referred to ## by `x`, a `splice`:idx: is performed. @@ -2807,7 +2851,7 @@ proc slurp*(filename: string): string {.magic: "Slurp".} proc staticRead*(filename: string): string {.magic: "Slurp".} ## Compile-time ``readFile`` proc for easy `resource`:idx: embedding: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## const myResource = staticRead"mydatafile.bin" ## ## ``slurp`` is an alias for ``staticRead``. @@ -2822,21 +2866,21 @@ proc staticExec*(command: string, input = ""): string {. ## if `input` is not an empty string, it will be passed as a standard input ## to the executed program. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## const buildInfo = "Revision " & staticExec("git rev-parse HEAD") & ## "\nCompiled on " & staticExec("uname -v") ## ## ``gorge`` is an alias for ``staticExec``. Note that you can use this proc - ## inside a pragma like `passC <nimrodc.html#passc-pragma>`_ or `passL - ## <nimrodc.html#passl-pragma>`_. + ## inside a pragma like `passC <nimc.html#passc-pragma>`_ or `passL + ## <nimc.html#passl-pragma>`_. -proc `+=`*[T: TOrdinal|uint|uint64](x: var T, y: T) {.magic: "Inc", noSideEffect.} +proc `+=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.magic: "Inc", noSideEffect.} ## Increments an ordinal -proc `-=`*[T: TOrdinal|uint|uint64](x: var T, y: T) {.magic: "Dec", noSideEffect.} +proc `-=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.magic: "Dec", noSideEffect.} ## Decrements an ordinal -proc `*=`*[T: TOrdinal|uint|uint64](x: var T, y: T) {.inline, noSideEffect.} = +proc `*=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.inline, noSideEffect.} = ## Binary `*=` operator for ordinals x = x * y @@ -2870,7 +2914,7 @@ proc instantiationInfo*(index = -1, fullPaths = false): tuple[ ## to retrieve information about the current filename and line number. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## import strutils ## ## template testException(exception, code: expr): stmt = @@ -2897,7 +2941,7 @@ template currentSourcePath*: string = instantiationInfo(-1, true).filename ## returns the full file-system path of the current source proc raiseAssert*(msg: string) {.noinline.} = - sysFatal(EAssertionFailed, msg) + sysFatal(AssertionError, msg) when true: proc failedAssertImpl*(msg: string) {.raises: [], tags: [].} = @@ -2910,12 +2954,12 @@ when true: template assert*(cond: bool, msg = "") = ## Raises ``EAssertionFailure`` with `msg` if `cond` is false. ## - ## Provides a means to implement `programming by contracts`:idx: in Nimrod. + ## Provides a means to implement `programming by contracts`:idx: in Nim. ## ``assert`` evaluates expression ``cond`` and if ``cond`` is false, it ## raises an ``EAssertionFailure`` exception. However, the compiler may not ## generate any code at all for ``assert`` if it is advised to do so through ## the ``-d:release`` or ``--assertions:off`` `command line switches - ## <nimrodc.html#command-line-switches>`_. + ## <nimc.html#command-line-switches>`_. ## ## Use ``assert`` for debugging purposes only. bind instantiationInfo @@ -2958,7 +3002,7 @@ template onFailedAssert*(msg: expr, code: stmt): stmt {.dirty, immediate.} = ## statements following `onFailedAssert` in the current lexical scope. ## Can be defined multiple times in a single function. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## proc example(x: int): TErrorCode = ## onFailedAssert(msg): @@ -2995,7 +3039,7 @@ proc shallow*(s: var string) {.noSideEffect, inline.} = type TNimrodNode {.final.} = object PNimrodNode* {.magic: "PNimrodNode".} = ref TNimrodNode - ## represents a Nimrod AST node. Macros operate on this type. + ## represents a Nim AST node. Macros operate on this type. when false: template eval*(blk: stmt): stmt = @@ -3024,7 +3068,7 @@ proc compiles*(x): bool {.magic: "Compiles", noSideEffect.} = ## without any semantic error. ## This can be used to check whether a type supports some operation: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## when not compiles(3 + 4): ## echo "'+' for integers is available" discard @@ -3046,14 +3090,14 @@ when hostOS != "standalone": if x == nil: x = y else: x.add(y) -proc locals*(): TObject {.magic: "Locals", noSideEffect.} = +proc locals*(): RootObj {.magic: "Locals", noSideEffect.} = ## generates a tuple constructor expression listing all the local variables ## in the current scope. This is quite fast as it does not rely ## on any debug or runtime information. Note that in constrast to what ## the official signature says, the return type is not ``TObject`` but a ## tuple of a structure that depends on the current scope. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## proc testLocals() = ## var ## a = "something" |