version0.7.10

This commit is contained in:
Andreas Rumpf
2009-06-08 08:13:09 +02:00
parent 4d4b3b1c04
commit 36818817bd
14 changed files with 1011 additions and 0 deletions

152
doc/abstypes.txt Normal file
View File

@@ -0,0 +1,152 @@
==============
Abstract types
==============
.. contents::
Abstract types in Nimrod provide a means to model different `units`:idx: of
a `base type`:idx:.
Use case 1: SQL strings
-----------------------
An SQL statement that is passed from Nimrod to an SQL database might be
modelled as a string. However, using string templates and filling in the
values is vulnerable to the famous `SQL injection attack`:idx:\:
.. code-block:: nimrod
proc query(db: TDbHandle, statement: TSQL) = ...
var
username: string
db.query("SELECT FROM users WHERE name = '$1'" % username)
# Horrible security whole, but the compiler does not mind!
This can be avoided by distinguishing strings that contain SQL from strings
that don't. Abstract types provide a means to introduce a new string type
``TSQL`` that is incompatible with ``string``:
.. code-block:: nimrod
type
TSQL = abstract string
proc query(db: TDbHandle, statement: TSQL) = ...
var
username: string
db.query("SELECT FROM users WHERE name = '$1'" % username)
# Error at compile time: `query` expects an SQL string!
It is an essential property of abstract types that they **do not** imply a
subtype relation between the abtract type and its base type. Explict type
conversions from ``string`` to ``TSQL`` are allowed:
.. code-block:: nimrod
proc properQuote(s: string): TSQL =
# quotes a string properly for an SQL statement
...
proc `%` (frmt: TSQL, values: openarray[string]): TSQL =
# quote each argument:
var v = values.each(properQuote)
# we need a temporary type for the type conversion :-(
type TStrSeq = seq[string]
# call strutils.`%`:
result = TSQL(string(frmt) % TStrSeq(v))
db.query("SELECT FROM users WHERE name = $1".TSQL % username)
Now we have compile-time checking against SQL injection attacks.
Since ``"".TSQL`` is transformed to ``TSQL("")`` no new syntax is needed
for nice looking ``TSQL`` string literals.
Use case 2: Money
-----------------
Different currencies should not be mixed in monetary calculations. Abstract
types are a perfect tool to model different currencies:
.. code-block:: nimrod
type
TDollar = abstract int
TEuro = abstract int
var
d: TDollar
e: TEuro
echo d + 12
# Error: cannot add a number with no unit with a ``TDollar``
Unfortunetaly, ``d + 12.TDollar`` is not allowed either,
because ``+`` is defined for ``int`` (among others), not for ``TDollar``. So
we define our own ``+`` for dollars:
.. code-block::
proc `+` (x, y: TDollar): TDollar =
result = TDollar(int(x) + int(y))
It does not make sense to multiply a dollar with a dollar, but with a
unit-less number; and the same holds for division:
.. code-block::
proc `*` (x: TDollar, y: int): TDollar =
result = TDollar(int(x) * y)
proc `*` (x: int, y: TDollar): TDollar =
result = TDollar(x * int(y))
proc `div` ...
This quickly gets tedious. The implementations are trivial and the compiler
should not generate all this code only to optimize it away later - after all
``+`` for dollars should produce the same binary code as ``+`` for ints.
The pragma ``borrow`` has been designed to solve this problem; in principle
it generates the trivial implementation for us:
.. code-block:: nimrod
proc `*` (x: TDollar, y: int): TDollar {.borrow.}
proc `*` (x: int, y: TDollar): TDollar {.borrow.}
proc `div` (x: TDollar, y: int): TDollar {.borrow.}
The ``borrow`` pragma makes the compiler use the same implementation as
the proc that deals with the abstract type's base type, so no code is
generated.
But it seems we still have to repeat all this boilerplate code for
the ``TEuro`` currency. Fortunately, Nimrod has a template mechanism:
.. code-block:: nimrod
template Additive(typ: typeExpr): stmt =
proc `+` *(x, y: typ): typ {.borrow.}
proc `-` *(x, y: typ): typ {.borrow.}
# unary operators:
proc `+` *(x: typ): typ {.borrow.}
proc `-` *(x: typ): typ {.borrow.}
template Multiplicative(typ, base: typeExpr): stmt =
proc `*` *(x: typ, y: base): typ {.borrow.}
proc `*` *(x: base, y: typ): typ {.borrow.}
proc `div` *(x: typ, y: base): typ {.borrow.}
proc `mod` *(x: typ, y: base): typ {.borrow.}
template Comparable(typ: typeExpr): stmt =
proc `<` * (x, y: typ): bool {.borrow.}
proc `<=` * (x, y: typ): bool {.borrow.}
proc `==` * (x, y: typ): bool {.borrow.}
template DefineCurrency(typ, base: expr): stmt =
type
typ* = abstract base
Additive(typ)
Multiplicative(typ, base)
Comparable(typ)
DefineCurrency(TDollar, int)
DefineCurrency(TEuro, int)

572
doc/astspec.txt Normal file
View File

@@ -0,0 +1,572 @@
The AST in Nimrod
=================
This section describes how the AST is modelled with Nimrod's type system.
The AST consists of nodes (``PNimrodNode``) with a variable number of
children. Each node has a field named ``kind`` which describes what the node
contains:
.. code-block:: nimrod
type
TNimrodNodeKind = enum ## kind of a node; only explanatory
nnkNone, ## invalid node kind
nnkEmpty, ## empty node
nnkIdent, ## node contains an identifier
nnkIntLit, ## node contains an int literal (example: 10)
nnkStrLit, ## node contains a string literal (example: "abc")
nnkNilLit, ## node contains a nil literal (example: nil)
nnkCaseStmt, ## node represents a case statement
... ## many more
PNimrodNode = ref TNimrodNode
TNimrodNode {.final.} = object
case kind ## the node's kind
of nnkNone, nnkEmpty, nnkNilLit:
nil ## node contains no additional fields
of nnkCharLit..nnkInt64Lit:
intVal: biggestInt ## the int literal
of nnkFloatLit..nnkFloat64Lit:
floatVal: biggestFloat ## the float literal
of nnkStrLit..nnkTripleStrLit:
strVal: string ## the string literal
of nnkIdent:
ident: TNimrodIdent ## the identifier
of nnkSym:
symbol: PNimrodSymbol ## the symbol (after symbol lookup phase)
else:
sons: seq[PNimrodNode] ## the node's sons (or children)
For the ``PNimrodNode`` type, the ``[]`` operator has been overloaded:
``n[i]`` is ``n``'s ``i``-th child.
To specify the AST for the different Nimrod constructs, the notation
``nodekind(son1, son2, ...)`` or ``nodekind(value)`` or
``nodekind(field=value)`` is used.
Leaf nodes/Atoms
================
A leaf of the AST often corresponds to a terminal symbol in the concrete
syntax.
----------------- ---------------------------------------------
Nimrod expression corresponding AST
----------------- ---------------------------------------------
``42`` ``nnkIntLit(intVal = 42)``
``42'i8`` ``nnkInt8Lit(intVal = 42)``
``42'i16`` ``nnkInt16Lit(intVal = 42)``
``42'i32`` ``nnkInt32Lit(intVal = 42)``
``42'i64`` ``nnkInt64Lit(intVal = 42)``
``42.0`` ``nnkFloatLit(floatVal = 42.0)``
``42.0'f32`` ``nnkFloat32Lit(floatVal = 42.0)``
``42.0'f64`` ``nnkFloat64Lit(floatVal = 42.0)``
``"abc"`` ``nnkStrLit(strVal = "abc")``
``r"abc"`` ``nnkRStrLit(strVal = "abc")``
``"""abc"""`` ``nnkTripleStrLit(strVal = "abc")``
``' '`` ``nnkCharLit(intVal = 32)``
``nil`` ``nnkNilLit()``
``myIdentifier`` ``nnkIdent(ident = !"myIdentifier")``
``myIdentifier`` after lookup pass: ``nnkSym(symbol = ...)``
----------------- ---------------------------------------------
Identifiers are ``nnkIdent`` nodes. After the name lookup pass these nodes
get transferred into ``nnkSym`` nodes. However, a macro receives an AST that
has not been checked for semantics and thus the identifiers have not been
looked up. Thus macros deal with ``nnkIdent`` nodes.
Calls/expressions
=================
Command call
------------
Concrete syntax:
.. code-block:: nimrod
echo "abc", "xyz"
AST:
.. code-block:: nimrod
nnkCommand(nnkIdent(!"echo"), nnkStrLit("abc"), nnkStrLit("xyz"))
Call with ``()``
----------------
Concrete syntax:
.. code-block:: nimrod
echo("abc", "xyz")
AST:
.. code-block:: nimrod
nnkCall(nnkIdent(!"echo"), nnkStrLit("abc"), nnkStrLit("xyz"))
Infix operator call
-------------------
Concrete syntax:
.. code-block:: nimrod
"abc" & "xyz"
AST:
.. code-block:: nimrod
nnkInfix(nnkIdent(!"&"), nnkStrLit("abc"), nnkStrLit("xyz"))
Prefix operator call
--------------------
Concrete syntax:
.. code-block:: nimrod
? "xyz"
AST:
.. code-block:: nimrod
nnkPrefix(nnkIdent(!"?"), nnkStrLit("abc"))
Postfix operator call
---------------------
**Note:** There are no postfix operators in Nimrod. However, the
``nnkPostfix`` node is used for the *asterisk export marker* ``*``:
Concrete syntax:
.. code-block:: nimrod
identifier*
AST:
.. code-block:: nimrod
nnkPostfix(nnkIdent(!"*"), nnkIdent(!"identifier"))
Call with named arguments
-------------------------
Concrete syntax:
.. code-block:: nimrod
writeln(file=stdout, "hallo")
AST:
.. code-block:: nimrod
nnkCall(nnkIdent(!"writeln"),
nnkExprEqExpr(nnkIdent(!"file"), nnkIdent(!"stdout")),
nnkStrLit("hallo"))
Dereference operator ``^``
--------------------------
Concrete syntax:
.. code-block:: nimrod
x^
AST:
.. code-block:: nimrod
nnkDerefExpr(nnkIdent(!"x"))
Addr operator
-------------
Concrete syntax:
.. code-block:: nimrod
addr(x)
AST:
.. code-block:: nimrod
nnkAddr(nnkIdent(!"x"))
Cast operator
-------------
Concrete syntax:
.. code-block:: nimrod
cast[T](x)
AST:
.. code-block:: nimrod
nnkCast(nnkIdent(!"T"), nnkIdent(!"x"))
Object access operator ``.``
----------------------------
Concrete syntax:
.. code-block:: nimrod
x.y
AST:
.. code-block:: nimrod
nnkDotExpr(nnkIdent(!"x"), nnkIdent(!"y"))
Array access operator ``[]``
----------------------------
Concrete syntax:
.. code-block:: nimrod
x[y]
AST:
.. code-block:: nimrod
nnkBracketExpr(nnkIdent(!"x"), nnkIdent(!"y"))
Parentheses
-----------
Parentheses for affecting operator precedence or tuple construction
are built with the ``nnkPar`` node.
Concrete syntax:
.. code-block:: nimrod
(1, 2, (3))
AST:
.. code-block:: nimrod
nnkPar(nnkIntLit(1), nnkIntLit(2), nnkPar(nnkIntLit(3)))
Curly braces
------------
Curly braces are used as the set constructor.
Concrete syntax:
.. code-block:: nimrod
{1, 2, 3}
AST:
.. code-block:: nimrod
nnkCurly(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3))
Brackets
--------
Brackets are used as the array constructor.
Concrete syntax:
.. code-block:: nimrod
[1, 2, 3]
AST:
.. code-block:: nimrod
nnkBracket(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3))
Ranges
------
Ranges occur in set constructors, case statement branches or array slices.
Concrete syntax:
.. code-block:: nimrod
1..3
AST:
.. code-block:: nimrod
nnkRange(nnkIntLit(1), nnkIntLit(3))
If expression
-------------
The representation of the if expression is subtle, but easy to traverse.
Concrete syntax:
.. code-block:: nimrod
if cond1: expr1 elif cond2: expr2 else: expr3
AST:
.. code-block:: nimrod
nnkIfExpr(
nnkElifExpr(cond1, expr1),
nnkElifExpr(cond2, expr2),
nnkElseExpr(expr3)
)
Statements
==========
If statement
------------
The representation of the if statement is subtle, but easy to traverse. If
there is no ``else`` branch, no ``nnkElse`` child exists.
Concrete syntax:
.. code-block:: nimrod
if cond1:
stmt1
elif cond2:
stmt2
elif cond3:
stmt3
else:
stmt4
AST:
.. code-block:: nimrod
nnkIfStmt(
nnkElifBranch(cond1, stmt1),
nnkElifBranch(cond2, stmt2),
nnkElifBranch(cond3, stmt3),
nnkElse(stmt4)
)
When statement
--------------
Like the ``if`` statement, but the root has the kind ``nnkWhenStmt``.
Assignment
----------
Concrete syntax:
.. code-block:: nimrod
x = 42
AST:
.. code-block:: nimrod
nnkAsgn(nnkIdent(!"x"), nnkIntLit(42))
Statement list
--------------
Concrete syntax:
.. code-block:: nimrod
stmt1
stmt2
stmt3
AST:
.. code-block:: nimrod
nnkStmtList(stmt1, stmt2, stmt3)
Case statement
--------------
Concrete syntax:
.. code-block:: nimrod
case expr1
of expr2, expr3..expr4:
stmt1
of expr5:
stmt2
elif cond1:
stmt3
else:
stmt4
AST:
.. code-block:: nimrod
nnkCaseStmt(
expr1,
nnkOfBranch(expr2, nnkRange(expr3, expr4), stmt1),
nnkOfBranch(expr5, stmt2),
nnkElifBranch(cond1, stmt3),
nnkElse(stmt4)
)
The ``nnkElifBranch`` and ``nnkElse`` parts may be missing.
While statement
---------------
Concrete syntax:
.. code-block:: nimrod
while expr1:
stmt1
AST:
.. code-block:: nimrod
nnkWhileStmt(expr1, stmt1)
For statement
-------------
Concrete syntax:
.. code-block:: nimrod
for ident1, ident2 in expr1:
stmt1
AST:
.. code-block:: nimrod
nnkForStmt(ident1, ident2, expr1, stmt1)
Try statement
-------------
Concrete syntax:
.. code-block:: nimrod
try:
stmt1
except e1, e2:
stmt2
except e3:
stmt3
except:
stmt4
finally:
stmt5
AST:
.. code-block:: nimrod
nnkTryStmt(
stmt1,
nnkExceptBranch(e1, e2, stmt2),
nnkExceptBranch(e3, stmt3),
nnkExceptBranch(stmt4),
nnkFinally(stmt5)
)
Return statement
----------------
Concrete syntax:
.. code-block:: nimrod
return expr1
AST:
.. code-block:: nimrod
nnkReturnStmt(expr1)
Yield statement
---------------
Like ``return``, but with ``nnkYieldStmt`` kind.
Discard statement
-----------------
Like ``return``, but with ``nnkDiscardStmt`` kind.
Continue statement
------------------
Concrete syntax:
.. code-block:: nimrod
continue
AST:
.. code-block:: nimrod
nnkContinueStmt()
Var section
-----------
To be written.
Const section
-------------
To be written.
Type section
------------
To be written.
Procedure declaration
---------------------
To be written.
Iterator declaration
--------------------
To be written.
Template declaration
--------------------
To be written.
Macro declaration
-----------------
To be written.
Special node kinds
==================
There are several node kinds that are used for semantic checking or code
generation. These are accessible from this module, but should not be used.
Other node kinds are especially designed to make AST manipulations easier.
These are explained here.
To be written.

9
examples/keyval.nim Normal file
View File

@@ -0,0 +1,9 @@
# Filter key=value pairs from "myfile.txt"
import regexprs
for x in lines("myfile.txt"):
if x =~ r"(\w+)=(.*)":
echo "Key: ", matches[1],
" Value: ", matches[2]

15
examples/luaex.nim Normal file
View File

@@ -0,0 +1,15 @@
# Embedds Lua into a Nimrod application
import
lua, lualib, lauxlib
const
code = """
print 'hi'
"""
var L = luaL_newstate()
luaL_openlibs(L)
discard luaL_loadbuffer(L, code, code.len, "line")
discard lua_pcall(L, 0, 0, 0)

6
examples/maximum.nim Normal file
View File

@@ -0,0 +1,6 @@
# Test high level features
import strutils
echo "Give a list of numbers (separated by spaces): "
stdin.readLine.splitSeq.each(parseInt).max.`$`.echo(" is the maximum!")

11
examples/myfile.txt Normal file
View File

@@ -0,0 +1,11 @@
kladsfa
asdflksadlfasf
adsfljksadfl
key=/usr/bin/value
key2=/ha/ha

12
examples/pythonex.nim Normal file
View File

@@ -0,0 +1,12 @@
# Example to embed Python into your application
import python
# IMPORTANT: Python on Windows does not like CR characters, so
# we use only \L here.
Py_Initialize()
discard PyRun_SimpleString("from time import time,ctime\L" &
"print 'Today is',ctime(time())\L")
Py_Finalize()

