diff options
-rw-r--r-- | doc/abstypes.txt | 152 | ||||
-rw-r--r-- | doc/astspec.txt | 572 | ||||
-rw-r--r-- | examples/keyval.nim | 9 | ||||
-rw-r--r-- | examples/luaex.nim | 15 | ||||
-rw-r--r-- | examples/maximum.nim | 6 | ||||
-rw-r--r-- | examples/myfile.txt | 11 | ||||
-rw-r--r-- | examples/pythonex.nim | 12 | ||||
-rw-r--r-- | examples/tclex.nim | 25 | ||||
-rw-r--r-- | tests/jsontest.json | 22 | ||||
-rw-r--r-- | tests/tarray2.nim | 18 | ||||
-rw-r--r-- | tests/tcurrncy.nim | 32 | ||||
-rw-r--r-- | tests/tident.nim | 22 | ||||
-rw-r--r-- | tests/titer3.nim | 7 | ||||
-rw-r--r-- | tests/xmltest.html | 108 |
14 files changed, 1011 insertions, 0 deletions
diff --git a/doc/abstypes.txt b/doc/abstypes.txt new file mode 100644 index 000000000..00a42639c --- /dev/null +++ b/doc/abstypes.txt @@ -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) + diff --git a/doc/astspec.txt b/doc/astspec.txt new file mode 100644 index 000000000..eec2808fd --- /dev/null +++ b/doc/astspec.txt @@ -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. + diff --git a/examples/keyval.nim b/examples/keyval.nim new file mode 100644 index 000000000..99a410e8c --- /dev/null +++ b/examples/keyval.nim @@ -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] + + diff --git a/examples/luaex.nim b/examples/luaex.nim new file mode 100644 index 000000000..a71f0fb05 --- /dev/null +++ b/examples/luaex.nim @@ -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) + diff --git a/examples/maximum.nim b/examples/maximum.nim new file mode 100644 index 000000000..5e4a9cc5e --- /dev/null +++ b/examples/maximum.nim @@ -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!") diff --git a/examples/myfile.txt b/examples/myfile.txt new file mode 100644 index 000000000..1df0d56f8 --- /dev/null +++ b/examples/myfile.txt @@ -0,0 +1,11 @@ +kladsfa + +asdflksadlfasf + + +adsfljksadfl + + +key=/usr/bin/value +key2=/ha/ha + diff --git a/examples/pythonex.nim b/examples/pythonex.nim new file mode 100644 index 000000000..e2664f350 --- /dev/null +++ b/examples/pythonex.nim @@ -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() + diff --git a/examples/tclex.nim b/examples/tclex.nim new file mode 100644 index 000000000..6d6d45b8f --- /dev/null +++ b/examples/tclex.nim @@ -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") + + diff --git a/tests/jsontest.json b/tests/jsontest.json new file mode 100644 index 000000000..27b5ba1d1 --- /dev/null +++ b/tests/jsontest.json @@ -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 +} + + diff --git a/tests/tarray2.nim b/tests/tarray2.nim new file mode 100644 index 000000000..eb0b75692 --- /dev/null +++ b/tests/tarray2.nim @@ -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] diff --git a/tests/tcurrncy.nim b/tests/tcurrncy.nim new file mode 100644 index 000000000..1d353abd6 --- /dev/null +++ b/tests/tcurrncy.nim @@ -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 + diff --git a/tests/tident.nim b/tests/tident.nim new file mode 100644 index 000000000..1ed9894c6 --- /dev/null +++ b/tests/tident.nim @@ -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) + diff --git a/tests/titer3.nim b/tests/titer3.nim new file mode 100644 index 000000000..b42113241 --- /dev/null +++ b/tests/titer3.nim @@ -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) + diff --git a/tests/xmltest.html b/tests/xmltest.html new file mode 100644 index 000000000..862a91d24 --- /dev/null +++ b/tests/xmltest.html @@ -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 © 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> + |