niminst: bugfixes; documentation changes

This commit is contained in:
Araq 2012-01-15 01:03:57 +01:00
commit f58cc49672
9 changed files with 70 additions and 85 deletions

View file

@ -1024,7 +1024,7 @@ proc getStrOrChar*(a: PNode): string =
proc isGenericRoutine*(s: PSym): bool = proc isGenericRoutine*(s: PSym): bool =
case s.kind case s.kind
of skProc, skTemplate, skMacro, skIterator, skMethod: of skProc, skTemplate, skMacro, skIterator, skMethod, skConverter:
result = s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty result = s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty
else: nil else: nil

View file

@ -736,37 +736,10 @@ variadic proc, it is implicitely converted to ``cstring`` too:
Even though the conversion is implict, it is not *safe*: The garbage collector Even though the conversion is implict, it is not *safe*: The garbage collector
does not consider a ``cstring`` to be a root and may collect the underlying does not consider a ``cstring`` to be a root and may collect the underlying
memory: memory. However in practice this almost never happens as the GC considers
stack roots conservatively. One can use the builtin procs ``GC_ref`` and
.. code-block:: nimrod ``GC_unref`` to keep the string data alive for the rare cases where it does
var nimStr = "example" not work.
var cStr: cstring = nimStr
var i = 0
while cStr[i] != '\0':
# since `nimStr`'s lifetime ended here the GC is allowed to free
# the memory occupied by "example":
GC_collect()
# now cStr points to garbage:
echo cStr[i]
inc i
However this a very contrived example; in practice this almost never happens.
One can use the builtin procs ``GC_ref`` and ``GC_unref`` to make this code
safe:
.. code-block:: nimrod
var nimStr = "example"
GC_ref(nimStr) # keep GC from freeing 'nimStr'
var cStr: cstring = nimStr
var i = 0
while cStr[i] != '\0':
# since `nimStr`'s lifetime ended here the GC is allowed to free
# the memory occupied by "example":
GC_collect()
# now cStr points to garbage:
echo cStr[i]
inc i
GC_unref(nimStr) # GC is allowed to free 'nimStr'
Structured types Structured types

View file

