documented AST overloading and some TR optimizations
This commit is contained in:
parent
40b611cc2f
commit
92f8f2e776
6 changed files with 109 additions and 10 deletions
|
|
@ -3973,18 +3973,95 @@ parameter is of the type ``varargs`` it is treated specially and it can match
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Example: Partial evaluation
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
The following example shows how some simple partial evaluation can be
|
||||||
|
implemented with term rewriting:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
proc p(x, y: int; cond: bool): int =
|
||||||
|
result = if cond: x + y else: x - y
|
||||||
|
|
||||||
|
template optP{p(x, y, true)}(x, y: expr): expr = x + y
|
||||||
|
template optP{p(x, y, false)}(x, y: expr): expr = x - y
|
||||||
|
|
||||||
|
|
||||||
|
Example: hoisting
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The following example how some form of hoisting can be implemented:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
import pegs
|
||||||
|
|
||||||
|
template optPeg{peg(pattern)}(pattern: string{lit}): TPeg =
|
||||||
|
var gl {.global, gensym.} = peg(pattern)
|
||||||
|
gl
|
||||||
|
|
||||||
|
for i in 0 .. 3:
|
||||||
|
echo match("(a b c)", peg"'(' @ ')'")
|
||||||
|
echo match("W_HI_Le", peg"\y 'while'")
|
||||||
|
|
||||||
|
The ``optPeg`` template optimizes the case of a peg constructor with a string
|
||||||
|
literal, so that the pattern will only be parsed once at program startup and
|
||||||
|
stored in global ``gl`` which is then re-used. This optimization is called
|
||||||
|
hoisting because it is comparable to classical loop hoisting.
|
||||||
|
|
||||||
|
|
||||||
AST based overloading
|
AST based overloading
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Parameter constraints can also be used for ordinary routine parameters; these
|
Parameter constraints can also be used for ordinary routine parameters; these
|
||||||
constraints affect ordinary overloading resolution then:
|
constraints affect ordinary overloading resolution then:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
proc optLit(a: string{lit|`const`}) =
|
||||||
|
echo "string literal"
|
||||||
|
proc optLit(a: string) =
|
||||||
|
echo "no string literal"
|
||||||
|
|
||||||
|
const
|
||||||
|
constant = "abc"
|
||||||
|
|
||||||
|
var
|
||||||
|
variable = "xyz"
|
||||||
|
|
||||||
|
optLit("literal")
|
||||||
|
optLit(constant)
|
||||||
|
optLit(variable)
|
||||||
|
|
||||||
However, the constraints ``alias`` and ``noalias`` are not available in
|
However, the constraints ``alias`` and ``noalias`` are not available in
|
||||||
ordinary routines.
|
ordinary routines.
|
||||||
|
|
||||||
|
|
||||||
|
Move optimization
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The ``call`` constraint is particular useful to implement a `move`:idx:
|
||||||
|
optimization for types that have copying semantics:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
proc `[]=`*(t: var TTable, key: string, val: string) =
|
||||||
|
## puts a (key, value)-pair into `t`. The semantics of string require
|
||||||
|
## a copy here:
|
||||||
|
let idx = findInsertionPosition(key)
|
||||||
|
t[idx] = key
|
||||||
|
t[idx] = val
|
||||||
|
|
||||||
|
proc `[]=`*(t: var TTable, key: string{call}, val: string{call}) =
|
||||||
|
## puts a (key, value)-pair into `t`. Optimized version that knows that
|
||||||
|
## the strings are unique and thus don't need to be copied:
|
||||||
|
let idx = findInsertionPosition(key)
|
||||||
|
shallowCopy t[idx], key
|
||||||
|
shallowCopy t[idx], val
|
||||||
|
|
||||||
|
var t: TTable
|
||||||
|
# overloading resolution ensures that the optimized []= is called here:
|
||||||
|
t["abc"] = "xyz"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Modules
|
Modules
|
||||||
=======
|
=======
|
||||||
Nimrod supports splitting a program into pieces by a `module`:idx: concept.
|
Nimrod supports splitting a program into pieces by a `module`:idx: concept.
|
||||||
|
|
@ -4692,10 +4769,14 @@ Threadvar pragma
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
A global variable can be marked with the `threadvar`:idx: pragma; it is
|
A global variable can be marked with the `threadvar`:idx: pragma; it is
|
||||||
a `thead-local`:idx: variable then:
|
a `thread-local`:idx: variable then:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
var checkpoints* {.threadvar.}: seq[string] = @[]
|
var checkpoints* {.threadvar.}: seq[string]
|
||||||
|
|
||||||
|
Due to implementation restrictions thread local variables cannot be
|
||||||
|
initialized within the ``var`` section. (Every thread local variable needs to
|
||||||
|
be replicated at thread creation.)
|
||||||
|
|
||||||
|
|
||||||
Actor model
|
Actor model
|
||||||
|
|
|
||||||
13
tests/patterns/thoist.nim
Normal file
13
tests/patterns/thoist.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
discard """
|
||||||
|
output: '''true
|
||||||
|
true'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pegs
|
||||||
|
|
||||||
|
template optPeg{peg(pattern)}(pattern: string{lit}): TPeg =
|
||||||
|
var gl {.global, gensym.} = peg(pattern)
|
||||||
|
gl
|
||||||
|
|
||||||
|
echo match("(a b c)", peg"'(' @ ')'")
|
||||||
|
echo match("W_HI_Le", peg"\y 'while'")
|
||||||
11
tests/patterns/tpartial.nim
Normal file
11
tests/patterns/tpartial.nim
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
discard """
|
||||||
|
output: '''-1'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc p(x, y: int; cond: bool): int =
|
||||||
|
result = if cond: x + y else: x - y
|
||||||
|
|
||||||
|
template optP{p(x, y, true)}(x, y: expr): expr = x - y
|
||||||
|
template optP{p(x, y, false)}(x, y: expr): expr = x + y
|
||||||
|
|
||||||
|
echo p(2, 4, true)
|
||||||
8
todo.txt
8
todo.txt
|
|
@ -1,18 +1,12 @@
|
||||||
version 0.9.2
|
version 0.9.2
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- document overloading based on ASTs
|
|
||||||
- implement ``partial`` pragma for partial evaluation: easily done with AST
|
|
||||||
overloading
|
|
||||||
- ``hoist`` pragma for loop hoisting: can be easily done with
|
|
||||||
AST overloading + global
|
|
||||||
- move semantics
|
|
||||||
|
|
||||||
- test&finish first class iterators:
|
- test&finish first class iterators:
|
||||||
* nested iterators
|
* nested iterators
|
||||||
* test generic iterators
|
* test generic iterators
|
||||||
- fix closure bug finally
|
- fix closure bug finally
|
||||||
- fix marshal bug
|
- fix marshal bug
|
||||||
|
- make PDF generation of the docs work again
|
||||||
|
|
||||||
|
|
||||||
version 0.9.X
|
version 0.9.X
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,6 @@ Roadmap to 1.0
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Version 0.9.2
|
Version 0.9.2
|
||||||
* overloading based on ASTs (like already possible for term rewriting macros)
|
|
||||||
* better interaction between macros, templates and overloading
|
* better interaction between macros, templates and overloading
|
||||||
* the symbol binding rules for generics and templates may change again
|
* the symbol binding rules for generics and templates may change again
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ Language Additions
|
||||||
- An ``export`` statement has been added to the language: It can be used for
|
- An ``export`` statement has been added to the language: It can be used for
|
||||||
symbol forwarding so client modules don't have to import a module's
|
symbol forwarding so client modules don't have to import a module's
|
||||||
dependencies explicitly.
|
dependencies explicitly.
|
||||||
|
- Overloading based on ASTs has been implemented.
|
||||||
|
|
||||||
|
|
||||||
2012-09-23 Version 0.9.0 released
|
2012-09-23 Version 0.9.0 released
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue