diff --git a/config/nimrod.cfg b/config/nimrod.cfg
index 4927bd455d..5f4c127862 100755
--- a/config/nimrod.cfg
+++ b/config/nimrod.cfg
@@ -1,99 +1,99 @@
-# Configuration file for the Nimrod Compiler.
-# (c) 2009 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!
-
-cc = gcc
+# Configuration file for the Nimrod Compiler.
+# (c) 2009 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!
+
+cc = gcc
@if nim:
# use the old fixed library for bootstrapping with Nim:
lib = "nimlib"
@end
-
-path="$lib/pure"
-path="$lib/impure"
-path="$lib/wrappers"
-path="$lib/wrappers/cairo"
-path="$lib/wrappers/gtk"
-path="$lib/wrappers/lua"
-path="$lib/wrappers/opengl"
-path="$lib/wrappers/pcre"
-path="$lib/wrappers/sdl"
-path="$lib/wrappers/x11"
-path="$lib/wrappers/zip"
-path="$lib/windows"
-path="$lib/posix"
-path="$lib/ecmas"
-
-@if release or quick:
- obj_checks:off
- field_checks:off
- range_checks:off
- bound_checks:off
- overflow_checks:off
- assertions:off
- stacktrace:off
- debugger:off
- line_dir:off
- dead_code_elim:on
-@end
-
-@if release:
- opt:speed
-@end
-
-# additional options always passed to the compiler:
---verbosity: "1"
+
+path="$lib/pure"
+path="$lib/impure"
+path="$lib/wrappers"
+path="$lib/wrappers/cairo"
+path="$lib/wrappers/gtk"
+path="$lib/wrappers/lua"
+path="$lib/wrappers/opengl"
+path="$lib/wrappers/pcre"
+path="$lib/wrappers/sdl"
+path="$lib/wrappers/x11"
+path="$lib/wrappers/zip"
+path="$lib/windows"
+path="$lib/posix"
+path="$lib/ecmas"
+
+@if release or quick:
+ obj_checks:off
+ field_checks:off
+ range_checks:off
+ bound_checks:off
+ overflow_checks:off
+ assertions:off
+ stacktrace:off
+ debugger:off
+ line_dir:off
+ dead_code_elim:on
+@end
+
+@if release:
+ opt:speed
+@end
+
+# additional options always passed to the compiler:
+--verbosity: "1"
--parallel_build: "0" # 0 to auto-detect number of processors
-
-hint[LineTooLong]=off
-#hint[XDeclaredButNotUsed]=off
-
-@if unix:
- @if not bsd:
- gcc.options.linker = "-ldl"
- @end
-@end
-
-# Configuration for the Intel C/C++ compiler:
-icc.options.always = "-cxxlib"
-icc.options.linker = "-cxxlib"
-
-# Configuration for the GNU C/C++ compiler:
-@if windows:
- gcc.path = r"$nimrod\dist\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 -fno-strict-aliasing"
-gcc.options.size = "-Os"
-#passl = "-pg"
-
-# Configuration for the LLVM GCC compiler:
-llvm_gcc.options.debug = "-g"
-llvm_gcc.options.always = "-w"
-llvm_gcc.options.speed = "-O2"
-llvm_gcc.options.size = "-Os"
-
-# Configuration for the Visual C/C++ compiler:
-vcc.options.linker = r"/F33554432" # set the stack size to 8 MB
-vcc.options.debug = "/RTC1 /ZI"
-vcc.options.always = "/nologo"
-vcc.options.speed = "/Ox /arch:SSE2"
-vcc.options.size = "/O1"
-
-# Configuration for the Digital Mars C/C++ compiler:
-@if windows:
- dmc.path = r"$nimrod\dist\dm\bin"
-@end
-
-# Configuration for the Tiny C Compiler:
-tcc.options.always = "-w"
+
+hint[LineTooLong]=off
+#hint[XDeclaredButNotUsed]=off
+
+@if unix:
+ @if not bsd:
+ gcc.options.linker = "-ldl"
+ @end
+@end
+
+# Configuration for the Intel C/C++ compiler:
+icc.options.always = "-cxxlib"
+icc.options.linker = "-cxxlib"
+
+# Configuration for the GNU C/C++ compiler:
+@if windows:
+ gcc.path = r"$nimrod\dist\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 -fno-strict-aliasing"
+gcc.options.size = "-Os"
+#passl = "-pg"
+
+# Configuration for the LLVM GCC compiler:
+llvm_gcc.options.debug = "-g"
+llvm_gcc.options.always = "-w"
+llvm_gcc.options.speed = "-O2"
+llvm_gcc.options.size = "-Os"
+
+# Configuration for the Visual C/C++ compiler:
+vcc.options.linker = r"/F33554432" # set the stack size to 8 MB
+vcc.options.debug = "/RTC1 /ZI"
+vcc.options.always = "/nologo"
+vcc.options.speed = "/Ox /arch:SSE2"
+vcc.options.size = "/O1"
+
+# Configuration for the Digital Mars C/C++ compiler:
+@if windows:
+ dmc.path = r"$nimrod\dist\dm\bin"
+@end
+
+# Configuration for the Tiny C Compiler:
+tcc.options.always = "-w"
diff --git a/data/advopt.txt b/data/advopt.txt
index 1fe4e0e6e4..b746853199 100755
--- a/data/advopt.txt
+++ b/data/advopt.txt
@@ -7,10 +7,10 @@ Advanced commands::
check checks the project for syntax and semantic
parse parses a single file (for debugging Nimrod)
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
+ -w, --warnings:on|off turn all warnings on|off
+ --warning[X]:on|off turn specific warning X on|off
+ --hints:on|off turn all hints on|off
+ --hint[X]:on|off turn specific hint X on|off
--lib:PATH set the system library path
-c, --compileOnly compile only; do not assemble or link
--noLinking compile but do not link
@@ -24,8 +24,8 @@ Advanced options:
-l, --passl:OPTION pass an option to the linker
--genMapping generate a mapping file containing
(Nimrod, mangled) identifier pairs
- --lineDir:on|off generation of #line directive ON|OFF
- --checkpoints:on|off turn on|off checkpoints; for debugging Nimrod
+ --lineDir:on|off generation of #line directive on|off
+ --checkpoints:on|off turn checkpoints on|off; for debugging Nimrod
--skipCfg do not read the general configuration file
--skipProjCfg do not read the project's configuration file
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
diff --git a/data/basicopt.txt b/data/basicopt.txt
index 136c058c0d..0201b84d74 100755
--- a/data/basicopt.txt
+++ b/data/basicopt.txt
@@ -14,18 +14,20 @@ Options:
-d, --define:SYMBOL define a conditional symbol
-u, --undef:SYMBOL undefine a conditional symbol
-f, --forceBuild force rebuilding of all modules
- --symbolFiles:on|off use symbol files to speed up compilation (buggy!)
- --stackTrace:on|off code generation for stack trace ON|OFF
- --lineTrace:on|off code generation for line trace ON|OFF
- --debugger:on|off turn Embedded Nimrod Debugger ON|OFF
- -x, --checks:on|off code generation for all runtime checks ON|OFF
- --objChecks:on|off code generation for obj conversion checks ON|OFF
- --fieldChecks:on|off code generation for case variant fields ON|OFF
- --rangeChecks:on|off code generation for range checks ON|OFF
- --boundChecks:on|off code generation for bound checks ON|OFF
- --overflowChecks:on|off code generation for over-/underflow checks ON|OFF
- -a, --assertions:on|off code generation for assertions ON|OFF
- --deadCodeElim:on|off whole program dead code elimination ON|OFF
+ --stackTrace:on|off turn stack tracing on|off
+ --lineTrace:on|off turn line tracing on|off
+ --debugger:on|off turn Embedded Nimrod Debugger on|off
+ -x, --checks:on|off turn all runtime checks on|off
+ --objChecks:on|off turn obj conversion checks on|off
+ --fieldChecks:on|off turn case variant field checks on|off
+ --rangeChecks:on|off turn range checks on|off
+ --boundChecks:on|off turn bound checks on|off
+ --overflowChecks:on|off turn int over-/underflow checks on|off
+ -a, --assertions:on|off turn assertions on|off
+ --floatChecks:on|off turn all floating point (NaN/Inf) checks on|off
+ --nanChecks:on|off turn NaN checks on|off
+ --infChecks:on|off turn Inf checks on|off
+ --deadCodeElim:on|off whole program dead code elimination on|off
--opt:none|speed|size optimize not at all or for speed|size
--app:console|gui|lib generate a console|GUI application|dynamic library
-r, --run run the compiled program with given arguments
diff --git a/doc/manual.txt b/doc/manual.txt
index 8399dc4b03..391f319a13 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -47,7 +47,7 @@ components called `locations`:idx:. A variable is basically a name for a
location. Each variable and location is of a certain `type`:idx:. The
variable's type is called `static type`:idx:, the location's type is called
`dynamic type`:idx:. If the static type is not the same as the dynamic type,
-it is a supertype or subtype of the dynamic type.
+it is a super-type or subtype of the dynamic type.
An `identifier`:idx: is a symbol declared as a name for a variable, type,
procedure, etc. The region of the program over which a declaration applies is
@@ -424,8 +424,8 @@ Integers, bool, characters and enumeration types (and subrange of these
types) belong to ordinal types.
-Pre-defined numerical types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Pre-defined integer types
+~~~~~~~~~~~~~~~~~~~~~~~~~
These integer types are pre-defined:
``int``
@@ -469,6 +469,14 @@ operation meaning
``int32`` type)
====================== ======================================================
+`Automatic type conversion`:idx: is performed in expressions where different
+kinds of integer types are used: the smaller type is converted to the larger.
+For further details, see `Convertible relation`_.
+
+
+Pre-defined floating point types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
The following floating point types are pre-defined:
``float``
@@ -482,16 +490,49 @@ floatXX
implementation supports ``float32`` and ``float64``. Literals of these types
have the suffix 'fXX.
-`Automatic type conversion`:idx: is performed in expressions where different
-kinds of integer types are used. However, if the type conversion
-loses information, the `EOutOfRange`:idx: exception is raised (if the error
-cannot be detected 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. Integer types are not converted to floating point
-types automatically and vice versa.
+of floating point types is performed: See `Convertible relation`_ for further
+details. Arithmetic performed on floating point types follows the IEEE
+standard. Integer types are not converted to floating point types automatically
+and vice versa.
+
+The IEEE standard defines five types of floating-point exceptions:
+
+* Invalid: operations with mathematically invalid operands,
+ for example 0.0/0.0, sqrt(-1.0), and log(-37.8).
+* Division by zero: divisor is zero and dividend is a finite nonzero number,
+ for example 1.0/0.0.
+* Overflow: operation produces a result that exceeds the range of the exponent,
+ for example MAXDOUBLE+0.0000000000001e308.
+* Underflow: operation produces a result that is too small to be represented
+ as a normal number, for example, MINDOUBLE * MINDOUBLE.
+* Inexact: operation produces a result that cannot be represented with infinite
+ precision, for example, 2.0 / 3.0, log(1.1) and 0.1 in input.
+
+The IEEE exceptions are either ignored at runtime or mapped to the
+Nimrod exceptions: `EFloatInvalidOp`:idx, `EFloatDivByZero`:idx:,
+`EFloatOverflow`:idx:, `EFloatUnderflow`:idx:, and `EFloatInexact`:idx:\.
+These exceptions inherit from the `EFloatingPoint`:idx: base class.
+
+Nimrod provides the pragmas `NaNChecks`:idx and `InfChecks`:idx:\ to control
+whether the IEEE exceptions are ignored or trap a Nimrod exception:
+
+.. code-block:: nimrod
+ {.NanChecks: on, InfChecks: on.}
+ var a = 1.0
+ var b = 0.0
+ echo b / b # raises EFloatInvalidOp
+ echo a / b # raises EFloatOverflow
+
+In the current implementation ``EFloatDivByZero`` and ``EFloatInexact`` are
+never raised. ``EFloatOverflow`` is raised instead of ``EFloatDivByZero``.
+There is also a `floatChecks`:idx: pragma that is a short-cut for the
+combination of ``NaNChecks`` and ``InfChecks`` pragmas. ``floatChecks`` are
+turned off as default.
+
+The only operations that are affected by the ``floatChecks`` pragma are
+the ``+``, ``-``, ``*``, ``/`` operators for floating point types.
Boolean type
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index a7c84a0ec6..4a94bc8cfc 100755
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -7,6 +7,10 @@
.. contents::
+ "Look at you, hacker. A pathetic creature of meat and bone, panting and
+ sweating as you run through my corridors. How can you challenge a perfect,
+ immortal machine?"
+
Introduction
============
@@ -242,7 +246,7 @@ memory, but nothing worse happens.
DeadCodeElim Pragma
-~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~
The `deadCodeElim`:idx: pragma only applies to whole modules: It tells the
compiler to activate (or deactivate) dead code elimination for the module the
pragma appers in.
@@ -304,13 +308,13 @@ Optimizing string handling
String assignments are sometimes expensive in Nimrod: They are required to
copy the whole string. However, the compiler is often smart enough to not copy
strings. Due to the argument passing semantics, strings are never copied when
-passed to subroutines. The compiler does not copy strings that are result from
-a procedure call, because the called procedure returns a new string anyway.
+passed to subroutines. The compiler does not copy strings that are a result from
+a procedure call, because the callee returns a new string anyway.
Thus it is efficient to do:
.. code-block:: Nimrod
var s = procA() # assignment will not copy the string; procA allocates a new
- # string anyway
+ # string already
However it is not efficient to do:
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index bca45894ca..50226f0f4a 100755
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -101,7 +101,7 @@ proc mean*(x: openarray[float]): float {.noSideEffect.} =
result = sum(x) / toFloat(len(x))
proc variance*(x: openarray[float]): float {.noSideEffect.} =
- ## computes the mean of the elements in `x`.
+ ## computes the variance of the elements in `x`.
## If `x` is empty, NaN is returned.
result = 0.0
var m = mean(x)
diff --git a/lib/system.nim b/lib/system.nim
index 4dbc0a93dc..e0f0b4fe52 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -222,10 +222,10 @@ type
EFloatingPoint* = object of ESynch ## base class for floating point exceptions
EFloatInvalidOp* {.compilerproc.} =
object of EFloatingPoint ## Invalid operation according to IEEE: Raised by
- ## 0.0/0.0, sqrt(-1.0), and log(-37.8) for example.
+ ## 0.0/0.0, for example.
EFloatDivByZero* {.compilerproc.} =
object of EFloatingPoint ## Division by zero. Divisor is zero and dividend
- ## is a finite nonzero number
+ ## is a finite nonzero number.
EFloatOverflow* {.compilerproc.} =
object of EFloatingPoint ## Overflow. Operation produces a result
## that exceeds the range of the exponent
diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim
index f097ee7942..b93bb9844d 100755
--- a/lib/system/arithm.nim
+++ b/lib/system/arithm.nim
@@ -314,3 +314,21 @@ when not defined(mulInt):
if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
return result
raiseOverflow()
+
+# We avoid setting the FPU control word here for compatibility with libraries
+# written in other languages.
+
+proc raiseFloatInvalidOp {.noinline, noreturn.} =
+ raise newException(EFloatInvalidOp, "FPU operation caused a NaN result")
+
+proc nanCheck(x: float64) {.compilerProc, inline.} =
+ if x != x: raiseFloatInvalidOp()
+
+proc raiseFloatOverflow(x: float64) {.noinline, noreturn.} =
+ if x > 0.0:
+ raise newException(EFloatOverflow, "FPU operation caused an overflow")
+ else:
+ raise newException(EFloatUnderflow, "FPU operations caused an underflow")
+
+proc infCheck(x: float64) {.compilerProc, inline.} =
+ if x != 0.0 and x*0.5 == x: raiseFloatOverflow(x)
diff --git a/lib/wrappers/lua/lua.nim b/lib/wrappers/lua/lua.nim
index 9bf4e673eb..f12c5e5a4d 100755
--- a/lib/wrappers/lua/lua.nim
+++ b/lib/wrappers/lua/lua.nim
@@ -37,16 +37,16 @@
when defined(MACOSX):
const
- LUA_NAME* = "liblua(5.2|5.1|5.0).dylib"
- LUA_LIB_NAME* = "liblua(5.2|5.1|5.0).dylib"
+ LUA_NAME* = "liblua(|5.2|5.1|5.0).dylib"
+ LUA_LIB_NAME* = "liblua(|5.2|5.1|5.0).dylib"
elif defined(UNIX):
const
- LUA_NAME* = "liblua(5.2|5.1|5.0).so.0"
- LUA_LIB_NAME* = "liblua(5.2|5.1|5.0).so.0"
+ LUA_NAME* = "liblua(|5.2|5.1|5.0).so.(|0)"
+ LUA_LIB_NAME* = "liblua(|5.2|5.1|5.0).so.(|0)"
else:
const
- LUA_NAME* = "lua(5.2|5.1|5.0).dll"
- LUA_LIB_NAME* = "lua(5.2|5.1|5.0).dll"
+ LUA_NAME* = "lua(|5.2|5.1|5.0).dll"
+ LUA_LIB_NAME* = "lua(|5.2|5.1|5.0).dll"
type
size_t* = int
Psize_t* = ptr size_t
@@ -56,7 +56,8 @@ const
LUA_RELEASE* = "Lua 5.1.1"
LUA_VERSION_NUM* = 501
LUA_COPYRIGHT* = "Copyright (C) 1994-2006 Lua.org, PUC-Rio"
- LUA_AUTHORS* = "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" # option for multiple returns in `lua_pcall' and `lua_call'
+ LUA_AUTHORS* = "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
+ # option for multiple returns in `lua_pcall' and `lua_call'
LUA_MULTRET* = - 1 #
#** pseudo-indices
#
@@ -74,19 +75,18 @@ const # thread status; 0 is OK
type
Plua_State* = Pointer
- lua_CFunction* = proc (L: Plua_State): int{.cdecl.} #
- #** functions that read/write blocks when loading/dumping Lua chunks
- #
-
+ lua_CFunction* = proc (L: Plua_State): int{.cdecl.}
+
+#
+#** functions that read/write blocks when loading/dumping Lua chunks
+#
type
lua_Reader* = proc (L: Plua_State, ud: Pointer, sz: Psize_t): cstring{.cdecl.}
lua_Writer* = proc (L: Plua_State, p: Pointer, sz: size_t, ud: Pointer): int{.
- cdecl.} #
- #** prototype for memory-allocation functions
- #
+ cdecl.}
lua_Alloc* = proc (ud, theptr: Pointer, osize, nsize: size_t){.cdecl.}
-const
+const
LUA_TNONE* = - 1
LUA_TNIL* = 0
LUA_TBOOLEAN* = 1
@@ -218,9 +218,10 @@ proc lua_getallocf*(L: Plua_State, ud: ptr Pointer): lua_Alloc{.cdecl,
dynlib: LUA_NAME, importc.}
proc lua_setallocf*(L: Plua_State, f: lua_Alloc, ud: Pointer){.cdecl,
dynlib: LUA_NAME, importc.}
- #
- #** Garbage-collection functions and options
- #
+
+#
+#** Garbage-collection functions and options
+#
const
LUA_GCSTOP* = 0
LUA_GCRESTART* = 1
@@ -229,11 +230,13 @@ const
LUA_GCCOUNTB* = 4
LUA_GCSTEP* = 5
LUA_GCSETPAUSE* = 6
- LUA_GCSETSTEPMUL* = 7 #
- #** ===============================================================
- #** some useful macros
- #** ===============================================================
- #
+ LUA_GCSETSTEPMUL* = 7
+
+#
+#** ===============================================================
+#** some useful macros
+#** ===============================================================
+#
proc lua_pop*(L: Plua_State, n: int)
proc lua_newtable*(L: Plua_state)
@@ -252,18 +255,20 @@ proc lua_pushliteral*(L: Plua_State, s: cstring)
proc lua_setglobal*(L: Plua_State, s: cstring)
proc lua_getglobal*(L: Plua_State, s: cstring)
proc lua_tostring*(L: Plua_State, i: int): cstring
- #
- #** compatibility macros and functions
- #
+#
+#** compatibility macros and functions
+#
proc lua_getregistry*(L: Plua_State)
proc lua_getgccount*(L: Plua_State): int
type
lua_Chunkreader* = lua_Reader
- lua_Chunkwriter* = lua_Writer #
- #** {======================================================================
- #** Debug API
- #** =======================================================================
- #
+ lua_Chunkwriter* = lua_Writer
+
+#
+#** {======================================================================
+#** Debug API
+#** =======================================================================
+#
const
LUA_HOOKCALL* = 0
@@ -297,11 +302,13 @@ type
i_ci*: int # active function
Plua_Debug* = ptr lua_Debug
- lua_Hook* = proc (L: Plua_State, ar: Plua_Debug){.cdecl.} #
- #** {======================================================================
- #** Debug API
- #** =======================================================================
- #
+ lua_Hook* = proc (L: Plua_State, ar: Plua_Debug){.cdecl.}
+
+#
+#** {======================================================================
+#** Debug API
+#** =======================================================================
+#
proc lua_getstack*(L: Plua_State, level: int, ar: Plua_Debug): int{.cdecl,
dynlib: LUA_NAME, importc.}
diff --git a/rod/ast.nim b/rod/ast.nim
index 90865fb788..0de61f4679 100755
--- a/rod/ast.nim
+++ b/rod/ast.nim
@@ -303,10 +303,10 @@ type
mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray,
mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref,
mGCunref, mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
- mDivI64, mModI64, mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI,
- mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, mMaxI64,
+ mDivI64, mModI64,
mAddF64, mSubF64, mMulF64, mDivF64,
-
+ mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI,
+ mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, mMaxI64,
mMinF64, mMaxF64, mAddU, mSubU, mMulU,
mDivU, mModU, mAddU64, mSubU64, mMulU64, mDivU64, mModU64, mEqI, mLeI, mLtI,
mEqI64, mLeI64, mLtI64, mEqF64, mLeF64, mLtF64, mLeU, mLtU, mLeU64, mLtU64,
diff --git a/rod/ccgexprs.nim b/rod/ccgexprs.nim
index f79a87ce43..cd02cad977 100755
--- a/rod/ccgexprs.nim
+++ b/rod/ccgexprs.nim
@@ -118,7 +118,8 @@ proc genRawSetData(cs: TBitSet, size: int): PRope =
frmt = "0x$1}$n"
appf(result, frmt, [toRope(toHex(Ze64(cs[i]), 2))])
else:
- result = intLiteral(bitSetToWord(cs, size)) # result := toRope('0x' + ToHex(bitSetToWord(cs, size), size * 2))
+ result = intLiteral(bitSetToWord(cs, size))
+ # result := toRope('0x' + ToHex(bitSetToWord(cs, size), size * 2))
proc genSetNode(p: BProc, n: PNode): PRope =
var
@@ -384,14 +385,12 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
"modInt64"]
opr: array[mAddi..mModi64, string] = ["+", "-", "*", "/", "%", "+", "-",
"*", "/", "%"]
- var
- a, b: TLoc
- t: PType
+ var a, b: TLoc
assert(e.sons[1].typ != nil)
assert(e.sons[2].typ != nil)
InitLocExpr(p, e.sons[1], a)
InitLocExpr(p, e.sons[2], b)
- t = skipTypes(e.typ, abstractRange)
+ var t = skipTypes(e.typ, abstractRange)
if getSize(t) >= platform.IntSize:
if optOverflowCheck in p.options:
useMagic(p.module, prc[m])
@@ -437,8 +436,12 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
const
- binArithTab: array[mShrI..mXor, string] = ["(NI$3)((NU$3)($1) >> (NU$3)($2))", #
- # ShrI
+ binArithTab: array[mAddF64..mXor, string] = [
+ "($1 + $2)", # AddF64
+ "($1 - $2)", # SubF64
+ "($1 * $2)", # MulF64
+ "($1 / $2)", # DivF64
+ "(NI$3)((NU$3)($1) >> (NU$3)($2))", # ShrI
"(NI$3)((NU$3)($1) << (NU$3)($2))", # ShlI
"(NI$3)($1 & $2)", # BitandI
"(NI$3)($1 | $2)", # BitorI
@@ -452,10 +455,6 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
"($1 ^ $2)", # BitxorI64
"(($1 <= $2) ? $1 : $2)", # MinI64
"(($1 >= $2) ? $1 : $2)", # MaxI64
- "($1 + $2)", # AddF64
- "($1 - $2)", # SubF64
- "($1 * $2)", # MulF64
- "($1 / $2)", # DivF64
"(($1 <= $2) ? $1 : $2)", # MinF64
"(($1 >= $2) ? $1 : $2)", # MaxF64
"(NI$3)((NU$3)($1) + (NU$3)($2))", # AddU
@@ -503,7 +502,8 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
assert(e.sons[1].typ != nil)
assert(e.sons[2].typ != nil)
InitLocExpr(p, e.sons[1], a)
- InitLocExpr(p, e.sons[2], b) # BUGFIX: cannot use result-type here, as it may be a boolean
+ InitLocExpr(p, e.sons[2], b)
+ # BUGFIX: cannot use result-type here, as it may be a boolean
s = max(getSize(a.t), getSize(b.t)) * 8
putIntoDest(p, d, e.typ,
ropef(binArithTab[op], [rdLoc(a), rdLoc(b), toRope(s)]))
@@ -672,14 +672,12 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
genRecordField(p, e.sons[0], d)
proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
- var
- a, b: TLoc
- ty: PType
- first: PRope
+ var a, b: TLoc
initLocExpr(p, e.sons[0], a)
initLocExpr(p, e.sons[1], b)
- ty = skipTypes(skipTypes(a.t, abstractVarRange), abstractPtrs)
- first = intLiteral(firstOrd(ty)) # emit range check:
+ var ty = skipTypes(skipTypes(a.t, abstractVarRange), abstractPtrs)
+ var first = intLiteral(firstOrd(ty))
+ # emit range check:
if (optBoundsCheck in p.options):
if not isConstExpr(e.sons[1]):
# semantic pass has already checked for const index expressions
@@ -696,12 +694,10 @@ proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
ropef("$1[($2)-$3]", [rdLoc(a), rdCharLoc(b), first]))
proc genCStringElem(p: BProc, e: PNode, d: var TLoc) =
- var
- a, b: TLoc
- ty: PType
+ var a, b: TLoc
initLocExpr(p, e.sons[0], a)
initLocExpr(p, e.sons[1], b)
- ty = skipTypes(a.t, abstractVarRange)
+ var ty = skipTypes(a.t, abstractVarRange)
if d.k == locNone: d.s = a.s
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
ropef("$1[$2]", [rdLoc(a), rdCharLoc(b)]))
@@ -719,12 +715,10 @@ proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) =
ropef("$1[$2]", [rdLoc(a), rdCharLoc(b)]))
proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) =
- var
- a, b: TLoc
- ty: PType
+ var a, b: TLoc
initLocExpr(p, e.sons[0], a)
initLocExpr(p, e.sons[1], b)
- ty = skipTypes(a.t, abstractVarRange)
+ var ty = skipTypes(a.t, abstractVarRange)
if ty.kind in {tyRef, tyPtr}:
ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check:
if (optBoundsCheck in p.options):
@@ -770,7 +764,7 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
getTemp(p, e.typ, tmp) # force it into a temp!
expr(p, e.sons[1], tmp)
L = getLabel(p)
- if m == mOr: # mAnd:
+ if m == mOr:
appf(p.s[cpsStmts], "if ($1) goto $2;$n", [rdLoc(tmp), L])
else:
appf(p.s[cpsStmts], "if (!($1)) goto $2;$n", [rdLoc(tmp), L])
@@ -888,15 +882,12 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
# appendChar(tmp0, 'z');
# asgn(s, tmp0);
# }
- var
- a, tmp: TLoc
- appends, lens: PRope
- L: int
+ var a, tmp: TLoc
useMagic(p.module, "rawNewString")
getTemp(p, e.typ, tmp)
- L = 0
- appends = nil
- lens = nil
+ var L = 0
+ var appends: PRope = nil
+ var lens: PRope = nil
for i in countup(0, sonsLen(e) - 2):
# compute the length expression:
initLocExpr(p, e.sons[i + 1], a)
@@ -1060,8 +1051,9 @@ proc genNewFinalize(p: BProc, e: PNode) =
oldModule: BModule
useMagic(p.module, "newObj")
refType = skipTypes(e.sons[1].typ, abstractVarRange)
- InitLocExpr(p, e.sons[1], a) # This is a little hack:
- # XXX this is also a bug, if the finalizer expression produces side-effects
+ InitLocExpr(p, e.sons[1], a)
+ # This is a little hack:
+ # XXX this is also a bug, if the finalizer expression produces side-effects
oldModule = p.module
p.module = gNimDat
InitLocExpr(p, e.sons[2], f)
@@ -1076,11 +1068,9 @@ proc genNewFinalize(p: BProc, e: PNode) =
genObjectInit(p, bt, a, false)
proc genRepr(p: BProc, e: PNode, d: var TLoc) =
- var
- a: TLoc
- t: PType
+ var a: TLoc
InitLocExpr(p, e.sons[1], a)
- t = skipTypes(e.sons[1].typ, abstractVarRange)
+ var t = skipTypes(e.sons[1].typ, abstractVarRange)
case t.kind
of tyInt..tyInt64:
UseMagic(p.module, "reprInt")
@@ -1108,8 +1098,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
of tyOpenArray:
useMagic(p.module, "reprOpenArray")
case a.t.kind
- of tyOpenArray:
- putIntoDest(p, d, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
+ of tyOpenArray: putIntoDest(p, d, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
of tyString, tySequence:
putIntoDest(p, d, e.typ, ropef("$1->data, $1->Sup.len", [rdLoc(a)]))
of tyArray, tyArrayConstr:
@@ -1137,8 +1126,7 @@ proc genDollar(p: BProc, n: PNode, d: var TLoc, magic, frmt: string) =
genAssignment(p, d, a, {})
proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
- var typ: PType
- typ = skipTypes(e.sons[1].Typ, abstractPtrs)
+ var typ = skipTypes(e.sons[1].Typ, abstractPtrs)
case typ.kind
of tyOpenArray:
while e.sons[1].kind == nkPassAsOpenArray: e.sons[1] = e.sons[1].sons[0]
@@ -1157,14 +1145,12 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
else: InternalError(e.info, "genArrayLen()")
proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
- var
- a, b: TLoc
- t: PType
+ var a, b: TLoc
assert(d.k == locNone)
useMagic(p.module, "setLengthSeq")
InitLocExpr(p, e.sons[1], a)
InitLocExpr(p, e.sons[2], b)
- t = skipTypes(e.sons[1].typ, abstractVar)
+ var t = skipTypes(e.sons[1].typ, abstractVar)
appf(p.s[cpsStmts], "$1 = ($3) setLengthSeq(&($1)->Sup, sizeof($4), $2);$n", [
rdLoc(a), rdLoc(b), getTypeDesc(p.module, t),
getTypeDesc(p.module, t.sons[0])])
@@ -1202,8 +1188,7 @@ proc fewCmps(s: PNode): bool =
elif elemType(s.typ).Kind in {tyInt, tyInt16..tyInt64}:
result = true # better not emit the set if int is basetype!
else:
- result = sonsLen(s) <=
- 8 # 8 seems to be a good value
+ result = sonsLen(s) <= 8 # 8 seems to be a good value
proc binaryExprIn(p: BProc, e: PNode, a, b, d: var TLoc, frmt: string) =
putIntoDest(p, d, e.typ, ropef(frmt, [rdLoc(a), rdSetElemLoc(b, a.t)]))
@@ -1224,16 +1209,14 @@ proc binaryStmtInExcl(p: BProc, e: PNode, d: var TLoc, frmt: string) =
appf(p.s[cpsStmts], frmt, [rdLoc(a), rdSetElemLoc(b, a.t)])
proc genInOp(p: BProc, e: PNode, d: var TLoc) =
- var
- a, b, x, y: TLoc
- length: int
+ var a, b, x, y: TLoc
if (e.sons[1].Kind == nkCurly) and fewCmps(e.sons[1]):
# a set constructor but not a constant set:
# do not emit the set, but generate a bunch of comparisons
initLocExpr(p, e.sons[2], a)
initLoc(b, locExpr, e.typ, OnUnknown)
b.r = toRope("(")
- length = sonsLen(e.sons[1])
+ var length = sonsLen(e.sons[1])
for i in countup(0, length - 1):
if e.sons[1].sons[i].Kind == nkRange:
InitLocExpr(p, e.sons[1].sons[i].sons[0], x)
@@ -1255,56 +1238,45 @@ proc genInOp(p: BProc, e: PNode, d: var TLoc) =
proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
const
- lookupOpr: array[mLeSet..mSymDiffSet, string] = ["for ($1 = 0; $1 < $2; $1++) { $n" &
- " $3 = (($4[$1] & ~ $5[$1]) == 0);$n" & " if (!$3) break;}$n", "for ($1 = 0; $1 < $2; $1++) { $n" &
+ lookupOpr: array[mLeSet..mSymDiffSet, string] = [
+ "for ($1 = 0; $1 < $2; $1++) { $n" &
+ " $3 = (($4[$1] & ~ $5[$1]) == 0);$n" &
+ " if (!$3) break;}$n", "for ($1 = 0; $1 < $2; $1++) { $n" &
" $3 = (($4[$1] & ~ $5[$1]) == 0);$n" & " if (!$3) break;}$n" &
- "if ($3) $3 = (memcmp($4, $5, $2) != 0);$n", "&", "|", "& ~", "^"]
- var
- size: int
- setType: PType
- a, b, i: TLoc
- ts: string
- setType = skipTypes(e.sons[1].Typ, abstractVar)
- size = int(getSize(setType))
+ "if ($3) $3 = (memcmp($4, $5, $2) != 0);$n",
+ "&", "|", "& ~", "^"]
+ var a, b, i: TLoc
+ var setType = skipTypes(e.sons[1].Typ, abstractVar)
+ var size = int(getSize(setType))
case size
of 1, 2, 4, 8:
case op
of mIncl:
- ts = "NI" & $(size * 8)
+ var ts = "NI" & $(size * 8)
binaryStmtInExcl(p, e, d,
"$1 |=(1<<((" & ts & ")($2)%(sizeof(" & ts & ")*8)));$n")
of mExcl:
- ts = "NI" & $(size * 8)
+ var ts = "NI" & $(size * 8)
binaryStmtInExcl(p, e, d, "$1 &= ~(1 << ((" & ts & ")($2) % (sizeof(" &
ts & ")*8)));$n")
of mCard:
if size <= 4: unaryExprChar(p, e, d, "countBits32", "countBits32($1)")
else: unaryExprChar(p, e, d, "countBits64", "countBits64($1)")
- of mLtSet:
- binaryExprChar(p, e, d, "", "(($1 & ~ $2 ==0)&&($1 != $2))")
- of mLeSet:
- binaryExprChar(p, e, d, "", "(($1 & ~ $2)==0)")
- of mEqSet:
- binaryExpr(p, e, d, "", "($1 == $2)")
- of mMulSet:
- binaryExpr(p, e, d, "", "($1 & $2)")
- of mPlusSet:
- binaryExpr(p, e, d, "", "($1 | $2)")
- of mMinusSet:
- binaryExpr(p, e, d, "", "($1 & ~ $2)")
- of mSymDiffSet:
- binaryExpr(p, e, d, "", "($1 ^ $2)")
+ of mLtSet: binaryExprChar(p, e, d, "", "(($1 & ~ $2 ==0)&&($1 != $2))")
+ of mLeSet: binaryExprChar(p, e, d, "", "(($1 & ~ $2)==0)")
+ of mEqSet: binaryExpr(p, e, d, "", "($1 == $2)")
+ of mMulSet: binaryExpr(p, e, d, "", "($1 & $2)")
+ of mPlusSet: binaryExpr(p, e, d, "", "($1 | $2)")
+ of mMinusSet: binaryExpr(p, e, d, "", "($1 & ~ $2)")
+ of mSymDiffSet: binaryExpr(p, e, d, "", "($1 ^ $2)")
of mInSet:
genInOp(p, e, d)
else: internalError(e.info, "genSetOp()")
else:
case op
- of mIncl:
- binaryStmtInExcl(p, e, d, "$1[$2/8] |=(1<<($2%8));$n")
- of mExcl:
- binaryStmtInExcl(p, e, d, "$1[$2/8] &= ~(1<<($2%8));$n")
- of mCard:
- unaryExprChar(p, e, d, "cardSet", "cardSet($1, " & $(size) & ')')
+ of mIncl: binaryStmtInExcl(p, e, d, "$1[$2/8] |=(1<<($2%8));$n")
+ of mExcl: binaryStmtInExcl(p, e, d, "$1[$2/8] &= ~(1<<($2%8));$n")
+ of mCard: unaryExprChar(p, e, d, "cardSet", "cardSet($1, " & $size & ')')
of mLtSet, mLeSet:
getTemp(p, getSysType(tyInt), i) # our counter
initLocExpr(p, e.sons[1], a)
@@ -1324,8 +1296,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
"for ($1 = 0; $1 < $2; $1++) $n" & " $3[$1] = $4[$1] $6 $5[$1];$n", [
rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b),
toRope(lookupOpr[op])])
- of mInSet:
- genInOp(p, e, d)
+ of mInSet: genInOp(p, e, d)
else: internalError(e.info, "genSetOp")
proc genOrd(p: BProc, e: PNode, d: var TLoc) =
@@ -1347,10 +1318,8 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) =
[getTypeDesc(p.module, e.typ), rdCharLoc(a)]))
proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
- var
- a: TLoc
- dest: PType
- dest = skipTypes(n.typ, abstractVar)
+ var a: TLoc
+ var dest = skipTypes(n.typ, abstractVar)
if not (optRangeCheck in p.options):
InitLocExpr(p, n.sons[0], a)
putIntoDest(p, d, n.typ, ropef("(($1) ($2))",
@@ -1367,12 +1336,10 @@ proc genConv(p: BProc, e: PNode, d: var TLoc) =
genCast(p, e, d)
proc passToOpenArray(p: BProc, n: PNode, d: var TLoc) =
- var
- a: TLoc
- dest: PType
+ var a: TLoc
while n.sons[0].kind == nkPassAsOpenArray:
n.sons[0] = n.sons[0].sons[0] # BUGFIX
- dest = skipTypes(n.typ, abstractVar)
+ var dest = skipTypes(n.typ, abstractVar)
case skipTypes(n.sons[0].typ, abstractVar).kind
of tyOpenArray:
initLocExpr(p, n.sons[0], a)
@@ -1398,11 +1365,9 @@ proc convCStrToStr(p: BProc, n: PNode, d: var TLoc) =
ropef("cstrToNimstr($1)", [rdLoc(a)]))
proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
- var
- a, b: PNode
- x: TLoc
- a = e.sons[1]
- b = e.sons[2]
+ var x: TLoc
+ var a = e.sons[1]
+ var b = e.sons[2]
if (a.kind == nkNilLit) or (b.kind == nkNilLit):
binaryExpr(p, e, d, "", "($1 == $2)")
elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""):
@@ -1431,9 +1396,7 @@ proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) =
expr(p, t.sons[i], arr)
proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
- var
- newSeq, elem, a, arr: TLoc
- L: int
+ var newSeq, elem, a, arr: TLoc
if t.kind == nkBracket:
t.sons[1].typ = t.typ
genSeqConstr(p, t.sons[1], d)
@@ -1442,7 +1405,7 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
if d.k == locNone:
getTemp(p, t.typ, d)
# generate call to newSeq before adding the elements per hand:
- L = int(lengthOrd(t.sons[1].typ))
+ var L = int(lengthOrd(t.sons[1].typ))
initLoc(newSeq, locExpr, t.typ, OnHeap)
newSeq.r = ropef("($1) newSeq($2, $3)", [getTypeDesc(p.module, t.typ),
genTypeInfo(p.module, t.typ), intLiteral(L)])
@@ -1451,17 +1414,37 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
for i in countup(0, L - 1):
initLoc(elem, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap)
elem.r = ropef("$1->data[$2]", [rdLoc(d), intLiteral(i)])
- elem.s = OnHeap # we know that sequences are on the heap
+ elem.s = OnHeap # we know that sequences are on the heap
initLoc(arr, locExpr, elemType(skipTypes(t.sons[1].typ, abstractInst)), a.s)
arr.r = ropef("$1[$2]", [rdLoc(a), intLiteral(i)])
genAssignment(p, elem, arr, {afDestIsNil, needToCopy})
+proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
+ if {optNanCheck, optInfCheck} * p.options != {}:
+ const opr: array[mAddF64..mDivF64, string] = ["+", "-", "*", "/"]
+ var a, b: TLoc
+ assert(e.sons[1].typ != nil)
+ assert(e.sons[2].typ != nil)
+ InitLocExpr(p, e.sons[1], a)
+ InitLocExpr(p, e.sons[2], b)
+ putIntoDest(p, d, e.typ, ropef("($2 $1 $3)", [
+ toRope(opr[m]), rdLoc(a), rdLoc(b)]))
+ if optNanCheck in p.options:
+ useMagic(p.module, "nanCheck")
+ appf(p.s[cpsStmts], "nanCheck($1);$n", [rdLoc(d)])
+ if optInfCheck in p.options:
+ useMagic(p.module, "infCheck")
+ appf(p.s[cpsStmts], "infCheck($1);$n", [rdLoc(d)])
+ else:
+ binaryArith(p, e, d, m)
+
proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
var line, filen: PRope
case op
of mOr, mAnd: genAndOr(p, e, d, op)
of mNot..mToBiggestInt: unaryArith(p, e, d, op)
of mUnaryMinusI..mAbsI64: unaryArithOverflow(p, e, d, op)
+ of mAddF64..mDivF64: binaryFloatArith(p, e, d, op)
of mShrI..mXor: binaryArith(p, e, d, op)
of mAddi..mModi64: binaryArithOverflow(p, e, d, op)
of mRepr: genRepr(p, e, d)
diff --git a/rod/cgen.nim b/rod/cgen.nim
index 302a821ba8..a5f910f8a2 100755
--- a/rod/cgen.nim
+++ b/rod/cgen.nim
@@ -327,7 +327,7 @@ proc libCandidates(s: string, dest: var TStringSeq) =
if le >= 0 and ri > le:
var prefix = copy(s, 0, le - 1)
var suffix = copy(s, ri + 1)
- for middle in split(copy(s, le + 1, ri - 1), {'|'}):
+ for middle in split(copy(s, le + 1, ri - 1), '|'):
libCandidates(prefix & middle & suffix, dest)
else:
add(dest, s)
diff --git a/rod/commands.nim b/rod/commands.nim
index c080b23e36..881519756a 100755
--- a/rod/commands.nim
+++ b/rod/commands.nim
@@ -47,18 +47,20 @@ Options:
-d, --define:SYMBOL define a conditional symbol
-u, --undef:SYMBOL undefine a conditional symbol
-f, --forceBuild force rebuilding of all modules
- --symbolFiles:on|off use symbol files to speed up compilation (buggy!)
- --stackTrace:on|off code generation for stack trace ON|OFF
- --lineTrace:on|off code generation for line trace ON|OFF
- --debugger:on|off turn Embedded Nimrod Debugger ON|OFF
- -x, --checks:on|off code generation for all runtime checks ON|OFF
- --objChecks:on|off code generation for obj conversion checks ON|OFF
- --fieldChecks:on|off code generation for case variant fields ON|OFF
- --rangeChecks:on|off code generation for range checks ON|OFF
- --boundChecks:on|off code generation for bound checks ON|OFF
- --overflowChecks:on|off code generation for over-/underflow checks ON|OFF
- -a, --assertions:on|off code generation for assertions ON|OFF
- --deadCodeElim:on|off whole program dead code elimination ON|OFF
+ --stackTrace:on|off turn stack tracing on|off
+ --lineTrace:on|off turn line tracing on|off
+ --debugger:on|off turn Embedded Nimrod Debugger on|off
+ -x, --checks:on|off turn all runtime checks on|off
+ --objChecks:on|off turn obj conversion checks on|off
+ --fieldChecks:on|off turn case variant field checks on|off
+ --rangeChecks:on|off turn range checks on|off
+ --boundChecks:on|off turn bound checks on|off
+ --overflowChecks:on|off turn int over-/underflow checks on|off
+ -a, --assertions:on|off turn assertions on|off
+ --floatChecks:on|off turn all floating point (NaN/Inf) checks on|off
+ --nanChecks:on|off turn NaN checks on|off
+ --infChecks:on|off turn Inf checks on|off
+ --deadCodeElim:on|off whole program dead code elimination on|off
--opt:none|speed|size optimize not at all or for speed|size
--app:console|gui|lib generate a console|GUI application|dynamic library
-r, --run run the compiled program with given arguments
@@ -76,10 +78,10 @@ Advanced commands::
check checks the project for syntax and semantic
parse parses a single file (for debugging Nimrod)
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
+ -w, --warnings:on|off turn all warnings on|off
+ --warning[X]:on|off turn specific warning X on|off
+ --hints:on|off turn all hints on|off
+ --hint[X]:on|off turn specific hint X on|off
--lib:PATH set the system library path
-c, --compileOnly compile only; do not assemble or link
--noLinking compile but do not link
@@ -93,8 +95,8 @@ Advanced options:
-l, --passl:OPTION pass an option to the linker
--genMapping generate a mapping file containing
(Nimrod, mangled) identifier pairs
- --lineDir:on|off generation of #line directive ON|OFF
- --checkpoints:on|off turn on|off checkpoints; for debugging Nimrod
+ --lineDir:on|off generation of #line directive on|off
+ --checkpoints:on|off turn checkpoints on|off; for debugging Nimrod
--skipCfg do not read the general configuration file
--skipProjCfg do not read the project's configuration file
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
@@ -152,9 +154,8 @@ proc InvalidCmdLineOption(pass: TCmdLinePass, switch: string, info: TLineInfo) =
proc splitSwitch(switch: string, cmd, arg: var string, pass: TCmdLinePass,
info: TLineInfo) =
- var i: int
cmd = ""
- i = 0
+ var i = 0
if (i < len(switch) + 0) and (switch[i] == '-'): inc(i)
if (i < len(switch) + 0) and (switch[i] == '-'): inc(i)
while i < len(switch) + 0:
@@ -188,13 +189,9 @@ proc ExpectNoArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass,
info: TLineInfo) =
- var
- i, x: int
- n: TNoteKind
- id: string
- id = "" # arg = "X]:on|off"
- i = 0
- n = hintMin
+ var id = "" # arg = "X]:on|off"
+ var i = 0
+ var n = hintMin
while (i < len(arg) + 0) and (arg[i] != ']'):
add(id, arg[i])
inc(i)
@@ -203,11 +200,11 @@ proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass,
if (i < len(arg) + 0) and (arg[i] in {':', '='}): inc(i)
else: InvalidCmdLineOption(pass, arg, info)
if state == wHint:
- x = findStr(msgs.HintsToStr, id)
+ var x = findStr(msgs.HintsToStr, id)
if x >= 0: n = TNoteKind(x + ord(hintMin))
else: InvalidCmdLineOption(pass, arg, info)
else:
- x = findStr(msgs.WarningsToStr, id)
+ var x = findStr(msgs.WarningsToStr, id)
if x >= 0: n = TNoteKind(x + ord(warnMin))
else: InvalidCmdLineOption(pass, arg, info)
case whichKeyword(copy(arg, i))
@@ -297,6 +294,10 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
if optProfiler in gOptions: DefineSymbol("profiler")
else: UndefSymbol("profiler")
of wChecks, wX: ProcessOnOffSwitch(checksOptions, arg, pass, info)
+ of wFloatChecks:
+ ProcessOnOffSwitch({optNanCheck, optInfCheck}, arg, pass, info)
+ of wInfChecks: ProcessOnOffSwitch({optInfCheck}, arg, pass, info)
+ of wNanChecks: ProcessOnOffSwitch({optNanCheck}, arg, pass, info)
of wObjChecks: ProcessOnOffSwitch({optObjCheck}, arg, pass, info)
of wFieldChecks: ProcessOnOffSwitch({optFieldCheck}, arg, pass, info)
of wRangeChecks: ProcessOnOffSwitch({optRangeCheck}, arg, pass, info)
diff --git a/rod/condsyms.nim b/rod/condsyms.nim
index f3ce40003e..0325a2b77c 100755
--- a/rod/condsyms.nim
+++ b/rod/condsyms.nim
@@ -69,8 +69,9 @@ proc countDefinedSymbols(): int =
proc InitDefines() =
initStrTable(gSymbols)
- DefineSymbol("nimrod") # 'nimrod' is always defined
- # add platform specific symbols:
+ DefineSymbol("nimrod") # 'nimrod' is always defined
+
+ # add platform specific symbols:
case targetCPU
of cpuI386: DefineSymbol("x86")
of cpuIa64: DefineSymbol("itanium")
@@ -103,7 +104,7 @@ proc InitDefines() =
DefineSymbol("posix")
else:
nil
- DefineSymbol("cpu" & $(cpu[targetCPU].bit))
+ DefineSymbol("cpu" & $cpu[targetCPU].bit)
DefineSymbol(normalize(endianToStr[cpu[targetCPU].endian]))
DefineSymbol(cpu[targetCPU].name)
DefineSymbol(platform.os[targetOS].name)
diff --git a/rod/docgen.nim b/rod/docgen.nim
index 3a69f963c1..66580149bb 100755
--- a/rod/docgen.nim
+++ b/rod/docgen.nim
@@ -536,7 +536,7 @@ proc renderRstToRst(d: PDoc, n: PRstNode): PRope =
result = ropef("$n$n$1.. index::$n$2", [ind, result])
of rnContents:
result = ropef("$n$n$1.. contents::", [ind])
- else: rawMessage(errCannotRenderX, rstnodeKindToStr[n.kind])
+ else: rawMessage(errCannotRenderX, $n.kind)
proc renderTocEntry(d: PDoc, e: TTocEntry): PRope =
result = dispF("
$2$n",
@@ -582,16 +582,12 @@ proc renderImage(d: PDoc, n: PRstNode): PRope =
if rsonsLen(n) >= 3: app(result, renderRstToOut(d, n.sons[2]))
proc renderCodeBlock(d: PDoc, n: PRstNode): PRope =
- var
- m: PRstNode
- g: TGeneralTokenizer
- langstr: string
- lang: TSourceLanguage
result = nil
if n.sons[2] == nil: return
- m = n.sons[2].sons[0]
+ var m = n.sons[2].sons[0]
if (m.kind != rnLeaf): InternalError("renderCodeBlock")
- langstr = strip(getArgument(n))
+ var langstr = strip(getArgument(n))
+ var lang: TSourceLanguage
if langstr == "":
lang = langNimrod # default language
else:
@@ -600,12 +596,12 @@ proc renderCodeBlock(d: PDoc, n: PRstNode): PRope =
rawMessage(warnLanguageXNotSupported, langstr)
result = toRope(m.text)
else:
+ var g: TGeneralTokenizer
initGeneralTokenizer(g, m.text)
while true:
getNextToken(g, lang)
case g.kind
- of gtEof:
- break
+ of gtEof: break
of gtNone, gtWhitespace:
app(result, copy(m.text, g.start + 0, g.length + g.start - 1 + 0))
else:
diff --git a/rod/ecmasgen.nim b/rod/ecmasgen.nim
index 0243843b79..91acb98b2c 100755
--- a/rod/ecmasgen.nim
+++ b/rod/ecmasgen.nim
@@ -75,7 +75,7 @@ proc initCompRes(r: var TCompRes) =
proc initProc(p: var TProc, globals: PGlobals, module: BModule, procDef: PNode,
options: TOptions) =
- p.blocks = @ []
+ p.blocks = @[]
p.options = options
p.module = module
p.procDef = procDef
@@ -87,8 +87,7 @@ const
tySet, tyVar, tyRef, tyPtr}
proc mapType(typ: PType): TEcmasTypeKind =
- var t: PType
- t = skipTypes(typ, abstractInst)
+ var t = skipTypes(typ, abstractInst)
case t.kind
of tyVar, tyRef, tyPtr:
if skipTypes(t.sons[0], abstractInst).kind in mappedToObject:
@@ -98,29 +97,20 @@ proc mapType(typ: PType): TEcmasTypeKind =
of tyPointer:
# treat a tyPointer like a typed pointer to an array of bytes
result = etyInt
- of tyRange, tyDistinct, tyOrdinal:
- result = mapType(t.sons[0])
- of tyInt..tyInt64, tyEnum, tyChar:
- result = etyInt
- of tyBool:
- result = etyBool
- of tyFloat..tyFloat128:
- result = etyFloat
- of tySet:
- result = etyObject # map a set to a table
- of tyString, tySequence:
- result = etyInt # little hack to get the right semantics
+ of tyRange, tyDistinct, tyOrdinal: result = mapType(t.sons[0])
+ of tyInt..tyInt64, tyEnum, tyChar: result = etyInt
+ of tyBool: result = etyBool
+ of tyFloat..tyFloat128: result = etyFloat
+ of tySet: result = etyObject # map a set to a table
+ of tyString, tySequence: result = etyInt # little hack to get right semantics
of tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray:
result = etyObject
- of tyNil:
- result = etyNull
+ of tyNil: result = etyNull
of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, tyNone,
tyForward, tyEmpty, tyExpr, tyStmt, tyTypeDesc:
result = etyNone
- of tyProc:
- result = etyProc
- of tyCString:
- result = etyString
+ of tyProc: result = etyProc
+ of tyCString: result = etyString
proc mangle(name: string): string =
result = ""
@@ -132,7 +122,7 @@ proc mangle(name: string): string =
nil
of 'a'..'z', '0'..'9':
add(result, name[i])
- else: result = result & 'X' & toHex(ord(name[i]), 2)
+ else: add(result, 'X' & toHex(ord(name[i]), 2))
proc mangleName(s: PSym): PRope =
result = s.loc.r
@@ -199,9 +189,8 @@ proc genObjectFields(p: var TProc, typ: PType, n: PNode): PRope =
else: internalError(n.info, "genObjectFields")
proc genObjectInfo(p: var TProc, typ: PType, name: PRope) =
- var s: PRope
- s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
- "finalizer: null};$n", [name, toRope(ord(typ.kind))])
+ var s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
+ "finalizer: null};$n", [name, toRope(ord(typ.kind))])
prepend(p.globals.typeInfo, s)
appf(p.globals.typeInfo, "var NNI$1 = $2;$n",
[toRope(typ.id), genObjectFields(p, typ, typ.n)])
@@ -301,9 +290,9 @@ proc genOr(p: var TProc, a, b: PNode, r: var TCompRes) =
type
TMagicFrmt = array[0..3, string]
-const # magic checked op; magic unchecked op; checked op; unchecked op
- ops: array[mAddi..mStrToStr, TMagicFrmt] = [["addInt", "", "addInt($1, $2)",
- "($1 + $2)"], # AddI
+const # magic checked op; magic unchecked op; checked op; unchecked op
+ ops: array[mAddi..mStrToStr, TMagicFrmt] = [
+ ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # AddI
["subInt", "", "subInt($1, $2)", "($1 - $2)"], # SubI
["mulInt", "", "mulInt($1, $2)", "($1 * $2)"], # MulI
["divInt", "", "divInt($1, $2)", "Math.floor($1 / $2)"], # DivI
@@ -313,6 +302,10 @@ const # magic checked op; magic unchecked op; checked op
["mulInt64", "", "mulInt64($1, $2)", "($1 * $2)"], # MulI64
["divInt64", "", "divInt64($1, $2)", "Math.floor($1 / $2)"], # DivI64
["modInt64", "", "modInt64($1, $2)", "Math.floor($1 % $2)"], # ModI64
+ ["", "", "($1 + $2)", "($1 + $2)"], # AddF64
+ ["", "", "($1 - $2)", "($1 - $2)"], # SubF64
+ ["", "", "($1 * $2)", "($1 * $2)"], # MulF64
+ ["", "", "($1 / $2)", "($1 / $2)"], # DivF64
["", "", "($1 >>> $2)", "($1 >>> $2)"], # ShrI
["", "", "($1 << $2)", "($1 << $2)"], # ShlI
["", "", "($1 & $2)", "($1 & $2)"], # BitandI
@@ -327,10 +320,6 @@ const # magic checked op; magic unchecked op; checked op
["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI64
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinI64
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI64
- ["", "", "($1 + $2)", "($1 + $2)"], # AddF64
- ["", "", "($1 - $2)", "($1 - $2)"], # SubF64
- ["", "", "($1 * $2)", "($1 * $2)"], # MulF64
- ["", "", "($1 / $2)", "($1 / $2)"], # DivF64
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64
["AddU", "AddU", "AddU($1, $2)", "AddU($1, $2)"], # AddU
@@ -461,8 +450,8 @@ proc genLineDir(p: var TProc, n: PNode, r: var TCompRes) =
appf(r.com, "F.line = $1;$n", [toRope(line)])
proc finishTryStmt(p: var TProc, r: var TCompRes, howMany: int) =
- for i in countup(1, howMany): app(r.com, "excHandler = excHandler.prev;" &
- tnl)
+ for i in countup(1, howMany):
+ app(r.com, "excHandler = excHandler.prev;" & tnl)
proc genWhileStmt(p: var TProc, n: PNode, r: var TCompRes) =
var
diff --git a/rod/expand_importc.nim b/rod/expand_importc.nim
new file mode 100755
index 0000000000..da233df0bd
--- /dev/null
+++ b/rod/expand_importc.nim
@@ -0,0 +1,23 @@
+#
+#
+# The Nimrod Compiler
+# (c) Copyright 2009 Andreas Rumpf
+#
+# See the file "copying.txt", included in this
+# distribution, for details about the copyright.
+#
+
+## Simple tool to expand ``importc`` pragmas. Used for the clean up process of
+## the diverse wrappers.
+
+import
+ os, ropes, idents, ast, pnimsyn, rnimsyn
+
+ times, commands, scanner, condsyms, options, msgs, nversion, nimconf, ropes,
+ extccomp, strutils, os, platform, main, parseopt
+
+if paramcount() == 0:
+ echo ""
+
+
+
diff --git a/rod/importer.nim b/rod/importer.nim
index 4b40ea8f8b..608bad0662 100755
--- a/rod/importer.nim
+++ b/rod/importer.nim
@@ -1,7 +1,7 @@
#
#
# The Nimrod Compiler
-# (c) Copyright 2008 Andreas Rumpf
+# (c) Copyright 2009 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@@ -37,15 +37,11 @@ proc getModuleFile(n: PNode): string =
result = ""
proc rawImportSymbol(c: PContext, s: PSym) =
- var
- check, copy, e: PSym
- etyp: PType # enumeration type
- it: TIdentIter
# This does not handle stubs, because otherwise loading on demand would be
# pointless in practice. So importing stubs is fine here!
- copy = s # do not copy symbols when importing!
+ var copy = s # do not copy symbols when importing!
# check if we have already a symbol of the same name:
- check = StrTableGet(c.tab.stack[importTablePos], s.name)
+ var check = StrTableGet(c.tab.stack[importTablePos], s.name)
if (check != nil) and (check.id != copy.id):
if not (s.kind in OverloadableSyms):
# s and check need to be qualified:
@@ -53,15 +49,16 @@ proc rawImportSymbol(c: PContext, s: PSym) =
IntSetIncl(c.AmbiguousSymbols, check.id)
StrTableAdd(c.tab.stack[importTablePos], copy)
if s.kind == skType:
- etyp = s.typ
+ var etyp = s.typ
if etyp.kind in {tyBool, tyEnum}:
for j in countup(0, sonsLen(etyp.n) - 1):
- e = etyp.n.sons[j].sym
+ var e = etyp.n.sons[j].sym
if (e.Kind != skEnumField):
InternalError(s.info, "rawImportSymbol")
# BUGFIX: because of aliases for enums the symbol may already
# have been put into the symbol table
# BUGFIX: but only iff they are the same symbols!
+ var it: TIdentIter
check = InitIdentIter(it, c.tab.stack[importTablePos], e.name)
while check != nil:
if check.id == e.id:
@@ -74,11 +71,8 @@ proc rawImportSymbol(c: PContext, s: PSym) =
addConverter(c, s) # rodgen assures that converters are no stubs
proc importSymbol(c: PContext, ident: PNode, fromMod: PSym) =
- var
- s, e: PSym
- it: TIdentIter
if (ident.kind != nkIdent): InternalError(ident.info, "importSymbol")
- s = StrTableGet(fromMod.tab, ident.ident)
+ var s = StrTableGet(fromMod.tab, ident.ident)
if s == nil: liMessage(ident.info, errUndeclaredIdentifier, ident.ident.s)
if s.kind == skStub: loadStub(s)
if not (s.Kind in ExportableSymKinds):
@@ -87,7 +81,8 @@ proc importSymbol(c: PContext, ident: PNode, fromMod: PSym) =
case s.Kind
of skProc, skMethod, skIterator, skMacro, skTemplate, skConverter:
# for a overloadable syms add all overloaded routines
- e = InitIdentIter(it, fromMod.tab, s.name)
+ var it: TIdentIter
+ var e = InitIdentIter(it, fromMod.tab, s.name)
while e != nil:
if (e.name.id != s.Name.id): InternalError(ident.info, "importSymbol: 3")
rawImportSymbol(c, e)
diff --git a/rod/main.nim b/rod/main.nim
index 65369b570f..c5390ba00c 100755
--- a/rod/main.nim
+++ b/rod/main.nim
@@ -31,8 +31,7 @@ var compMods: TFileModuleMap = @ []
proc registerModule(filename: string, module: PSym) =
# all compiled modules
- var length: int
- length = len(compMods)
+ var length = len(compMods)
setlen(compMods, length + 1)
compMods[length].filename = filename
compMods[length].module = module
@@ -50,6 +49,9 @@ proc newModule(filename: string): PSym =
result.id = - 1 # for better error checking
result.kind = skModule
result.name = getIdent(splitFile(filename).name)
+ if not isNimrodIdentifier(result.name.s):
+ rawMessage(errIdentifierExpected, result.name.s)
+
result.owner = result # a module belongs to itself
result.info = newLineInfo(filename, 1, 1)
incl(result.flags, sfUsed)
@@ -68,11 +70,8 @@ proc importModule(filename: string): PSym =
liMessage(result.info, errAttemptToRedefine, result.Name.s)
proc CompileModule(filename: string, isMainFile, isSystemFile: bool): PSym =
- var
- rd: PRodReader
- f: string
- rd = nil
- f = addFileExt(filename, nimExt)
+ var rd: PRodReader = nil
+ var f = addFileExt(filename, nimExt)
result = newModule(filename)
if isMainFile: incl(result.flags, sfMainModule)
if isSystemFile: incl(result.flags, sfSystemModule)
diff --git a/rod/nimrod.cfg b/rod/nimrod.cfg
index 51b675525e..0c286472bc 100755
--- a/rod/nimrod.cfg
+++ b/rod/nimrod.cfg
@@ -9,3 +9,4 @@
@elif vcc:
# cgen.speed = ""
@end
+
diff --git a/rod/nimrod.nim b/rod/nimrod.nim
index 950c687e05..b5ed532c93 100755
--- a/rod/nimrod.nim
+++ b/rod/nimrod.nim
@@ -17,11 +17,7 @@ var
cmdLineInfo: TLineInfo
proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
- var
- p: TOptParser
- bracketLe: int
- key, val: string
- p = parseopt.init()
+ var p = parseopt.init()
while true:
parseopt.next(p)
case p.kind
@@ -30,10 +26,10 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
of cmdLongOption, cmdShortOption:
# hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
# we fix this here
- bracketLe = strutils.find(p.key, '[')
+ var bracketLe = strutils.find(p.key, '[')
if bracketLe >= 0:
- key = copy(p.key, 0, bracketLe - 1)
- val = copy(p.key, bracketLe + 1) & ':' & p.val
+ var key = copy(p.key, 0, bracketLe - 1)
+ var val = copy(p.key, bracketLe + 1) & ':' & p.val
ProcessSwitch(key, val, pass, cmdLineInfo)
else:
ProcessSwitch(p.key, p.val, pass, cmdLineInfo)
@@ -49,21 +45,18 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
rawMessage(errArgsNeedRunOption)
proc HandleCmdLine() =
- var
- command, filename, prog: string
- start: TTime
- start = getTime()
+ var start = getTime()
if paramCount() == 0:
writeCommandLineUsage()
else:
# Process command line arguments:
- command = ""
- filename = ""
+ var command = ""
+ var filename = ""
ProcessCmdLine(passCmd1, command, filename)
if filename != "": options.projectPath = splitFile(filename).dir
nimconf.LoadConfig(filename) # load the right config file
- # now process command line arguments again, because some options in the
- # command line can overwite the config file's settings
+ # now process command line arguments again, because some options in the
+ # command line can overwite the config file's settings
extccomp.initVars()
command = ""
filename = ""
@@ -74,16 +67,12 @@ proc HandleCmdLine() =
rawMessage(hintSuccessX, [$(gLinesCompiled), $(getTime() - start)])
if optRun in gGlobalOptions:
when defined(unix):
- prog = "./" & quoteIfContainsWhite(changeFileExt(filename, ""))
+ var prog = "./" & quoteIfContainsWhite(changeFileExt(filename, ""))
else:
- prog = quoteIfContainsWhite(changeFileExt(filename, ""))
+ var prog = quoteIfContainsWhite(changeFileExt(filename, ""))
execExternalProgram(prog & ' ' & arguments)
-#{@emit
-# GC_disableMarkAndSweep();
-#}
-
cmdLineInfo = newLineInfo("command line", - 1, - 1)
condsyms.InitDefines()
HandleCmdLine()
-quit(options.gExitcode)
\ No newline at end of file
+quit(options.gExitcode)
diff --git a/rod/options.nim b/rod/options.nim
index 69c8692631..15bca38b60 100755
--- a/rod/options.nim
+++ b/rod/options.nim
@@ -14,11 +14,14 @@ type # please make sure we have under 32 options
# (improves code efficiency a lot!)
TOption* = enum # **keep binary compatible**
optNone, optObjCheck, optFieldCheck, optRangeCheck, optBoundsCheck,
- optOverflowCheck, optNilCheck, optAssert, optLineDir, optWarns, optHints,
+ optOverflowCheck, optNilCheck,
+ optNaNCheck, optInfCheck,
+ optAssert, optLineDir, optWarns, optHints,
optOptimizeSpeed, optOptimizeSize, optStackTrace, # stack tracing support
optLineTrace, # line tracing support (includes stack tracing)
optEndb, # embedded debugger
- optByRef, # use pass by ref for objects (for interfacing with C)
+ optByRef, # use pass by ref for objects
+ # (for interfacing with C)
optCheckpoints, # check for checkpoints (used for debugging)
optProfiler # profiler turned on
TOptions* = set[TOption]
@@ -50,12 +53,7 @@ type # please make sure we have under 32 options
const
ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck,
- optOverflowCheck, optBoundsCheck, optAssert}
- optionToStr*: array[TOption, string] = ["optNone", "optObjCheck",
- "optFieldCheck", "optRangeCheck", "optBoundsCheck", "optOverflowCheck",
- "optNilCheck", "optAssert", "optLineDir", "optWarns", "optHints",
- "optOptimizeSpeed", "optOptimizeSize", "optStackTrace", "optLineTrace",
- "optEmdb", "optByRef", "optCheckpoints", "optProfiler"]
+ optOverflowCheck, optBoundsCheck, optAssert, optNaNCheck, optInfCheck}
var
gOptions*: TOptions = {optObjCheck, optFieldCheck, optRangeCheck,
diff --git a/rod/pragmas.nim b/rod/pragmas.nim
index 71ff3db228..050c0bc061 100755
--- a/rod/pragmas.nim
+++ b/rod/pragmas.nim
@@ -32,7 +32,8 @@ const
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir,
wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal,
wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop, wBreakpoint,
- wCheckpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated}
+ wCheckpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated, wFloatChecks,
+ wInfChecks, wNanChecks}
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure, wDeprecated}
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
@@ -220,6 +221,9 @@ proc processOption(c: PContext, n: PNode) =
of wBoundchecks: OnOff(c, n, {optBoundsCheck})
of wOverflowchecks: OnOff(c, n, {optOverflowCheck})
of wNilchecks: OnOff(c, n, {optNilCheck})
+ of wFloatChecks: OnOff(c, n, {optNanCheck, optInfCheck})
+ of wNaNchecks: OnOff(c, n, {optNanCheck})
+ of wInfChecks: OnOff(c, n, {optInfCheck})
of wAssertions: OnOff(c, n, {optAssert})
of wWarnings: OnOff(c, n, {optWarns})
of wHints: OnOff(c, n, {optHints})
@@ -434,7 +438,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks,
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
wLinedir, wStacktrace, wLinetrace, wOptimization, wByRef, wCallConv,
- wDebugger, wProfiler:
+ wDebugger, wProfiler, wFloatChecks, wNanChecks, wInfChecks:
processOption(c, it) # calling conventions (boring...):
of firstCallConv..lastCallConv:
assert(sym != nil)
diff --git a/rod/rst.nim b/rod/rst.nim
index 18ee3c78ef..925794584b 100755
--- a/rod/rst.nim
+++ b/rod/rst.nim
@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
-# This module implements a *reStructuredText* parser. A larget
+# This module implements a *reStructuredText* parser. A large
# subset is provided.
import
@@ -33,25 +33,17 @@ type
rnFieldName, # consisting of a field name ...
rnFieldBody, # ... and a field body
rnOptionList, rnOptionListItem, rnOptionGroup, rnOption, rnOptionString,
- rnOptionArgument, rnDescription, rnLiteralBlock, rnQuotedLiteralBlock, rnLineBlock, #
- # the
- # |
- # thingie
+ rnOptionArgument, rnDescription, rnLiteralBlock, rnQuotedLiteralBlock,
+ rnLineBlock, # the | thingie
rnLineBlockItem, # sons of the | thing
rnBlockQuote, # text just indented
- rnTable, rnGridTable, rnTableRow, rnTableHeaderCell, rnTableDataCell, rnLabel, #
- # used
- # for
- # footnotes
- # and
- # other
- # things
+ rnTable, rnGridTable, rnTableRow, rnTableHeaderCell, rnTableDataCell,
+ rnLabel, # used for footnotes and other things
rnFootnote, # a footnote
rnCitation, # similar to footnote
rnStandaloneHyperlink, rnHyperlink, rnRef, rnDirective, # a directive
- rnDirArg, rnRaw, rnTitle, rnContents, rnImage, rnFigure, rnCodeBlock, rnContainer, #
- # ``container``
- # directive
+ rnDirArg, rnRaw, rnTitle, rnContents, rnImage, rnFigure, rnCodeBlock,
+ rnContainer, # ``container`` directive
rnIndex, # index directve:
# .. index::
# key
@@ -64,22 +56,8 @@ type
rnInterpretedText, # "`"
rnInlineLiteral, # "``"
rnSubstitutionReferences, # "|"
- rnLeaf # a leaf; the node's text field contains the leaf val
-
-const
- rstnodekindToStr*: array[TRstNodeKind, string] = ["Inner", "Headline",
- "Overline", "Transition", "Paragraph", "BulletList", "BulletItem",
- "EnumList", "EnumItem", "DefList", "DefItem", "DefName", "DefBody",
- "FieldList", "Field", "FieldName", "FieldBody", "OptionList",
- "OptionListItem", "OptionGroup", "Option", "OptionString", "OptionArgument",
- "Description", "LiteralBlock", "QuotedLiteralBlock", "LineBlock",
- "LineBlockItem", "BlockQuote", "Table", "GridTable", "TableRow",
- "TableHeaderCell", "TableDataCell", "Label", "Footnote", "Citation",
- "StandaloneHyperlink", "Hyperlink", "Ref", "Directive", "DirArg", "Raw",
- "Title", "Contents", "Image", "Figure", "CodeBlock", "Container", "Index",
- "SubstitutionDef", "GeneralRole", "Sub", "Sup", "Idx", "Emphasis",
- "StrongEmphasis", "InterpretedText", "InlineLiteral",
- "SubstitutionReferences", "Leaf"]
+ rnLeaf # a leaf; the node's text field contains the
+ # leaf val
type # the syntax tree of RST:
PRSTNode* = ref TRstNode
@@ -513,7 +491,6 @@ proc clearIndex(index: PRstNode, filename: string) =
proc setIndexPair(index, key, val: PRstNode) =
var e, a, b: PRstNode
- # writeln(rstnodekindToStr[key.kind], ': ', rstnodekindToStr[val.kind]);
assert(index.kind == rnDefList)
assert(key.kind != rnDefName)
a = newRstNode(rnDefName)
@@ -590,7 +567,7 @@ proc isInlineMarkupEnd(p: TRstParser, markup: string): bool =
result = false
proc isInlineMarkupStart(p: TRstParser, markup: string): bool =
- var c, d: Char
+ var d: Char
result = p.tok[p.idx].symbol == markup
if not result:
return # Rule 1:
@@ -606,7 +583,7 @@ proc isInlineMarkupStart(p: TRstParser, markup: string): bool =
if p.tok[p.idx - 1].symbol == "\\":
result = false
else:
- c = p.tok[p.idx - 1].symbol[0]
+ var c = p.tok[p.idx - 1].symbol[0]
case c
of '\'', '\"': d = c
of '(': d = ')'
@@ -641,30 +618,19 @@ proc match(p: TRstParser, start: int, expr: string): bool =
# 'T' always true
# 'E' whitespace, indent or eof
# 'e' tkWord or '#' (for enumeration lists)
- var
- i, j, last, length: int
- c: char
- i = 0
- j = start
- last = len(expr) + 0 - 1
+ var i = 0
+ var j = start
+ var last = len(expr) + 0 - 1
while i <= last:
case expr[i]
- of 'w':
- result = p.tok[j].kind == tkWord
- of ' ':
- result = p.tok[j].kind == tkWhite
- of 'i':
- result = p.tok[j].kind == tkIndent
- of 'p':
- result = p.tok[j].kind == tkPunct
- of 'a':
- result = p.tok[j].kind == tkAdornment
- of 'o':
- result = p.tok[j].kind == tkOther
- of 'T':
- result = true
- of 'E':
- result = p.tok[j].kind in {tkEof, tkWhite, tkIndent}
+ of 'w': result = p.tok[j].kind == tkWord
+ of ' ': result = p.tok[j].kind == tkWhite
+ of 'i': result = p.tok[j].kind == tkIndent
+ of 'p': result = p.tok[j].kind == tkPunct
+ of 'a': result = p.tok[j].kind == tkAdornment
+ of 'o': result = p.tok[j].kind == tkOther
+ of 'T': result = true
+ of 'E': result = p.tok[j].kind in {tkEof, tkWhite, tkIndent}
of 'e':
result = (p.tok[j].kind == tkWord) or (p.tok[j].symbol == "#")
if result:
@@ -674,8 +640,8 @@ proc match(p: TRstParser, start: int, expr: string): bool =
else:
nil
else:
- c = expr[i]
- length = 0
+ var c = expr[i]
+ var length = 0
while (i <= last) and (expr[i] == c):
inc(i)
inc(length)
@@ -688,25 +654,22 @@ proc match(p: TRstParser, start: int, expr: string): bool =
result = true
proc fixupEmbeddedRef(n, a, b: PRstNode) =
- var sep, incr: int
- sep = - 1
+ var sep = - 1
for i in countdown(rsonsLen(n) - 2, 0):
if n.sons[i].text == "<":
sep = i
break
- if (sep > 0) and (n.sons[sep - 1].text[0] == ' '): incr = 2
- else: incr = 1
+ var incr = if (sep > 0) and (n.sons[sep - 1].text[0] == ' '): 2 else: 1
for i in countup(0, sep - incr): addSon(a, n.sons[i])
for i in countup(sep + 1, rsonsLen(n) - 2): addSon(b, n.sons[i])
proc parsePostfix(p: var TRstParser, n: PRstNode): PRstNode =
- var a, b: PRstNode
result = n
if isInlineMarkupEnd(p, "_"):
inc(p.idx)
if (p.tok[p.idx - 2].symbol == "`") and (p.tok[p.idx - 3].symbol == ">"):
- a = newRstNode(rnInner)
- b = newRstNode(rnInner)
+ var a = newRstNode(rnInner)
+ var b = newRstNode(rnInner)
fixupEmbeddedRef(n, a, b)
if rsonsLen(a) == 0:
result = newRstNode(rnStandaloneHyperlink)
@@ -799,33 +762,32 @@ proc parseUntil(p: var TRstParser, father: PRstNode, postfix: string,
else: rstMessage(p, errXExpected, postfix)
proc parseInline(p: var TRstParser, father: PRstNode) =
- var n: PRstNode
case p.tok[p.idx].kind
of tkPunct:
if isInlineMarkupStart(p, "**"):
inc(p.idx)
- n = newRstNode(rnStrongEmphasis)
+ var n = newRstNode(rnStrongEmphasis)
parseUntil(p, n, "**", true)
addSon(father, n)
elif isInlineMarkupStart(p, "*"):
inc(p.idx)
- n = newRstNode(rnEmphasis)
+ var n = newRstNode(rnEmphasis)
parseUntil(p, n, "*", true)
addSon(father, n)
elif isInlineMarkupStart(p, "``"):
inc(p.idx)
- n = newRstNode(rnInlineLiteral)
+ var n = newRstNode(rnInlineLiteral)
parseUntil(p, n, "``", false)
addSon(father, n)
elif isInlineMarkupStart(p, "`"):
inc(p.idx)
- n = newRstNode(rnInterpretedText)
+ var n = newRstNode(rnInterpretedText)
parseUntil(p, n, "`", true)
n = parsePostfix(p, n)
addSon(father, n)
elif isInlineMarkupStart(p, "|"):
inc(p.idx)
- n = newRstNode(rnSubstitutionReferences)
+ var n = newRstNode(rnSubstitutionReferences)
parseUntil(p, n, "|", false)
addSon(father, n)
else:
@@ -838,9 +800,8 @@ proc parseInline(p: var TRstParser, father: PRstNode) =
else: assert(false)
proc getDirective(p: var TRstParser): string =
- var j: int
if (p.tok[p.idx].kind == tkWhite) and (p.tok[p.idx + 1].kind == tkWord):
- j = p.idx
+ var j = p.idx
inc(p.idx)
result = p.tok[p.idx].symbol
inc(p.idx)
@@ -859,13 +820,12 @@ proc getDirective(p: var TRstParser): string =
result = ""
proc parseComment(p: var TRstParser): PRstNode =
- var indent: int
case p.tok[p.idx].kind
of tkIndent, tkEof:
if p.tok[p.idx + 1].kind == tkIndent:
inc(p.idx) # empty comment
else:
- indent = p.tok[p.idx].ival
+ var indent = p.tok[p.idx].ival
while True:
case p.tok[p.idx].kind
of tkEof:
@@ -903,18 +863,15 @@ proc parseLine(p: var TRstParser, father: PRstNode) =
proc parseSection(p: var TRstParser, result: PRstNode)
proc parseField(p: var TRstParser): PRstNode =
- var
- col, indent: int
- fieldname, fieldbody: PRstNode
result = newRstNode(rnField)
- col = p.tok[p.idx].col
+ var col = p.tok[p.idx].col
inc(p.idx) # skip :
- fieldname = newRstNode(rnFieldname)
+ var fieldname = newRstNode(rnFieldname)
parseUntil(p, fieldname, ":", false)
- fieldbody = newRstNode(rnFieldbody)
+ var fieldbody = newRstNode(rnFieldbody)
if p.tok[p.idx].kind != tkIndent: parseLine(p, fieldbody)
if p.tok[p.idx].kind == tkIndent:
- indent = p.tok[p.idx].ival
+ var indent = p.tok[p.idx].ival
if indent > col:
pushInd(p, indent)
parseSection(p, fieldbody)
@@ -923,10 +880,9 @@ proc parseField(p: var TRstParser): PRstNode =
addSon(result, fieldbody)
proc parseFields(p: var TRstParser): PRstNode =
- var col: int
result = nil
if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx + 1].symbol == ":"):
- col = p.tok[p.idx].ival # BUGFIX!
+ var col = p.tok[p.idx].ival # BUGFIX!
result = newRstNode(rnFieldList)
inc(p.idx)
while true:
@@ -938,17 +894,15 @@ proc parseFields(p: var TRstParser): PRstNode =
break
proc getFieldValue(n: PRstNode, fieldname: string): string =
- var f: PRstNode
result = ""
if n.sons[1] == nil: return
if (n.sons[1].kind != rnFieldList):
- InternalError("getFieldValue (2): " & rstnodeKindToStr[n.sons[1].kind])
+ InternalError("getFieldValue (2): " & $n.sons[1].kind)
for i in countup(0, rsonsLen(n.sons[1]) - 1):
- f = n.sons[1].sons[i]
+ var f = n.sons[1].sons[i]
if cmpIgnoreStyle(addNodes(f.sons[0]), fieldname) == 0:
result = addNodes(f.sons[1])
- if result == "":
- result = "\x01\x01" # indicates that the field exists
+ if result == "": result = "\x01\x01" # indicates that the field exists
return
proc getArgument(n: PRstNode): string =
@@ -957,13 +911,10 @@ proc getArgument(n: PRstNode): string =
proc parseDotDot(p: var TRstParser): PRstNode
proc parseLiteralBlock(p: var TRstParser): PRstNode =
- var
- indent: int
- n: PRstNode
result = newRstNode(rnLiteralBlock)
- n = newRstNode(rnLeaf, "")
+ var n = newRstNode(rnLeaf, "")
if p.tok[p.idx].kind == tkIndent:
- indent = p.tok[p.idx].ival
+ var indent = p.tok[p.idx].ival
inc(p.idx)
while True:
case p.tok[p.idx].kind
@@ -1003,8 +954,7 @@ proc tokenAfterNewline(p: TRstParser): int =
else: inc(result)
proc isLineBlock(p: TRstParser): bool =
- var j: int
- j = tokenAfterNewline(p)
+ var j = tokenAfterNewline(p)
result = (p.tok[p.idx].col == p.tok[j].col) and (p.tok[j].symbol == "|") or
(p.tok[j].col > p.tok[p.idx].col)
@@ -1015,8 +965,7 @@ proc predNL(p: TRstParser): bool =
(p.tok[p.idx - 1].ival == currInd(p))
proc isDefList(p: TRstParser): bool =
- var j: int
- j = tokenAfterNewline(p)
+ var j = tokenAfterNewline(p)
result = (p.tok[p.idx].col < p.tok[j].col) and
(p.tok[j].kind in {tkWord, tkOther, tkPunct}) and
(p.tok[j - 2].symbol != "::")
@@ -1063,17 +1012,14 @@ proc whichSection(p: TRstParser): TRstNodeKind =
else: result = rnLeaf
proc parseLineBlock(p: var TRstParser): PRstNode =
- var
- col: int
- item: PRstNode
result = nil
if p.tok[p.idx + 1].kind == tkWhite:
- col = p.tok[p.idx].col
+ var col = p.tok[p.idx].col
result = newRstNode(rnLineBlock)
pushInd(p, p.tok[p.idx + 2].col)
inc(p.idx, 2)
while true:
- item = newRstNode(rnLineBlockItem)
+ var item = newRstNode(rnLineBlockItem)
parseSection(p, item)
addSon(result, item)
if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col) and
@@ -1120,12 +1066,11 @@ proc parseParagraphWrapper(p: var TRstParser): PRstNode =
parseParagraph(p, result)
proc parseHeadline(p: var TRstParser): PRstNode =
- var c: Char
result = newRstNode(rnHeadline)
parseLine(p, result)
assert(p.tok[p.idx].kind == tkIndent)
assert(p.tok[p.idx + 1].kind == tkAdornment)
- c = p.tok[p.idx + 1].symbol[0]
+ var c = p.tok[p.idx + 1].symbol[0]
inc(p.idx, 2)
result.level = getLevel(p.s.underlineToLevel, p.s.uLevel, c)
@@ -1136,8 +1081,7 @@ proc tokEnd(p: TRstParser): int =
result = p.tok[p.idx].col + len(p.tok[p.idx].symbol) - 1
proc getColumns(p: var TRstParser, cols: var TIntSeq) =
- var L: int
- L = 0
+ var L = 0
while true:
inc(L)
setlen(cols, L)
@@ -1161,8 +1105,8 @@ proc parseSimpleTable(p: var TRstParser): PRstNode =
q: TRstParser
a, b: PRstNode
result = newRstNode(rnTable)
- cols = @ []
- row = @ []
+ cols = @[]
+ row = @[]
a = nil
c = p.tok[p.idx].symbol[0]
while true:
@@ -1177,8 +1121,8 @@ proc parseSimpleTable(p: var TRstParser): PRstNode =
if a != nil:
for j in countup(0, rsonsLen(a) - 1): a.sons[j].kind = rnTableHeaderCell
if p.tok[p.idx].kind == tkEof: break
- for j in countup(0, high(row)):
- row[j] = "" # the following while loop iterates over the lines a single cell may span:
+ for j in countup(0, high(row)): row[j] = ""
+ # the following while loop iterates over the lines a single cell may span:
line = p.tok[p.idx].line
while true:
i = 0
@@ -1212,8 +1156,7 @@ proc parseTransition(p: var TRstParser): PRstNode =
if p.tok[p.idx].kind == tkIndent: inc(p.idx)
proc parseOverline(p: var TRstParser): PRstNode =
- var c: char
- c = p.tok[p.idx].symbol[0]
+ var c = p.tok[p.idx].symbol[0]
inc(p.idx, 2)
result = newRstNode(rnOverline)
while true:
@@ -1232,19 +1175,15 @@ proc parseOverline(p: var TRstParser): PRstNode =
if p.tok[p.idx].kind == tkIndent: inc(p.idx)
proc parseBulletList(p: var TRstParser): PRstNode =
- var
- bullet: string
- col: int
- item: PRstNode
result = nil
if p.tok[p.idx + 1].kind == tkWhite:
- bullet = p.tok[p.idx].symbol
- col = p.tok[p.idx].col
+ var bullet = p.tok[p.idx].symbol
+ var col = p.tok[p.idx].col
result = newRstNode(rnBulletList)
pushInd(p, p.tok[p.idx + 2].col)
inc(p.idx, 2)
while true:
- item = newRstNode(rnBulletItem)
+ var item = newRstNode(rnBulletItem)
parseSection(p, item)
addSon(result, item)
if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col) and
@@ -1256,23 +1195,20 @@ proc parseBulletList(p: var TRstParser): PRstNode =
popInd(p)
proc parseOptionList(p: var TRstParser): PRstNode =
- var
- a, b, c: PRstNode
- j: int
result = newRstNode(rnOptionList)
while true:
if match(p, p.idx, "-w") or match(p, p.idx, "--w") or
match(p, p.idx, "/w"):
- a = newRstNode(rnOptionGroup)
- b = newRstNode(rnDescription)
- c = newRstNode(rnOptionListItem)
+ var a = newRstNode(rnOptionGroup)
+ var b = newRstNode(rnDescription)
+ var c = newRstNode(rnOptionListItem)
while not (p.tok[p.idx].kind in {tkIndent, tkEof}):
if (p.tok[p.idx].kind == tkWhite) and (len(p.tok[p.idx].symbol) > 1):
inc(p.idx)
break
addSon(a, newLeaf(p))
inc(p.idx)
- j = tokenAfterNewline(p)
+ var j = tokenAfterNewline(p)
if (j > 0) and (p.tok[j - 1].kind == tkIndent) and
(p.tok[j - 1].ival > currInd(p)):
pushInd(p, p.tok[j - 1].ival)
@@ -1288,26 +1224,24 @@ proc parseOptionList(p: var TRstParser): PRstNode =
break
proc parseDefinitionList(p: var TRstParser): PRstNode =
- var
- j, col: int
- a, b, c: PRstNode
result = nil
- j = tokenAfterNewLine(p) - 1
+ var j = tokenAfterNewLine(p) - 1
if (j >= 1) and (p.tok[j].kind == tkIndent) and
(p.tok[j].ival > currInd(p)) and (p.tok[j - 1].symbol != "::"):
- col = p.tok[p.idx].col
+ var col = p.tok[p.idx].col
result = newRstNode(rnDefList)
while true:
j = p.idx
- a = newRstNode(rnDefName)
- parseLine(p, a) #writeln('after def line: ', p.tok[p.idx].ival :1, ' ', col : 1);
- if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival > currInd(p)) and
+ var a = newRstNode(rnDefName)
+ parseLine(p, a)
+ if (p.tok[p.idx].kind == tkIndent) and
+ (p.tok[p.idx].ival > currInd(p)) and
(p.tok[p.idx + 1].symbol != "::") and
not (p.tok[p.idx + 1].kind in {tkIndent, tkEof}):
pushInd(p, p.tok[p.idx].ival)
- b = newRstNode(rnDefBody)
+ var b = newRstNode(rnDefBody)
parseSection(p, b)
- c = newRstNode(rnDefItem)
+ var c = newRstNode(rnDefItem)
addSon(c, a)
addSon(c, b)
addSon(result, c)
@@ -1329,23 +1263,20 @@ proc parseEnumList(p: var TRstParser): PRstNode =
const
wildcards: array[0..2, string] = ["(e) ", "e) ", "e. "]
wildpos: array[0..2, int] = [1, 0, 0]
- var
- w, col, j: int
- item: PRstNode
result = nil
- w = 0
+ var w = 0
while w <= 2:
if match(p, p.idx, wildcards[w]): break
inc(w)
if w <= 2:
- col = p.tok[p.idx].col
+ var col = p.tok[p.idx].col
result = newRstNode(rnEnumList)
inc(p.idx, wildpos[w] + 3)
- j = tokenAfterNewLine(p)
+ var j = tokenAfterNewLine(p)
if (p.tok[j].col == p.tok[p.idx].col) or match(p, j, wildcards[w]):
pushInd(p, p.tok[p.idx].col)
while true:
- item = newRstNode(rnEnumItem)
+ var item = newRstNode(rnEnumItem)
parseSection(p, item)
addSon(result, item)
if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col) and
@@ -1363,19 +1294,15 @@ proc sonKind(father: PRstNode, i: int): TRstNodeKind =
if i < rsonsLen(father): result = father.sons[i].kind
proc parseSection(p: var TRstParser, result: PRstNode) =
- var
- a: PRstNode
- k: TRstNodeKind
- leave: bool
while true:
- leave = false
+ var leave = false
assert(p.idx >= 0)
while p.tok[p.idx].kind == tkIndent:
if currInd(p) == p.tok[p.idx].ival:
inc(p.idx)
elif p.tok[p.idx].ival > currInd(p):
pushInd(p, p.tok[p.idx].ival)
- a = newRstNode(rnBlockQuote)
+ var a = newRstNode(rnBlockQuote)
parseSection(p, a)
addSon(result, a)
popInd(p)
@@ -1384,39 +1311,27 @@ proc parseSection(p: var TRstParser, result: PRstNode) =
break
if leave: break
if p.tok[p.idx].kind == tkEof: break
- a = nil
- k = whichSection(p)
+ var a: PRstNode = nil
+ var k = whichSection(p)
case k
of rnLiteralBlock:
inc(p.idx) # skip '::'
a = parseLiteralBlock(p)
- of rnBulletList:
- a = parseBulletList(p)
- of rnLineblock:
- a = parseLineBlock(p)
- of rnDirective:
- a = parseDotDot(p)
- of rnEnumList:
- a = parseEnumList(p)
- of rnLeaf:
- rstMessage(p, errNewSectionExpected)
- of rnParagraph:
- nil
- of rnDefList:
- a = parseDefinitionList(p)
+ of rnBulletList: a = parseBulletList(p)
+ of rnLineblock: a = parseLineBlock(p)
+ of rnDirective: a = parseDotDot(p)
+ of rnEnumList: a = parseEnumList(p)
+ of rnLeaf: rstMessage(p, errNewSectionExpected)
+ of rnParagraph: nil
+ of rnDefList: a = parseDefinitionList(p)
of rnFieldList:
dec(p.idx)
a = parseFields(p)
- of rnTransition:
- a = parseTransition(p)
- of rnHeadline:
- a = parseHeadline(p)
- of rnOverline:
- a = parseOverline(p)
- of rnTable:
- a = parseSimpleTable(p)
- of rnOptionList:
- a = parseOptionList(p)
+ of rnTransition: a = parseTransition(p)
+ of rnHeadline: a = parseHeadline(p)
+ of rnOverline: a = parseOverline(p)
+ of rnTable: a = parseSimpleTable(p)
+ of rnOptionList: a = parseOptionList(p)
else: InternalError("rst.parseSection()")
if (a == nil) and (k != rnDirective):
a = newRstNode(rnParagraph)
@@ -1491,14 +1406,10 @@ proc dirInclude(p: var TRstParser): PRstNode =
# The text encoding of the external data file. Defaults to the document's
# encoding (if specified).
#
- var
- n: PRstNode
- filename, path: string
- q: TRstParser
result = nil
- n = parseDirective(p, {hasArg, argIsFile, hasOptions}, nil)
- filename = strip(addNodes(n.sons[0]))
- path = findFile(filename)
+ var n = parseDirective(p, {hasArg, argIsFile, hasOptions}, nil)
+ var filename = strip(addNodes(n.sons[0]))
+ var path = findFile(filename)
if path == "":
rstMessage(p, errCannotOpenFile, filename)
else:
@@ -1507,6 +1418,7 @@ proc dirInclude(p: var TRstParser): PRstNode =
result = newRstNode(rnLiteralBlock)
addSon(result, newRstNode(rnLeaf, readFile(path)))
else:
+ var q: TRstParser
initParser(q, p.s)
q.filename = filename
getTokens(readFile(path), false, q.tok) # workaround a GCC bug:
@@ -1515,15 +1427,12 @@ proc dirInclude(p: var TRstParser): PRstNode =
result = parseDoc(q)
proc dirCodeBlock(p: var TRstParser): PRstNode =
- var
- n: PRstNode
- filename, path: string
result = parseDirective(p, {hasArg, hasOptions}, parseLiteralBlock)
- filename = strip(getFieldValue(result, "file"))
+ var filename = strip(getFieldValue(result, "file"))
if filename != "":
- path = findFile(filename)
+ var path = findFile(filename)
if path == "": rstMessage(p, errCannotOpenFile, filename)
- n = newRstNode(rnLiteralBlock)
+ var n = newRstNode(rnLiteralBlock)
addSon(n, newRstNode(rnLeaf, readFile(path)))
result.sons[2] = n
result.kind = rnCodeBlock
@@ -1567,28 +1476,23 @@ proc dirRaw(p: var TRstParser): PRstNode =
# The text encoding of the external raw data (file or URL).
# Defaults to the document's encoding (if specified).
#
- var filename, path, f: string
result = parseDirective(p, {hasOptions}, parseSectionWrapper)
result.kind = rnRaw
- filename = getFieldValue(result, "file")
+ var filename = getFieldValue(result, "file")
if filename != "":
- path = findFile(filename)
+ var path = findFile(filename)
if path == "":
rstMessage(p, errCannotOpenFile, filename)
else:
- f = readFile(path)
+ var f = readFile(path)
result = newRstNode(rnRaw)
addSon(result, newRstNode(rnLeaf, f))
proc parseDotDot(p: var TRstParser): PRstNode =
- var
- d: string
- col: int
- a, b: PRstNode
result = nil
- col = p.tok[p.idx].col
+ var col = p.tok[p.idx].col
inc(p.idx)
- d = getDirective(p)
+ var d = getDirective(p)
if d != "":
pushInd(p, col)
case getDirKind(d)
@@ -1606,14 +1510,15 @@ proc parseDotDot(p: var TRstParser): PRstNode =
elif match(p, p.idx, " _"):
# hyperlink target:
inc(p.idx, 2)
- a = getReferenceName(p, ":")
+ var a = getReferenceName(p, ":")
if p.tok[p.idx].kind == tkWhite: inc(p.idx)
- b = untilEol(p)
+ var b = untilEol(p)
setRef(p, rstnodeToRefname(a), b)
elif match(p, p.idx, " |"):
# substitution definitions:
inc(p.idx, 2)
- a = getReferenceName(p, "|")
+ var a = getReferenceName(p, "|")
+ var b: PRstNode
if p.tok[p.idx].kind == tkWhite: inc(p.idx)
if cmpIgnoreStyle(p.tok[p.idx].symbol, "replace") == 0:
inc(p.idx)
@@ -1628,32 +1533,28 @@ proc parseDotDot(p: var TRstParser): PRstNode =
elif match(p, p.idx, " ["):
# footnotes, citations
inc(p.idx, 2)
- a = getReferenceName(p, "]")
+ var a = getReferenceName(p, "]")
if p.tok[p.idx].kind == tkWhite: inc(p.idx)
- b = untilEol(p)
+ var b = untilEol(p)
setRef(p, rstnodeToRefname(a), b)
else:
result = parseComment(p)
proc resolveSubs(p: var TRstParser, n: PRstNode): PRstNode =
- var
- x: int
- y: PRstNode
- e, key: string
result = n
if n == nil: return
case n.kind
of rnSubstitutionReferences:
- x = findSub(p, n)
+ var x = findSub(p, n)
if x >= 0:
result = p.s.subs[x].value
else:
- key = addNodes(n)
- e = getEnv(key)
+ var key = addNodes(n)
+ var e = getEnv(key)
if e != "": result = newRstNode(rnLeaf, e)
else: rstMessage(p, warnUnknownSubstitutionX, key)
of rnRef:
- y = findRef(p, rstnodeToRefname(n))
+ var y = findRef(p, rstnodeToRefname(n))
if y != nil:
result = newRstNode(rnHyperlink)
n.kind = rnInner
diff --git a/rod/scanner.nim b/rod/scanner.nim
index c7fcbb0626..a2535cc5c0 100755
--- a/rod/scanner.nim
+++ b/rod/scanner.nim
@@ -139,18 +139,22 @@ proc fillToken*(L: var TToken)
proc isKeyword(kind: TTokType): bool =
result = (kind >= tokKeywordLow) and (kind <= tokKeywordHigh)
+proc isNimrodIdentifier*(s: string): bool =
+ if s[0] in SymStartChars:
+ for c in items(s):
+ if c notin SymChars: return
+ result = true
+
proc pushInd(L: var TLexer, indent: int) =
- var length: int
- length = len(L.indentStack)
+ var length = len(L.indentStack)
setlen(L.indentStack, length + 1)
if (indent > L.indentStack[length - 1]):
L.indentstack[length] = indent
else:
- InternalError("pushInd") #writeln('push indent ', indent);
+ InternalError("pushInd")
proc popInd(L: var TLexer) =
- var length: int
- length = len(L.indentStack)
+ var length = len(L.indentStack)
setlen(L.indentStack, length - 1)
proc findIdent(L: TLexer, indent: int): bool =
@@ -161,12 +165,9 @@ proc findIdent(L: TLexer, indent: int): bool =
proc tokToStr(tok: PToken): string =
case tok.tokType
- of tkIntLit..tkInt64Lit:
- result = $(tok.iNumber)
- of tkFloatLit..tkFloat64Lit:
- result = $(tok.fNumber)
- of tkInvalid, tkStrLit..tkCharLit, tkComment:
- result = tok.literal
+ of tkIntLit..tkInt64Lit: result = $tok.iNumber
+ of tkFloatLit..tkFloat64Lit: result = $tok.fNumber
+ of tkInvalid, tkStrLit..tkCharLit, tkComment: result = tok.literal
of tkParLe..tkColon, tkEof, tkInd, tkSad, tkDed, tkAccent:
result = tokTypeToStr[tok.tokType]
else:
@@ -194,7 +195,7 @@ proc fillToken(L: var TToken) =
proc openLexer(lex: var TLexer, filename: string, inputstream: PLLStream) =
openBaseLexer(lex, inputstream)
- lex.indentStack = @ [0]
+ lex.indentStack = @[0]
lex.filename = filename
lex.indentAhead = - 1
diff --git a/rod/wordrecg.nim b/rod/wordrecg.nim
index c460d019e9..9054dcc888 100755
--- a/rod/wordrecg.nim
+++ b/rod/wordrecg.nim
@@ -51,7 +51,9 @@ type
wLinksys, wDeprecated, wVarargs, wByref, wCallconv, wBreakpoint, wDebugger,
wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline,
wFastcall, wClosure, wNoconv, wOn, wOff, wChecks, wRangechecks,
- wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wW,
+ wBoundchecks, wOverflowchecks, wNilchecks,
+ wFloatchecks, wNanChecks, wInfChecks,
+ wAssertions, wWarnings, wW,
wHints, wOptimization, wSpeed, wSize, wNone, wPath, wP, wD, wU, wDebuginfo,
wCompileonly, wNolinking, wForcebuild, wF, wDeadCodeElim, wSafecode,
wCompileTime, wGc, wRefc, wBoehm, wA, wOpt, wO, wApp, wConsole, wGui,
@@ -100,7 +102,10 @@ const
"byref", "callconv", "breakpoint", "debugger", "nimcall", "stdcall",
"cdecl", "safecall", "syscall", "inline", "noinline", "fastcall", "closure",
"noconv", "on", "off", "checks", "rangechecks", "boundchecks",
- "overflowchecks", "nilchecks", "assertions", "warnings", "w", "hints",
+ "overflowchecks", "nilchecks",
+ "floatchecks", "nanchecks", "infchecks",
+
+ "assertions", "warnings", "w", "hints",
"optimization", "speed", "size", "none", "path", "p", "d", "u", "debuginfo",
"compileonly", "nolinking", "forcebuild", "f", "deadcodeelim", "safecode",
"compiletime", "gc", "refc", "boehm", "a", "opt", "o", "app", "console",
diff --git a/start.bat b/start.bat
new file mode 100755
index 0000000000..694a795204
--- /dev/null
+++ b/start.bat
@@ -0,0 +1,5 @@
+@echo off
+REM COLOR 0A
+SET NIMRODPATH=.
+SET PATH=%NIMRODPATH%\bin;%NIMRODPATH%\dist\mingw\bin;%PATH%
+cmd
diff --git a/tests/99bottles.nim b/tests/99bottles.nim
new file mode 100755
index 0000000000..14904ac0fb
--- /dev/null
+++ b/tests/99bottles.nim
@@ -0,0 +1 @@
+# Test if the compiler detects invalid module names
diff --git a/tests/tfloat1.nim b/tests/tfloat1.nim
new file mode 100755
index 0000000000..89911dd614
--- /dev/null
+++ b/tests/tfloat1.nim
@@ -0,0 +1,8 @@
+# Test new floating point exceptions
+
+{.floatChecks: on.}
+
+var x = 0.8
+var y = 0.0
+
+echo x / y #OUT Error: unhandled exception: FPU operation caused an overflow [EFloatOverflow]
diff --git a/tests/tfloat2.nim b/tests/tfloat2.nim
new file mode 100755
index 0000000000..92421d4462
--- /dev/null
+++ b/tests/tfloat2.nim
@@ -0,0 +1,8 @@
+# Test new floating point exceptions
+
+{.floatChecks: on.}
+
+var x = 0.0
+var y = 0.0
+
+echo x / y #OUT Error: unhandled exception: FPU operation caused a NaN result [EFloatInvalidOp]