@ -31,9 +31,9 @@ We start the tour with a modified "hello world" program:
.. code-block:: Nimrod .. code-block:: Nimrod
# This is a comment # This is a comment
Echo("What's your name? ") echo("What's your name? ")
var name: string = readLine(stdin) var name: string = readLine(stdin)
Echo("Hi, ", name, "!") echo("Hi, ", name, "!")
Save this code to the file "greetings.nim". Now compile and run it:: Save this code to the file "greetings.nim". Now compile and run it::
@ -65,12 +65,12 @@ done with spaces only, tabulators are not allowed.
String literals are enclosed in double quotes. The ``var`` statement declares String literals are enclosed in double quotes. The ``var`` statement declares
a new variable named ``name`` of type ``string`` with the value that is a new variable named ``name`` of type ``string`` with the value that is
returned by the ``readline`` procedure. Since the compiler knows that returned by the ``readLine`` procedure. Since the compiler knows that
``readline`` returns a string, you can leave out the type in the declaration ``readLine`` returns a string, you can leave out the type in the declaration
(this is called `local type inference`:idx:). So this will work too: (this is called `local type inference`:idx:). So this will work too:
.. code-block:: Nimrod .. code-block:: Nimrod
var name = readline(stdin) var name = readLine(stdin)
Note that this is basically the only form of type inference that exists in Note that this is basically the only form of type inference that exists in
Nimrod: it is a good compromise between brevity and readability. Nimrod: it is a good compromise between brevity and readability.
@ -140,10 +140,10 @@ which code snippet the comment refers to. Since comments are a proper part of
the syntax, watch their indentation: the syntax, watch their indentation:
.. code-block:: .. code-block::
Echo("Hello!") echo("Hello!")
# comment has the same indentation as above statement -> fine # comment has the same indentation as above statement -> fine
Echo("Hi!") echo("Hi!")
# comment has not the right indentation -> syntax error! # comment has not the correct indentation level -> syntax error!
**Note**: To comment out a large piece of code, it is often better to use a **Note**: To comment out a large piece of code, it is often better to use a
``when false:`` statement. ``when false:`` statement.
@ -244,7 +244,7 @@ The if statement is one way to branch the control flow:
elif name == "name": elif name == "name":
echo("Very funny, your name is name.") echo("Very funny, your name is name.")
else: else:
Echo("Hi, ", name, "!") echo("Hi, ", name, "!")
There can be zero or more elif parts, and the else part is optional. The There can be zero or more elif parts, and the else part is optional. The
keyword ``elif`` is short for ``else if``, and is useful to avoid excessive keyword ``elif`` is short for ``else if``, and is useful to avoid excessive
@ -267,7 +267,7 @@ a multi-branch:
of "Dave", "Frank": of "Dave", "Frank":
echo("Cool name!") echo("Cool name!")
else: else:
Echo("Hi, ", name, "!") echo("Hi, ", name, "!")
As it can be seen, for an ``of`` branch a comma separated list of values is also As it can be seen, for an ``of`` branch a comma separated list of values is also
allowed. allowed.
@ -280,11 +280,11 @@ For integers or other ordinal types value ranges are also possible:
# this statement will be explained later: # this statement will be explained later:
from strutils import parseInt from strutils import parseInt
Echo("A number please: ") echo("A number please: ")
let n = parseInt(readLine(stdin)) let n = parseInt(readLine(stdin))
case n case n
of 0..2, 4..7: Echo("The number is in the set: {0, 1, 2, 4, 5, 6, 7}") of 0..2, 4..7: echo("The number is in the set: {0, 1, 2, 4, 5, 6, 7}")
of 3, 8: Echo("The number is 3 or 8") of 3, 8: echo("The number is 3 or 8")
However, the above code does not compile: the reason is that you have to cover However, the above code does not compile: the reason is that you have to cover
every value that ``n`` may contain, but the code only handles the values every value that ``n`` may contain, but the code only handles the values
@ -295,8 +295,8 @@ the compiler that for every other value nothing should be done:
.. code-block:: nimrod .. code-block:: nimrod
... ...
case n case n
of 0..2, 4..7: Echo("The number is in the set: {0, 1, 2, 4, 5, 6, 7}") of 0..2, 4..7: echo("The number is in the set: {0, 1, 2, 4, 5, 6, 7}")
of 3, 8: Echo("The number is 3 or 8") of 3, 8: echo("The number is 3 or 8")
else: nil else: nil
The ``nil`` statement is a *do nothing* statement. The compiler knows that a The ``nil`` statement is a *do nothing* statement. The compiler knows that a
@ -316,10 +316,10 @@ The while statement is a simple looping construct:
.. code-block:: nimrod .. code-block:: nimrod
Echo("What's your name? ") echo("What's your name? ")
var name = readLine(stdin) var name = readLine(stdin)
while name == "": while name == "":
Echo("Please tell me your name: ") echo("Please tell me your name: ")
name = readLine(stdin) name = readLine(stdin)
# no ``var``, because we do not declare a new variable here # no ``var``, because we do not declare a new variable here
@ -334,9 +334,9 @@ The `for`:idx: statement is a construct to loop over any element an *iterator*
provides. The example uses the built-in ``countup`` iterator: provides. The example uses the built-in ``countup`` iterator:
.. code-block:: nimrod .. code-block:: nimrod
Echo("Counting to ten: ") echo("Counting to ten: ")
for i in countup(1, 10): for i in countup(1, 10):
Echo($i) echo($i)
The built-in ``$`` operator turns an integer (``int``) and many other types The built-in ``$`` operator turns an integer (``int``) and many other types
into a string. The variable ``i`` is implicitly declared by the ``for`` loop into a string. The variable ``i`` is implicitly declared by the ``for`` loop
@ -345,18 +345,18 @@ through the values 1, 2, .., 10. Each value is ``echo``-ed. This code does
the same: the same:
.. code-block:: nimrod .. code-block:: nimrod
Echo("Counting to 10: ") echo("Counting to 10: ")
var i = 1 var i = 1
while i <= 10: while i <= 10:
Echo($i) echo($i)
inc(i) # increment i by 1 inc(i) # increment i by 1
Counting down can be achieved as easily (but is less often needed): Counting down can be achieved as easily (but is less often needed):
.. code-block:: nimrod .. code-block:: nimrod
Echo("Counting down from 10 to 1: ") echo("Counting down from 10 to 1: ")
for i in countdown(10, 1): for i in countdown(10, 1):
Echo($i) echo($i)
Since counting up occurs so often in programs, Nimrod has a special syntax that Since counting up occurs so often in programs, Nimrod has a special syntax that
calls the ``countup`` iterator implicitly: calls the ``countup`` iterator implicitly:
@ -400,18 +400,18 @@ unless a label of a block is given:
.. code-block:: nimrod .. code-block:: nimrod
block myblock: block myblock:
Echo("entering block") echo("entering block")
while true: while true:
Echo("looping") echo("looping")
break # leaves the loop, but not the block break # leaves the loop, but not the block
Echo("still in block") echo("still in block")
block myblock2: block myblock2:
Echo("entering block") echo("entering block")
while true: while true:
Echo("looping") echo("looping")
break myblock2 # leaves the block (and the loop) break myblock2 # leaves the block (and the loop)
Echo("still in block") echo("still in block")
Continue statement Continue statement
@ -423,7 +423,7 @@ the next iteration immediately:
while true: while true:
let x = readLine(stdin) let x = readLine(stdin)
if x == "": continue if x == "": continue
Echo(x) echo(x)
When statement When statement
@ -516,17 +516,17 @@ of a `procedure` is needed. (Some languages call them *methods* or
.. code-block:: nimrod .. code-block:: nimrod
proc yes(question: string): bool = proc yes(question: string): bool =
Echo(question, " (y/n)") echo(question, " (y/n)")
while true: while true:
case readLine(stdin) case readLine(stdin)
of "y", "Y", "yes", "Yes": return true of "y", "Y", "yes", "Yes": return true
of "n", "N", "no", "No": return false of "n", "N", "no", "No": return false
else: Echo("Please be clear: yes or no") else: echo("Please be clear: yes or no")
if yes("Should I delete all your important files?"): if yes("Should I delete all your important files?"):
Echo("I'm sorry Dave, I'm afraid I can't do that.") echo("I'm sorry Dave, I'm afraid I can't do that.")
else: else:
Echo("I think you know what the problem is just as well as I do.") echo("I think you know what the problem is just as well as I do.")
This example shows a procedure named ``yes`` that asks the user a ``question`` This example shows a procedure named ``yes`` that asks the user a ``question``
and returns true if he answered "yes" (or something similar) and returns and returns true if he answered "yes" (or something similar) and returns
@ -662,8 +662,8 @@ Nimrod provides the ability to overload procedures similar to C++:
if x: return "true" if x: return "true"
else: return "false" else: return "false"
Echo(toString(13)) # calls the toString(x: int) proc echo(toString(13)) # calls the toString(x: int) proc
Echo(toString(true)) # calls the toString(x: bool) proc echo(toString(true)) # calls the toString(x: bool) proc
(Note that ``toString`` is usually the ``$`` operator in Nimrod.) (Note that ``toString`` is usually the ``$`` operator in Nimrod.)
The compiler chooses the most appropriate proc for the ``toString`` calls. How The compiler chooses the most appropriate proc for the ``toString`` calls. How
@ -704,7 +704,7 @@ The "``" notation can also be used to call an operator just like a procedure
with a real name: with a real name:
.. code-block:: nimrod .. code-block:: nimrod
if `==`( `+`(3, 4), 7): Echo("True") if `==`( `+`(3, 4), 7): echo("True")
Forward declarations Forward declarations
@ -738,9 +738,9 @@ Iterators
Let's return to the boring counting example: Let's return to the boring counting example:
.. code-block:: nimrod .. code-block:: nimrod
Echo("Counting to ten: ") echo("Counting to ten: ")
for i in countup(1, 10): for i in countup(1, 10):
Echo($i) echo($i)
Can a ``countup`` proc be written that supports this loop? Lets try: Can a ``countup`` proc be written that supports this loop? Lets try:

View file

@ -387,17 +387,17 @@ The `try`:idx: statement handles exceptions:
f: TFile f: TFile
if open(f, "numbers.txt"): if open(f, "numbers.txt"):
try: try:
var a = readLine(f) let a = readLine(f)
var b = readLine(f) let b = readLine(f)
echo("sum: " & $(parseInt(a) + parseInt(b))) echo "sum: ", parseInt(a) + parseInt(b)
except EOverflow: except EOverflow:
echo("overflow!") echo "overflow!"
except EInvalidValue: except EInvalidValue:
echo("could not convert string to integer") echo "could not convert string to integer"
except EIO: except EIO:
echo("IO error!") echo "IO error!"
except: except:
echo("Unknown exception!") echo "Unknown exception!"
# reraise the unknown exception: # reraise the unknown exception:
raise raise
finally: finally:

View file

@ -1,8 +1,8 @@
version 0.8.14 version 0.8.14
============== ==============
- improve niminst
- fix line info in assertions - fix line info in assertions
- bug: tsortdev does not run with native GC
version 0.9.0 version 0.9.0
============= =============
@ -47,7 +47,6 @@ Bugs
without ``-d:release`` leaks memory; good way to figure out how a without ``-d:release`` leaks memory; good way to figure out how a
fixed amount of stack can hold an arbitrary number of GC roots! fixed amount of stack can hold an arbitrary number of GC roots!
- bug: temp2.nim triggers weird compiler and except.nim bug - bug: temp2.nim triggers weird compiler and except.nim bug
- bug: tsortdev does not run with native GC
version 0.9.XX version 0.9.XX

View file

@ -15,7 +15,7 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c ?{f} -o ?{changeFileExt(f, "o")}
# linkCmd.add(" " & changeFileExt(f, "o")) # linkCmd.add(" " & changeFileExt(f, "o"))
# end for # end for
ECHO %LINKER% %LINK_FLAGS% -o ?{c.binPaths[0]}\?{toLower(c.name)}.exe ?linkCmd ECHO %LINKER% %LINK_FLAGS% -o ?{firstBinPath(c)\toLower(c.name)}.exe ?linkCmd
%LINKER% %LINK_FLAGS% -o ?{c.binPaths[0]}\?{toLower(c.name)}.exe ?linkCmd %LINKER% %LINK_FLAGS% -o ?{firstBinPath(c)\toLower(c.name)}.exe ?linkCmd
ECHO SUCCESS ECHO SUCCESS

View file

@ -90,8 +90,8 @@ case $myos in
$CC $COMP_FLAGS -Ibuild -c ?{f} -o ?{changeFileExt(f, "o")} || exit 1 $CC $COMP_FLAGS -Ibuild -c ?{f} -o ?{changeFileExt(f, "o")} || exit 1
# add(linkCmd, " \\\n" & changeFileExt(f, "o")) # add(linkCmd, " \\\n" & changeFileExt(f, "o"))
# end for # end for
echo "$LINKER $LINK_FLAGS -o ?{c.binPaths[0]}/?{toLower(c.name)} ?linkCmd" echo "$LINKER $LINK_FLAGS -o ?{firstBinPath(c)/toLower(c.name)} ?linkCmd"
$LINKER $LINK_FLAGS -o ?{c.binPaths[0]}/?{toLower(c.name)} ?linkCmd || exit 1 $LINKER $LINK_FLAGS -o ?{firstBinPath(c)/toLower(c.name)} ?linkCmd || exit 1
;; ;;
# end for # end for
*) *)

View file

@ -86,6 +86,13 @@ proc initConfigData(c: var TConfigData) =
c.uninstallScript = false c.uninstallScript = false
c.vars = newStringTable(modeStyleInsensitive) c.vars = newStringTable(modeStyleInsensitive)
proc firstBinPath(c: TConfigData): string =
if c.binPaths.len > 0: result = c.binPaths[0]
else: result = ""
proc `\`(a, b: string): string =
result = if a.len == 0: b else: a & '\\' & b
proc skipRoot(f: string): string = proc skipRoot(f: string): string =
# "abc/def/xyz" --> "def/xyz" # "abc/def/xyz" --> "def/xyz"
var i = 0 var i = 0

View file

@ -106,8 +106,14 @@ Roadmap to 1.0
============== ==============
Version 0.9.0 Version 0.9.0
* closures and anonymous procs * closures
* recursive iterators/coroutines * recursive iterators/coroutines
Version 0.9.x
* 2-phase type system for better interaction between macros, templates * 2-phase type system for better interaction between macros, templates
and overloading and overloading
* term rewriting macros
* the syntactic distinction between statements and expressions will be
removed
* forward declarations will likely be removed