diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/manual.md | 46 | ||||
-rw-r--r-- | doc/manual_experimental.md | 35 | ||||
-rw-r--r-- | doc/nimdoc.css | 9 | ||||
-rw-r--r-- | doc/nims.md | 33 | ||||
-rw-r--r-- | doc/tut3.md | 30 |
5 files changed, 128 insertions, 25 deletions
diff --git a/doc/manual.md b/doc/manual.md index 045749450..5c36a0a7b 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -3220,6 +3220,15 @@ A const section declares constants whose values are constant expressions: Once declared, a constant's symbol can be used as a constant expression. +The value part of a constant declaration opens a new scope for each constant, +so no symbols declared in the constant value are accessible outside of it. + + ```nim + const foo = (var a = 1; a) + const bar = a # error + let baz = a # error + ``` + See [Constants and Constant Expressions] for details. Static statement/expression @@ -4454,7 +4463,42 @@ as an example: Overloading of the subscript operator ------------------------------------- -The `[]` subscript operator for arrays/openarrays/sequences can be overloaded. +The `[]` subscript operator for arrays/openarrays/sequences can be overloaded +for any type (with some exceptions) by defining a routine with the name `[]`. + + ```nim + type Foo = object + data: seq[int] + + proc `[]`(foo: Foo, i: int): int = + result = foo.data[i] + + let foo = Foo(data: @[1, 2, 3]) + echo foo[1] # 2 + ``` + +Assignment to subscripts can also be overloaded by naming a routine `[]=`, +which has precedence over assigning to the result of `[]`. + + ```nim + type Foo = object + data: seq[int] + + proc `[]`(foo: Foo, i: int): int = + result = foo.data[i] + proc `[]=`(foo: var Foo, i: int, val: int) = + foo.data[i] = val + + var foo = Foo(data: @[1, 2, 3]) + echo foo[1] # 2 + foo[1] = 5 + echo foo.data # @[1, 5, 3] + echo foo[1] # 5 + ``` + +Overloads of the subscript operator cannot be applied to routine or type +symbols themselves, as this conflicts with the syntax for instantiating +generic parameters, i.e. `foo[int](1, 2, 3)` or `Foo[int]`. Methods diff --git a/doc/manual_experimental.md b/doc/manual_experimental.md index 6998e313d..da51d59ad 100644 --- a/doc/manual_experimental.md +++ b/doc/manual_experimental.md @@ -2533,8 +2533,7 @@ renaming the captured symbols should be used instead so that the code is not affected by context changes. Since this change may affect runtime behavior, the experimental switch -`openSym`, or `genericsOpenSym` and `templateOpenSym` for only the respective -routines, needs to be enabled; and a warning is given in the case where an +`openSym` needs to be enabled; and a warning is given in the case where an injected symbol would replace a captured symbol not bound by `bind` and the experimental switch isn't enabled. @@ -2555,7 +2554,7 @@ template oldTempl(): string = value # warning: a new `value` has been injected, use `bind` or turn on `experimental:openSym` echo oldTempl() # "captured" -{.experimental: "openSym".} # or {.experimental: "genericsOpenSym".} for just generic procs +{.experimental: "openSym".} proc bar[T](): string = foo(123): @@ -2568,8 +2567,6 @@ proc baz[T](): string = return value assert baz[int]() == "captured" -# {.experimental: "templateOpenSym".} would be needed here if genericsOpenSym was used - template barTempl(): string = block: foo(123): @@ -2590,6 +2587,34 @@ modified `nnkOpenSymChoice` node but macros that want to support the experimental feature should still handle `nnkOpenSym`, as the node kind would simply not be generated as opposed to being removed. +Another experimental switch `genericsOpenSym` exists that enables this behavior +at instantiation time, meaning templates etc can enable it specifically when +they are being called. However this does not generate `nnkOpenSym` nodes +(unless the other switch is enabled) and so doesn't reflect the regular +behavior of the switch. + +```nim +const value = "captured" +template foo(x: int, body: untyped): untyped = + let value {.inject.} = "injected" + {.push experimental: "genericsOpenSym".} + body + {.pop.} + +proc bar[T](): string = + foo(123): + return value +echo bar[int]() # "injected" + +template barTempl(): string = + block: + var res: string + foo(123): + res = value + res +assert barTempl() == "injected" +``` + VTable for methods ================== diff --git a/doc/nimdoc.css b/doc/nimdoc.css index a9e4ac9c6..0c399e4c1 100644 --- a/doc/nimdoc.css +++ b/doc/nimdoc.css @@ -623,8 +623,8 @@ pre { table.line-nums-table { border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; + border: 1px solid var(--border); + background-color: var(--secondary-background); border-collapse: separate; margin-top: 15px; margin-bottom: 25px; } @@ -660,6 +660,9 @@ table { border-collapse: collapse; border-color: var(--third-background); border-spacing: 0; +} + +table:not(.line-nums-table) { font-size: 0.9em; } @@ -678,7 +681,7 @@ table th.docinfo-name { text-align: right; } -table tr:hover { +table:not(.line-nums-table) tr:hover { background-color: var(--third-background); } diff --git a/doc/nims.md b/doc/nims.md index 42cc6e124..987cc2096 100644 --- a/doc/nims.md +++ b/doc/nims.md @@ -61,43 +61,44 @@ Standard library modules At least the following standard library modules are available: -* [macros](macros.html) -* [os](os.html) -* [strutils](strutils.html) -* [math](math.html) -* [distros](distros.html) -* [sugar](sugar.html) * [algorithm](algorithm.html) * [base64](base64.html) * [bitops](bitops.html) * [chains](chains.html) * [colors](colors.html) * [complex](complex.html) +* [distros](distros.html) +* [std/editdistance](editdistance.html) * [htmlgen](htmlgen.html) +* [htmlparser](htmlparser.html) * [httpcore](httpcore.html) +* [json](json.html) * [lenientops](lenientops.html) +* [macros](macros.html) +* [math](math.html) * [options](options.html) +* [os](os.html) +* [parsecfg](parsecfg.html) +* [parsecsv](parsecsv.html) +* [parsejson](parsejson.html) +* [parsesql](parsesql.html) * [parseutils](parseutils.html) * [punycode](punycode.html) * [random](random.html) +* [ropes](ropes.html) +* [std/setutils](setutils.html) * [stats](stats.html) * [strformat](strformat.html) * [strmisc](strmisc.html) * [strscans](strscans.html) +* [strtabs](strtabs.html) +* [strutils](strutils.html) +* [sugar](sugar.html) * [unicode](unicode.html) +* [unidecode](unidecode.html) * [uri](uri.html) -* [std/editdistance](editdistance.html) * [std/wordwrap](wordwrap.html) -* [parsecsv](parsecsv.html) -* [parsecfg](parsecfg.html) -* [parsesql](parsesql.html) * [xmlparser](xmlparser.html) -* [htmlparser](htmlparser.html) -* [ropes](ropes.html) -* [json](json.html) -* [parsejson](parsejson.html) -* [strtabs](strtabs.html) -* [unidecode](unidecode.html) In addition to the standard Nim syntax ([system](system.html) module), NimScripts support the procs and templates defined in the diff --git a/doc/tut3.md b/doc/tut3.md index 67f49c879..3a55d4790 100644 --- a/doc/tut3.md +++ b/doc/tut3.md @@ -322,6 +322,36 @@ used to get this output. raise newException(AssertionDefect, $a & " != " & $b) ``` + +Going further +------------- + +It is possible to create more complex macros by combining different +`NimNode` symbols with `quote do:` expressions. For example, you may +use `newStmtList` to build your macro iteratively, and `ident` in cases +in which you wish to create an identifier from a string, as shown below. + + ```nim + import std/macros + + macro createProcedures() = + result = newStmtList() + + for i in 0..<10: + let name = ident("myProc" & $i) + let content = newLit("I am procedure number #" & $i) + + result.add quote do: + proc `name`() = + echo `content` + + createProcedures() + myProc7() + ``` + +The call to `myProc7` will echo `I am procedure number #7`. + + With Power Comes Responsibility ------------------------------- |