25
examples/tclex.nim Normal file
View File

@@ -0,0 +1,25 @@
# Example to embed TCL in Nimrod
import tcl, os
const
myScript = """puts "Hello, World - In quotes" """
myScript2 = """
package require Tk
pack [entry .e -textvar e -width 50]
bind .e <Return> {
set e [regsub { *=.*} $e ""] ;# remove evaluation (Chris)
catch {expr [string map {/ *1./} $e]} res
append e " = $res"
}
"""
Tcl_FindExecutable(getApplicationFilename())
var interp = Tcl_CreateInterp()
if interp == nil: quit("cannot create TCL interpreter")
if Tcl_Init(interp) != TCL_OK:
quit("cannot init interpreter")
if Tcl_Eval(interp, myScript) != TCL_OK:
quit("cannot execute script.tcl")

22
tests/jsontest.json Normal file
View File

@@ -0,0 +1,22 @@
// Simple JSON test file
// (c) 2009 Andreas Rumpf
/* a long comment */
{
"key1": null,
"key2": [
{},
{ },
[],
[ /* empty array */ ],
-1e10 // another comment
] ,
"key3": false
}

18
tests/tarray2.nim Normal file
View File

@@ -0,0 +1,18 @@
# simple check for one dimensional arrays
type
TMyArray = array[0..2, int]
proc mul(a, b: TMyarray): TMyArray =
result = a
for i in 0..len(a)-1:
result[i] = a[i] * b[i]
var
x, y, z: TMyArray
x = [ 4, 5, 6 ]
y = x
echo repr(mul(x, y))
#OUT [16, 25, 36]

