diff --git a/cogapp.py b/cogapp.py
index 4c2e92bf0..54c5e5e3a 100644
--- a/cogapp.py
+++ b/cogapp.py
@@ -1,15 +1,17 @@
""" Cog code generation tool.
http://nedbatchelder.com/code/cog
-
+
Copyright 2004-2008, Ned Batchelder.
"""
# $Id: cogapp.py 141 2008-05-22 10:56:43Z nedbat $
+# modified to run with Python1.5.2 by Andreas Rumpf
import md5, os, re, string, sys, traceback, types
-import imp, compiler
+import imp
import copy, getopt, shlex
from cStringIO import StringIO
+from string import strip, split, join, replace
__all__ = ['Cog', 'CogUsageError']
@@ -56,7 +58,7 @@ class CogError(Exception):
Exception.__init__(self, "%s(%d): %s" % (file, line, msg))
else:
Exception.__init__(self, msg)
-
+
class CogUsageError(CogError):
""" An error in usage of command-line arguments in cog.
"""
@@ -78,7 +80,7 @@ class Redirectable:
def __init__(self):
self.stdout = sys.stdout
self.stderr = sys.stderr
-
+
def setOutput(self, stdout=None, stderr=None):
""" Assign new files for standard out and/or standard error.
"""
@@ -94,12 +96,16 @@ class CogGenerator(Redirectable):
Redirectable.__init__(self)
self.markers = []
self.lines = []
-
+
def parseMarker(self, l):
self.markers.append(l)
-
+
def parseLine(self, l):
- self.lines.append(l.strip('\n'))
+ s = 0
+ e = len(l)
+ while s < len(l) and l[s] == '\n': s = s + 1
+ while e >= 1 and l[e-1] == '\n': e = e - 1
+ self.lines.append(l[s:e+1])
def getCode(self):
""" Extract the executable Python code from the generator.
@@ -109,11 +115,17 @@ class CogGenerator(Redirectable):
# then remove it from all the lines.
prefIn = commonPrefix(self.markers + self.lines)
if prefIn:
- self.markers = [ l.replace(prefIn, '', 1) for l in self.markers ]
- self.lines = [ l.replace(prefIn, '', 1) for l in self.lines ]
+ tmp = []
+ for l in self.markers: tmp.append(replace(l, prefIn, '', 1))
+ self.markers = tmp
+ tmp = []
+ for l in self.lines: tmp.append(replace(l, prefIn, '', 1))
+ self.lines = tmp
+ #self.markers = [ l.replace(prefIn, '', 1) for l in self.markers ]
+ #self.lines = [ l.replace(prefIn, '', 1) for l in self.lines ]
return reindentBlock(self.lines, '')
-
+
def evaluate(self, cog, globals, fname='cog generator'):
# figure out the right whitespace prefix for the output
prefOut = whitePrefix(self.markers)
@@ -121,17 +133,22 @@ class CogGenerator(Redirectable):
intext = self.getCode()
if not intext:
return ''
-
- # In Python 2.2, the last line has to end in a newline.
- intext = "import cog\n" + intext + "\n"
- code = compiler.compile(intext, filename=str(fname), mode='exec')
+ # In Python 2.2, the last line has to end in a newline.
+ intext = "import cog\n" + replace(intext, "\r\n", "\n") + "\n"
+ code = None
+ try:
+ import compiler
+ except ImportError:
+ code = compile(intext, str(fname), 'exec')
+ if code == None:
+ code = compiler.compile(intext, filename=str(fname), mode='exec')
# Make sure the "cog" module has our state.
cog.cogmodule.msg = self.msg
cog.cogmodule.out = self.out
cog.cogmodule.outl = self.outl
cog.cogmodule.error = self.error
-
+
self.outstring = ''
eval(code, globals)
@@ -139,31 +156,31 @@ class CogGenerator(Redirectable):
# ends with a newline, or it will be joined to the
# end-output line, ruining cog's idempotency.
if self.outstring and self.outstring[-1] != '\n':
- self.outstring += '\n'
+ self.outstring = self.outstring + '\n'
return reindentBlock(self.outstring, prefOut)
def msg(self, s):
- print >>self.stdout, "Message: "+s
+ self.stdout.write("Message: "+s+"\n")
def out(self, sOut='', dedent=False, trimblanklines=False):
""" The cog.out function.
"""
if trimblanklines and ('\n' in sOut):
- lines = sOut.split('\n')
- if lines[0].strip() == '':
+ lines = split(sOut, '\n')
+ if strip(lines[0]) == '':
del lines[0]
- if lines and lines[-1].strip() == '':
+ if lines and strip(lines[-1]) == '':
del lines[-1]
- sOut = '\n'.join(lines)+'\n'
+ sOut = join(lines,'\n')+'\n'
if dedent:
sOut = reindentBlock(sOut)
- self.outstring += sOut
+ self.outstring = self.outstring + sOut
- def outl(self, sOut='', **kw):
+ def outl(self, sOut='', dedent=False, trimblanklines=False):
""" The cog.outl function.
"""
- self.out(sOut, **kw)
+ self.out(sOut, dedent, trimblanklines)
self.out('\n')
def error(self, msg='Error raised by cog generator.'):
@@ -185,7 +202,7 @@ class NumberedFileReader:
def readline(self):
l = self.f.readline()
if l:
- self.n += 1
+ self.n = self.n + 1
return l
def linenumber(self):
@@ -211,7 +228,7 @@ class CogOptions:
self.bEofCanBeEnd = False
self.sSuffix = None
self.bNewlines = False
-
+
def __cmp__(self, other):
""" Comparison operator for tests to use.
"""
@@ -225,7 +242,7 @@ class CogOptions:
def addToIncludePath(self, dirs):
""" Add directories to the include path.
"""
- dirs = dirs.split(os.pathsep)
+ dirs = split(dirs, os.pathsep)
self.includePath.extend(dirs)
def parseArgs(self, argv):
@@ -244,7 +261,7 @@ class CogOptions:
elif o == '-D':
if a.count('=') < 1:
raise CogUsageError("-D takes a name=value argument")
- name, value = a.split('=', 1)
+ name, value = split(a, '=', 1)
self.defines[name] = value
elif o == '-e':
self.bWarnEmpty = True
@@ -281,6 +298,14 @@ class CogOptions:
raise CogUsageError("Can't use -o with -r (they are opposites)")
+def mydigest(hasher):
+ result = ""
+ for c in hasher.digest():
+ x = hex(ord(c))[2:]
+ if len(x) == 1: x = "0" + x
+ result = result + x
+ return result
+
class Cog(Redirectable):
""" The Cog engine.
"""
@@ -294,19 +319,19 @@ class Cog(Redirectable):
self.options = CogOptions()
self.sOutputMode = 'w'
-
+
self.installCogModule()
def showWarning(self, msg):
- print >>self.stdout, "Warning:", msg
+ self.stdout.write("Warning: " + msg + "\n")
def isBeginSpecLine(self, s):
return string.find(s, self.sBeginSpec) >= 0
-
+
def isEndSpecLine(self, s):
return string.find(s, self.sEndSpec) >= 0 and \
not self.isEndOutputLine(s)
-
+
def isEndOutputLine(self, s):
return string.find(s, self.sEndOutput) >= 0
@@ -317,7 +342,7 @@ class Cog(Redirectable):
self.cogmodule = imp.new_module('cog')
self.cogmodule.path = []
sys.modules['cog'] = self.cogmodule
-
+
def processFile(self, fIn, fOut, fname=None, globals=None):
""" Process an input file object to an output file object.
fIn and fOut can be file objects, or file names.
@@ -326,19 +351,19 @@ class Cog(Redirectable):
sFileIn = fname or ''
sFileOut = fname or ''
# Convert filenames to files.
- if isinstance(fIn, types.StringTypes):
+ if type(fIn) == type(""):
# Open the input file.
sFileIn = fIn
fIn = open(fIn, 'r')
- if isinstance(fOut, types.StringTypes):
+ if type(fOut) == type(""):
# Open the output file.
sFileOut = fOut
fOut = open(fOut, self.sOutputMode)
fIn = NumberedFileReader(fIn)
-
+
bSawCog = False
-
+
self.cogmodule.inFile = sFileIn
self.cogmodule.outFile = sFileOut
@@ -383,12 +408,12 @@ class Cog(Redirectable):
raise CogError("Cog code markers inverted",
file=sFileIn, line=firstLineNum)
else:
- sCode = l[beg+len(self.sBeginSpec):end].strip()
+ sCode = strip(l[beg+len(self.sBeginSpec):end])
gen.parseLine(sCode)
else:
# Deal with an ordinary code block.
l = fIn.readline()
-
+
# Get all the lines in the spec
while l and not self.isEndSpecLine(l):
if self.isBeginSpecLine(l):
@@ -409,9 +434,9 @@ class Cog(Redirectable):
if not self.options.bDeleteCode:
fOut.write(l)
gen.parseMarker(l)
-
+
l = fIn.readline()
-
+
# Eat all the lines in the output section. While reading past
# them, compute the md5 hash of the old output.
hasher = md5.new()
@@ -424,14 +449,14 @@ class Cog(Redirectable):
file=sFileIn, line=fIn.linenumber())
hasher.update(l)
l = fIn.readline()
- curHash = hasher.hexdigest()
+ curHash = mydigest(hasher)
if not l and not self.options.bEofCanBeEnd:
# We reached end of file before we found the end output line.
raise CogError("Missing '%s' before end of file." % self.sEndOutput,
file=sFileIn, line=fIn.linenumber())
- # Write the output of the spec to be the new output if we're
+ # Write the output of the spec to be the new output if we're
# supposed to generate code.
hasher = md5.new()
if not self.options.bNoGenerate:
@@ -440,10 +465,10 @@ class Cog(Redirectable):
sGen = self.suffixLines(sGen)
hasher.update(sGen)
fOut.write(sGen)
- newHash = hasher.hexdigest()
-
+ newHash = mydigest(hasher)
+
bSawCog = True
-
+
# Write the ending output line
hashMatch = self.reEndOutput.search(l)
if self.options.bHashOutput:
@@ -453,17 +478,17 @@ class Cog(Redirectable):
raise CogError("Output has been edited! Delete old checksum to unprotect.",
file=sFileIn, line=fIn.linenumber())
# Create a new end line with the correct hash.
- endpieces = l.split(hashMatch.group(0), 1)
+ endpieces = split(l, hashMatch.group(0), 1)
else:
# There was no old hash, but we want a new hash.
- endpieces = l.split(self.sEndOutput, 1)
- l = (self.sEndFormat % newHash).join(endpieces)
+ endpieces = split(l, self.sEndOutput, 1)
+ l = join(endpieces, (self.sEndFormat % newHash))
else:
# We don't want hashes output, so if there was one, get rid of
# it.
if hashMatch:
- l = l.replace(hashMatch.groupdict()['hashsect'], '', 1)
-
+ l = replace(l, hashMatch.groupdict()['hashsect'], '', 1)
+
if not self.options.bDeleteCode:
fOut.write(l)
l = fIn.readline()
@@ -473,14 +498,14 @@ class Cog(Redirectable):
# A regex for non-empty lines, used by suffixLines.
reNonEmptyLines = re.compile("^\s*\S+.*$", re.MULTILINE)
-
+
def suffixLines(self, text):
""" Add suffixes to the lines in text, if our options desire it.
text is many lines, as a single string.
"""
if self.options.sSuffix:
# Find all non-blank lines, and add the suffix to the end.
- repl = r"\g<0>" + self.options.sSuffix.replace('\\', '\\\\')
+ repl = r"\g<0>" + replace(self.options.sSuffix, '\\', '\\\\')
text = self.reNonEmptyLines.sub(repl, text)
return text
@@ -492,7 +517,7 @@ class Cog(Redirectable):
fNew = StringIO()
self.processFile(fOld, fNew, fname=fname)
return fNew.getvalue()
-
+
def replaceFile(self, sOldPath, sNewText):
""" Replace file sOldPath with the contents sNewText
"""
@@ -500,7 +525,7 @@ class Cog(Redirectable):
# Need to ensure we can write.
if self.options.sMakeWritableCmd:
# Use an external command to make the file writable.
- cmd = self.options.sMakeWritableCmd.replace('%s', sOldPath)
+ cmd = replace(self.options.sMakeWritableCmd, '%s', sOldPath)
self.stdout.write(os.popen(cmd).read())
if not os.access(sOldPath, os.W_OK):
raise CogError("Couldn't make %s writable" % sOldPath)
@@ -541,23 +566,23 @@ class Cog(Redirectable):
self.sOutputMode = 'w'
if self.options.bNewlines:
self.sOutputMode = 'wb'
-
+
# How we process the file depends on where the output is going.
if self.options.sOutputName:
self.processFile(sFile, self.options.sOutputName, sFile)
elif self.options.bReplace:
# We want to replace the cog file with the output,
# but only if they differ.
- print >>self.stdout, "Cogging %s" % sFile,
+ self.stdout.write("Cogging %s" % sFile)
bNeedNewline = True
-
+
try:
fOldFile = open(sFile)
sOldText = fOldFile.read()
fOldFile.close()
sNewText = self.processString(sOldText, fname=sFile)
if sOldText != sNewText:
- print >>self.stdout, " (changed)"
+ self.stdout.write(" (changed)\n")
bNeedNewline = False
self.replaceFile(sFile, sNewText)
finally:
@@ -566,7 +591,7 @@ class Cog(Redirectable):
# same line, but also make sure to break the line before
# any traceback.
if bNeedNewline:
- print >>self.stdout
+ self.stdout.write('\n')
else:
self.processFile(sFile, self.stdout, sFile)
finally:
@@ -594,7 +619,7 @@ class Cog(Redirectable):
self.options.parseArgs(args[1:])
self.options.validate()
-
+
if args[0][0] == '@':
if self.options.sOutputName:
raise CogUsageError("Can't use -o with @file")
@@ -613,22 +638,22 @@ class Cog(Redirectable):
# Provide help if asked for anywhere in the command line.
if '-?' in argv or '-h' in argv:
- print >>self.stderr, usage,
+ self.stderr.write(usage)
return
self.options.parseArgs(argv)
self.options.validate()
if self.options.bShowVersion:
- print >>self.stdout, "Cog version %s" % __version__
+ self.stdout.write("Cog version %s\n" % __version__)
return
if self.options.args:
- for a in self.options.args:
+ for a in self.options.args:
self.processArguments([a])
else:
raise CogUsageError("No files to process")
-
+
def main(self, argv):
""" Handle the command-line execution for cog.
"""
@@ -637,14 +662,14 @@ class Cog(Redirectable):
self.callableMain(argv)
return 0
except CogUsageError, err:
- print >>self.stderr, err
- print >>self.stderr, "(for help use -?)"
+ self.stderr.write(err + "\n")
+ self.stderr.write("(for help use -?)\n")
return 2
except CogGeneratedError, err:
- print >>self.stderr, "Error: %s" % err
+ self.stderr.write("Error: %s\n" % err)
return 3
except CogError, err:
- print >>self.stderr, err
+ self.stderr.write(err + "\n")
return 1
except:
traceback.print_exc(None, self.stderr)
diff --git a/config/doctempl.cfg b/config/doctempl.cfg
deleted file mode 100644
index 4f99af78f..000000000
--- a/config/doctempl.cfg
+++ /dev/null
@@ -1,291 +0,0 @@
-# This is the config file for the documentation generator.
-# (c) 2008 Andreas Rumpf
-# Feel free to edit the templates as you need.
-
-split.item.toc = "25"
-# too long entries in the table of contents get truncated
-# after this number of characters
-
-doc.section = """
-
-"""
-
-doc.section.toc = """
-
- $sectionTitle
-
-
-"""
-
-doc.item = """
-$header
-
-$desc
-
-"""
-
-doc.item.toc = """
- $name
-"""
-
-doc.toc = """
-"""
-
-doc.body_toc = """
-$tableofcontents
-
-$moduledesc
-$content
-
-"""
-
-doc.body_no_toc = """
-$moduledesc
-$content
-"""
-
-doc.file = """
-
-
-
-
-
-$title
-
-
-
-
-
-
-
$title
-$content
-Generated: $date $time UTC
-
-
-
-"""
-
diff --git a/config/my_nimrod.cfg b/config/my_nimrod.cfg
index 7c74cc3ae..8c4bb8cec 100644
--- a/config/my_nimrod.cfg
+++ b/config/my_nimrod.cfg
@@ -9,12 +9,14 @@
# Environment variables cannot be used in the options, however!
# Just call the compiler with several options:
-cc = @if unix: gcc @else: vcc @end
+cc = @if macosx or windows: llvm_gcc @else: gcc @end
lib="$nimrod/lib"
path="$lib/base"
path="$lib/base/gtk"
path="$lib/base/cairo"
path="$lib/base/x11"
+path="$lib/base/sdl"
+path="$lib/base/opengl"
path="$lib/windows"
path="$lib/posix"
path="$lib/ecmas"
@@ -25,20 +27,23 @@ path="$lib/extra"
stacktrace:off
debugger:off
line_dir:off
+ opt:speed
@end
# additional defines:
#define=""
# additional options always passed to the compiler:
-force_build
line_dir=off
-cfilecache=on
+
+# use the new experimental symbol files for speeding up compilation:
+#--symbol_files
+--verbosity: "1"
hint[LineTooLong]=off
hint[XDeclaredButNotUsed]=off
@if unix:
- passl= "-ldl"
+ @if not bsd: passl= "-ldl" @end
path = "$lib/base/gtk"
@end
@@ -50,10 +55,12 @@ hint[XDeclaredButNotUsed]=off
# Configuration for the LLVM GCC compiler:
@if windows:
llvm_gcc.path = r"$nimrod\dist\llvm-gcc4.2\bin"
+@elif macosx:
+ llvm_gcc.path = r"/Users/andreasrumpf/download/C/llvm-gcc4.2-2.3-x86-darwin8/bin"
@end
llvm_gcc.options.debug = "-g"
llvm_gcc.options.always = "-w"
-llvm_gcc.options.speed = "-O3 -ffast-math"
+llvm_gcc.options.speed = "-O2 -fno-strict-aliasing -ffast-math"
llvm_gcc.options.size = "-Os -ffast-math"
# Configuration for the Borland C++ Compiler:
@@ -62,23 +69,24 @@ llvm_gcc.options.size = "-Os -ffast-math"
@end
bcc.options.debug = ""
# turn off warnings about unreachable code and inline procs:
-bcc.options.always = "-w- -H- -q -RT- -a8 -w-8027 -w-8066"
+bcc.options.always = "-H- -q -RT- -a8 -w-8027 -w-8066 -w-8004"
bcc.options.speed = "-O2 -6"
bcc.options.size = "-O1 -6"
# Configuration for the Visual C/C++ compiler:
@if vcc:
- @prepend_env path r"C:\Eigenes\compiler\vcc2005\Common7\IDE;"
- @prepend_env INCLUDE r"C:\Eigenes\compiler\vcc2005\VC\include;C:\Eigenes\compiler\vcc2005\VC\ATLMFC\INCLUDE;"
- @prepend_env LIB r"C:\Eigenes\compiler\vcc2005\VC\lib;C:\Eigenes\compiler\vcc2005\SDK\v2.0\Lib;"
+ @prepend_env path r"C:\Programme\Microsoft Visual Studio 9.0\Common7\IDE;"
+ @prepend_env INCLUDE r"C:\Programme\Microsoft Visual Studio 9.0\VC\include;C:\Programme\Microsoft Visual Studio 9.0\VC\ATLMFC\INCLUDE;C:\Programme\Microsoft SDKs\Windows\v6.0A\Include;"
+ @prepend_env LIB r"C:\Programme\Microsoft Visual Studio 9.0\VC\lib;C:\Programme\Microsoft Visual Studio 9.0\SDK\v2.0\Lib;C:\Programme\Microsoft SDKs\Windows\v6.0A\Lib;"
+ passl: r"/F33554432" # set the stack size to 8 MB
@end
@if windows:
- vcc.path = r"C:\Eigenes\compiler\vcc2005\VC\bin"
+ vcc.path = r"C:\Programme\Microsoft Visual Studio 9.0\VC\bin"
@end
vcc.options.debug = "/RTC1 /ZI"
vcc.options.always = "/nologo"
-vcc.options.speed = "/Ogityb2 /G7 /arch:SSE2"
-vcc.options.size = "/O1 /G7"
+vcc.options.speed = "/Ox /arch:SSE2"
+vcc.options.size = "/O1"
# Configuration for the Watcom C/C++ compiler:
@if windows:
@@ -122,10 +130,11 @@ lcc.options.size = "-O -p6"
# Configuration for the Tiny C Compiler:
@if windows:
- tcc.path = r"C:\eigenes\compiler\tcc\bin"
+ tcc.path = r"C:\Eigenes\compiler\tcc-0.9.23\tcc"
+ tcc.options.always = r"-IC:\Eigenes\compiler\tcc-0.9.23\include " &
+ r"-IC:\Eigenes\compiler\tcc-0.9.23\include\winapi"
@end
-tcc.options.debug = "-b"
-tcc.options.always = ""
+tcc.options.debug = ""
tcc.options.speed = ""
tcc.options.size = ""
@@ -146,7 +155,7 @@ icc.options.always = "-w"
icc.options.speed = "-O3 -ffast-math"
icc.options.size = "-Os -ffast-math"
-@write "used default config file"
+@write "used special config file"
@if ecmascript:
@write "Target is ECMAScript! No unsafe features are allowed!"
diff --git a/config/nimrod.cfg b/config/nimrod.cfg
index 0b4ddc6e7..eb8ad707f 100644
--- a/config/nimrod.cfg
+++ b/config/nimrod.cfg
@@ -1,5 +1,4 @@
# Configuration file for the Nimrod Compiler.
-# Generated by the koch.py script.
# (c) 2008 Andreas Rumpf
# Feel free to edit the default values as you need.
@@ -8,38 +7,42 @@
# @putenv "key" "val"
# Environment variables cannot be used in the options, however!
-# Just call the compiler with several options:
-cc = @if unix: gcc @else: vcc @end
+cc = @if windows: llvm_gcc @else: gcc @end
lib="$nimrod/lib"
path="$lib/base"
path="$lib/base/gtk"
path="$lib/base/cairo"
path="$lib/base/x11"
+path="$lib/base/sdl"
+path="$lib/base/opengl"
+path="$lib/base/zip"
path="$lib/windows"
path="$lib/posix"
path="$lib/ecmas"
path="$lib/extra"
@if release:
- checks:off
+ obj_checks:off
+ field_checks:off
+ range_checks:off
+ bound_checks:off
+ overflow_checks:off
+ assertions:off
+
stacktrace:off
debugger:off
line_dir:off
+ opt:speed
@end
-# additional defines:
-#define=""
# additional options always passed to the compiler:
-force_build
-line_dir=off
-cfilecache=on
+--verbosity: "1"
hint[LineTooLong]=off
-hint[XDeclaredButNotUsed]=off
+#hint[XDeclaredButNotUsed]=off
@if unix:
- passl= "-ldl"
- path = "$lib/base/gtk"
+ @if not bsd: passl= "-ldl" @end
@end
@if icc:
@@ -50,107 +53,48 @@ hint[XDeclaredButNotUsed]=off
# Configuration for the LLVM GCC compiler:
@if windows:
llvm_gcc.path = r"$nimrod\dist\llvm-gcc4.2\bin"
+@elif macosx:
+ llvm_gcc.path =
+ r"/Users/andreasrumpf/download/C/llvm-gcc4.2-2.3-x86-darwin8/bin"
@end
llvm_gcc.options.debug = "-g"
llvm_gcc.options.always = "-w"
-llvm_gcc.options.speed = "-O3 -ffast-math"
-llvm_gcc.options.size = "-Os -ffast-math"
-
-# Configuration for the Borland C++ Compiler:
-@if windows:
- bcc.path = r"C:\eigenes\compiler\cbuilder5\bin"
-@end
-bcc.options.debug = ""
-# turn off warnings about unreachable code and inline procs:
-bcc.options.always = "-w- -H- -q -RT- -a8 -w-8027 -w-8066"
-bcc.options.speed = "-O2 -6"
-bcc.options.size = "-O1 -6"
+llvm_gcc.options.speed = "-O2"
+llvm_gcc.options.size = "-Os"
# Configuration for the Visual C/C++ compiler:
@if vcc:
- @prepend_env path r"C:\Programme\Microsoft Visual Studio 9.0\Common7\IDE;"
- @prepend_env INCLUDE r"C:\Programme\Microsoft Visual Studio 9.0\VC\include;C:\Programme\Microsoft Visual Studio 9.0\VC\ATLMFC\INCLUDE;C:\Programme\Microsoft SDKs\Windows\v6.0A\Include;"
- @prepend_env LIB r"C:\Programme\Microsoft Visual Studio 9.0\VC\lib;C:\Programme\Microsoft Visual Studio 9.0\SDK\v2.0\Lib;C:\Programme\Microsoft SDKs\Windows\v6.0A\Lib;"
passl: r"/F33554432" # set the stack size to 8 MB
@end
-@if windows:
- vcc.path = r"C:\Programme\Microsoft Visual Studio 9.0\VC\bin"
-@end
vcc.options.debug = "/RTC1 /ZI"
vcc.options.always = "/nologo"
-vcc.options.speed = "/Ogityb2 /G7 /arch:SSE2"
-vcc.options.size = "/O1 /G7"
-
-# Configuration for the Watcom C/C++ compiler:
-@if windows:
- wcc.path = r"C:\eigenes\compiler\watcom\binnt"
-@end
-wcc.options.debug = "-d2"
-wcc.options.always = "-6 -zw -w-"
-wcc.options.speed = "-ox -on -6 -d0 -fp6 -zW"
-wcc.options.size = "-ox -on -6 -d0 -fp6 -zW"
+vcc.options.speed = "/Ox /arch:SSE2"
+vcc.options.size = "/O1"
# Configuration for the GNU C/C++ compiler:
@if windows:
gcc.path = r"C:\eigenes\compiler\mingw\bin"
@end
+#gcc.exe = "gcc-4.1"
+#gcc.linkerExe = "gcc-4.1"
gcc.options.debug = "-g"
@if macosx:
gcc.options.always = "-w -fasm-blocks"
@else:
gcc.options.always = "-w"
@end
-gcc.options.speed = "-O3 -ffast-math"
-gcc.options.size = "-Os -ffast-math"
+gcc.options.speed = "-O3 -fno-strict-aliasing"
+gcc.options.size = "-Os"
# Configuration for the Digital Mars C/C++ compiler:
@if windows:
dmc.path = r"C:\eigenes\compiler\d\dm\bin"
@end
-dmc.options.debug = "-g"
-dmc.options.always = "-Jm"
-dmc.options.speed = "-ff -o -6"
-dmc.options.size = "-ff -o -6"
-
-# Configuration for the LCC compiler:
-@if windows:
- lcc.path = r"C:\eigenes\compiler\lcc\bin"
-@end
-lcc.options.debug = "-g5"
-lcc.options.always = "-e1"
-lcc.options.speed = "-O -p6"
-lcc.options.size = "-O -p6"
# Configuration for the Tiny C Compiler:
@if windows:
tcc.path = r"C:\Eigenes\compiler\tcc-0.9.23\tcc"
tcc.options.always = r"-IC:\Eigenes\compiler\tcc-0.9.23\include " &
- r"-IC:\Eigenes\compiler\tcc-0.9.23\include\winapi"
+ r"-IC:\Eigenes\compiler\tcc-0.9.23\include\winapi"
@end
-tcc.options.debug = ""
-tcc.options.speed = ""
-tcc.options.size = ""
-
-# Configuration for the Pelles C compiler:
-@if windows:
- pcc.path = r"C:\eigenes\compiler\pellesc\bin"
-@end
-pcc.options.debug = "-Zi"
-pcc.options.always = "-Ze"
-pcc.options.speed = "-Ox"
-pcc.options.size = "-Os"
-
-@if windows:
- icc.path = r"c:\eignes\compiler\icc\bin"
-@end
-icc.options.debug = "-g"
-icc.options.always = "-w"
-icc.options.speed = "-O3 -ffast-math"
-icc.options.size = "-Os -ffast-math"
-
-@write "used special config file"
-
-@if ecmascript:
- @write "Target is ECMAScript! No unsafe features are allowed!"
-@end
-
+tcc.options.always = "-w"
diff --git a/config/old_doctempl.cfg b/config/old_doctempl.cfg
deleted file mode 100644
index 876086382..000000000
--- a/config/old_doctempl.cfg
+++ /dev/null
@@ -1,287 +0,0 @@
-# This is the config file for the documentation generator.
-# (c) 2008 Andreas Rumpf
-# Feel free to edit the templates as you need.
-
-doc.section = """
-
-"""
-
-doc.section.toc = """
-
- $sectionTitle
-
-
-"""
-
-doc.item = """
-$header
-
-$desc
-
-"""
-
-doc.item.toc = """
- $name
-"""
-
-doc.toc = """
-"""
-
-doc.body_toc = """
-$tableofcontents
-
-$moduledesc
-$content
-
-"""
-
-doc.body_no_toc = """
-$moduledesc
-$content
-"""
-
-doc.file = """
-
-
-
-
-
-$title
-
-
-
-
-
-
-
$title
-$content
-Generated: $date $time UTC
-
-
-
-"""
-
diff --git a/config/old_nimrod.cfg b/config/old_nimrod.cfg
deleted file mode 100644
index 250b813cf..000000000
--- a/config/old_nimrod.cfg
+++ /dev/null
@@ -1,165 +0,0 @@
-# Configuration file for the Nimrod Compiler.
-# Generated by the koch.py script.
-# (c) 2008 Andreas Rumpf
-
-# Feel free to edit the default values as you need.
-
-# You may set environment variables with
-# @putenv "key" "val"
-# Environment variables cannot be used in the options, however!
-
-# Just call the compiler with several options:
-cc = @if unix: gcc @else: vcc @end
-lib="$nimrod/lib"
-path="$lib/base"
-path="$lib/base/gtk"
-path="$lib/base/cairo"
-path="$lib/base/x11"
-path="$lib/windows"
-path="$lib/posix"
-path="$lib/ecmas"
-path="$lib/extra"
-
-@if release:
- checks:off
- stacktrace:off
- debugger:off
- line_dir:off
-@end
-
-# additional defines:
-#define=""
-# additional options always passed to the compiler:
-force_build
-line_dir=off
-cfilecache=on
-
-hint[LineTooLong]=off
-hint[XDeclaredButNotUsed]=off
-
-@if unix:
- passl= "-ldl"
- path = "$lib/base/gtk"
-@end
-
-@if icc:
- passl = "-cxxlib"
- passc = "-cxxlib"
-@end
-
-# Configuration for the LLVM GCC compiler:
-@if windows:
- llvm_gcc.path = r"$nimrod\dist\llvm-gcc4.2\bin"
-@end
-llvm_gcc.options.debug = "-g"
-llvm_gcc.options.always = "-w"
-llvm_gcc.options.speed = "-O3 -ffast-math"
-llvm_gcc.options.size = "-Os -ffast-math"
-
-# Configuration for the Borland C++ Compiler:
-@if windows:
- bcc.path = r"C:\eigenes\compiler\cbuilder5\bin"
-@end
-bcc.options.debug = ""
-# turn off warnings about unreachable code and inline procs:
-bcc.options.always = "-w- -H- -q -RT- -a8 -w-8027 -w-8066"
-bcc.options.speed = "-O2 -6"
-bcc.options.size = "-O1 -6"
-
-# Configuration for the Visual C/C++ compiler:
-#@if vcc:
-# @prepend_env path r"C:\Eigenes\compiler\vcc2005\Common7\IDE;"
-# @prepend_env INCLUDE r"C:\Eigenes\compiler\vcc2005\VC\include;C:\Eigenes\compiler\vcc2005\VC\ATLMFC\INCLUDE;"
-# @prepend_env LIB r"C:\Eigenes\compiler\vcc2005\VC\lib;C:\Eigenes\compiler\vcc2005\SDK\v2.0\Lib;"
-#@end
-#@if windows:
-# vcc.path = r"C:\Eigenes\compiler\vcc2005\VC\bin"
-#@end
-
-@if vcc:
- @prepend_env path r"C:\Programme\Microsoft Visual Studio 9.0\Common7\IDE;"
- @prepend_env INCLUDE r"C:\Programme\Microsoft Visual Studio 9.0\VC\include;C:\Programme\Microsoft Visual Studio 9.0\VC\ATLMFC\INCLUDE;C:\Programme\Microsoft SDKs\Windows\v6.0A\Include;"
- @prepend_env LIB r"C:\Programme\Microsoft Visual Studio 9.0\VC\lib;C:\Programme\Microsoft Visual Studio 9.0\SDK\v2.0\Lib;C:\Programme\Microsoft SDKs\Windows\v6.0A\Lib;"
- passl: r"/F8388608" # set the stack size to 8 MB
-@end
-@if windows:
- vcc.path = r"C:\Programme\Microsoft Visual Studio 9.0\VC\bin"
-@end
-vcc.options.debug = "/RTC1 /ZI"
-vcc.options.always = "/nologo"
-vcc.options.speed = "/Ogityb2 /G7 /arch:SSE2"
-vcc.options.size = "/O1 /G7"
-
-# Configuration for the Watcom C/C++ compiler:
-@if windows:
- wcc.path = r"C:\eigenes\compiler\watcom\binnt"
-@end
-wcc.options.debug = "-d2"
-wcc.options.always = "-6 -zw -w-"
-wcc.options.speed = "-ox -on -6 -d0 -fp6 -zW"
-wcc.options.size = "-ox -on -6 -d0 -fp6 -zW"
-
-# Configuration for the GNU C/C++ compiler:
-@if windows:
- gcc.path = r"C:\eigenes\compiler\mingw\bin"
-@end
-gcc.options.debug = "-g"
-@if macosx:
- gcc.options.always = "-w -fasm-blocks"
-@else:
- gcc.options.always = "-w"
-@end
-gcc.options.speed = "-O3 -ffast-math"
-gcc.options.size = "-Os -ffast-math"
-
-# Configuration for the Digital Mars C/C++ compiler:
-@if windows:
- dmc.path = r"C:\eigenes\compiler\d\dm\bin"
-@end
-dmc.options.debug = "-g"
-dmc.options.always = "-Jm"
-dmc.options.speed = "-ff -o -6"
-dmc.options.size = "-ff -o -6"
-
-# Configuration for the LCC compiler:
-@if windows:
- lcc.path = r"C:\eigenes\compiler\lcc\bin"
-@end
-lcc.options.debug = "-g5"
-lcc.options.always = "-e1"
-lcc.options.speed = "-O -p6"
-lcc.options.size = "-O -p6"
-
-# Configuration for the Tiny C Compiler:
-@if windows:
- tcc.path = r"C:\Eigenes\compiler\tcc-0.9.23\tcc"
- tcc.options.always = r"-IC:\Eigenes\compiler\tcc-0.9.23\include " &
- r"-IC:\Eigenes\compiler\tcc-0.9.23\include\winapi"
-@end
-tcc.options.debug = ""
-tcc.options.speed = ""
-tcc.options.size = ""
-
-# Configuration for the Pelles C compiler:
-@if windows:
- pcc.path = r"C:\eigenes\compiler\pellesc\bin"
-@end
-pcc.options.debug = "-Zi"
-pcc.options.always = "-Ze"
-pcc.options.speed = "-Ox"
-pcc.options.size = "-Os"
-
-@if windows:
- icc.path = r"c:\eignes\compiler\icc\bin"
-@end
-icc.options.debug = "-g"
-icc.options.always = "-w"
-icc.options.speed = "-O3 -ffast-math"
-icc.options.size = "-Os -ffast-math"
-
-@write "used special config file"
-
-@if ecmascript:
- @write "Target is ECMAScript! No unsafe features are allowed!"
-@end
-
diff --git a/configure b/configure
index d3fe66d92..613c79350 100644
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /usr/bin/env sh
-python koch.py $@ configure
+echo "there is nothing to configure"
diff --git a/data/advopt.txt b/data/advopt.txt
index 626a000e4..4d9dda7c2 100644
--- a/data/advopt.txt
+++ b/data/advopt.txt
@@ -4,21 +4,17 @@ Advanced commands::
gen_depend generate a DOT file containing the
module dependency graph
list_def list all defined conditionals and exit
- rst2html converts a reStructuredText file to HTML
check checks the project for syntax and semantic
parse parses a single file (for debugging Nimrod)
- scan tokenizes a single file (for debugging Nimrod)
- debugtrans for debugging the transformation pass
Advanced options:
-w, --warnings:on|off warnings ON|OFF
--warning[X]:on|off specific warning X ON|OFF
--hints:on|off hints ON|OFF
--hint[X]:on|off specific hint X ON|OFF
- --cc:C_COMPILER set the C/C++ compiler to use
--lib:PATH set the system library path
-c, --compile_only compile only; do not assemble or link
--no_linking compile but do not link
- --gen_script generate a compile script (in the 'rod_gen'
+ --gen_script generate a compile script (in the 'nimcache'
subdirectory named 'compile_$project$scriptext')
--os:SYMBOL set the target operating system (cross-compilation)
--cpu:SYMBOL set the target processor (cross-compilation)
@@ -27,17 +23,13 @@ Advanced options:
-l, --passl:OPTION pass an option to the linker
--gen_mapping generate a mapping file containing
(Nimrod, mangled) identifier pairs
- --merge_output generate only one C output file
--line_dir:on|off generation of #line directive ON|OFF
--checkpoints:on|off turn on|off checkpoints; for debugging Nimrod
--skip_cfg do not read the general configuration file
--skip_proj_cfg do not read the project's configuration file
--import:MODULE_FILE import the given module implicitly for each module
- --maxerr:NUMBER stop compilation after NUMBER errors; broken!
- --ast_cache:on|off caching of ASTs ON|OFF (default: OFF)
- --c_file_cache:on|off caching of generated C files ON|OFF (default: OFF)
--index:FILE use FILE to generate a documenation index file
--putenv:key=value set an environment variable
--list_cmd list the commands used to execute external programs
- -v, --verbose show what Nimrod is doing
- --version show detailed version information
+ --verbosity:0|1|2|3 set Nimrod's verbosity level (0 is default)
+ -v, --version show detailed version information
diff --git a/data/ast.yml b/data/ast.yml
index 72a1b02b5..6bbffae3f 100644
--- a/data/ast.yml
+++ b/data/ast.yml
@@ -8,61 +8,52 @@
#
{
-'SymFlag': [ # already 32 flags!
- 'sfTypeCheck', # wether macro parameters should be type checked
+'SymFlag': [ # already 26 flags!
+ 'sfUsed', # read access of sym (for warnings) or simply used
+ 'sfStar', # symbol has * visibility
+ 'sfMinus', # symbol has - visibility
+ 'sfInInterface', # symbol is in interface section declared
+ 'sfFromGeneric', # symbol is instantiation of a generic; this is needed
+ # for symbol file generation; such symbols should always
+ # be written into the ROD file
+ 'sfGlobal', # symbol is at global scope
+
'sfForward', # symbol is forward directed
'sfImportc', # symbol is external; imported
'sfExportc', # symbol is exported (under a specified name)
'sfVolatile', # variable is volatile
- 'sfUsed', # read access of sym (for warnings) or simply used
- 'sfWrite', # write access of variable (for hints)
'sfRegister', # variable should be placed in a register
'sfPure', # object is "pure" that means it has no type-information
- 'sfCodeGenerated', # wether we have already code generated for the proc
- 'sfPrivate', # symbol should be made private after module compilation
- 'sfGlobal', # symbol is at global scope
+
'sfResult', # variable is 'result' in proc
'sfNoSideEffect', # proc has no side effects
'sfMainModule', # module is the main module
'sfSystemModule', # module is the system module
'sfNoReturn', # proc never returns (an exit proc)
'sfAddrTaken', # the variable's address is taken (ex- or implicitely)
- 'sfInInterface', # symbol is in interface section declared
- 'sfNoStatic', # symbol is used within an iterator (needed for codegen)
- # so it cannot be 'static' in the C code
- # this is called 'nostatic' in the pragma section
'sfCompilerProc', # proc is a compiler proc, that is a C proc that is
# needed for the code generator
- 'sfCppMethod', # proc is a C++ method
+ 'sfCppMethod', # proc is a C++ method (not implemented yet)
'sfDiscriminant', # field is a discriminant in a record/object
'sfDeprecated', # symbol is deprecated
'sfInClosure', # variable is accessed by a closure
- 'sfIsCopy', # symbol is a copy; needed for proper name mangling
- 'sfStar', # symbol has * visibility
- 'sfMinus' # symbol has - visibility
+ 'sfTypeCheck', # wether macro parameters should be type checked
+ 'sfCompileTime', # proc can be evaluated at compile time
+ 'sfThreadVar', # variable is a thread variable
+ 'sfMerge', # proc can be merged with itself
],
'TypeFlag': [
- 'tfIsDistinct', # better use this flag to make it easier for accessing
- # typeKind in the code generators
- 'tfGeneric', # type is a generic one
- 'tfExternal', # type is external
- 'tfImported', # type is imported from C
- 'tfInfoGenerated', # whether we have generated type information for this type
- 'tfSemChecked', # used to mark types that's semantic has been checked;
- # used to prevend endless loops during semantic checking
- 'tfHasOutParams', # for a proc or iterator p:
- # it indicates that p has out or in out parameters: this
- # is used to speed up semantic checking a bit
- 'tfEnumHasWholes', # enum cannot be mapped into a range
'tfVarargs', # procedure has C styled varargs
- 'tfFinal' # is the object final?
+ 'tfFinal', # is the object final?
+ 'tfAcyclic', # type is acyclic (for GC optimization)
+ 'tfEnumHasWholes' # enum cannot be mapped into a range
],
'TypeKind': [ # order is important!
# Don't forget to change hti.nim if you make a change here
'tyNone', 'tyBool', 'tyChar',
- 'tyEmptySet', 'tyArrayConstr', 'tyNil',
+ 'tyEmpty', 'tyArrayConstr', 'tyNil',
'tyGeneric',
'tyGenericInst', # instantiated generic type
'tyGenericParam',
@@ -89,7 +80,9 @@
'nfBase2', # nfBase10 is default, so not needed
'nfBase8',
'nfBase16',
- 'nfAllConst' # used to mark complex expressions constant
+ 'nfAllConst', # used to mark complex expressions constant
+ 'nfTransf', # node has been transformed
+ 'nfSem', # node has been checked for semantics
],
'NodeKind': [ # these are pure nodes
@@ -223,6 +216,8 @@
'nkBlockExpr', # a statement block ending in an expr; this is used
# to allowe powerful multi-line templates that open a
# temporary scope
+ 'nkStmtListType', # a statement list ending in a type; for macros
+ 'nkBlockType', # a statement block ending in a type; for macros
'nkVm', # indicates a virtual instruction; integer field is
# used for the concrete opcode
@@ -264,6 +259,8 @@
'skEnumField', # an identifier in an enum
'skForVar', # a for loop variable
'skModule', # module identifier
- 'skLabel' # a label (for block statement)
+ 'skLabel', # a label (for block statement)
+ 'skStub' # symbol is a stub and not yet loaded from the ROD
+ # file (it is loaded on demand, which may mean: never)
]
}
diff --git a/data/basicopt.txt b/data/basicopt.txt
index dff49c3e8..7ff8ef136 100644
--- a/data/basicopt.txt
+++ b/data/basicopt.txt
@@ -1,12 +1,10 @@
Usage::
nimrod command [options] inputfile [arguments]
Command::
- compile compile project with default code generator (C)
- compile_to_c compile project with C code generator
- compile_to_cpp compile project with C++ code generator
- compile_to_ecmascript compile project to ECMAScript code (experimental)
- doc generate the documentation for inputfile;
- with --run switch opens it with $BROWSER
+ compile, c compile project with default code generator (C)
+ compile_to_c, cc compile project with C code generator
+ doc generate the documentation for inputfile
+ rst2html converts a reStructuredText file to HTML
Arguments:
arguments are passed to the program being run (if --run option is selected)
Options:
@@ -14,7 +12,8 @@ Options:
-o, --out:FILE set the output filename
-d, --define:SYMBOL define a conditional symbol
-u, --undef:SYMBOL undefine a conditional symbol
- -b, --force_build force rebuilding of all modules
+ -f, --force_build force rebuilding of all modules
+ --symbol_files:on|off use symbol files to speed up compilation (buggy!)
--stack_trace:on|off code generation for stack trace ON|OFF
--line_trace:on|off code generation for line trace ON|OFF
--debugger:on|off turn Embedded Nimrod Debugger ON|OFF
diff --git a/data/changes.txt b/data/changes.txt
deleted file mode 100644
index a449b7a62..000000000
--- a/data/changes.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-0.1.0
-* new config system
-* new build system
-* source renderer
-* pas2nim integrated
-* support for C++
-* local variables are always initialized
-* Rod file reader and writer
-* new --out, -o command line options
-* fixed bug in nimconf.pas: we now have several
- string token types
-* changed nkIdentDef to nkIdentDefs
-* added type(expr) in the parser and the grammer
-* added template
-* added command calls
-* added case in records/objects
-* added --skip_proj_cfg switch for nim.dpr
-* added missing features to pasparse
-* rewrote the source generator
-* ``addr`` and ``cast`` are now keywords; grammar updated
-* implemented ` notation; grammar updated
-* specification replaced by a manual
diff --git a/data/magic.yml b/data/magic.yml
index 519505eab..9c03028be 100644
--- a/data/magic.yml
+++ b/data/magic.yml
@@ -3,16 +3,20 @@
[
'None',
'Defined',
-'New',
-'NewFinalize',
'Low',
'High',
'SizeOf',
-'RegisterFinalizer',
+'Is',
'Succ',
'Pred',
'Inc',
'Dec',
+'Ord',
+
+'New',
+'NewFinalize',
+'NewSeq',
+'RegisterFinalizer',
'LengthOpenArray',
'LengthStr',
'LengthArray',
@@ -20,8 +24,9 @@
'Incl',
'Excl',
'Card',
-'Ord',
'Chr',
+'GCref',
+'GCunref',
# binary arithmetic with and without overflow checking:
'AddI',
@@ -161,7 +166,6 @@
'AppendSeqSeq',
'InRange',
'InSet',
-'Is',
'Asgn',
'Repr',
'Exit',
@@ -170,15 +174,34 @@
'Assert',
'Swap',
'IsNil',
+'ArrToSeq',
-# magic type constructors:
+# magic types:
'Array',
'OpenArray',
'Range',
'Set',
'Seq',
+'Int',
+'Int8',
+'Int16',
+'Int32',
+'Int64',
+'Float',
+'Float32',
+'Float64',
+'Bool',
+'Char',
+'String',
+'Cstring',
+'Pointer',
+'AnyEnum',
+'EmptySet',
+'IntSetBaseType',
+'Nil',
# magic constants:
+'IsMainModule',
'CompileDate',
'CompileTime',
'NimrodVersion',
diff --git a/data/messages.yml b/data/messages.yml
index 8892b2c3f..a90f9e4a8 100644
--- a/data/messages.yml
+++ b/data/messages.yml
@@ -153,7 +153,8 @@
{'errSizeTooBig': "computing the type's size produced an overflow"},
{'errSetTooBig': 'set is too large'},
{'errBaseTypeMustBeOrdinal': 'base type of a set must be an ordinal'},
-{'errInheritanceOnlyWithNonFinalObjects': 'inheritance only works non-final objects'},
+{'errInheritanceOnlyWithNonFinalObjects':
+ 'inheritance only works with non-final objects'},
{'errInheritanceOnlyWithEnums': 'inheritance only works with an enum'},
{'errIllegalRecursionInTypeX': "illegal recursion in type '$1'"},
{'errCannotInstantiateX': "cannot instantiate: '$1'"},
@@ -278,16 +279,17 @@
# hints:
{'hintSuccess': 'operation successful'},
+{'hintSuccessX': 'operation successful ($1 lines compiled; $2 sec total)'},
{'hintLineTooLong': 'line too long'},
{'hintXDeclaredButNotUsed': "'$1' is declared but not used"},
{'hintConvToBaseNotNeeded': 'conversion to base object is not needed'},
{'hintConvFromXtoItselfNotNeeded': 'conversion from $1 to itself is pointless'},
{'hintExprAlwaysX': "expression evaluates always to '$1'"},
-{'hintMo2FileInvalid': "mo2 file '$1' is invalid"},
-{'hintModuleHasChanged': "module '$1' has been changed"},
-{'hintCannotOpenMo2File': "mo2 file '$1' does not exist"},
{'hintQuitCalled': "quit() called"},
-{'hintProcessing': "processing"},
+{'hintProcessing': "processing $1"},
+{'hintCodeBegin': "generated code listing:"},
+{'hintCodeEnd': "end of listing"},
+{'hintConf': "used config file '$1'"},
# user hint message:
{'hintUser': '$1'}
diff --git a/data/readme.txt b/data/readme.txt
index 9cea8806a..b72016d6e 100644
--- a/data/readme.txt
+++ b/data/readme.txt
@@ -1,5 +1,2 @@
-This directory contains data files in a format called YAML_. These files
-are required for building Nimrod.
-
-
-.. _YAML: http://www.yaml.org/
+This directory contains data files in Python or ordinary text format. These
+files are required for building Nimrod.
diff --git a/doc/filelist.txt b/doc/filelist.txt
index cdb06cb9c..5d9f1125e 100644
--- a/doc/filelist.txt
+++ b/doc/filelist.txt
@@ -11,6 +11,7 @@ ast type definitions of the abstract syntax tree (AST) and
node constructors
astalgo algorithms for containers of AST nodes; converting the
AST to YAML; the symbol table
+passes implement the passes managemer for passes over the AST
trees few algorithms for nodes; this module is less important
types module for traversing type graphs; also contain several
helpers for dealing with types
@@ -23,19 +24,15 @@ semtypes contains the semantic checking phase for types
idents implements a general mapping from identifiers to an internal
representation (``PIdent``) that is used, so that a simple
- pointer comparison suffices to say whether two Nimrod
- identifiers are equivalent
+ id-comparison suffices to say whether two Nimrod identifiers
+ are equivalent
ropes implements long strings using represented as trees for
lazy evaluation; used mainly by the code generators
ccgobj contains type definitions neeeded for C code generation
and some helpers
-ccgmangl contains the name mangler for converting Nimrod
- identifiers to their C counterparts
ccgutils contains helpers for the C code generator
-ccgtemps contains the handling of temporary variables for the
- C code generator
ccgtypes the generator for C types
ccgstmts the generator for statements
ccgexprs the generator for expressions
diff --git a/doc/grammar.txt b/doc/grammar.txt
index 03f4b65b9..d8387670b 100644
--- a/doc/grammar.txt
+++ b/doc/grammar.txt
@@ -1,187 +1,187 @@
-module ::= ([COMMENT] [SAD] stmt)*
-
-optComma ::= [ ',' ] [COMMENT] [IND]
-operator ::= OP0 | OR | XOR | AND | OP3 | OP4 | OP5 | IS | ISNOT | IN | NOTIN
- | OP6 | DIV | MOD | SHL | SHR | OP7 | NOT
-
-prefixOperator ::= OP0 | OP3 | OP4 | OP5 | OP6 | OP7 | NOT
-
-optInd ::= [COMMENT] [IND]
-
-
-lowestExpr ::= orExpr ( OP0 optInd orExpr )*
-orExpr ::= andExpr ( OR | XOR optInd andExpr )*
-andExpr ::= cmpExpr ( AND optInd cmpExpr )*
-cmpExpr ::= ampExpr ( OP3 | IS | ISNOT | IN | NOTIN optInd ampExpr )*
-ampExpr ::= plusExpr ( OP4 optInd plusExpr )*
-plusExpr ::= mulExpr ( OP5 optInd mulExpr )*
-mulExpr ::= dollarExpr ( OP6 | DIV | MOD | SHL | SHR optInd dollarExpr )*
-dollarExpr ::= primary ( OP7 optInd primary )*
-
-namedTypeOrExpr ::=
- DOTDOT [expr]
- | expr [EQUALS (expr [DOTDOT expr] | typeDescK | DOTDOT [expr] )
- | DOTDOT [expr]]
- | typeDescK
-
-castExpr ::= CAST BRACKET_LE optInd typeDesc BRACKERT_RI
- PAR_LE optInd expr PAR_RI
-addrExpr ::= ADDR PAR_LE optInd expr PAR_RI
-symbol ::= ACC (KEYWORD | IDENT | operator | PAR_LE PAR_RI
- | BRACKET_LE BRACKET_RI) ACC | IDENT
-accExpr ::= KEYWORD | IDENT | operator [DOT KEYWORD | IDENT | operator]
- paramList
-primary ::= ( prefixOperator optInd )* ( IDENT | literal | ACC accExpr ACC
- | castExpr | addrExpr ) (
- DOT optInd symbol
- #| CURLY_LE namedTypeDescList CURLY_RI
- | PAR_LE optInd
- namedExprList
- PAR_RI
- | BRACKET_LE optInd
- (namedTypeOrExpr optComma)*
- BRACKET_RI
- | CIRCUM
- | pragma )*
-
-literal ::= INT_LIT | INT8_LIT | INT16_LIT | INT32_LIT | INT64_LIT
- | FLOAT_LIT | FLOAT32_LIT | FLOAT64_LIT
- | STR_LIT | RSTR_LIT | TRIPLESTR_LIT
- | CHAR_LIT | RCHAR_LIT
- | NIL
- | BRACKET_LE optInd (expr [COLON expr] optComma )* BRACKET_RI # []-Constructor
- | CURLY_LE optInd (expr [DOTDOT expr] optComma )* CURLY_RI # {}-Constructor
- | PAR_LE optInd (expr [COLON expr] optComma )* PAR_RI # ()-Constructor
-
-
-exprList ::= ( expr optComma )*
-
-namedExpr ::= expr [EQUALS expr] # actually this is symbol EQUALS expr|expr
-namedExprList ::= ( namedExpr optComma )*
-
-exprOrSlice ::= expr [ DOTDOT expr ]
-sliceList ::= ( exprOrSlice optComma )+
-
-anonymousProc ::= LAMBDA paramList [pragma] EQUALS stmt
-expr ::= lowestExpr
- | anonymousProc
- | IF expr COLON expr
- (ELIF expr COLON expr)*
- ELSE COLON expr
-
-namedTypeDesc ::= typeDescK | expr [EQUALS (typeDescK | expr)]
-namedTypeDescList ::= ( namedTypeDesc optComma )*
-
-qualifiedIdent ::= symbol [ DOT symbol ]
-
-typeDescK ::= VAR typeDesc
- | REF typeDesc
- | PTR typeDesc
- | TYPE expr
- | TUPLE tupleDesc
- | PROC paramList [pragma]
-
-typeDesc ::= typeDescK | primary
-
-optSemicolon ::= [SEMICOLON]
-
-macroStmt ::= COLON [stmt] (OF [sliceList] COLON stmt
- | ELIF expr COLON stmt
- | EXCEPT exceptList COLON stmt )*
- [ELSE COLON stmt]
-
-simpleStmt ::= returnStmt
- | yieldStmt
- | discardStmt
- | raiseStmt
- | breakStmt
- | continueStmt
- | pragma
- | importStmt
- | fromStmt
- | includeStmt
- | exprStmt
-complexStmt ::= ifStmt | whileStmt | caseStmt | tryStmt | forStmt
- | blockStmt | asmStmt
- | procDecl | iteratorDecl | macroDecl | templateDecl
- | constSection | typeSection | whenStmt | varSection
-
-indPush ::= IND # push
-stmt ::= simpleStmt [SAD]
- | indPush (complexStmt | simpleStmt)
- ([SAD] (complexStmt | simpleStmt) )*
- DED
-
-exprStmt ::= lowestExpr [EQUALS expr | (expr optComma)* [macroStmt]]
-returnStmt ::= RETURN [expr]
-yieldStmt ::= YIELD expr
-discardStmt ::= DISCARD expr
-raiseStmt ::= RAISE [expr]
-breakStmt ::= BREAK [symbol]
-continueStmt ::= CONTINUE
-ifStmt ::= IF expr COLON stmt (ELIF expr COLON stmt)* [ELSE COLON stmt]
-whenStmt ::= WHEN expr COLON stmt (ELIF expr COLON stmt)* [ELSE COLON stmt]
-caseStmt ::= CASE expr (OF sliceList COLON stmt)*
- (ELIF expr COLON stmt)*
- [ELSE COLON stmt]
-whileStmt ::= WHILE expr COLON stmt
-forStmt ::= FOR (symbol optComma)+ IN expr [DOTDOT expr] COLON stmt
-exceptList ::= (qualifiedIdent optComma)*
-
-tryStmt ::= TRY COLON stmt
- (EXCEPT exceptList COLON stmt)*
- [FINALLY COLON stmt]
-asmStmt ::= ASM [pragma] (STR_LIT | RSTR_LIT | TRIPLESTR_LIT)
-blockStmt ::= BLOCK [symbol] COLON stmt
-importStmt ::= IMPORT ((symbol | STR_LIT | RSTR_LIT | TRIPLESTR_LIT) [AS symbol] optComma)+
-includeStmt ::= INCLUDE ((symbol | STR_LIT | RSTR_LIT | TRIPLESTR_LIT) optComma)+
-fromStmt ::= FROM (symbol | STR_LIT | RSTR_LIT | TRIPLESTR_LIT) IMPORT (symbol optComma)+
-
-pragma ::= CURLYDOT_LE (expr [COLON expr] optComma)+ (CURLYDOT_RI | CURLY_RI)
-
-paramList ::= [PAR_LE ((symbol optComma)+ COLON typeDesc optComma)* PAR_RI] [COLON typeDesc]
-
-genericParams ::= BRACKET_LE (symbol [EQUALS typeDesc] )* BRACKET_RI
-
-procDecl ::= PROC symbol ["*"] [genericParams]
- paramList [pragma]
- [EQUALS stmt]
-macroDecl ::= MACRO symbol ["*"] [genericParams] paramList [pragma]
- [EQUALS stmt]
-iteratorDecl ::= ITERATOR symbol ["*"] [genericParams] paramList [pragma]
- [EQUALS stmt]
-templateDecl ::= TEMPLATE symbol ["*"] [genericParams] paramList [pragma]
- [EQUALS stmt]
-
-colonAndEquals ::= [COLON typeDesc] EQUALS expr
-
-constDecl ::= symbol ["*"] [pragma] colonAndEquals [COMMENT | IND COMMENT]
- | COMMENT
-constSection ::= CONST indPush constDecl (SAD constDecl)* DED
-typeDef ::= typeDesc | objectDef | enumDef
-
-objectIdentPart ::=
- (symbol ["*" | "-"] [pragma] optComma)+ COLON typeDesc [COMMENT | IND COMMENT]
-
-objectWhen ::= WHEN expr COLON [COMMENT] objectPart
- (ELIF expr COLON [COMMENT] objectPart)*
- [ELSE COLON [COMMENT] objectPart]
-objectCase ::= CASE expr COLON typeDesc [COMMENT]
- (OF sliceList COLON [COMMENT] objectPart)*
- [ELSE COLON [COMMENT] objectPart]
-
-objectPart ::= objectWhen | objectCase | objectIdentPart
- | indPush objectPart (SAD objectPart)* DED
-tupleDesc ::= BRACKET_LE optInd ((symbol optComma)+ COLON typeDesc optComma)* BRACKET_RI
-
-objectDef ::= OBJECT [pragma] [OF typeDesc] objectPart
-enumDef ::= ENUM [OF typeDesc] (symbol [EQUALS expr] optComma [COMMENT | IND COMMENT])+
-
-typeDecl ::= COMMENT
- | symbol ["*"] [genericParams] [EQUALS typeDef] [COMMENT | IND COMMENT]
-
-typeSection ::= TYPE indPush typeDecl (SAD typeDecl)* DED
-
-colonOrEquals ::= COLON typeDesc [EQUALS expr] | EQUALS expr
-varPart ::= (symbol ["*" | "-"] [pragma] optComma)+ colonOrEquals [COMMENT | IND COMMENT]
-varSection ::= VAR (varPart | indPush (COMMENT|varPart) (SAD (COMMENT|varPart))* DED)
+module ::= ([COMMENT] [SAD] stmt)*
+
+optComma ::= [ ',' ] [COMMENT] [IND]
+operator ::= OP0 | OR | XOR | AND | OP3 | OP4 | OP5 | IS | ISNOT | IN | NOTIN
+ | OP6 | DIV | MOD | SHL | SHR | OP7 | NOT
+
+prefixOperator ::= OP0 | OP3 | OP4 | OP5 | OP6 | OP7 | NOT
+
+optInd ::= [COMMENT] [IND]
+
+
+lowestExpr ::= orExpr ( OP0 optInd orExpr )*
+orExpr ::= andExpr ( OR | XOR optInd andExpr )*
+andExpr ::= cmpExpr ( AND optInd cmpExpr )*
+cmpExpr ::= ampExpr ( OP3 | IS | ISNOT | IN | NOTIN optInd ampExpr )*
+ampExpr ::= plusExpr ( OP4 optInd plusExpr )*
+plusExpr ::= mulExpr ( OP5 optInd mulExpr )*
+mulExpr ::= dollarExpr ( OP6 | DIV | MOD | SHL | SHR optInd dollarExpr )*
+dollarExpr ::= primary ( OP7 optInd primary )*
+
+namedTypeOrExpr ::=
+ DOTDOT [expr]
+ | expr [EQUALS (expr [DOTDOT expr] | typeDescK | DOTDOT [expr] )
+ | DOTDOT [expr]]
+ | typeDescK
+
+castExpr ::= CAST BRACKET_LE optInd typeDesc BRACKERT_RI
+ PAR_LE optInd expr PAR_RI
+addrExpr ::= ADDR PAR_LE optInd expr PAR_RI
+symbol ::= ACC (KEYWORD | IDENT | operator | PAR_LE PAR_RI
+ | BRACKET_LE BRACKET_RI | EQUALS | literal )+ ACC
+ | IDENT
+primary ::= ( prefixOperator optInd )* ( symbol | constructor |
+ | castExpr | addrExpr ) (
+ DOT optInd symbol
+ #| CURLY_LE namedTypeDescList CURLY_RI
+ | PAR_LE optInd
+ namedExprList
+ PAR_RI
+ | BRACKET_LE optInd
+ (namedTypeOrExpr optComma)*
+ BRACKET_RI
+ | CIRCUM
+ | pragma )*
+
+literal ::= INT_LIT | INT8_LIT | INT16_LIT | INT32_LIT | INT64_LIT
+ | FLOAT_LIT | FLOAT32_LIT | FLOAT64_LIT
+ | STR_LIT | RSTR_LIT | TRIPLESTR_LIT
+ | CHAR_LIT | RCHAR_LIT
+ | NIL
+
+constructor ::= literal
+ | BRACKET_LE optInd (expr [COLON expr] optComma )* BRACKET_RI # []-Constructor
+ | CURLY_LE optInd (expr [DOTDOT expr] optComma )* CURLY_RI # {}-Constructor
+ | PAR_LE optInd (expr [COLON expr] optComma )* PAR_RI # ()-Constructor
+
+exprList ::= ( expr optComma )*
+
+namedExpr ::= expr [EQUALS expr] # actually this is symbol EQUALS expr|expr
+namedExprList ::= ( namedExpr optComma )*
+
+exprOrSlice ::= expr [ DOTDOT expr ]
+sliceList ::= ( exprOrSlice optComma )+
+
+anonymousProc ::= LAMBDA paramList [pragma] EQUALS stmt
+expr ::= lowestExpr
+ | anonymousProc
+ | IF expr COLON expr
+ (ELIF expr COLON expr)*
+ ELSE COLON expr
+
+namedTypeDesc ::= typeDescK | expr [EQUALS (typeDescK | expr)]
+namedTypeDescList ::= ( namedTypeDesc optComma )*
+
+qualifiedIdent ::= symbol [ DOT symbol ]
+
+typeDescK ::= VAR typeDesc
+ | REF typeDesc
+ | PTR typeDesc
+ | TYPE expr
+ | TUPLE tupleDesc
+ | PROC paramList [pragma]
+
+typeDesc ::= typeDescK | primary
+
+optSemicolon ::= [SEMICOLON]
+
+macroStmt ::= COLON [stmt] (OF [sliceList] COLON stmt
+ | ELIF expr COLON stmt
+ | EXCEPT exceptList COLON stmt )*
+ [ELSE COLON stmt]
+
+simpleStmt ::= returnStmt
+ | yieldStmt
+ | discardStmt
+ | raiseStmt
+ | breakStmt
+ | continueStmt
+ | pragma
+ | importStmt
+ | fromStmt
+ | includeStmt
+ | exprStmt
+complexStmt ::= ifStmt | whileStmt | caseStmt | tryStmt | forStmt
+ | blockStmt | asmStmt
+ | procDecl | iteratorDecl | macroDecl | templateDecl
+ | constSection | typeSection | whenStmt | varSection
+
+indPush ::= IND # push
+stmt ::= simpleStmt [SAD]
+ | indPush (complexStmt | simpleStmt)
+ ([SAD] (complexStmt | simpleStmt) )*
+ DED
+
+exprStmt ::= lowestExpr [EQUALS expr | (expr optComma)* [macroStmt]]
+returnStmt ::= RETURN [expr]
+yieldStmt ::= YIELD expr
+discardStmt ::= DISCARD expr
+raiseStmt ::= RAISE [expr]
+breakStmt ::= BREAK [symbol]
+continueStmt ::= CONTINUE
+ifStmt ::= IF expr COLON stmt (ELIF expr COLON stmt)* [ELSE COLON stmt]
+whenStmt ::= WHEN expr COLON stmt (ELIF expr COLON stmt)* [ELSE COLON stmt]
+caseStmt ::= CASE expr (OF sliceList COLON stmt)*
+ (ELIF expr COLON stmt)*
+ [ELSE COLON stmt]
+whileStmt ::= WHILE expr COLON stmt
+forStmt ::= FOR (symbol optComma)+ IN expr [DOTDOT expr] COLON stmt
+exceptList ::= (qualifiedIdent optComma)*
+
+tryStmt ::= TRY COLON stmt
+ (EXCEPT exceptList COLON stmt)*
+ [FINALLY COLON stmt]
+asmStmt ::= ASM [pragma] (STR_LIT | RSTR_LIT | TRIPLESTR_LIT)
+blockStmt ::= BLOCK [symbol] COLON stmt
+importStmt ::= IMPORT ((symbol | STR_LIT | RSTR_LIT | TRIPLESTR_LIT) [AS symbol] optComma)+
+includeStmt ::= INCLUDE ((symbol | STR_LIT | RSTR_LIT | TRIPLESTR_LIT) optComma)+
+fromStmt ::= FROM (symbol | STR_LIT | RSTR_LIT | TRIPLESTR_LIT) IMPORT (symbol optComma)+
+
+pragma ::= CURLYDOT_LE (expr [COLON expr] optComma)+ (CURLYDOT_RI | CURLY_RI)
+
+paramList ::= [PAR_LE ((symbol optComma)+ COLON typeDesc optComma)* PAR_RI] [COLON typeDesc]
+
+genericParams ::= BRACKET_LE (symbol [EQUALS typeDesc] )* BRACKET_RI
+
+procDecl ::= PROC symbol ["*"] [genericParams]
+ paramList [pragma]
+ [EQUALS stmt]
+macroDecl ::= MACRO symbol ["*"] [genericParams] paramList [pragma]
+ [EQUALS stmt]
+iteratorDecl ::= ITERATOR symbol ["*"] [genericParams] paramList [pragma]
+ [EQUALS stmt]
+templateDecl ::= TEMPLATE symbol ["*"] [genericParams] paramList [pragma]
+ [EQUALS stmt]
+
+colonAndEquals ::= [COLON typeDesc] EQUALS expr
+
+constDecl ::= symbol ["*"] [pragma] colonAndEquals [COMMENT | IND COMMENT]
+ | COMMENT
+constSection ::= CONST indPush constDecl (SAD constDecl)* DED
+typeDef ::= typeDesc | objectDef | enumDef
+
+objectIdentPart ::=
+ (symbol ["*" | "-"] [pragma] optComma)+ COLON typeDesc [COMMENT | IND COMMENT]
+
+objectWhen ::= WHEN expr COLON [COMMENT] objectPart
+ (ELIF expr COLON [COMMENT] objectPart)*
+ [ELSE COLON [COMMENT] objectPart]
+objectCase ::= CASE expr COLON typeDesc [COMMENT]
+ (OF sliceList COLON [COMMENT] objectPart)*
+ [ELSE COLON [COMMENT] objectPart]
+
+objectPart ::= objectWhen | objectCase | objectIdentPart | NIL
+ | indPush objectPart (SAD objectPart)* DED
+tupleDesc ::= BRACKET_LE optInd ((symbol optComma)+ COLON typeDesc optComma)* BRACKET_RI
+
+objectDef ::= OBJECT [pragma] [OF typeDesc] objectPart
+enumDef ::= ENUM [OF typeDesc] (symbol [EQUALS expr] optComma [COMMENT | IND COMMENT])+
+
+typeDecl ::= COMMENT
+ | symbol ["*"] [genericParams] [EQUALS typeDef] [COMMENT | IND COMMENT]
+
+typeSection ::= TYPE indPush typeDecl (SAD typeDecl)* DED
+
+colonOrEquals ::= COLON typeDesc [EQUALS expr] | EQUALS expr
+varPart ::= (symbol ["*" | "-"] [pragma] optComma)+ colonOrEquals [COMMENT | IND COMMENT]
+varSection ::= VAR (varPart | indPush (COMMENT|varPart) (SAD (COMMENT|varPart))* DED)
diff --git a/doc/intern.txt b/doc/intern.txt
index 382eea947..4d65c1e55 100644
--- a/doc/intern.txt
+++ b/doc/intern.txt
@@ -32,7 +32,7 @@ Path Purpose
``config`` configuration files for Nimrod go into here
``lib`` the Nimrod library lives here; ``rod`` depends
on it!
-``web`` website of Nimrod; generated by ``genweb.py``
+``web`` website of Nimrod; generated by ``koch.py``
from the ``*.txt`` and ``*.tmpl`` files
``koch`` the Koch Build System (written for Nimrod)
``obj`` generated ``*.obj`` files go into here
@@ -49,20 +49,19 @@ and Free Pascal can compile the Nimrod compiler.
Requirements for bootstrapping:
-- Free Pascal (I used version 2.2); it may not be needed
-- Python (should work with 2.4 or higher) and the code generator *cog*
- (included in this distribution!)
+- Free Pascal (I used version 2.2) [optional]
+- Python (should work with version 1.5 or higher)
- C compiler -- one of:
- * win32-lcc
- * Borland C++ (tested with 5.5)
+ * win32-lcc (currently broken)
+ * Borland C++ (tested with 5.5; currently broken)
* Microsoft C++
* Digital Mars C++
- * Watcom C++ (currently broken; a fix is welcome!)
+ * Watcom C++ (currently broken)
* GCC
* Intel C++
- * Pelles C
+ * Pelles C (currently broken)
* llvm-gcc
| Compiling the compiler is a simple matter of running:
@@ -75,7 +74,7 @@ If you want to debug the compiler, use the command::
The ``koch.py`` script is Nimrod's maintainance script: Everything that has
been automated is accessible with it. It is a replacement for make and shell
-scripting with the advantage that it is more portable and is easier to read.
+scripting with the advantage that it is more portable.
Coding standards
@@ -124,7 +123,7 @@ Complex assignments
We already knew the type information as a graph in the compiler.
Thus we need to serialize this graph as RTTI for C code generation.
-Look at the files ``lib/typeinfo.nim``, ``lib/hti.nim`` for more information.
+Look at the file ``lib/hti.nim`` for more information.
The Garbage Collector
@@ -135,18 +134,11 @@ Introduction
We use the term *cell* here to refer to everything that is traced
(sequences, refs, strings).
-This section describes how the new GC works. The old algorithms
-all had the same problem: Too complex to get them right. This one
-tries to find the right compromise.
+This section describes how the new GC works.
The basic algorithm is *Deferrent reference counting* with cycle detection.
References in the stack are not counted for better performance and easier C
-code generation. The GC starts by traversing the hardware stack and increments
-the reference count (RC) of every cell that it encounters. After the GC has
-done its work the stack is traversed again and the RC of every cell
-that it encounters are decremented again. Thus no marking bits in the RC are
-needed. Between these stack traversals the GC has a complete accurate view over
-the RCs.
+code generation.
Each cell has a header consisting of a RC and a pointer to its type
descriptor. However the program does not know about these, so they are placed at
@@ -156,72 +148,44 @@ is extremely important that ``pointer`` is not confused with a ``PCell``
as this would lead to a memory corruption.
-When to trigger a collection
-----------------------------
-
-Since there are really two different garbage collectors (reference counting
-and mark and sweep) we use two different heuristics when to run the passes.
-The RC-GC pass is fairly cheap: Thus we use an additive increase (7 pages)
-for the RC_Threshold and a multiple increase for the CycleThreshold.
-
-
-The AT and ZCT sets
--------------------
-
-The GC maintains two sets throughout the lifetime of
-the program (plus two temporary ones). The AT (*any table*) simply contains
-every cell. The ZCT (*zero count table*) contains every cell whose RC is
-zero. This is used to reclaim most cells fast.
-
-The ZCT contains redundant information -- the AT alone would suffice.
-However, traversing the AT and look if the RC is zero would touch every living
-cell in the heap! That's why the ZCT is updated whenever a RC drops to zero.
-The ZCT is not updated when a RC is incremented from zero to one, as
-this would be too costly.
-
-
The CellSet data structure
--------------------------
-The AT and ZCT depend on an extremely efficient datastructure for storing a
-set of pointers - this is called a ``PCellSet`` in the source code.
+The GC depends on an extremely efficient datastructure for storing a
+set of pointers - this is called a ``TCellSet`` in the source code.
Inserting, deleting and searching are done in constant time. However,
-modifying a ``PCellSet`` during traversation leads to undefined behaviour.
+modifying a ``TCellSet`` during traversation leads to undefined behaviour.
.. code-block:: Nimrod
type
- PCellSet # hidden
+ TCellSet # hidden
- proc allocCellSet: PCellSet # make a new set
- proc deallocCellSet(s: PCellSet) # empty the set and free its memory
- proc incl(s: PCellSet, elem: PCell) # include an element
- proc excl(s: PCellSet, elem: PCell) # exclude an element
+ proc CellSetInit(s: var TCellSet) # initialize a new set
+ proc CellSetDeinit(s: var TCellSet) # empty the set and free its memory
+ proc incl(s: var TCellSet, elem: PCell) # include an element
+ proc excl(s: var TCellSet, elem: PCell) # exclude an element
- proc `in`(elem: PCell, s: PCellSet): bool
+ proc `in`(elem: PCell, s: TCellSet): bool # tests membership
- iterator elements(s: PCellSet): (elem: PCell)
+ iterator elements(s: TCellSet): (elem: PCell)
-All the operations have to be performed efficiently. Because a Cellset can
-become huge (the AT contains every allocated cell!) a hash table is not
-suitable for this.
+All the operations have to be perform efficiently. Because a Cellset can
+become huge a hash table alone is not suitable for this.
-We use a mixture of bitset and patricia tree for this. One node in the
-patricia tree contains a bitset that decribes a page of the operating system
-(not always, but that doesn't matter).
-So including a cell is done as follows:
+We use a mixture of bitset and hash table for this. The hash table maps *pages*
+to a page descriptor. The page descriptor contains a bit for any possible cell
+address within this page. So including a cell is done as follows:
- Find the page descriptor for the page the cell belongs to.
- Set the appropriate bit in the page descriptor indicating that the
cell points to the start of a memory block.
Removing a cell is analogous - the bit has to be set to zero.
-Single page descriptors are never deleted from the tree. Typically a page
-descriptor is only 19 words big, so it does not waste much by not deleting
-it. Apart from that the AT and ZCT are rebuilt frequently, so removing a
-single page descriptor from the tree is never necessary.
+Single page descriptors are never deleted from the hash table. This is not
+needed as the data structures need to be periodically rebuilt anyway.
-Complete traversal is done like so::
+Complete traversal is done in this way::
for each page decriptor d:
for each bit in d:
@@ -265,103 +229,12 @@ roughly like this:
Note that for systems with a continous stack (which most systems have)
the check whether the ref is on the stack is very cheap (only two
comparisons). Another advantage of this scheme is that the code produced is
-a tiny bit smaller.
+smaller.
The algorithm in pseudo-code
----------------------------
-Now we come to the nitty-gritty. The algorithm works in several phases.
-
-Phase 1 - Consider references from stack
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-::
-
- for each pointer p in the stack: incRef(p)
-
-This is necessary because references in the hardware stack are not traced for
-better performance. After Phase 1 the RCs are accurate.
-
-
-Phase 2 - Free the ZCT
-~~~~~~~~~~~~~~~~~~~~~~
-This is how things used to (not) work::
-
- for p in elements(ZCT):
- if RC(p) == 0:
- call finalizer of p
- for c in children(p): decRef(c) # free its children recursively
- # if necessary; the childrens RC >= 1, BUT they may still be in the ZCT!
- free(p)
- else:
- remove p from the ZCT
-
-Instead we do it this way. Note that the recursion is gone too!
-::
-
- newZCT = nil
- for p in elements(ZCT):
- if RC(p) == 0:
- call finalizer of p
- for c in children(p):
- assert(RC(c) > 0)
- dec(RC(c))
- if RC(c) == 0:
- if newZCT == nil: newZCT = allocCellSet()
- incl(newZCT, c)
- free(p)
- else:
- # nothing to do! We will use the newZCS
-
- deallocCellSet(ZCT)
- ZCT = newZCT
-
-This phase is repeated until enough memory is available or the ZCT is nil.
-If still not enough memory is available the cyclic detector gets its chance
-to do something.
-
-
-Phase 3 - Cycle detection
-~~~~~~~~~~~~~~~~~~~~~~~~~
-Cycle detection works by subtracting internal reference counts::
-
- newAT = allocCellSet()
-
- for y in elements(AT):
- # pretend that y is dead:
- for c in children(y):
- dec(RC(c))
- # note that this should not be done recursively as we have all needed
- # pointers in the AT! This makes it more efficient too!
-
- proc restore(y: PCell) =
- # unfortunately, the recursion here cannot be eliminated easily
- if y not_in newAT:
- incl(newAT, y)
- for c in children(y):
- inc(RC(c)) # restore proper reference counts!
- restore(c)
-
- for y in elements(AT) with rc > 0:
- restore(y)
-
- for y in elements(AT) with rc == 0:
- free(y) # if pretending worked, it was part of a cycle
-
- AT = newAT
-
-
-Phase 4 - Ignore references from stack again
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-::
-
- for each pointer p in the stack:
- dec(RC(p))
- if RC(p) == 0: incl(ZCT, p)
-
-Now the RCs correctly discard any references from the stack. One can also see
-this as a temporary marking operation. Things that are referenced from stack
-are marked during the GC's operarion and now have to be unmarked.
-
+To be written.
The compiler's architecture
diff --git a/doc/lib.txt b/doc/lib.txt
index 2fef5934d..ccd97aa6e 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -1,131 +1,216 @@
-=======================
-Nimrod Standard Library
-=======================
-
-:Author: Andreas Rumpf
-:Version: |nimrodversion|
-
-Though the Nimrod Standard Library is still evolving, it is already quite
-usable. It is divided into basic libraries that contains modules that virtually
-every program will need and advanced libraries which are more heavy weight.
-Advanced libraries are in the ``lib/base`` directory.
-
-Basic libraries
-===============
-
-* `system `_
- Basic procs and operators that every program needs. It also provides IO
- facilities for reading and writing text and binary files. It is imported
- implicitly by the compiler. Do not import it directly. It relies on compiler
- magic to work.
-
-* `strutils `_
- This module contains common string handling operations like converting a
- string into uppercase, splitting a string into substrings, searching for
- substrings, replacing substrings.
-
-* `os `_
- Basic operating system facilities like retrieving environment variables,
- reading command line arguments, working with directories, running shell
- commands, etc. This module is -- like any other basic library --
- platform independant.
-
-* `math `_
- Mathematical operations like cosine, square root.
-
-* `complex `_
- This module implements complex numbers and their mathematical operations.
-
-* `times `_
- The ``times`` module contains basic support for working with time.
-
-* `parseopt `_
- The ``parseopt`` module implements a command line option parser. This
- supports long and short command options with optional values and command line
- arguments.
-
-* `parsecfg `_
- The ``parsecfg`` module implements a high performance configuration file
- parser. The configuration file's syntax is similar to the Windows ``.ini``
- format, but much more powerful, as it is not a line based parser. String
- literals, raw string literals and triple quote string literals are supported
- as in the Nimrod programming language.
-
-* `strtabs `_
- The ``strtabs`` module implements an efficient hash table that is a mapping
- from strings to strings. Supports a case-sensitive, case-insensitive and
- style-insensitive mode. An efficient string substitution operator ``%``
- for the string table is also provided.
-
-* `hashes `_
- This module implements efficient computations of hash values for diverse
- Nimrod types.
-
-* `lexbase `_
- This is a low leve module that implements an extremely efficent buffering
- scheme for lexers and parsers. This is used by the ``parsecfg`` module.
-
-
-Advanced libaries
-=================
-
-* `regexprs `_
- This module contains procedures and operators for handling regular
- expressions.
-
-* `dialogs `_
- This module implements portable dialogs for Nimrod; the implementation
- builds on the GTK interface. On Windows, native dialogs are shown if
- appropriate.
-
-
-Wrappers
-========
-
-Note that the generated HTML for some of these wrappers is so huge, that it is
-not contained in the distribution. You can then find them on the website.
-
-* `posix `_
- Contains a wrapper for the POSIX standard.
-* `windows `_
- Contains a wrapper for the Win32 API.
-* `shellapi `_
- Contains a wrapper for the ``shellapi.h`` header.
-* `shfolder `_
- Contains a wrapper for the ``shfolder.h`` header.
-* `mmsystem `_
- Contains a wrapper for the ``mmsystem.h`` header.
-* `ole2 `_
- Contains GUIDs for OLE2 automation support.
-* `nb30 `_
- This module contains the definitions for portable NetBIOS 3.0 support.
-* `cairo `_
- Wrapper for the cairo library.
-* `cairoft `_
- Wrapper for the cairoft library.
-* `cairowin32 `_
- Wrapper for the cairowin32 library.
-* `cairoxlib `_
- Wrapper for the cairoxlib library.
-* `atk `_
- Wrapper for the atk library.
-* `gdk2 `_
- Wrapper for the gdk2 library.
-* `gdk2pixbuf `_
- Wrapper for the gdk2pixbuf library.
-* `gdkglext `_
- Wrapper for the gdkglext library.
-* `glib2 `_
- Wrapper for the glib2 library.
-* `gtk2 `_
- Wrapper for the gtk2 library.
-* `gtkglext `_
- Wrapper for the gtkglext library.
-* `gtkhtml `_
- Wrapper for the gtkhtml library.
-* `libglade2 `_
- Wrapper for the libglade2 library.
-* `pango `_
- Wrapper for the pango library.
-* `pangoutils `_
- Wrapper for the pangoutils library.
+=======================
+Nimrod Standard Library
+=======================
+
+:Author: Andreas Rumpf
+:Version: |nimrodversion|
+
+Though the Nimrod Standard Library is still evolving, it is already quite
+usable. It is divided into basic libraries that contains modules that virtually
+every program will need and advanced libraries which are more heavy weight.
+Advanced libraries are in the ``lib/base`` directory.
+
+Basic libraries
+===============
+
+* `system `_
+ Basic procs and operators that every program needs. It also provides IO
+ facilities for reading and writing text and binary files. It is imported
+ implicitly by the compiler. Do not import it directly. It relies on compiler
+ magic to work.
+
+* `strutils `_
+ This module contains common string handling operations like converting a
+ string into uppercase, splitting a string into substrings, searching for
+ substrings, replacing substrings.
+
+* `os `_
+ Basic operating system facilities like retrieving environment variables,
+ reading command line arguments, working with directories, running shell
+ commands, etc. This module is -- like any other basic library --
+ platform independant.
+
+* `math `_
+ Mathematical operations like cosine, square root.
+
+* `complex `_
+ This module implements complex numbers and their mathematical operations.
+
+* `times `_
+ The ``times`` module contains basic support for working with time.
+
+* `parseopt `_
+ The ``parseopt`` module implements a command line option parser. This
+ supports long and short command options with optional values and command line
+ arguments.
+
+* `parsecfg `_
+ The ``parsecfg`` module implements a high performance configuration file
+ parser. The configuration file's syntax is similar to the Windows ``.ini``
+ format, but much more powerful, as it is not a line based parser. String
+ literals, raw string literals and triple quote string literals are supported
+ as in the Nimrod programming language.
+
+* `strtabs `_
+ The ``strtabs`` module implements an efficient hash table that is a mapping
+ from strings to strings. Supports a case-sensitive, case-insensitive and
+ style-insensitive mode. An efficient string substitution operator ``%``
+ for the string table is also provided.
+
+* `streams `_
+ This module provides a stream interface and two implementations thereof:
+ the `PFileStream` and the `PStringStream` which implement the stream
+ interface for Nimrod file objects (`TFile`) and strings. Other modules
+ may provide other implementations for this standard stream interface.
+
+* `hashes `_
+ This module implements efficient computations of hash values for diverse
+ Nimrod types.
+
+* `lexbase `_
+ This is a low level module that implements an extremely efficent buffering
+ scheme for lexers and parsers. This is used by the ``parsecfg`` module.
+
+
+Advanced libaries
+=================
+
+* `regexprs `_
+ This module contains procedures and operators for handling regular
+ expressions.
+
+* `dialogs `_
+ This module implements portable dialogs for Nimrod; the implementation
+ builds on the GTK interface. On Windows, native dialogs are shown if
+ appropriate.
+
+* `zipfiles `_
+ This module implements a zip archive creator/reader/modifier.
+
+Wrappers
+========
+
+Note that the generated HTML for some of these wrappers is so huge, that it is
+not contained in the distribution. You can then find them on the website.
+
+* `posix `_
+ Contains a wrapper for the POSIX standard.
+* `windows `_
+ Contains a wrapper for the Win32 API.
+* `shellapi `_
+ Contains a wrapper for the ``shellapi.h`` header.
+* `shfolder `_
+ Contains a wrapper for the ``shfolder.h`` header.
+* `mmsystem `_
+ Contains a wrapper for the ``mmsystem.h`` header.
+* `ole2 `_
+ Contains GUIDs for OLE2 automation support.
+* `nb30 `_
+ This module contains the definitions for portable NetBIOS 3.0 support.
+* `cairo `_
+ Wrapper for the cairo library.
+* `cairoft `_
+ Wrapper for the cairoft library.
+* `cairowin32 `_
+ Wrapper for the cairowin32 library.
+* `cairoxlib `_
+ Wrapper for the cairoxlib library.
+* `atk `_
+ Wrapper for the atk library.
+* `gdk2 `_
+ Wrapper for the gdk2 library.
+* `gdk2pixbuf `_
+ Wrapper for the gdk2pixbuf library.
+* `gdkglext `_
+ Wrapper for the gdkglext library.
+* `glib2 `_
+ Wrapper for the glib2 library.
+* `gtk2 `_
+ Wrapper for the gtk2 library.
+* `gtkglext `_
+ Wrapper for the gtkglext library.
+* `gtkhtml `_
+ Wrapper for the gtkhtml library.
+* `libglade2 `_
+ Wrapper for the libglade2 library.
+* `pango `_
+ Wrapper for the pango library.
+* `pangoutils `_
+ Wrapper for the pangoutils library.
+* `gl `_
+ Part of the wrapper for OpenGL.
+* `glext `_
+ Part of the wrapper for OpenGL.
+* `glu `_
+ Part of the wrapper for OpenGL.
+* `glut `_
+ Part of the wrapper for OpenGL.
+* `glx `_
+ Part of the wrapper for OpenGL.
+* `wingl `_
+ Part of the wrapper for OpenGL.
+* `lua `_
+ Part of the wrapper for Lua.
+* `lualib `_
+ Part of the wrapper for Lua.
+* `lauxlib `_
+ Part of the wrapper for Lua.
+* `odbcsql `_
+ interface to the ODBC driver.
+* `zlib `_
+ Wrapper for the zlib library.
+* `sdl `_
+ Part of the wrapper for SDL.
+* `sdl_gfx `_
+ Part of the wrapper for SDL.
+* `sdl_image `_
+ Part of the wrapper for SDL.
+* `sdl_mixer `_
+ Part of the wrapper for SDL.
+* `sdl_net `_
+ Part of the wrapper for SDL.
+* `sdl_ttf `_
+ Part of the wrapper for SDL.
+* `smpeg `_
+ Part of the wrapper for SDL.
+* `cursorfont `_
+ Part of the wrapper for X11.
+* `keysym `_
+ Part of the wrapper for X11.
+* `x `_
+ Part of the wrapper for X11.
+* `xatom `_
+ Part of the wrapper for X11.
+* `xcms `_
+ Part of the wrapper for X11.
+* `xf86dga `_
+ Part of the wrapper for X11.
+* `xf86vmode `_
+ Part of the wrapper for X11.
+* `xi `_
+ Part of the wrapper for X11.
+* `xinerama `_
+ Part of the wrapper for X11.
+* `xkb `_
+ Part of the wrapper for X11.
+* `xkblib `_
+ Part of the wrapper for X11.
+* `xlib `_
+ Part of the wrapper for X11.
+* `xrandr `_
+ Part of the wrapper for X11.
+* `xrender `_
+ Part of the wrapper for X11.
+* `xresource `_
+ Part of the wrapper for X11.
+* `xshm `_
+ Part of the wrapper for X11.
+* `xutil `_
+ Part of the wrapper for X11.
+* `xv `_
+ Part of the wrapper for X11.
+* `xvlib `_
+ Part of the wrapper for X11.
+* `libzip `_
+ Interface to the `lib zip `_ library by
+ Dieter Baron and Thomas Klausner.
diff --git a/doc/manual.txt b/doc/manual.txt
index babd96813..1c8faf4ac 100644
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -160,8 +160,8 @@ case-sensitive and even underscores are ignored:
this is that this allows programmers to use their own prefered spelling style
and libraries written by different programmers cannot use incompatible
conventions. The editors or IDE can show the identifiers as preferred. Another
-advantage is that it frees the programmer from remembering the spelling of an
-identifier.
+advantage is that it frees the programmer from remembering the exact spelling
+of an identifier.
Literal strings
@@ -601,20 +601,20 @@ Array and sequence types
has the same type. Arrays always have a fixed length which is specified at
compile time (except for open arrays). They can be indexed by any ordinal type.
A parameter ``A`` may be an *open array*, in which case it is indexed by
-integers from 0 to ``len(A)-1``.
+integers from 0 to ``len(A)-1``. An array expression may be constructed by the
+array constructor ``[]``.
`Sequences`:idx: are similar to arrays but of dynamic length which may change
during runtime (like strings). A sequence ``S`` is always indexed by integers
-from 0 to ``len(S)-1`` and its bounds are checked. Sequences can also be
-constructed by the array constructor ``[]``.
+from 0 to ``len(S)-1`` and its bounds are checked. Sequences can be
+constructed by the array constructor ``[]`` in conjunction with the array to
+sequence operator ``@``. Another way to allocate space for a sequence is to
+call the built-in ``newSeq`` procedure.
A sequence may be passed to a parameter that is of type *open array*, but
not to a multi-dimensional open array, because it is impossible to do so in an
efficient manner.
-An array expression may be constructed by the array constructor ``[]``.
-A constructed array is assignment compatible to a sequence.
-
Example:
.. code-block:: nimrod
@@ -625,13 +625,13 @@ Example:
var
x: TIntArray
y: TIntSeq
- x = [1, 2, 3, 4, 5, 6] # [] this is the array constructor that is compatible
- # with arrays, open arrays and
- y = [1, 2, 3, 4, 5, 6] # sequences
+ x = [1, 2, 3, 4, 5, 6] # [] this is the array constructor
+ y = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence
-The lower bound of an array may be received by the built-in proc
+The lower bound of an array or sequence may be received by the built-in proc
``low()``, the higher bound by ``high()``. The length may be
-received by ``len()``.
+received by ``len()``. ``low()`` for a sequence or an open array always returns
+0, as this is the first valid index.
Arrays are always bounds checked (at compile-time or at runtime). These
checks can be disabled via pragmas or invoking the compiler with the
@@ -644,15 +644,15 @@ A variable of a `tuple`:idx: or `object`:idx: type is a heterogenous storage
container.
A tuple or object defines various named *fields* of a type. A tuple defines an
*order* of the fields additionally. Tuples are meant for heterogenous storage
-types with no overhead and few abstraction possibilities. The constructor ``()``
-can be used to construct tuples. The order of the fields in the constructor
-must match the order of the tuple's definition. Different tuple-types are
-*equivalent* if they specify the same fields of the same type in the same
-order.
+types with no overhead and few abstraction possibilities. The constructor ``()``
+can be used to construct tuples. The order of the fields in the constructor
+must match the order of the tuple's definition. Different tuple-types are
+*equivalent* if they specify the same fields of the same type in the same
+order.
-The assignment operator for tuples copies each component.
-The default assignment operator for objects is not defined. The programmer may
-provide one, however.
+The assignment operator for tuples copies each component.
+The default assignment operator for objects is not defined. The programmer may
+provide one, however.
.. code-block:: nimrod
@@ -662,7 +662,7 @@ provide one, however.
# and an age
var
person: TPerson
- person = (name: "Peter", age: 30)
+ person = (name: "Peter", age: 30)
# the same, but less readable:
person = ("Peter", 30)
@@ -670,8 +670,8 @@ The implementation aligns the fields for best access performance. The alignment
is done in a way that is compatible the way the C compiler does it.
Objects provide many features that tuples do not. Object provide inheritance
-and information hiding. Objects have access to their type at runtime, so that
-the ``is`` operator can be used to determine the object's type.
+and information hiding. Objects have access to their type at runtime, so that
+the ``is`` operator can be used to determine the object's type.
.. code-block:: nimrod
@@ -689,9 +689,51 @@ the ``is`` operator can be used to determine the object's type.
assert(student is TStudent) # is true
Object fields that should be visible outside from the defining module, have to
-marked by ``*``. In contrast to tuples, different object types are
+marked by ``*``. In contrast to tuples, different object types are
never *equivalent*.
+Object variants
+~~~~~~~~~~~~~~~
+Often an object hierarchy is overkill in certain situations where simple
+`variant`:idx: types are needed.
+
+An example:
+
+.. code-block:: nimrod
+
+ # This is an example how an abstract syntax tree could be modelled in Nimrod
+ type
+ TNodeKind = enum # the different node types
+ nkInt, # a leaf with an integer value
+ nkFloat, # a leaf with a float value
+ nkString, # a leaf with a string value
+ nkAdd, # an addition
+ nkSub, # a subtraction
+ nkIf # an if statement
+ PNode = ref TNode
+ TNode = object
+ case kind: TNodeKind # the ``kind`` field is the discriminator
+ of nkInt: intVal: int
+ of nkFloat: floavVal: float
+ of nkString: strVal: string
+ of nkAdd, nkSub:
+ leftOp, rightOp: PNode
+ of nkIf:
+ condition, thenPart, elsePart: PNode
+
+ var
+ n: PNode
+ new(n) # creates a new node
+ n.kind = nkFloat
+ n.floatVal = 0.0 # valid, because ``n.kind==nkFloat``, so that it fits
+ # the following statement raises an `EInvalidField` exception, because
+ # n.kind's value does not fit:
+ n.strVal = ""
+
+As can been seen from the example, an advantage to an object hierarchy is that
+no casting between different object types is needed. Yet, access to invalid
+object fields raises an exception.
+
Set type
~~~~~~~~
@@ -749,7 +791,7 @@ The ``^`` operator can be used to derefer a reference, the ``addr`` procedure
returns the address of an item. An address is always an untraced reference.
Thus the usage of ``addr`` is an *unsafe* feature.
-The ``.`` (access a tuple/object field operator)
+The ``.`` (access a tuple/object field operator)
and ``[]`` (array/string/sequence index operator) operators perform implicit
dereferencing operations for reference types:
@@ -773,7 +815,7 @@ further information.
Special care has to be taken if an untraced object contains traced objects like
traced references, strings or sequences: In order to free everything properly,
-the built-in procedure ``finalize`` has to be called before freeing the
+the built-in procedure ``GCunref`` has to be called before freeing the
untraced memory manually!
.. XXX finalizers for traced objects
@@ -867,7 +909,7 @@ statement.
Statements are separated into `simple statements`:idx: and
`complex statements`:idx:.
-Simple statements are statements that cannot contain other statements, like
+Simple statements are statements that cannot contain other statements like
assignments, calls or the ``return`` statement; complex statements can
contain other statements. To avoid the `dangling else problem`:idx:, complex
statements always have to be intended::
@@ -1028,10 +1070,10 @@ Example:
The `case`:idx: statement is similar to the if statement, but it represents
a multi-branch selection. The expression after the keyword ``case`` is
evaluated and if its value is in a *vallist* the corresponding statements
-(after the ``of`` keyword) are executed. If the value is no given *vallist*
-the ``else`` part is executed. If there is no ``else`` part and not all
-possible values that ``expr`` can hold occur in a ``vallist``, a static
-error is given. This holds only for expressions of ordinal types.
+(after the ``of`` keyword) are executed. If the value is not in any
+given *slicelist* the ``else`` part is executed. If there is no ``else``
+part and not all possible values that ``expr`` can hold occur in a ``vallist``,
+a static error is given. This holds only for expressions of ordinal types.
If the expression is not of an ordinal type, and no ``else`` part is
given, control just passes after the ``case`` statement.
@@ -1331,10 +1373,8 @@ is used if the caller does not provide a value for this parameter. Example:
`Operators`:idx: are procedures with a special operator symbol as identifier:
.. code-block:: nimrod
- proc `$` (x: int): string = # converts an integer to a string;
- # since it has one parameter this is a prefix
- # operator. With two parameters it would be
- # an infix operator.
+ proc `$` (x: int): string =
+ # converts an integer to a string; this is a prefix operator.
return intToStr(x)
Calling a procedure can be done in many different ways:
@@ -1544,7 +1584,7 @@ own file. Modules enable `information hiding`:idx: and
`separate compilation`:idx:. A module may gain access to symbols of another
module by the `import`:idx: statement. `Recursive module dependancies`:idx: are
allowed, but slightly subtle. Only top-level symbols that are marked with an
-asterisk (``*``) are exported.
+asterisk (``*``) are exported.
The algorithm for compiling modules is:
@@ -1557,8 +1597,8 @@ This is best illustrated by an example:
.. code-block:: nimrod
# Module A
type
- T1* = int
- import B # the compiler starts parsing B
+ T1* = int # Module A exports the type ``T1``
+ import B # the compiler starts parsing B
proc main() =
var i = p(3) # works because B has been parsed completely here
@@ -1660,12 +1700,19 @@ Nimrod source code. The conditional symbols go into a special symbol table.
The compiler defines the target processor and the target operating
system as conditional symbols.
+Warning: The ``define`` pragma is deprecated as it conflicts with separate
+compilation! One should use boolean constants as a replacement - this is
+cleaner anyway.
+
undef pragma
------------
The `undef`:idx: pragma the counterpart to the define pragma. It undefines a
conditional symbol.
+Warning: The ``undef`` pragma is deprecated as it conflicts with separate
+compilation!
+
error pragma
------------
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index e49dfacb6..0bd9bdc91 100644
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -34,8 +34,15 @@ Advanced command line switches are:
Configuration file
------------------
-The ``nimrod`` executable loads the configuration file ``config/nimrod.cfg``
-unless this is suppressed by the ``--skip_cfg`` command line option.
+The default configuration file is ``nimrod.cfg``. The ``nimrod`` executable
+looks for it in the following directories (in this order):
+
+1. ``/home/$user/.config/nimrod.cfg`` (UNIX) or ``$APPDATA/nimrod.cfg`` (Windows)
+2. ``$nimrod/config/nimrod.cfg`` (UNIX, Windows)
+3. ``/etc/nimrod.cfg`` (UNIX)
+
+The search stops as soon as a configuration file has been found. The reading
+of ``nimrod.cfg`` can be suppressed by the ``--skip_cfg`` command line option.
Configuration settings can be overwritten in a project specific
configuration file that is read automatically. This specific file has to
be in the same directory as the project and be of the same name, except
@@ -47,11 +54,10 @@ Command line settings have priority over configuration file settings.
Nimrod's directory structure
----------------------------
The generated files that Nimrod produces all go into a subdirectory called
-``rod_gen``. This makes it easy to write a script that deletes all generated
-files. For example the generated C code for the module ``path/modA.nim``
-will become ``path/rod_gen/modA.c``.
+``nimcache`` in your project directory. This makes it easy to delete all
+generated files.
-However, the generated C code is not platform independant! C code generated for
+However, the generated C code is not platform independant. C code generated for
Linux does not compile on Windows, for instance. The comment on top of the
C file lists the OS, CPU and CC the file has been compiled for.
@@ -77,10 +83,46 @@ Because Nimrod generates C code it needs some "red tape" to work properly.
Thus lots of options and pragmas for tweaking the generated C code are
available.
+Importc Pragma
+~~~~~~~~~~~~~~
+The `importc`:idx: pragma provides a means to import a type, a variable, or a
+procedure from C. The optional argument is a string containing the C
+identifier. If the argument is missing, the C name is the Nimrod
+identifier *exactly as spelled*:
+
+.. code-block::
+ proc printf(formatstr: cstring) {.importc: "printf", varargs.}
+
+
+Exportc Pragma
+~~~~~~~~~~~~~~
+The `exportc`:idx: pragma provides a means to export a type, a variable, or a
+procedure to C. The optional argument is a string containing the C
+identifier. If the argument is missing, the C name is the Nimrod
+identifier *exactly as spelled*:
+
+.. code-block:: Nimrod
+ proc callme(formatstr: cstring) {.exportc: "callMe", varargs.}
+
+
+Dynlib Pragma
+~~~~~~~~~~~~~
+With the `dynlib`:idx: pragma a procedure or a variable can be imported from
+a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX). The
+non-optional argument has to be the name of the dynamic library:
+
+.. code-block:: Nimrod
+ proc gtk_image_new(): PGtkWidget {.cdecl, dynlib: "libgtk-x11-2.0.so", importc.}
+
+In general, importing a dynamic library does not require any special linker
+options or linking with import libraries. This also
+implies that no *devel* packages need to be installed.
+
+
No_decl Pragma
~~~~~~~~~~~~~~
The `no_decl`:idx: pragma can be applied to almost any symbol (variable, proc,
-type, etc.) and is one of the most important for interoperability with C:
+type, etc.) and is sometimes useful for interoperability with C:
It tells Nimrod that it should not generate a declaration for the symbol in
the C code. Thus it makes the following possible, for example:
@@ -89,17 +131,7 @@ the C code. Thus it makes the following possible, for example:
EOF {.importc: "EOF", no_decl.}: cint # pretend EOF was a variable, as
# Nimrod does not know its value
-Varargs Pragma
-~~~~~~~~~~~~~~
-The `varargs`:idx: pragma can be applied to procedures only. It tells Nimrod
-that the proc can take a variable number of parameters after the last
-specified parameter. Nimrod string values will be converted to C
-strings automatically:
-
-.. code-block:: Nimrod
- proc printf(formatstr: cstring) {.nodecl, varargs.}
-
- printf("hallo %s", "world") # "world" will be passed as C string
+However, the ``header`` pragma is often the better alternative.
Header Pragma
@@ -119,12 +151,25 @@ in angle brackets: ``<>``. If no angle brackets are given, Nimrod
encloses the header file in ``""`` in the generated C code.
+Varargs Pragma
+~~~~~~~~~~~~~~
+The `varargs`:idx: pragma can be applied to procedures only. It tells Nimrod
+that the proc can take a variable number of parameters after the last
+specified parameter. Nimrod string values will be converted to C
+strings automatically:
+
+.. code-block:: Nimrod
+ proc printf(formatstr: cstring) {.nodecl, varargs.}
+
+ printf("hallo %s", "world") # "world" will be passed as C string
+
+
No_static Pragma
~~~~~~~~~~~~~~~~
The `no_static`:idx: pragma can be applied to almost any symbol and specifies
that it shall not be declared ``static`` in the generated C code. Note that
symbols in the interface part of a module never get declared ``static``, so
-only in special cases is this pragma necessary.
+only in very special cases this pragma is necessary.
Line_dir Option
@@ -171,8 +216,29 @@ The `register`:idx: pragma is for variables only. It declares the variable as
in a hardware register for faster access. C compilers usually ignore this
though and for good reason: Often they do a better job without it anyway.
-In highly specific cases (a dispatch loop of interpreters for example) it
-may provide benefits, though.
+In highly specific cases (a dispatch loop of an bytecode interpreter for
+example) it may provide benefits, though.
+
+
+Acyclic Pragma
+~~~~~~~~~~~~~~
+The `acyclic`:idx: pragma can be used for object types to mark them as acyclic
+even though they seem to be cyclic. This is an **optimization** for the garbage
+collector to not consider objects of this type as part of a cycle::
+
+ type
+ PNode = ref TNode
+ TNode {.acyclic, final.} = object
+ left, right: PNode
+ data: string
+
+In the example a tree structure is declared with the ``TNode`` type. Note that
+the type definition is recursive thus the GC has to assume that objects of
+this type may form a cyclic graph. The ``acyclic`` pragma passes the
+information that this cannot happen to the GC. If the programmer uses the
+``acyclic`` pragma for data types that are in reality cyclic, the GC may leak
+memory, but nothing worse happens.
+
Disabling certain messages
@@ -244,12 +310,17 @@ efficient than any hand-coded scheme.
The ECMAScript code generator
=============================
+Note: As of version 0.7.0 the ECMAScript code generator is not maintained any
+longer. Help if you are interested.
+
Note: I use the term `ECMAScript`:idx: here instead of `JavaScript`:idx:, since
it is the proper term.
+The ECMAScript code generator is experimental!
+
Nimrod targets ECMAScript 1.5 which is supported by any widely used browser.
Since ECMAScript does not have a portable means to include another module,
-Nimrod just generate a long ``.js`` file.
+Nimrod just generates a long ``.js`` file.
Features or modules that the ECMAScript platform does not support are not
available. This includes:
diff --git a/doc/spec.txt b/doc/spec.txt
deleted file mode 100644
index 3bad06e97..000000000
--- a/doc/spec.txt
+++ /dev/null
@@ -1,1297 +0,0 @@
-====================
-Nimrod Specification
-====================
-
-:Author: Andreas Rumpf
-
-.. contents::
-
-
-About this document
-===================
-
-This document describes the lexis, the syntax, and the semantics of Nimrod.
-However, this is only a first draft. Some parts need to be more precise,
-features may be added to the language, etc.
-
-The language constructs are explained using an extended BNF, in
-which ``(a)*`` means 0 or more ``a``'s, ``a+`` means 1 or more ``a``'s, and
-``(a)?`` means an optional *a*; an alternative spelling for optional parts is
-``[a]``. The ``|`` symbol is used to mark alternatives
-and has the lowest precedence. Parentheses may be used to group elements.
-Non-terminals are in lowercase, terminal symbols (including keywords) are in
-UPPERCASE. An example::
-
- if_stmt ::= IF expr COLON stmts (ELIF expr COLON stmts)* [ELSE stmts]
-
-
-Definitions
-===========
-
-The following defintions are the same as their counterparts in the
-specification of the Modula-3 programming language.
-
-A Nimrod program specifies a computation that acts on a sequence of digital
-components called `locations`. A variable is a set of locations that
-represents a mathematical value according to a convention determined by the
-variable's *type*. If a value can be represented by some variable of type
-``T``, then we say that the value is a *member* of ``T`` and ``T`` *contains*
-the value.
-
-An *identifier* is a symbol declared as a name for a variable, type,
-procedure, etc. The region of the program over which a declaration applies is
-called the *scope* of the declaration. Scopes can be nested. The meaning of an
-identifier is determined by the smallest enclosing scope in which the
-identifier is declared.
-
-An expression specifies a computation that produces a value or variable.
-Expressions that produce variables are called `designators`. A designator
-can denote either a variable or the value of that variable, depending on
-the context. Some designators are *readonly*, which means that they cannot
-be used in contexts that might change the value of the variable. A
-designator that is not readonly is called *writable*. Expressions whose
-values can be determined statically are called *constant expressions*;
-they are never designators.
-
-A `static error` is an error that the implementation must detect before
-program execution. Violations of the language definition are static
-errors unless they are explicitly classified as runtime errors.
-
-A `checked runtime error` is an error that the implementation must detect
-and report at runtime. The method for reporting such errors is via *raising
-exceptions*. However, an implementation may provide a means to disable these
-runtime checks. See the section *pragmas* for details.
-
-An `unchecked runtime error` is an error that is not guaranteed to be
-detected, and can cause the subsequent behavior of the computation to
-be arbitrary. Unchecked runtime errors cannot occur if only `safe`
-language features are used.
-
-
-Lexical Analysis
-================
-
-Indentation
------------
-
-Nimrod's standard grammar describes an `indentation sensitive` language.
-This means that all the control structures are recognized by the indentation.
-Indentation consists only of spaces; tabulators are not allowed.
-
-The terminals ``IND`` (indentation), ``DED`` (dedentation) and ``SAD``
-(same indentation) are generated by the scanner, denoting an indentation.
-Using tabulators for the indentation is not allowed.
-
-These terminals are only generated for *logical lines*, i.e. not for an empty
-line and not for a line with only whitespace or comments.
-
-The parser and the scanner communicate over a stack which indentation terminal
-should be generated: The stack consists of integers counting the spaces. The
-stack is initialized with a zero on its top. The scanner reads from the stack:
-If the current indentation token consists of more spaces than the entry at the
-top of the stack, a ``IND`` token is generated, else if it consists of the same
-number of spaces, a ``SAD`` token is generated. If it consists of fewer spaces,
-a ``DED`` token is generated for any item on the stack that is greater than the
-current. These items are then popped from the stack by the scanner. At the end
-of the file, a ``DED`` token is generated for each number remaining on the
-stack that is larger than zero.
-
-Because the grammar contains some optional ``IND`` tokens, the scanner cannot
-push new indentation levels. This has to be done by the parser. The symbol
-``IND_PUSH`` indicates that the ``IND`` token should be pushed onto the stack
-by the parser.
-
-An Example how this works::
-
- if_stmt ::= IF expr COLON stmts (ELIF expr COLON stmts)* (ELSE stmts)?
- stmts ::= IND_PUSH (stmt [SAD])+ DED | stmt [SAD]
-
- if expr0:
- stmt1 # would be valid because, SAD is not generated any longer!
-
- if expr0:
- stmt1 # scanner: IND; parser pushes 2 onto the stack
- if expr3: stmt5 # DED; ... SAD eaten by stmt5
- else: stmt6 #
- if expr4: stmt7
- if expr:
- stmt1 # scanner: IND; the parser pushes 2 onto the stack
- stmt2 # scanner: SAD (because indentation is 2)
- elif expr2: # scanner: DED (because indentation is 0)
- stmts3 # scanner: IND; the parser pushes 2 onto the stack
- else: # scanner: DED;
- stmt4 # scanner: IND; the parser pushes 2 onto the stack
- # scanner generates 1 DED, because end of file and 1 item on stack
-
-
-
-Identifiers & Keywords
-----------------------
-
-`Identifiers` in Nimrod can be any string of letters, digits
-and underscores, beginning with a letter. Two immediate following
-underscores ``__`` are not allowed::
-
- letter ::= 'A'..'Z' | 'a'..'z'
- digit ::= '0'..'9'
- IDENTIFIER ::= letter ( ['_'] letter | digit )*
-
-The following `keywords` are reserved and cannot be used as identifiers::
-
- ${keywords}
-
-Some keywords are unused; they are reserved for future developments of the
-language.
-
-Nimrod is a `style-insensitive` language. This means that it is not
-case-sensitive and even underscores are ignored:
-**type** is a reserved word, and so is **TYPE** or **T_Y_P_E**. The idea behind
-this is, that this allows programmers to use their own prefered spelling style.
-Editors can show the identifiers as configured.
-
-
-Literal strings
----------------
-
-`Literal strings` can be delimited by matching double quotes, and can contain
-the following `escape sequences`:
-
-================== ==================================
- Escape sequence Meaning
-================== ==================================
- ``\n`` `newline`
- ``\r`` `carriage return`
- ``\l`` `line feed`
- ``\f`` `form feed`
- ``\t`` `tabulator`
- ``\v`` `vertical tabulator`
- ``\\`` `backslash`
- ``\"`` `quotation mark`
- ``\'`` `apostrophe`
- ``\y`` `character with number y`
- ``\a`` `alert`
- ``\b`` `backspace`
- ``\e`` `escape` `[ESC]`
-================== ==================================
-
-
-Strings in Nimrod may contain any 8-bit value, except embedded zeros,
-which are not allowed for compability with `C`.
-
-Literal strings can also be delimited by three double squotes
-``"""`` ... ``"""``.
-Literals in this form may run for several lines, may contain ``"`` and do not
-interpret any escape sequences.
-For convenience, when the opening ``"""`` is immediately
-followed by a newline, the newline is not included in the string.
-`Raw string literals` are preceded with the letter ``r`` (or ``R``)
-and are delimited by matching double quotes (just like ordinary string
-literals) and do not interpret the escape sequences.
-
-
-Literal characters
-------------------
-
-Character literals are enclosed in single quotes ``''`` and can contain the
-same escape sequences as strings - with one exception: ``\n`` is not allowed
-as it may be wider than one character (often it is the pair CR/LF for example).
-
-
-Numerical constants
--------------------
-
-`Numerical constants` are of a single type and have the form::
-
- hexdigit ::= digit | 'A'..'F' | 'a'..'f'
- octdigit ::= '0'..'7'
- bindigit ::= '0'..'1'
- INT_LIT ::= digit ( ['_'] digit )*
- | '0' ('x' | 'X' ) hexdigit ( ['_'] hexdigit )*
- | '0o' octdigit ( ['_'] octdigit )*
- | '0' ('b' | 'B' ) bindigit ( ['_'] bindigit )*
-
- INT8_LIT ::= INT_LIT '\'' ('i' | 'I' ) '8'
- INT16_LIT ::= INT_LIT '\'' ('i' | 'I' ) '16'
- INT32_LIT ::= INT_LIT '\'' ('i' | 'I' ) '32'
- INT64_LIT ::= INT_LIT '\'' ('i' | 'I' ) '64'
-
- exponent ::= ('e' | 'E' ) ['+' | '-'] digit ( ['_'] digit )*
- FLOAT_LIT ::= digit (['_'] digit)* ('.' (['_'] digit)* [exponent] |exponent)
- FLOAT32_LIT ::= ( FLOAT_LIT | INT_LIT ) '\'' ('f' | 'F') '32'
- FLOAT64_LIT ::= ( FLOAT_LIT | INT_LIT ) '\'' ('f' | 'F') '64'
-
-
-As can be seen in the productions, numerical constants can contain unterscores
-for readability. Integer and floating point literals may be given in decimal (no
-prefix), binary (prefix ``0b``), octal (prefix ``0o``) and
-hexadecimal (prefix ``0x``) notation.
-
-There exists a literal for each numerical type that are
-defined. The suffix starting with an apostophe ('\'') is called a
-`type suffix`. Literals without a type prefix are of the type ``int``, unless
-the literal contains a dot or an ``E`` in which case it is of type ``float``.
-
-The following table specifies type suffixes:
-
-================= =========================
- Type Suffix Resulting type of literal
-================= =========================
- ``'i8`` int8
- ``'i16`` int16
- ``'i32`` int32
- ``'i64`` int64
- ``'f32`` float32
- ``'f64`` float64
-================= =========================
-
-Floating point literals may also be in binary, octal or hexadecimal
-notation:
-``0B0_10001110100_0000101001000111101011101111111011000101001101001001'f64``
-is approximately 1.72826e35 according to the IEEE floating point standard.
-
-
-
-
-Comments
---------
-
-`Comments` start anywhere outside a string with the hash character ``#``.
-Comments run until the end of the line. Comments are tokens; they are only
-allowed at certain places in the input file as they belong to the syntax. This
-is essential for performing correct source-to-source transformations or
-documentation generators.
-
-
-Other tokens
-------------
-
-The following strings denote other tokens::
-
- ( ) { } [ ] , ; [. .] {. .} (. .)
- : = ^ .. `
-
-``..`` takes precedence over other tokens that contain a dot: ``{..}`` are the
-three tokens ``{``, ``..``, ``}`` and not the two tokens ``{.``, ``.}``.
-
-In Nimrod one can define his own operators. An `operator` is any
-combination of the following characters that are not listed above::
-
- + - * / < >
- = @ $ ~ & %
- ! ? ^ . |
-
-These keywords are also operators:
-``and or not xor shl shr div mod in notin is isnot``.
-
-
-Syntax
-======
-
-This section lists Nimrod's standard syntax in ENBF. How the parser receives
-indentation tokens is already described in the Lexical Analysis section.
-
-Nimrod allows user-definable operators.
-Binary operators have 8 different levels of precedence. For user-defined
-operators, the precedence depends on the first character the operator consists
-of. All binary operators are left-associative.
-
-================ ============================================== ================== ===============
-Precedence level Operators First characters Terminal symbol
-================ ============================================== ================== ===============
- 7 (highest) ``$`` OP7
- 6 ``* / div mod shl shr %`` ``* % \ /`` OP6
- 5 ``+ -`` ``+ ~ |`` OP5
- 4 ``&`` ``&`` OP4
- 3 ``== <= < >= > != in not_in is isnot`` ``= < > !`` OP3
- 2 ``and`` OP2
- 1 ``or xor`` OP1
- 0 (lowest) ``? @ ^ ` : .`` OP0
-================ ============================================== ================== ===============
-
-
-The grammar's start symbol is ``module``. The grammar is LL(1) and therefore
-not ambigious.
-
-.. include:: grammar.txt
- :literal:
-
-
-
-Semantics
-=========
-
-Constants
----------
-
-Constants are symbols which are bound to a value. The constant's value
-cannot change. The compiler must be able to evaluate the expression in a
-constant declaration at compile time. This means that most of the functions in
-the runtime library cannot be used in a constant declaration.
-
-Operators such as ``+, -, *, /, not, and, or, div, mod`` and the procedures
-``addr, ord, chr, sizeof, trunc, round, frac, odd, abs`` can be used, however.
-An implementation may restrict the usage of ``addr`` in constant expressions.
-
-
-Types
------
-
-All expressions have a type which is known at compile time. Thus Nimrod is
-statically typed. One can declare new types, which is in
-essence defining an identifier that can be used to denote this custom type
-when declaring variables further in the source code.
-
-These are the major type classes:
-
-* ordinal types (consist of integer, bool, character, enumeration
- (and subranges thereof) types)
-* floating point types
-* string type
-* structured types
-* reference (pointer) type
-* procedural type
-
-
-Ordinal types
-~~~~~~~~~~~~~
-Ordinal types have the following characteristics:
-
-- Ordinal types are countable and ordered. This property allows
- the operation of functions as Inc, Ord, Dec on ordinal types to be defined.
-- Ordinal values have a smallest possible value. Trying to count farther
- down than the smallest value gives a checked runtime or static error.
-- Ordinal values have a largest possible value. Trying to count farther
- than the largest value gives a checked runtime or static error.
-
-Signed integers, bool, characters and enumeration types (and subrange of these
-types) belong to ordinal types. Unsigned integer types are special in the way
-that over- and underflows generate no errors, but wrap around.
-
-Pre-defined numerical types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-These integer types are pre-defined:
-
-``int``
- the generic signed integer type; its size is platform dependant
- (a compiler should choose the processor's fastest integer type)
- this type should be used in general. An integer literal that has no type
- suffix is of this type.
-
-intXX
- an implementation may define additional signed integer types
- of XX bits using this naming scheme (example: int16 is a 16 bit wide integer).
- The current implementation supports ``int8``, ``int16``, ``int32``, ``int64``.
- Literals of these types have the suffix 'iXX.
-
-
-There are no unsigned integer types, only *unsigned operations* that treat their
-arguments as unsigned. Unsigned operations all wrap around; they may not lead to
-over- or underflow errors.
-
-The following floating point types are pre-defined:
-
-``float``
- the generic floating point type; its size is platform dependant
- (a compiler should choose the processor's fastest floating point type)
- this type should be used in general
-
-floatXX
- an implementation may define additional floating point types of XX bits using
- this naming scheme (example: float64 is a 64 bit wide float). The current
- implementation supports ``float32`` and ``float64``. Literals of these types
- have the suffix 'fXX.
-
-Automatic type conversion in expressions where different kinds
-of integer types are used is performed. However, if the type conversion
-loses information, the `EConvertError` exception is raised. An implementation
-may detect certain cases of the convert error at compile time.
-
-Automatic type conversion in expressions with different kinds
-of floating point types is performed: The smaller type is
-converted to the larger. Arithmetic performed on floating point types
-follows the IEEE standard.
-
-
-Boolean type
-~~~~~~~~~~~~
-The boolean type is named ``bool`` in Nimrod and can be one of the two
-pre-defined values ``true`` and ``false``. Conditions in while,
-if, elif, when statements need to be of type bool.
-
-This condition should hold::
-
- ord(false) == 0 and ord(true) == 1
-
-The operators ``not, and, or, xor`` are defined for the bool type.
-The ``and`` and ``or`` operators perform short-cut evaluation.
-Example::
-
- while p != nil and p.name != "xyz":
- # p.name is not evaluated if p == nil
- p = p.next
-
-
-The size of the bool type is implementation-dependant, typically it is
-one byte.
-
-
-Character type
-~~~~~~~~~~~~~~
-The character type is named ``char`` in Nimrod and uses the platform's
-native encoding. Thus on nearly every platform its size is one byte due to
-the popular UTF-8 encoding.
-Character literals are enclosed in single quotes ``''``.
-
-.. Note:: For platform-independant character handling is the ``encoding``
- standard module.
-
-
-Enumeration types
-~~~~~~~~~~~~~~~~~
-Enumeration types define a new type whose values consist only of the ones
-specified.
-The values are ordered by the order in enum's declaration. Example::
-
- type
- TDirection = enum
- north, east, south, west
-
-
-Now the following holds::
-
- ord(north) == 0
- ord(east) == 1
- ord(south) == 2
- ord(west) == 3
-
-Thus, north < east < south < west. The comparison operators can be used
-with enumeration types.
-
-An implemenation should store enumeration types with the minimal number of
-bytes required for the particular enum, unless efficiency would be affected by
-doing so.
-
-For better interfacing to other programming languages, the fields of enum
-types can be assigned an explicit ordinal value. However, the ordinal values
-have to be in ascending order appropriately. A field whose ordinal value that
-is not explicitly given, gets the value of the previous field + 1.
-
-An explicit ordered enum can have *wholes*::
-
- type
- TTokenType = enum
- a = 2, b = 4, c = 89 # wholes are valid
-
-However, it is then not an ordinal anymore, so it is not possible to use these
-enums as an index type for arrays. The procedures ``inc``, ``dec``, ``succ``
-and ``pred`` are not available for them.
-
-
-Subrange types
-~~~~~~~~~~~~~~
-A subrange type is a range of values from an ordinal type (the host type).
-To define a subrange type, one must specify it's limiting values: the highest
-and lowest value of the type::
-
- type
- TSubrange = range[0..5]
-
-
-``TSubrange`` is a subrange of an integer which can only hold the values 0
-to 5. Assigning an other value to a variable of type ``TSubrange`` is a
-checked runtime error (or static error if it can be statically
-determined). Assignments from the base type to one of its subrange types
-(and vice versa) are allowed.
-
-An implemenation should give it the same size as its base type.
-
-
-String type
-~~~~~~~~~~~
-All string literals are of the type string. A string in Nimrod is very
-similar to a sequence of characters. However, strings in Nimrod both are
-zero-terminated and have a length field. One can retrieve the length with the
-builtin ``length`` procedure; the length never counts the terminating zero.
-The assignment operator for strings always copies the string.
-
-Strings are compared by their lexicographical order. All comparison operators
-are available. String can be indexed like arrays (lower bound is 0). Unlike
-arrays, they can be used in case statements::
-
- case paramStr(i)
- of "-v": incl(options, optVerbose)
- of "-h", "-?": incl(options, optHelp)
- else: write(stdout, "invalid command line option!\n")
-
-
-Structured types
-~~~~~~~~~~~~~~~~
-A variable of a structured type can hold multiple values at the same time.
-Stuctured types can be nested to unlimited levels. Arrays, sequences, records,
-objects and sets belong to the structured types.
-
-Array type
-~~~~~~~~~~
-Arrays are a homogenous type, meaning that each element in the array has the
-same type. Arrays always have a fixed length which is specified at compile time
-(except for open arrays). They can be indexed by any ordinal type. A parameter
-may leave out the index type in the declaration making it an
-*open array*. An open array ``A`` is always indexed by integers from 0 to
-``length(A)-1``.
-
-A sequence may be passed to a parameter that is of type *open array*, but
-not to a multi-dimensional open array, because it is impossible to do so in an
-efficient manner.
-
-An array expression may be constructed by the array constructor ``[]``.
-A constructed array is assignment compatible to a sequence.
-
-Example::
-
- type
- TIntArray = array[0..5, int]
- var
- x: TIntArray
- x = [1, 2, 3, 4, 5, 6] # this is the array constructor
-
-The lower bound of an array may be received by the built-in proc
-``low()``, the higher bound by ``high()``. The length may be
-received by ``length()``.
-
-Arrays are always bounds checked (at compile-time or at runtime). An
-implementation may provide a means to disable these checks.
-
-
-Sequence type
-~~~~~~~~~~~~~
-Sequences are similar to arrays but of dynamic length which may change
-during runtime (like strings). A sequence ``S`` is always indexed by integers
-from 0 to ``length(S)-1`` and its bounds are checked. Sequences can also be
-constructed by the array constructor ``[]``.
-
-
-Record and object types
-~~~~~~~~~~~~~~~~~~~~~~~
-A variable of a record or object type is a heterogenous storage container.
-A record or object defines various named *fields* of a type. The assignment
-operator for records and objects always copies the whole record/object. The
-constructor ``[]`` can be used to initialize records/objects. A field may
-be given a default value. Fields with default values do not have to be listed
-in a record construction, all other fields have to be listed.
-::
-
- type
- TPerson = record # type representing a person
- name: string # a person consists of a name
- age: int = 30 # and an age which default value is 30
-
- var
- person: TPerson
- person = (name: "Peter") # person.age is its default value (30)
-
-An implementation may align or even reorder the fields for best access
-performance. The alignment may be specified with the `align`
-pragma. If an alignment is specified the compiler shall not reorder the fields.
-
-The difference between records and objects is that objects allow inheritance.
-Objects have access to their type at runtime, so that the ``is`` operator
-can be used to determine the object's type. Assignment from an object to its
-parents' object leads to a static or runtime error (the
-`EInvalidObjectAssignment` exception is raised).
-::
-
- type
- TPerson = object
- name: string
- age: int
-
- TStudent = object of TPerson # a student is a person
- id: int # with an id field
-
- var
- student: TStudent
- person: TPerson
- student = (name: "Peter", age: 89, id: 3)
- person = (name: "Mary", age: 17)
- assert(student is TStudent) # is true
- person = student # this is an error; person has no storage for id.
-
-
-Set type
-~~~~~~~~
-The `set type` models the mathematical notion of a set. The set's
-basetype can only be an ordinal type. The reason is that sets are implemented
-as bit vectors. Sets are designed for high performance computing.
-
-.. Note:: The sets module can be used for sets of other types.
-
-Sets can be constructed via the set constructor: ``{}`` is the empty set. The
-empty set is type combatible with any special set type. The constructor
-can also be used to include elements (and ranges of elements) in the set::
-
- {'a'..'z', '0'..'9'} # This constructs a set that conains the
- # letters from 'a' to 'z' and the digits
- # from '0' to '9'
-
-These operations are supported by sets:
-
-================== ==========================================================
-operation meaning
-================== ==========================================================
- A + B union of two sets
- A * B intersection of two sets
- A - B difference of two sets (A without B's elements)
- A == B set equality
- A <= B subset relation (A is subset of B or equal to B)
- A < B strong subset relation (A is a real subset of B)
- e in A set membership (A contains element e)
- A >< B symmetric set difference (= (A - B) + (B - A))
- card(A) the cardinality of A (number of elements in A)
- incl(A, elem) same as A = A + {elem}, but may be faster
- excl(A, elem) same as A = A - {elem}, but may be faster
-================== ==========================================================
-
-Reference type
-~~~~~~~~~~~~~~
-References (similiar to `pointers` in other programming languages) are a way to
-introduce many-to-one relationships. This means different references can point
-to and modify the same location in memory. References should be used sparingly
-in a program. They are only needed for constructing graphs.
-
-Nimrod distinguishes between *traced* and *untraced* references. Untraced
-references are also called `pointers`. The difference between them is that
-traced references are garbage collected, untraced are not. Thus untraced
-references are *unsafe*. However for certain low-level operations (accessing
-the hardware) untraced references are unavoidable.
-
-Traced references are declared with the **ref** keyword, untraced references
-are declared with the **ptr** keyword.
-
-The ``^`` operator can be used to derefer a reference, the ``addr`` procedure
-returns the address of an item. An address is always an untraced reference.
-Thus the usage of ``addr`` is an *unsafe* feature.
-
-The ``.`` (access a record field operator) and ``[]`` (array/string/sequence
-index operator) operators perform implicit dereferencing operations for
-reference types::
-
- type
- PNode = ref TNode
- TNode = record
- le, ri: PNode
- data: int
-
- var
- n: PNode
- new(n)
- n.data = 9 # no need to write n^.data
-
-As can be seen by the example, reference types are the only types that can be
-used in *implicit forward declarations*: TNode may be used before it is
-defined, because only a refence to it is needed.
-
-To allocate a new traced object, the built-in procedure ``new`` has to be used.
-To deal with untraced memory, the procedures ``alloc``, ``dealloc`` and
-``realloc`` can be used. The documentation of the system module contains
-further information.
-
-Special care has to be taken if an untraced object contains traced objects like
-traced references, strings or sequences: In order to free everything properly,
-the built-in procedure ``finalize`` has to be called before freeing the
-untraced memory manually!
-
-.. XXX finalizers for traced objects
-
-Procedural type
-~~~~~~~~~~~~~~~
-A procedural type is internally a pointer to procedure. Thus ``nil`` is an
-allowed value for variables of a procedural type. Nimrod uses procedural types
-to achieve `functional` programming techniques. Dynamic dispatch for OOP
-constructs can also be implemented with procedural types.
-
-Example::
-
- type
- TCallback = proc (x: int) {.cdecl.}
-
- proc printItem(x: Int) = ...
-
- proc forEach(c: TCallback) =
- ...
-
- forEach(printItem) # this will NOT work because calling conventions differ
-
-A subtle issue with procedural types is that the calling convention of the
-procedure influences the type compability: Procedural types are only compatible
-if they have the same calling convention.
-
-Altough a Nimrod implementation may provide additional calling conventions
-the following shall always exist:
-
-``cdecl``
- is used for interfacing with C; indicates that a proc shall
- use the same calling convention as the C compiler.
-
-``inline``
- indicates that the caller of the proc should not call it,
- but rather inline its code in place for improved efficiency. Note that
- this is only a hint for the compiler: It may completely ignore it and
- it may inline procedures that are not marked as ``inline``.
-
-``closure``
- indicates that the procedure expects a context, a `closure` that needs
- to be passed to the procedure.
-
-
-Statements
-----------
-Nimrod uses the common statement/expression paradigma: Statements do not
-produce a value in contrast to expressions. Call expressions are statements.
-If the called procedure returns a value, it is not a valid statement
-as statements do not produce values. To evaluate an expression for
-side-effects and throwing its value away, one can use the ``discard``
-statement.
-
-Statements are separated into `simple statements` and `complex statements`.
-Simple statements are statements that cannot contain other statements, like
-assignments, calls or the ``return`` statement; complex statements can
-contain other statements. To avoid the `dangling else problem`, complex
-statements always have to be intended::
-
- XXX
-
-
-
-Discard statement
-~~~~~~~~~~~~~~~~~
-
-Syntax::
-
- discard_stmt ::= discard expr
-
-The `discard` statement evaluates its expression for side-effects and throws
-the expression's resulting value away. If the expression has no side-effects,
-this shall generate at least a warning from the compiler.
-
-
-Var statement
-~~~~~~~~~~~~~
-
-Syntax::
-
- varlist ::= identlist [asgn_opr expr doc]
- var_section ::= var varlist
- | var INDENT(x > I[-1]) PUSH(x) varlist
- { INDENT(x) varlist } POP
-
-`Var` statements simply declare new local and global variables and may
-initialize them. A comma seperated list of variables can be used to specify
-variables of the same type::
-
- var
- a: int = 0
- x, y, z: int
-
-However, an initializer is not allowed for such a list as its semantic
-would be ambigious in some cases. If an initializer is given the type
-can be omitted: The variable is of the same type as the initializing
-expression.
-
-
-If statement
-~~~~~~~~~~~~
-
-Syntax::
-
- if_stmt ::= PUSH(x = I[-1]) if expr ":" stmts
- { INDENT(x) elif expr ":" stmts }
- [ INDENT(x) else ":" stmts ]
- POP
-
-The `if` statement is a simple way to make a branch in the control flow:
-The expression after the keyword ``if`` is evaluated, if it is true
-the corresponding statements after the ``:`` are executed. Otherwise
-the expression after the ``elif`` is evaluated (if there is an
-``elif`` branch), if it is true the corresponding statements after
-the ``:`` are executed. This goes on until the last ``elif``. If all
-conditions fail, the ``else`` part is executed. If there is no ``else``
-part, execution continues with the statement after the ``if`` statement.
-
-
-Case statement
-~~~~~~~~~~~~~~
-
-Syntax::
-
- case_stmt ::= PUSH(I[-1]) case expr
- INDENT(x>=I[-1]) of vallist ":" stmts
- { INDENT(x) of vallist ":" stmts }
- { INDENT(x) elif expr ":" stmts }
- [ INDENT(x) else ":" stmts ]
- POP
-
-The `case` statement is similar to the if statement, but it represents
-a multi-branch selection. The expression after the keyword ``case`` is
-evaluated and if its value is in a *vallist* the corresponding statements
-(after the ``of`` keyword) are executed. If the value is no given *vallist*
-the ``else`` part is executed. If there is no ``else`` part and not all
-possible values that ``expr`` can hold occur in a ``vallist``, a static
-error shall be given. This holds only for expressions of ordinal types.
-If the expression is not of an ordinal type, and no ``else`` part is
-given, control just passes after the ``case`` statement.
-
-To suppress the static error in the ordinal case the programmer needs
-to write an ``else`` part with a ``nil`` statement.
-
-
-When statement
-~~~~~~~~~~~~~~
-
-Syntax::
-
- when_stmt ::= PUSH(x=I[-1]) when expr ":" stmts
- { INDENT(x) elif expr ":" stmts }
- [ INDENT(x) else ":" stmts ]
- POP
-
-The `when` statement is almost identical to the ``if`` statement with some
-exceptions:
-
-* Each ``expr`` has to be a constant expression of type ``bool``.
-* The statements do not open a new scope if they introduce new identifiers.
-* The statements that belong to the expression that evaluated to true are
- translated by the compiler, the other statements are not checked for
- syntax or semantics at all! This holds also for any ``expr`` coming
- after the expression that evaluated to true.
-
-The ``when`` statement enables conditional compilation techniques. As
-a special syntatic extension, the ``when `` construct is also available
-within ``record`` or ``object`` definitions.
-
-
-Raise statement
-~~~~~~~~~~~~~~~
-
-Syntax::
-
- raise_stmt ::= raise [qualified_identifier [comma expr]]
-
-Apart from built-in operations like array indexing, memory allocation, etc.
-the ``raise`` statement is the only way to raise an exception. The
-identifier has to be the name of a previously declared exception. A
-comma followed by an expression may follow; the expression must be of type
-``string`` or ``cstring``; this is an error message that can be extracted
-with the `getCurrentExceptionMsg` procedure in the module ``system``.
-
-If no exception name is given, the current exception is `re-raised`. The
-`ENoExceptionToReraise` exception is raised if there is no exception to
-re-raise. It follows that the ``raise`` statement *always* raises an
-exception.
-
-
-Try statement
-~~~~~~~~~~~~~
-
-Syntax::
-
- try_stmt ::= PUSH(x=I[-1]) try ":" stmts
- { INDENT(x) except exceptlist ":" stmts }
- [ INDENT(x) except ":" stmts ]
- [ INDENT(x) finally ":" stmts ]
- POP
-
-The statements after the ``try`` are executed in sequential order unless
-an exception ``e`` is raised. If the exception type of ``e`` matches any
-of the list ``exceptlist`` the corresponding statements are executed.
-The statements following the ``except`` clauses are called
-`exception handlers`.
-
-The empty ``except`` clause is executed if there is an exception that is
-in no list. It is similiar to an ``else`` clause in ``if`` statements.
-
-If there is a ``finally`` clause given, it is always executed after the
-exception handlers.
-
-The exception is *consumed* in an exception handler. However, an
-exception handler may raise another exception. If the exception is not
-handled, it is propagated through the call stack. This means that often
-the rest of the procedure - that is not within a ``finally`` clause -
-is not executed (if an exception occurs).
-
-
-Block statement
-~~~~~~~~~~~~~~~
-
-Syntax::
-
- block_stmt ::= block [IDENTIFIER] ":" stmts
-
-The block statement is a means to group statements to a (named) `block`.
-Inside the block, the ``break`` statement is allowed to leave the block
-immediately. A ``break`` statement can contain a name of a surrounding
-block to specify which block is to leave.
-
-
-Break statement
-~~~~~~~~~~~~~~~
-
-Syntax::
-
- break_stmt ::= break [IDENTIFIER]
-
-The break statement is used to leave a block immediately. If ``IDENTIFIER``
-is given, it is the name of the enclosing block that is to leave. If it is
-absent, the innermost block is leaved.
-
-
-While statement
-~~~~~~~~~~~~~~~
-
-Syntax::
-
- while_stmt ::= WHILE expr COLON stmts
-
-The `while` statement is executed until the ``expr`` evaluates to false.
-Endless loops are no error. ``while`` statements open an `implicit block`,
-so that they can be aborted by a ``break`` statement.
-
-
-For statement & iterators
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Syntax::
-
- for_stmt ::= PUSH(x=I[-1]) for exprlist in expr [".." expr] ":" stmts
- POP
-
-The `for` statement is an abstract mechanism to iterate over the elements
-of a container. It relies on an *iterator* to do so. Like ``while``
-statements, ``for`` statements open an `implicit block`, so that they
-can be aborted by a ``break`` statement.
-
-XXX
-
-
-
-Assembler statement
-~~~~~~~~~~~~~~~~~~~
-Syntax::
-
- asm_stmt ::= asm [CHAR_LITERAL] STRING_LITERAL
-
-The direct embedding of assembler code into Nimrod code is supported by the
-unsafe ``asm`` statement. Identifiers in the assembler code that refer to
-Nimrod identifiers shall be enclosed in a special character which can be
-specified right after the ``asm`` keyword. The default special character is
-``'!'``. An implementation does not need to support the assembler statement,
-giving a static error if it encounters one.
-
-
-Modules
--------
-Nimrod supports splitting a program into pieces by a module concept. Modules
-make separate compilation possible. Each module needs to be in its own file.
-Modules consist of an interface and an implementation section. The interface
-section lists the symbols that can be imported from other modules. Thus modules
-enable `information hiding`. The interface section may not contain any
-code that is executable. This means that only the headers of procedures can
-appear in the interface. A module may gain access to symbols of another module
-by the `import` statement. Recursive module dependancies are allowed, but
-slightly subtle.
-
-The algorithm for compiling modules is:
-
-- Compile the whole module as usual, following import statements recursively
-- if we have a cycle only import the already parsed symbols (in the interface
- of course); if an unknown identifier occurs then abort
-
-This is best illustrated by an example::
-
- # Module A
- interface
- type
- T1 = int
- import B # the compiler starts parsing B
-
- implementation
-
- proc main() =
- var i = p(3) # works because B has been parsed completely here
-
- main()
-
-
- # Module B
- interface
- import A # A is not parsed here! Only the already known symbols
- # of A are imported here.
-
- proc p(x: A.T1): A.T1 # this works because the compiler has already
- # added T1 to A's interface symbol table
-
- implementation
-
- proc p(x: A.T1): A.T1 = return x + 1
-
-
-Scope rules
------------
-Identifiers are valid from the point of their declaration until the end of
-the block in which the declaration occurred. The range where the identifier
-is known is the `scope` of the identifier. The exact scope of an identifier
-depends on the way it was declared.
-
-Block scope
-~~~~~~~~~~~
-The *scope* of a variable declared in the declaration part of a block
-is valid from the point of declaration until the end of the block. If a
-block contains a second block, in which the identifier is redeclared,
-then inside this block, the second declaration will be valid. Upon
-leaving the inner block, the first declaration is valid again. An
-identifier cannot be redefined in the same block, except if valid for
-procedure or iterator overloading purposes.
-
-
-Record or object scope
-~~~~~~~~~~~~~~~~~~~~~~
-The field identifiers inside a record or object definition are valid in the
-following places:
-
-* To the end of the record definition
-* Field designators of a variable of the given record type.
-* In all descendent types of the object type.
-
-Module scope
-~~~~~~~~~~~~
-All identifiers in the interface part of a module are valid from the point of
-declaration, until the end of the module. Furthermore, the identifiers are
-known in other modules that import the module. Identifiers from indirectly
-dependent modules are *not* available. Identifiers declared in the
-implementation part of a module are valid from the point of declaration to
-the end of the module. The ``system`` module is automatically imported in
-all other modules.
-
-If a module imports an identifier by two different modules,
-each occurance of the identifier has to be qualified, unless it is an
-overloaded procedure or iterator in which case the overloading
-resolution takes place::
-
- # Module A
- interface
- var x: string
-
- # Module B
- interface
- var x: int
-
- # Module C
- import A, B, io
- write(stdout, x) # error: x is ambigious
- write(sdtout, A.x) # no error: qualifier used
-
-
-Messages
-========
-
-A Nimrod compiler has to emit different kinds of messages: `hint`,
-`warning`, and `error` messages. `errors` have to be emitted if the compiler
-encounters any static errors. If and when the other two message kinds are
-emitted is not specified, unless a message is requested with the
-``hint`` or ``warning`` pragma.
-
-Pragmas
-=======
-Pragmas are Nimrod's method to give the compiler additional information/
-commands without introducing a massive number of new keywords. Pragmas are
-processed on the fly during parsing. Pragmas are always enclosed in the
-special ``{.`` and ``.}`` curly brackets. There are a number of pragmas
-that a compiler has to process; a compiler may define additional pragmas
-not specified here.
-
-
-define pragma
--------------
-The `define` pragma defines a conditional symbol. This symbol may only be
-used in other pragmas and in the ``defined`` expression and not in ordinary
-Nimrod source code. The conditional symbols go into a special symbol table.
-The compiler shall define the target processor and the target operating
-system as conditional symbols. See `Annex A `_ for a list of specified
-processors and operating systems. The Syntax of the define pragma is::
-
- define_pragma ::= curlydot_le "define" colon IDENTIFIER curlydot_ri
-
-
-undef pragma
-------------
-The `undef` pragma the counterpart to the define pragma. It undefines a
-conditional symbol. Syntax::
-
- undef_pragma ::= curlydot_le "undef" colon IDENTIFIER curlydot_ri
-
-
-error pragma
-------------
-The `error` pragma is used to make the compiler output an error message with
-the given content. Compilation may abort after an error (or not). Syntax::
-
- error_pragma ::= curlydot_le "error" colon STRING_LITERAL curlydot_ri
-
-
-fatal pragma
-------------
-The `fatal` pragma is used to make the compiler output an error message with
-the given content. In contrast to the ``error`` pragma, compilation
-is guaranteed to be aborted by this pragma. Syntax::
-
- fatal_pragma ::= curlydot_le "fatal" colon STRING_LITERAL curlydot_ri
-
-
-warning pragma
---------------
-The `warning` pragma is used to make the compiler output a warning message with
-the given content. Compilation continues after the warning. Syntax::
-
- warning_pragma ::= curlydot_le "warning" colon STRING_LITERAL curlydot_ri
-
-
-hint pragma
------------
-The `hint` pragma is used to make the compiler output a hint message with
-the given content. Compilation continues after the hint. Syntax::
-
-
- hint_pragma ::= curlydot_le "hint" colon STRING_LITERAL curlydot_ri
-
-
-
-compilation option pragmas
---------------------------
-The listed pragmas here can be used to override the code generation options
-for a section of code.
-::
-
- "{." pragma: val {pragma: val} ".}"
-
-
-An implementation should provide at least the following possible options (it can
-add various others). If an implementation does not recognize the option, a
-warning shall be given to the user.
-
-=============== =============== ============================================
-pragma allowed values description
-=============== =============== ============================================
-checks on|off Turns the code generation for all runtime
- checks on or off.
-bound_checks on|off Turns the code generation for array bound
- checks on or off.
-overflow_checks on|off Turns the code generation for over- or
- underflow checks on or off.
-nil_checks on|off Turns the code generation for nil pointer
- checks on or off.
-assertions on|off Turns the code generation for assertions
- on or off.
-warnings on|off Turns the warning messages of the compiler
- on or off.
-hints on|off Turns the hint messages of the compiler
- on or off.
-optimization none|speed|size Optimize the code for speed or size, or
- disable optimization. For non-optimizing
- compilers this option has no effect.
- Neverless they must parse it properly.
-callconv cdecl|... Specifies the default calling convention for
- all procedures (and procedure types) that
- follow.
-=============== =============== ============================================
-
-Example::
-
- {.checks: off, optimization: speed.}
- # compile without runtime checks and optimize for speed
-
-
-push and pop pragmas
---------------------
-The push/pop pragmas are very similar to the option directive,
-but are used to override the settings temporarily. Example::
-
- {.push checks: off.}
- # compile this section without runtime checks as it is
- # speed critical
- # ... some code ...
- {.pop.} # restore old settings
-
-
-Annex A: List of conditional symbols
-====================================
-
-``posix`` is defined on any POSIX compatible operating system.
-
-+----------------------------+-----------------+
-| Operating System | Symbols |
-+============================+=================+
-| AIX | aix, posix |
-+----------------------------+-----------------+
-| Compaq Tru64 UNIX | tru64, posix |
-+----------------------------+-----------------+
-| Digital UNIX | tru64, posix |
-+----------------------------+-----------------+
-| OSF/1 | tru64, posix |
-+----------------------------+-----------------+
-| FreeBSD | freebsd, |
-| | posix, |
-| | bsd |
-+----------------------------+-----------------+
-| GNU/Linux | linux, |
-| | posix |
-+----------------------------+-----------------+
-| HP-UX | hpux, |
-| | posix |
-+----------------------------+-----------------+
-| Irix | irix, |
-| | posix |
-+----------------------------+-----------------+
-| MacOS X | macosx, |
-| | posix |
-+----------------------------+-----------------+
-| NetBSD | netbsd, |
-| | posix, |
-| | bsd |
-+----------------------------+-----------------+
-| OpenBSD | openbsd, |
-| | posix, |
-| | bsd |
-+----------------------------+-----------------+
-| Solaris | solaris, |
-| | posix |
-+----------------------------+-----------------+
-| Windows (all variants) | windows |
-+----------------------------+-----------------+
-
-
-+----------------------------+-----------------+
-| Processor | Symbols |
-+============================+=================+
-| Compaq Alpha | alpha |
-+----------------------------+-----------------+
-| HP Precision Architecture | hppa |
-+----------------------------+-----------------+
-| INTEL x86 | x86 |
-+----------------------------+-----------------+
-| AMD/INTEL x86 64bit | x86_64, |
-| | amd64 |
-+----------------------------+-----------------+
-| MIPS RISC | mips |
-+----------------------------+-----------------+
-| IBM Power PC | powerpc |
-+----------------------------+-----------------+
-| SPARC | sparc |
-+----------------------------+-----------------+
-| MicroSPARC | sparc |
-+----------------------------+-----------------+
-| UltraSPARC | sparc |
-+----------------------------+-----------------+
-
-On targets for 16, 32 or 64 bit processors the symbols ``cpu16``, ``cpu32``
-or ``cpu64`` shall be defined respectively. On little endian machines the
-symbol ``little_endian`` and on big endian ones the symbol ``big_endian``
-are defined.
diff --git a/doc/theindex.txt b/doc/theindex.txt
index 0c0e621e7..997329242 100644
--- a/doc/theindex.txt
+++ b/doc/theindex.txt
@@ -1,4873 +1,7470 @@
-
-=====
-Index
-=====
-
-.. index::
-
-
- `!=`:idx:
- `system.html#235 `_
-
- `$`:idx:
- * `system.html#328 `_
- * `system.html#329 `_
- * `system.html#330 `_
- * `system.html#331 `_
- * `system.html#332 `_
- * `system.html#333 `_
- * `system.html#334 `_
- * `times.html#109 `_
- * `times.html#110 `_
-
- `%`:idx:
- * `strutils.html#129 `_
- * `strutils.html#130 `_
- * `strtabs.html#112 `_
-
- `%%`:idx:
- * `system.html#320 `_
- * `system.html#321 `_
-
- `&`:idx:
- * `system.html#245 `_
- * `system.html#246 `_
- * `system.html#247 `_
- * `system.html#248 `_
- * `system.html#358 `_
- * `system.html#359 `_
- * `system.html#360 `_
- * `system.html#361 `_
-
- `*`:idx:
- * `system.html#159 `_
- * `system.html#178 `_
- * `system.html#196 `_
- * `system.html#207 `_
- * `complex.html#107 `_
-
- `*%`:idx:
- * `system.html#316 `_
- * `system.html#317 `_
-
- `+`:idx:
- * `system.html#154 `_
- * `system.html#157 `_
- * `system.html#173 `_
- * `system.html#176 `_
- * `system.html#192 `_
- * `system.html#194 `_
- * `system.html#208 `_
- * `complex.html#103 `_
-
- `+%`:idx:
- * `system.html#312 `_
- * `system.html#313 `_
-
- `-`:idx:
- * `system.html#155 `_
- * `system.html#158 `_
- * `system.html#174 `_
- * `system.html#177 `_
- * `system.html#193 `_
- * `system.html#195 `_
- * `system.html#209 `_
- * `complex.html#104 `_
- * `complex.html#105 `_
- * `times.html#113 `_
-
- `-%`:idx:
- * `system.html#314 `_
- * `system.html#315 `_
-
- `-+-`:idx:
- `system.html#210 `_
-
- `/`:idx:
- * `system.html#197 `_
- * `os.html#117 `_
- * `complex.html#106 `_
-
- `/%`:idx:
- * `system.html#318 `_
- * `system.html#319 `_
-
- `/../`:idx:
- `os.html#121 `_
-
- `<`:idx:
- * `system.html#169 `_
- * `system.html#188 `_
- * `system.html#200 `_
- * `system.html#227 `_
- * `system.html#228 `_
- * `system.html#229 `_
- * `system.html#230 `_
- * `system.html#231 `_
- * `system.html#232 `_
- * `system.html#233 `_
- * `system.html#234 `_
-
- `<%`:idx:
- * `system.html#324 `_
- * `system.html#325 `_
-
- `<=`:idx:
- * `system.html#168 `_
- * `system.html#187 `_
- * `system.html#199 `_
- * `system.html#220 `_
- * `system.html#221 `_
- * `system.html#222 `_
- * `system.html#223 `_
- * `system.html#224 `_
- * `system.html#225 `_
- * `system.html#226 `_
-
- `<=%`:idx:
- * `system.html#322 `_
- * `system.html#323 `_
-
- `==`:idx:
- * `system.html#167 `_
- * `system.html#186 `_
- * `system.html#198 `_
- * `system.html#211 `_
- * `system.html#212 `_
- * `system.html#213 `_
- * `system.html#214 `_
- * `system.html#215 `_
- * `system.html#216 `_
- * `system.html#217 `_
- * `system.html#218 `_
- * `system.html#219 `_
- * `system.html#363 `_
- * `complex.html#102 `_
-
- `>`:idx:
- `system.html#237 `_
-
- `>%`:idx:
- `system.html#327 `_
-
- `>=`:idx:
- `system.html#236 `_
-
- `>=%`:idx:
- `system.html#326 `_
-
- `[]`:idx:
- `strtabs.html#107 `_
-
- `[]=`:idx:
- `strtabs.html#106 `_
-
- `[ESC]`:idx:
- `manual.html#134 `_
-
- `ABDAY_1`:idx:
- `posix.html#400 `_
-
- `ABDAY_2`:idx:
- `posix.html#401 `_
-
- `ABDAY_3`:idx:
- `posix.html#402 `_
-
- `ABDAY_4`:idx:
- `posix.html#403 `_
-
- `ABDAY_5`:idx:
- `posix.html#404 `_
-
- `ABDAY_6`:idx:
- `posix.html#405 `_
-
- `ABDAY_7`:idx:
- `posix.html#406 `_
-
- `ABMON_1`:idx:
- `posix.html#419 `_
-
- `ABMON_10`:idx:
- `posix.html#428 `_
-
- `ABMON_11`:idx:
- `posix.html#429 `_
-
- `ABMON_12`:idx:
- `posix.html#430 `_
-
- `ABMON_2`:idx:
- `posix.html#420 `_
-
- `ABMON_3`:idx:
- `posix.html#421 `_
-
- `ABMON_4`:idx:
- `posix.html#422 `_
-
- `ABMON_5`:idx:
- `posix.html#423 `_
-
- `ABMON_6`:idx:
- `posix.html#424 `_
-
- `ABMON_7`:idx:
- `posix.html#425 `_
-
- `ABMON_8`:idx:
- `posix.html#426 `_
-
- `ABMON_9`:idx:
- `posix.html#427 `_
-
- `abs`:idx:
- * `system.html#170 `_
- * `system.html#189 `_
- * `system.html#201 `_
- * `complex.html#108 `_
-
- `access`:idx:
- `posix.html#959 `_
-
- `add`:idx:
- * `system.html#249 `_
- * `system.html#250 `_
- * `system.html#251 `_
- * `system.html#252 `_
- * `system.html#253 `_
-
- `addQuitProc`:idx:
- `system.html#287 `_
-
- `AIO_ALLDONE`:idx:
- `posix.html#204 `_
-
- `aio_cancel`:idx:
- `posix.html#778 `_
-
- `AIO_CANCELED`:idx:
- `posix.html#205 `_
-
- `aio_error`:idx:
- `posix.html#779 `_
-
- `aio_fsync`:idx:
- `posix.html#780 `_
-
- `AIO_NOTCANCELED`:idx:
- `posix.html#206 `_
-
- `aio_read`:idx:
- `posix.html#781