32
tests/tcurrncy.nim Normal file
View File

@@ -0,0 +1,32 @@
template Additive(typ: typeDesc): stmt =
proc `+` *(x, y: typ): typ {.borrow.}
proc `-` *(x, y: typ): typ {.borrow.}
# unary operators:
proc `+` *(x: typ): typ {.borrow.}
proc `-` *(x: typ): typ {.borrow.}
template Multiplicative(typ, base: typeDesc): stmt =
proc `*` *(x: typ, y: base): typ {.borrow.}
proc `*` *(x: base, y: typ): typ {.borrow.}
proc `div` *(x: typ, y: base): typ {.borrow.}
proc `mod` *(x: typ, y: base): typ {.borrow.}
template Comparable(typ: typeDesc): stmt =
proc `<` * (x, y: typ): bool {.borrow.}
proc `<=` * (x, y: typ): bool {.borrow.}
proc `==` * (x, y: typ): bool {.borrow.}
template DefineCurrency(typ, base: expr): stmt =
type
typ* = abstract base
Additive(typ)
Multiplicative(typ, base)
Comparable(typ)
proc `$` * (t: typ): string {.borrow.}
DefineCurrency(TDollar, int)
DefineCurrency(TEuro, int)
echo($( 12.TDollar + 13.TDollar )) #OUT 25

22
tests/tident.nim Normal file
View File

@@ -0,0 +1,22 @@
type
TIdObj* = object of TObject
id*: int # unique id; use this for comparisons and not the pointers
PIdObj* = ref TIdObj
PIdent* = ref TIdent
TIdent*{.acyclic.} = object
s*: string
proc myNewString(L: int): string {.inline.} =
result = newString(L)
if result.len == L: echo("Length correct")
else: echo("bug")
for i in 0..L-1:
if result[i] == '\0':
echo("Correct")
else:
echo("Wrong")
var s = myNewString(8)

7
tests/titer3.nim Normal file
View File

@@ -0,0 +1,7 @@
# yield inside an iterator, but not in a loop:
iterator iter1(a: openArray[int]): int =
yield a[0] #ERROR_MSG 'yield' only allowed in a loop of an iterator
var x = [[1, 2, 3], [4, 5, 6]]
for y in iter1(x[0]): write(stdout, $y)

108
tests/xmltest.html Normal file
View File

@@ -0,0 +1,108 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Nimrod Programming Language</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="style/style.css" />
</head>
<>
<div id="main">
<div id="links">
<!-- **** INSERT LINKS HERE **** -->
</div>
<div id="logo"><h1>Nimrod Programming Language</h1></div>
<div id="content">
<div id="menu">
<ul>
<li><a
href="index.html" title = "Nimrod - home" home</a></li>
<!-- error: > missing -->
<li><a
href="news.html" title = "Nimrod - news">news</></>
<li><a
href="documentation.html" title = "Nimrod - docs">docs</a></li>
<li><a id="selected"
href="download.html" title = "Nimrod - download">download</a></li>
<li><a
href="community.html" title = "Nimrod - community">community</a></li>
<li><a
href="question.html" title = "Nimrod - FAQ">FAQ</a></li>
</ul>
</div>
<div id="column1">
<div class="sidebaritem">
<div class="sbihead">
<h1>latest news</h1>
</div>
<div class="sbicontent">
<p><span class="newsdate">2009-01-22</span><br />Forum added!<br /><span class="newsdate">2009-01-07</span><br />Nimrod version 0.7.4 has been released! Get it <a class="reference external" href="./download.html">here</a>.<br /><span class="newsdate">2008-12-12</span><br />Nimrod version 0.7.2 has been released!<br /><span class="newsdate">2008-11-16</span><br />Nimrod version 0.7.0 has been released!<br /><span class="newsdate">2008-08-22</span><br />Nimrod version 0.6.0 has been released!<br /><span class="newsdate">2008-06-22</span><br />This page is finally online!<br /></p>
</div>
</div>
<div class="sidebaritem">
<div class="sbihead">
<h1>additional links</h1>
</div>
<div class="sbilinks">
<!-- **** INSERT ADDITIONAL LINKS HERE **** -->
<ul>
<li><a class="reference" href="http://gcc.gnu.org">GCC</a></li>
<li><a class="reference" href="http://llvm.org">LLVM</a></li>
</ul>
</div>
</div>
</div>
<div id="column2">
<blockquote><p>There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence. -- Jeremy S. Anderson.</p></blockquote>
<p>Here you can download the latest version of the Nimrod Compiler. Please choose your platform:</p>
<ul class="simple"><li>source-based installation: <a class="reference external" href="download/nimrod_0.7.4.zip">download/nimrod_0.7.4.zip</a></li>
<li>installer for Windows (i386): <a class="reference external" href="download/nimrod_0.7.4.exe">download/nimrod_0.7.4.exe</a> (includes LLVM and everything else you need)</li>
</ul>
<p>The source-based installation should work on most UNIX-like systems. Currently, it has been tested on these systems:</p>
<ul class="simple"><li>Linux: i386, AMD64</li>
<li>Mac OS X: i386</li>
<li>FreeBSD: i386</li>
</ul>
<h1 id="installation">Installation</h1><h2 id="installation-on-linux-unix">Installation on Linux/UNIX</h2><dl class="docutils"><dt>Note:</dt>
<dd>A C compiler is required - knowledge of C is not!</dd>
</dl>
<p>The GNU C Compiler is fully supported, other compilers may work. The C compiler should be in your <tt class="docutils literal"><span class="pre">$PATH</span></tt> (most likely the case). Note that some few Linux distributions do not ship with a GCC compiler preinstalled - then you have to install it.</p>
<p>Install Nimrod by downloading the appropriate <tt class="docutils literal"><span class="pre">.zip</span></tt> file and extracting it to a directory of your choice. The Nimrod Compiler will stay in this directory (unless you copy it somewhere else). The compiler does not need write access to its directory anymore, so copying the nimrod folder to <tt class="docutils literal"><span class="pre">/opt</span></tt> does work.</p>
<p>Then run the following command:<pre>
sh build.sh</pre>
</p>
<p>Unlike other software, Nimrod does not distribute its files over the whole file hierarchy. This has the advantage that you can deinstall it by just deleting its folder. The disadvantage is that you have to add it to your <tt class="docutils literal"><span class="pre">PATH</span></tt> manually. An alternative is to create a symbolic link in <tt class="docutils literal"><span class="pre">/usr/bin</span></tt>:<pre>
[sudo] ln -s $your_install_dir/bin/nimrod /usr/bin/nimrod</pre>
</p>
<h2 id="installation-on-the-macintosh">Installation on the Macintosh</h2><p>Only MacOS X is supported. Since MacOS X is UNIX based too, it works like the installation on Linux. You need to install Apple's developer's tools for the GNU Compiler Collection though.</p>
<h2 id="installation-on-windows">Installation on Windows</h2><p>Install Nimrod by downloading and running the <tt class="docutils literal"><span class="pre">nimrod_$version.exe</span></tt> file. As default, the <tt class="docutils literal"><span class="pre">LLVM-GCC</span></tt> compiler is used that is bundled with this installer. You can change the configuration file to use another C compiler.</p>
<p>Currently, the following C compilers are supported under Windows:</p>
<ul class="simple"><li><p>Microsoft's Visual C++<br /><a class="reference external" href="http://msdn.microsoft.com/visualc">http://msdn.microsoft.com/visualc</a><br />(You need the SDK too - but not the full one: Essential are only the win32api header files and import libraries.)<br /></p></li>
<li><p>Gnu C Compiler (the mingw version; the cygwin version has not been tested!)<br /><a class="reference external" href="http://www.mingw.org/download.shtml">http://www.mingw.org/download.shtml</a><br /></p></li>
<li><p>LLVM with GNU C/C++ frontend<br /><a class="reference external" href="http://llvm.org/releases/download.html#2.2">http://llvm.org/releases/download.html#2.2</a><br /></p></li>
<li><p>Digital Mars C++<br /><a class="reference external" href="http://www.digitalmars.com/download/freecompiler.html">http://www.digitalmars.com/download/freecompiler.html</a><br /></p></li>
</ul>
<p>For better compile times I recommend Digital Mars C++ -- it is easy to install and a small package.</p>
<pre>
x < 0 && y >= 0
</pre>
</div>
</div>
<div id="footer">
copyright &copy; 2009 Andreas Rumpf | Last update: 2009-02-10
| <a class="reference" href="http://validator.w3.org/check?uri=referer">XHTML 1.1</a>
| <a class="reference" href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>
| <a class="reference" href="http://www.dcarter.co.uk">design by dcarter</a>
</div>
</div>
</body>
</html>