floating point checks
This commit is contained in:
parent
911c1cb301
commit
3b7ef2288f
30 changed files with 611 additions and 631 deletions
|
|
@ -7,10 +7,10 @@ Advanced commands::
|
||||||
check checks the project for syntax and semantic
|
check checks the project for syntax and semantic
|
||||||
parse parses a single file (for debugging Nimrod)
|
parse parses a single file (for debugging Nimrod)
|
||||||
Advanced options:
|
Advanced options:
|
||||||
-w, --warnings:on|off warnings ON|OFF
|
-w, --warnings:on|off turn all warnings on|off
|
||||||
--warning[X]:on|off specific warning X ON|OFF
|
--warning[X]:on|off turn specific warning X on|off
|
||||||
--hints:on|off hints ON|OFF
|
--hints:on|off turn all hints on|off
|
||||||
--hint[X]:on|off specific hint X ON|OFF
|
--hint[X]:on|off turn specific hint X on|off
|
||||||
--lib:PATH set the system library path
|
--lib:PATH set the system library path
|
||||||
-c, --compileOnly compile only; do not assemble or link
|
-c, --compileOnly compile only; do not assemble or link
|
||||||
--noLinking compile but do not link
|
--noLinking compile but do not link
|
||||||
|
|
@ -24,8 +24,8 @@ Advanced options:
|
||||||
-l, --passl:OPTION pass an option to the linker
|
-l, --passl:OPTION pass an option to the linker
|
||||||
--genMapping generate a mapping file containing
|
--genMapping generate a mapping file containing
|
||||||
(Nimrod, mangled) identifier pairs
|
(Nimrod, mangled) identifier pairs
|
||||||
--lineDir:on|off generation of #line directive ON|OFF
|
--lineDir:on|off generation of #line directive on|off
|
||||||
--checkpoints:on|off turn on|off checkpoints; for debugging Nimrod
|
--checkpoints:on|off turn checkpoints on|off; for debugging Nimrod
|
||||||
--skipCfg do not read the general configuration file
|
--skipCfg do not read the general configuration file
|
||||||
--skipProjCfg do not read the project's configuration file
|
--skipProjCfg do not read the project's configuration file
|
||||||
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
|
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
|
||||||
|
|
|
||||||
|
|
@ -14,18 +14,20 @@ Options:
|
||||||
-d, --define:SYMBOL define a conditional symbol
|
-d, --define:SYMBOL define a conditional symbol
|
||||||
-u, --undef:SYMBOL undefine a conditional symbol
|
-u, --undef:SYMBOL undefine a conditional symbol
|
||||||
-f, --forceBuild force rebuilding of all modules
|
-f, --forceBuild force rebuilding of all modules
|
||||||
--symbolFiles:on|off use symbol files to speed up compilation (buggy!)
|
--stackTrace:on|off turn stack tracing on|off
|
||||||
--stackTrace:on|off code generation for stack trace ON|OFF
|
--lineTrace:on|off turn line tracing on|off
|
||||||
--lineTrace:on|off code generation for line trace ON|OFF
|
--debugger:on|off turn Embedded Nimrod Debugger on|off
|
||||||
--debugger:on|off turn Embedded Nimrod Debugger ON|OFF
|
-x, --checks:on|off turn all runtime checks on|off
|
||||||
-x, --checks:on|off code generation for all runtime checks ON|OFF
|
--objChecks:on|off turn obj conversion checks on|off
|
||||||
--objChecks:on|off code generation for obj conversion checks ON|OFF
|
--fieldChecks:on|off turn case variant field checks on|off
|
||||||
--fieldChecks:on|off code generation for case variant fields ON|OFF
|
--rangeChecks:on|off turn range checks on|off
|
||||||
--rangeChecks:on|off code generation for range checks ON|OFF
|
--boundChecks:on|off turn bound checks on|off
|
||||||
--boundChecks:on|off code generation for bound checks ON|OFF
|
--overflowChecks:on|off turn int over-/underflow checks on|off
|
||||||
--overflowChecks:on|off code generation for over-/underflow checks ON|OFF
|
-a, --assertions:on|off turn assertions on|off
|
||||||
-a, --assertions:on|off code generation for assertions ON|OFF
|
--floatChecks:on|off turn all floating point (NaN/Inf) checks on|off
|
||||||
--deadCodeElim:on|off whole program dead code elimination 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
|
--opt:none|speed|size optimize not at all or for speed|size
|
||||||
--app:console|gui|lib generate a console|GUI application|dynamic library
|
--app:console|gui|lib generate a console|GUI application|dynamic library
|
||||||
-r, --run run the compiled program with given arguments
|
-r, --run run the compiled program with given arguments
|
||||||
|
|
|
||||||
|
|
@ -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
|
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
|
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,
|
`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,
|
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
|
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.
|
types) belong to ordinal types.
|
||||||
|
|
||||||
|
|
||||||
Pre-defined numerical types
|
Pre-defined integer types
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
These integer types are pre-defined:
|
These integer types are pre-defined:
|
||||||
|
|
||||||
``int``
|
``int``
|
||||||
|
|
@ -469,6 +469,14 @@ operation meaning
|
||||||
``int32`` type)
|
``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:
|
The following floating point types are pre-defined:
|
||||||
|
|
||||||
``float``
|
``float``
|
||||||
|
|
@ -482,16 +490,49 @@ floatXX
|
||||||
implementation supports ``float32`` and ``float64``. Literals of these types
|
implementation supports ``float32`` and ``float64``. Literals of these types
|
||||||
have the suffix 'fXX.
|
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
|
Automatic type conversion in expressions with different kinds
|
||||||
of floating point types is performed: the smaller type is
|
of floating point types is performed: See `Convertible relation`_ for further
|
||||||
converted to the larger. Arithmetic performed on floating point types
|
details. Arithmetic performed on floating point types follows the IEEE
|
||||||
follows the IEEE standard. Integer types are not converted to floating point
|
standard. Integer types are not converted to floating point types automatically
|
||||||
types automatically and vice versa.
|
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
|
Boolean type
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
.. contents::
|
.. 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
|
Introduction
|
||||||
============
|
============
|
||||||
|
|
@ -242,7 +246,7 @@ memory, but nothing worse happens.
|
||||||
|
|
||||||
|
|
||||||
DeadCodeElim Pragma
|
DeadCodeElim Pragma
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
The `deadCodeElim`:idx: pragma only applies to whole modules: It tells the
|
The `deadCodeElim`:idx: pragma only applies to whole modules: It tells the
|
||||||
compiler to activate (or deactivate) dead code elimination for the module the
|
compiler to activate (or deactivate) dead code elimination for the module the
|
||||||
pragma appers in.
|
pragma appers in.
|
||||||
|
|
@ -304,13 +308,13 @@ Optimizing string handling
|
||||||
String assignments are sometimes expensive in Nimrod: They are required to
|
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
|
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
|
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
|
passed to subroutines. The compiler does not copy strings that are a result from
|
||||||
a procedure call, because the called procedure returns a new string anyway.
|
a procedure call, because the callee returns a new string anyway.
|
||||||
Thus it is efficient to do:
|
Thus it is efficient to do:
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
var s = procA() # assignment will not copy the string; procA allocates a new
|
var s = procA() # assignment will not copy the string; procA allocates a new
|
||||||
# string anyway
|
# string already
|
||||||
|
|
||||||
However it is not efficient to do:
|
However it is not efficient to do:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ proc mean*(x: openarray[float]): float {.noSideEffect.} =
|
||||||
result = sum(x) / toFloat(len(x))
|
result = sum(x) / toFloat(len(x))
|
||||||
|
|
||||||
proc variance*(x: openarray[float]): float {.noSideEffect.} =
|
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.
|
## If `x` is empty, NaN is returned.
|
||||||
result = 0.0
|
result = 0.0
|
||||||
var m = mean(x)
|
var m = mean(x)
|
||||||
|
|
|
||||||
|
|
@ -222,10 +222,10 @@ type
|
||||||
EFloatingPoint* = object of ESynch ## base class for floating point exceptions
|
EFloatingPoint* = object of ESynch ## base class for floating point exceptions
|
||||||
EFloatInvalidOp* {.compilerproc.} =
|
EFloatInvalidOp* {.compilerproc.} =
|
||||||
object of EFloatingPoint ## Invalid operation according to IEEE: Raised by
|
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.} =
|
EFloatDivByZero* {.compilerproc.} =
|
||||||
object of EFloatingPoint ## Division by zero. Divisor is zero and dividend
|
object of EFloatingPoint ## Division by zero. Divisor is zero and dividend
|
||||||
## is a finite nonzero number
|
## is a finite nonzero number.
|
||||||
EFloatOverflow* {.compilerproc.} =
|
EFloatOverflow* {.compilerproc.} =
|
||||||
object of EFloatingPoint ## Overflow. Operation produces a result
|
object of EFloatingPoint ## Overflow. Operation produces a result
|
||||||
## that exceeds the range of the exponent
|
## that exceeds the range of the exponent
|
||||||
|
|
|
||||||
|
|
@ -314,3 +314,21 @@ when not defined(mulInt):
|
||||||
if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
|
if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
|
||||||
return result
|
return result
|
||||||
raiseOverflow()
|
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)
|
||||||
|
|
|
||||||
|
|
@ -37,16 +37,16 @@
|
||||||
|
|
||||||
when defined(MACOSX):
|
when defined(MACOSX):
|
||||||
const
|
const
|
||||||
LUA_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"
|
LUA_LIB_NAME* = "liblua(|5.2|5.1|5.0).dylib"
|
||||||
elif defined(UNIX):
|
elif defined(UNIX):
|
||||||
const
|
const
|
||||||
LUA_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"
|
LUA_LIB_NAME* = "liblua(|5.2|5.1|5.0).so.(|0)"
|
||||||
else:
|
else:
|
||||||
const
|
const
|
||||||
LUA_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"
|
LUA_LIB_NAME* = "lua(|5.2|5.1|5.0).dll"
|
||||||
type
|
type
|
||||||
size_t* = int
|
size_t* = int
|
||||||
Psize_t* = ptr size_t
|
Psize_t* = ptr size_t
|
||||||
|
|
@ -56,7 +56,8 @@ const
|
||||||
LUA_RELEASE* = "Lua 5.1.1"
|
LUA_RELEASE* = "Lua 5.1.1"
|
||||||
LUA_VERSION_NUM* = 501
|
LUA_VERSION_NUM* = 501
|
||||||
LUA_COPYRIGHT* = "Copyright (C) 1994-2006 Lua.org, PUC-Rio"
|
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 #
|
LUA_MULTRET* = - 1 #
|
||||||
#** pseudo-indices
|
#** pseudo-indices
|
||||||
#
|
#
|
||||||
|
|
@ -74,16 +75,15 @@ const # thread status; 0 is OK
|
||||||
|
|
||||||
type
|
type
|
||||||
Plua_State* = Pointer
|
Plua_State* = Pointer
|
||||||
lua_CFunction* = proc (L: Plua_State): int{.cdecl.} #
|
lua_CFunction* = proc (L: Plua_State): int{.cdecl.}
|
||||||
#** functions that read/write blocks when loading/dumping Lua chunks
|
|
||||||
#
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#** functions that read/write blocks when loading/dumping Lua chunks
|
||||||
|
#
|
||||||
type
|
type
|
||||||
lua_Reader* = proc (L: Plua_State, ud: Pointer, sz: Psize_t): cstring{.cdecl.}
|
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{.
|
lua_Writer* = proc (L: Plua_State, p: Pointer, sz: size_t, ud: Pointer): int{.
|
||||||
cdecl.} #
|
cdecl.}
|
||||||
#** prototype for memory-allocation functions
|
|
||||||
#
|
|
||||||
lua_Alloc* = proc (ud, theptr: Pointer, osize, nsize: size_t){.cdecl.}
|
lua_Alloc* = proc (ud, theptr: Pointer, osize, nsize: size_t){.cdecl.}
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
@ -218,9 +218,10 @@ proc lua_getallocf*(L: Plua_State, ud: ptr Pointer): lua_Alloc{.cdecl,
|
||||||
dynlib: LUA_NAME, importc.}
|
dynlib: LUA_NAME, importc.}
|
||||||
proc lua_setallocf*(L: Plua_State, f: lua_Alloc, ud: Pointer){.cdecl,
|
proc lua_setallocf*(L: Plua_State, f: lua_Alloc, ud: Pointer){.cdecl,
|
||||||
dynlib: LUA_NAME, importc.}
|
dynlib: LUA_NAME, importc.}
|
||||||
#
|
|
||||||
#** Garbage-collection functions and options
|
#
|
||||||
#
|
#** Garbage-collection functions and options
|
||||||
|
#
|
||||||
const
|
const
|
||||||
LUA_GCSTOP* = 0
|
LUA_GCSTOP* = 0
|
||||||
LUA_GCRESTART* = 1
|
LUA_GCRESTART* = 1
|
||||||
|
|
@ -229,11 +230,13 @@ const
|
||||||
LUA_GCCOUNTB* = 4
|
LUA_GCCOUNTB* = 4
|
||||||
LUA_GCSTEP* = 5
|
LUA_GCSTEP* = 5
|
||||||
LUA_GCSETPAUSE* = 6
|
LUA_GCSETPAUSE* = 6
|
||||||
LUA_GCSETSTEPMUL* = 7 #
|
LUA_GCSETSTEPMUL* = 7
|
||||||
#** ===============================================================
|
|
||||||
#** some useful macros
|
#
|
||||||
#** ===============================================================
|
#** ===============================================================
|
||||||
#
|
#** some useful macros
|
||||||
|
#** ===============================================================
|
||||||
|
#
|
||||||
|
|
||||||
proc lua_pop*(L: Plua_State, n: int)
|
proc lua_pop*(L: Plua_State, n: int)
|
||||||
proc lua_newtable*(L: Plua_state)
|
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_setglobal*(L: Plua_State, s: cstring)
|
||||||
proc lua_getglobal*(L: Plua_State, s: cstring)
|
proc lua_getglobal*(L: Plua_State, s: cstring)
|
||||||
proc lua_tostring*(L: Plua_State, i: int): 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_getregistry*(L: Plua_State)
|
||||||
proc lua_getgccount*(L: Plua_State): int
|
proc lua_getgccount*(L: Plua_State): int
|
||||||
type
|
type
|
||||||
lua_Chunkreader* = lua_Reader
|
lua_Chunkreader* = lua_Reader
|
||||||
lua_Chunkwriter* = lua_Writer #
|
lua_Chunkwriter* = lua_Writer
|
||||||
#** {======================================================================
|
|
||||||
#** Debug API
|
#
|
||||||
#** =======================================================================
|
#** {======================================================================
|
||||||
#
|
#** Debug API
|
||||||
|
#** =======================================================================
|
||||||
|
#
|
||||||
|
|
||||||
const
|
const
|
||||||
LUA_HOOKCALL* = 0
|
LUA_HOOKCALL* = 0
|
||||||
|
|
@ -297,11 +302,13 @@ type
|
||||||
i_ci*: int # active function
|
i_ci*: int # active function
|
||||||
|
|
||||||
Plua_Debug* = ptr lua_Debug
|
Plua_Debug* = ptr lua_Debug
|
||||||
lua_Hook* = proc (L: Plua_State, ar: Plua_Debug){.cdecl.} #
|
lua_Hook* = proc (L: Plua_State, ar: Plua_Debug){.cdecl.}
|
||||||
#** {======================================================================
|
|
||||||
#** Debug API
|
#
|
||||||
#** =======================================================================
|
#** {======================================================================
|
||||||
#
|
#** Debug API
|
||||||
|
#** =======================================================================
|
||||||
|
#
|
||||||
|
|
||||||
proc lua_getstack*(L: Plua_State, level: int, ar: Plua_Debug): int{.cdecl,
|
proc lua_getstack*(L: Plua_State, level: int, ar: Plua_Debug): int{.cdecl,
|
||||||
dynlib: LUA_NAME, importc.}
|
dynlib: LUA_NAME, importc.}
|
||||||
|
|
|
||||||
|
|
@ -303,10 +303,10 @@ type
|
||||||
mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray,
|
mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray,
|
||||||
mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref,
|
mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref,
|
||||||
mGCunref, mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
|
mGCunref, mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
|
||||||
mDivI64, mModI64, mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI,
|
mDivI64, mModI64,
|
||||||
mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, mMaxI64,
|
|
||||||
mAddF64, mSubF64, mMulF64, mDivF64,
|
mAddF64, mSubF64, mMulF64, mDivF64,
|
||||||
|
mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI,
|
||||||
|
mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, mMaxI64,
|
||||||
mMinF64, mMaxF64, mAddU, mSubU, mMulU,
|
mMinF64, mMaxF64, mAddU, mSubU, mMulU,
|
||||||
mDivU, mModU, mAddU64, mSubU64, mMulU64, mDivU64, mModU64, mEqI, mLeI, mLtI,
|
mDivU, mModU, mAddU64, mSubU64, mMulU64, mDivU64, mModU64, mEqI, mLeI, mLtI,
|
||||||
mEqI64, mLeI64, mLtI64, mEqF64, mLeF64, mLtF64, mLeU, mLtU, mLeU64, mLtU64,
|
mEqI64, mLeI64, mLtI64, mEqF64, mLeF64, mLtF64, mLeU, mLtU, mLeU64, mLtU64,
|
||||||
|
|
|
||||||
191
rod/ccgexprs.nim
191
rod/ccgexprs.nim
|
|
@ -118,7 +118,8 @@ proc genRawSetData(cs: TBitSet, size: int): PRope =
|
||||||
frmt = "0x$1}$n"
|
frmt = "0x$1}$n"
|
||||||
appf(result, frmt, [toRope(toHex(Ze64(cs[i]), 2))])
|
appf(result, frmt, [toRope(toHex(Ze64(cs[i]), 2))])
|
||||||
else:
|
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 =
|
proc genSetNode(p: BProc, n: PNode): PRope =
|
||||||
var
|
var
|
||||||
|
|
@ -384,14 +385,12 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
"modInt64"]
|
"modInt64"]
|
||||||
opr: array[mAddi..mModi64, string] = ["+", "-", "*", "/", "%", "+", "-",
|
opr: array[mAddi..mModi64, string] = ["+", "-", "*", "/", "%", "+", "-",
|
||||||
"*", "/", "%"]
|
"*", "/", "%"]
|
||||||
var
|
var a, b: TLoc
|
||||||
a, b: TLoc
|
|
||||||
t: PType
|
|
||||||
assert(e.sons[1].typ != nil)
|
assert(e.sons[1].typ != nil)
|
||||||
assert(e.sons[2].typ != nil)
|
assert(e.sons[2].typ != nil)
|
||||||
InitLocExpr(p, e.sons[1], a)
|
InitLocExpr(p, e.sons[1], a)
|
||||||
InitLocExpr(p, e.sons[2], b)
|
InitLocExpr(p, e.sons[2], b)
|
||||||
t = skipTypes(e.typ, abstractRange)
|
var t = skipTypes(e.typ, abstractRange)
|
||||||
if getSize(t) >= platform.IntSize:
|
if getSize(t) >= platform.IntSize:
|
||||||
if optOverflowCheck in p.options:
|
if optOverflowCheck in p.options:
|
||||||
useMagic(p.module, prc[m])
|
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) =
|
proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
const
|
const
|
||||||
binArithTab: array[mShrI..mXor, string] = ["(NI$3)((NU$3)($1) >> (NU$3)($2))", #
|
binArithTab: array[mAddF64..mXor, string] = [
|
||||||
# ShrI
|
"($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)((NU$3)($1) << (NU$3)($2))", # ShlI
|
||||||
"(NI$3)($1 & $2)", # BitandI
|
"(NI$3)($1 & $2)", # BitandI
|
||||||
"(NI$3)($1 | $2)", # BitorI
|
"(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)", # BitxorI64
|
||||||
"(($1 <= $2) ? $1 : $2)", # MinI64
|
"(($1 <= $2) ? $1 : $2)", # MinI64
|
||||||
"(($1 >= $2) ? $1 : $2)", # MaxI64
|
"(($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)", # MinF64
|
||||||
"(($1 >= $2) ? $1 : $2)", # MaxF64
|
"(($1 >= $2) ? $1 : $2)", # MaxF64
|
||||||
"(NI$3)((NU$3)($1) + (NU$3)($2))", # AddU
|
"(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[1].typ != nil)
|
||||||
assert(e.sons[2].typ != nil)
|
assert(e.sons[2].typ != nil)
|
||||||
InitLocExpr(p, e.sons[1], a)
|
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
|
s = max(getSize(a.t), getSize(b.t)) * 8
|
||||||
putIntoDest(p, d, e.typ,
|
putIntoDest(p, d, e.typ,
|
||||||
ropef(binArithTab[op], [rdLoc(a), rdLoc(b), toRope(s)]))
|
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)
|
genRecordField(p, e.sons[0], d)
|
||||||
|
|
||||||
proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
|
proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var
|
var a, b: TLoc
|
||||||
a, b: TLoc
|
|
||||||
ty: PType
|
|
||||||
first: PRope
|
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, e.sons[0], a)
|
||||||
initLocExpr(p, e.sons[1], b)
|
initLocExpr(p, e.sons[1], b)
|
||||||
ty = skipTypes(skipTypes(a.t, abstractVarRange), abstractPtrs)
|
var ty = skipTypes(skipTypes(a.t, abstractVarRange), abstractPtrs)
|
||||||
first = intLiteral(firstOrd(ty)) # emit range check:
|
var first = intLiteral(firstOrd(ty))
|
||||||
|
# emit range check:
|
||||||
if (optBoundsCheck in p.options):
|
if (optBoundsCheck in p.options):
|
||||||
if not isConstExpr(e.sons[1]):
|
if not isConstExpr(e.sons[1]):
|
||||||
# semantic pass has already checked for const index expressions
|
# 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]))
|
ropef("$1[($2)-$3]", [rdLoc(a), rdCharLoc(b), first]))
|
||||||
|
|
||||||
proc genCStringElem(p: BProc, e: PNode, d: var TLoc) =
|
proc genCStringElem(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var
|
var a, b: TLoc
|
||||||
a, b: TLoc
|
|
||||||
ty: PType
|
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, e.sons[0], a)
|
||||||
initLocExpr(p, e.sons[1], b)
|
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
|
if d.k == locNone: d.s = a.s
|
||||||
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
|
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
|
||||||
ropef("$1[$2]", [rdLoc(a), rdCharLoc(b)]))
|
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)]))
|
ropef("$1[$2]", [rdLoc(a), rdCharLoc(b)]))
|
||||||
|
|
||||||
proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) =
|
proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) =
|
||||||
var
|
var a, b: TLoc
|
||||||
a, b: TLoc
|
|
||||||
ty: PType
|
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, e.sons[0], a)
|
||||||
initLocExpr(p, e.sons[1], b)
|
initLocExpr(p, e.sons[1], b)
|
||||||
ty = skipTypes(a.t, abstractVarRange)
|
var ty = skipTypes(a.t, abstractVarRange)
|
||||||
if ty.kind in {tyRef, tyPtr}:
|
if ty.kind in {tyRef, tyPtr}:
|
||||||
ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check:
|
ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check:
|
||||||
if (optBoundsCheck in p.options):
|
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!
|
getTemp(p, e.typ, tmp) # force it into a temp!
|
||||||
expr(p, e.sons[1], tmp)
|
expr(p, e.sons[1], tmp)
|
||||||
L = getLabel(p)
|
L = getLabel(p)
|
||||||
if m == mOr: # mAnd:
|
if m == mOr:
|
||||||
appf(p.s[cpsStmts], "if ($1) goto $2;$n", [rdLoc(tmp), L])
|
appf(p.s[cpsStmts], "if ($1) goto $2;$n", [rdLoc(tmp), L])
|
||||||
else:
|
else:
|
||||||
appf(p.s[cpsStmts], "if (!($1)) goto $2;$n", [rdLoc(tmp), L])
|
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');
|
# appendChar(tmp0, 'z');
|
||||||
# asgn(s, tmp0);
|
# asgn(s, tmp0);
|
||||||
# }
|
# }
|
||||||
var
|
var a, tmp: TLoc
|
||||||
a, tmp: TLoc
|
|
||||||
appends, lens: PRope
|
|
||||||
L: int
|
|
||||||
useMagic(p.module, "rawNewString")
|
useMagic(p.module, "rawNewString")
|
||||||
getTemp(p, e.typ, tmp)
|
getTemp(p, e.typ, tmp)
|
||||||
L = 0
|
var L = 0
|
||||||
appends = nil
|
var appends: PRope = nil
|
||||||
lens = nil
|
var lens: PRope = nil
|
||||||
for i in countup(0, sonsLen(e) - 2):
|
for i in countup(0, sonsLen(e) - 2):
|
||||||
# compute the length expression:
|
# compute the length expression:
|
||||||
initLocExpr(p, e.sons[i + 1], a)
|
initLocExpr(p, e.sons[i + 1], a)
|
||||||
|
|
@ -1060,7 +1051,8 @@ proc genNewFinalize(p: BProc, e: PNode) =
|
||||||
oldModule: BModule
|
oldModule: BModule
|
||||||
useMagic(p.module, "newObj")
|
useMagic(p.module, "newObj")
|
||||||
refType = skipTypes(e.sons[1].typ, abstractVarRange)
|
refType = skipTypes(e.sons[1].typ, abstractVarRange)
|
||||||
InitLocExpr(p, e.sons[1], a) # This is a little hack:
|
InitLocExpr(p, e.sons[1], a)
|
||||||
|
# This is a little hack:
|
||||||
# XXX this is also a bug, if the finalizer expression produces side-effects
|
# XXX this is also a bug, if the finalizer expression produces side-effects
|
||||||
oldModule = p.module
|
oldModule = p.module
|
||||||
p.module = gNimDat
|
p.module = gNimDat
|
||||||
|
|
@ -1076,11 +1068,9 @@ proc genNewFinalize(p: BProc, e: PNode) =
|
||||||
genObjectInit(p, bt, a, false)
|
genObjectInit(p, bt, a, false)
|
||||||
|
|
||||||
proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var
|
var a: TLoc
|
||||||
a: TLoc
|
|
||||||
t: PType
|
|
||||||
InitLocExpr(p, e.sons[1], a)
|
InitLocExpr(p, e.sons[1], a)
|
||||||
t = skipTypes(e.sons[1].typ, abstractVarRange)
|
var t = skipTypes(e.sons[1].typ, abstractVarRange)
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyInt..tyInt64:
|
of tyInt..tyInt64:
|
||||||
UseMagic(p.module, "reprInt")
|
UseMagic(p.module, "reprInt")
|
||||||
|
|
@ -1108,8 +1098,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
of tyOpenArray:
|
of tyOpenArray:
|
||||||
useMagic(p.module, "reprOpenArray")
|
useMagic(p.module, "reprOpenArray")
|
||||||
case a.t.kind
|
case a.t.kind
|
||||||
of tyOpenArray:
|
of tyOpenArray: putIntoDest(p, d, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
|
||||||
putIntoDest(p, d, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
|
|
||||||
of tyString, tySequence:
|
of tyString, tySequence:
|
||||||
putIntoDest(p, d, e.typ, ropef("$1->data, $1->Sup.len", [rdLoc(a)]))
|
putIntoDest(p, d, e.typ, ropef("$1->data, $1->Sup.len", [rdLoc(a)]))
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
|
|
@ -1137,8 +1126,7 @@ proc genDollar(p: BProc, n: PNode, d: var TLoc, magic, frmt: string) =
|
||||||
genAssignment(p, d, a, {})
|
genAssignment(p, d, a, {})
|
||||||
|
|
||||||
proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
var typ: PType
|
var typ = skipTypes(e.sons[1].Typ, abstractPtrs)
|
||||||
typ = skipTypes(e.sons[1].Typ, abstractPtrs)
|
|
||||||
case typ.kind
|
case typ.kind
|
||||||
of tyOpenArray:
|
of tyOpenArray:
|
||||||
while e.sons[1].kind == nkPassAsOpenArray: e.sons[1] = e.sons[1].sons[0]
|
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()")
|
else: InternalError(e.info, "genArrayLen()")
|
||||||
|
|
||||||
proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
|
proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var
|
var a, b: TLoc
|
||||||
a, b: TLoc
|
|
||||||
t: PType
|
|
||||||
assert(d.k == locNone)
|
assert(d.k == locNone)
|
||||||
useMagic(p.module, "setLengthSeq")
|
useMagic(p.module, "setLengthSeq")
|
||||||
InitLocExpr(p, e.sons[1], a)
|
InitLocExpr(p, e.sons[1], a)
|
||||||
InitLocExpr(p, e.sons[2], b)
|
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", [
|
appf(p.s[cpsStmts], "$1 = ($3) setLengthSeq(&($1)->Sup, sizeof($4), $2);$n", [
|
||||||
rdLoc(a), rdLoc(b), getTypeDesc(p.module, t),
|
rdLoc(a), rdLoc(b), getTypeDesc(p.module, t),
|
||||||
getTypeDesc(p.module, t.sons[0])])
|
getTypeDesc(p.module, t.sons[0])])
|
||||||
|
|
@ -1202,8 +1188,7 @@ proc fewCmps(s: PNode): bool =
|
||||||
elif elemType(s.typ).Kind in {tyInt, tyInt16..tyInt64}:
|
elif elemType(s.typ).Kind in {tyInt, tyInt16..tyInt64}:
|
||||||
result = true # better not emit the set if int is basetype!
|
result = true # better not emit the set if int is basetype!
|
||||||
else:
|
else:
|
||||||
result = sonsLen(s) <=
|
result = sonsLen(s) <= 8 # 8 seems to be a good value
|
||||||
8 # 8 seems to be a good value
|
|
||||||
|
|
||||||
proc binaryExprIn(p: BProc, e: PNode, a, b, d: var TLoc, frmt: string) =
|
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)]))
|
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)])
|
appf(p.s[cpsStmts], frmt, [rdLoc(a), rdSetElemLoc(b, a.t)])
|
||||||
|
|
||||||
proc genInOp(p: BProc, e: PNode, d: var TLoc) =
|
proc genInOp(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var
|
var a, b, x, y: TLoc
|
||||||
a, b, x, y: TLoc
|
|
||||||
length: int
|
|
||||||
if (e.sons[1].Kind == nkCurly) and fewCmps(e.sons[1]):
|
if (e.sons[1].Kind == nkCurly) and fewCmps(e.sons[1]):
|
||||||
# a set constructor but not a constant set:
|
# a set constructor but not a constant set:
|
||||||
# do not emit the set, but generate a bunch of comparisons
|
# do not emit the set, but generate a bunch of comparisons
|
||||||
initLocExpr(p, e.sons[2], a)
|
initLocExpr(p, e.sons[2], a)
|
||||||
initLoc(b, locExpr, e.typ, OnUnknown)
|
initLoc(b, locExpr, e.typ, OnUnknown)
|
||||||
b.r = toRope("(")
|
b.r = toRope("(")
|
||||||
length = sonsLen(e.sons[1])
|
var length = sonsLen(e.sons[1])
|
||||||
for i in countup(0, length - 1):
|
for i in countup(0, length - 1):
|
||||||
if e.sons[1].sons[i].Kind == nkRange:
|
if e.sons[1].sons[i].Kind == nkRange:
|
||||||
InitLocExpr(p, e.sons[1].sons[i].sons[0], x)
|
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) =
|
proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
const
|
const
|
||||||
lookupOpr: array[mLeSet..mSymDiffSet, string] = ["for ($1 = 0; $1 < $2; $1++) { $n" &
|
lookupOpr: array[mLeSet..mSymDiffSet, string] = [
|
||||||
" $3 = (($4[$1] & ~ $5[$1]) == 0);$n" & " if (!$3) break;}$n", "for ($1 = 0; $1 < $2; $1++) { $n" &
|
"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" &
|
" $3 = (($4[$1] & ~ $5[$1]) == 0);$n" & " if (!$3) break;}$n" &
|
||||||
"if ($3) $3 = (memcmp($4, $5, $2) != 0);$n", "&", "|", "& ~", "^"]
|
"if ($3) $3 = (memcmp($4, $5, $2) != 0);$n",
|
||||||
var
|
"&", "|", "& ~", "^"]
|
||||||
size: int
|
var a, b, i: TLoc
|
||||||
setType: PType
|
var setType = skipTypes(e.sons[1].Typ, abstractVar)
|
||||||
a, b, i: TLoc
|
var size = int(getSize(setType))
|
||||||
ts: string
|
|
||||||
setType = skipTypes(e.sons[1].Typ, abstractVar)
|
|
||||||
size = int(getSize(setType))
|
|
||||||
case size
|
case size
|
||||||
of 1, 2, 4, 8:
|
of 1, 2, 4, 8:
|
||||||
case op
|
case op
|
||||||
of mIncl:
|
of mIncl:
|
||||||
ts = "NI" & $(size * 8)
|
var ts = "NI" & $(size * 8)
|
||||||
binaryStmtInExcl(p, e, d,
|
binaryStmtInExcl(p, e, d,
|
||||||
"$1 |=(1<<((" & ts & ")($2)%(sizeof(" & ts & ")*8)));$n")
|
"$1 |=(1<<((" & ts & ")($2)%(sizeof(" & ts & ")*8)));$n")
|
||||||
of mExcl:
|
of mExcl:
|
||||||
ts = "NI" & $(size * 8)
|
var ts = "NI" & $(size * 8)
|
||||||
binaryStmtInExcl(p, e, d, "$1 &= ~(1 << ((" & ts & ")($2) % (sizeof(" &
|
binaryStmtInExcl(p, e, d, "$1 &= ~(1 << ((" & ts & ")($2) % (sizeof(" &
|
||||||
ts & ")*8)));$n")
|
ts & ")*8)));$n")
|
||||||
of mCard:
|
of mCard:
|
||||||
if size <= 4: unaryExprChar(p, e, d, "countBits32", "countBits32($1)")
|
if size <= 4: unaryExprChar(p, e, d, "countBits32", "countBits32($1)")
|
||||||
else: unaryExprChar(p, e, d, "countBits64", "countBits64($1)")
|
else: unaryExprChar(p, e, d, "countBits64", "countBits64($1)")
|
||||||
of mLtSet:
|
of mLtSet: binaryExprChar(p, e, d, "", "(($1 & ~ $2 ==0)&&($1 != $2))")
|
||||||
binaryExprChar(p, e, d, "", "(($1 & ~ $2 ==0)&&($1 != $2))")
|
of mLeSet: binaryExprChar(p, e, d, "", "(($1 & ~ $2)==0)")
|
||||||
of mLeSet:
|
of mEqSet: binaryExpr(p, e, d, "", "($1 == $2)")
|
||||||
binaryExprChar(p, e, d, "", "(($1 & ~ $2)==0)")
|
of mMulSet: binaryExpr(p, e, d, "", "($1 & $2)")
|
||||||
of mEqSet:
|
of mPlusSet: binaryExpr(p, e, d, "", "($1 | $2)")
|
||||||
binaryExpr(p, e, d, "", "($1 == $2)")
|
of mMinusSet: binaryExpr(p, e, d, "", "($1 & ~ $2)")
|
||||||
of mMulSet:
|
of mSymDiffSet: binaryExpr(p, e, d, "", "($1 ^ $2)")
|
||||||
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:
|
of mInSet:
|
||||||
genInOp(p, e, d)
|
genInOp(p, e, d)
|
||||||
else: internalError(e.info, "genSetOp()")
|
else: internalError(e.info, "genSetOp()")
|
||||||
else:
|
else:
|
||||||
case op
|
case op
|
||||||
of mIncl:
|
of mIncl: binaryStmtInExcl(p, e, d, "$1[$2/8] |=(1<<($2%8));$n")
|
||||||
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 mExcl:
|
of mCard: unaryExprChar(p, e, d, "cardSet", "cardSet($1, " & $size & ')')
|
||||||
binaryStmtInExcl(p, e, d, "$1[$2/8] &= ~(1<<($2%8));$n")
|
|
||||||
of mCard:
|
|
||||||
unaryExprChar(p, e, d, "cardSet", "cardSet($1, " & $(size) & ')')
|
|
||||||
of mLtSet, mLeSet:
|
of mLtSet, mLeSet:
|
||||||
getTemp(p, getSysType(tyInt), i) # our counter
|
getTemp(p, getSysType(tyInt), i) # our counter
|
||||||
initLocExpr(p, e.sons[1], a)
|
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", [
|
"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),
|
rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b),
|
||||||
toRope(lookupOpr[op])])
|
toRope(lookupOpr[op])])
|
||||||
of mInSet:
|
of mInSet: genInOp(p, e, d)
|
||||||
genInOp(p, e, d)
|
|
||||||
else: internalError(e.info, "genSetOp")
|
else: internalError(e.info, "genSetOp")
|
||||||
|
|
||||||
proc genOrd(p: BProc, e: PNode, d: var TLoc) =
|
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)]))
|
[getTypeDesc(p.module, e.typ), rdCharLoc(a)]))
|
||||||
|
|
||||||
proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
|
proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
|
||||||
var
|
var a: TLoc
|
||||||
a: TLoc
|
var dest = skipTypes(n.typ, abstractVar)
|
||||||
dest: PType
|
|
||||||
dest = skipTypes(n.typ, abstractVar)
|
|
||||||
if not (optRangeCheck in p.options):
|
if not (optRangeCheck in p.options):
|
||||||
InitLocExpr(p, n.sons[0], a)
|
InitLocExpr(p, n.sons[0], a)
|
||||||
putIntoDest(p, d, n.typ, ropef("(($1) ($2))",
|
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)
|
genCast(p, e, d)
|
||||||
|
|
||||||
proc passToOpenArray(p: BProc, n: PNode, d: var TLoc) =
|
proc passToOpenArray(p: BProc, n: PNode, d: var TLoc) =
|
||||||
var
|
var a: TLoc
|
||||||
a: TLoc
|
|
||||||
dest: PType
|
|
||||||
while n.sons[0].kind == nkPassAsOpenArray:
|
while n.sons[0].kind == nkPassAsOpenArray:
|
||||||
n.sons[0] = n.sons[0].sons[0] # BUGFIX
|
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
|
case skipTypes(n.sons[0].typ, abstractVar).kind
|
||||||
of tyOpenArray:
|
of tyOpenArray:
|
||||||
initLocExpr(p, n.sons[0], a)
|
initLocExpr(p, n.sons[0], a)
|
||||||
|
|
@ -1398,11 +1365,9 @@ proc convCStrToStr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
ropef("cstrToNimstr($1)", [rdLoc(a)]))
|
ropef("cstrToNimstr($1)", [rdLoc(a)]))
|
||||||
|
|
||||||
proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
|
proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var
|
var x: TLoc
|
||||||
a, b: PNode
|
var a = e.sons[1]
|
||||||
x: TLoc
|
var b = e.sons[2]
|
||||||
a = e.sons[1]
|
|
||||||
b = e.sons[2]
|
|
||||||
if (a.kind == nkNilLit) or (b.kind == nkNilLit):
|
if (a.kind == nkNilLit) or (b.kind == nkNilLit):
|
||||||
binaryExpr(p, e, d, "", "($1 == $2)")
|
binaryExpr(p, e, d, "", "($1 == $2)")
|
||||||
elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""):
|
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)
|
expr(p, t.sons[i], arr)
|
||||||
|
|
||||||
proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
|
proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
|
||||||
var
|
var newSeq, elem, a, arr: TLoc
|
||||||
newSeq, elem, a, arr: TLoc
|
|
||||||
L: int
|
|
||||||
if t.kind == nkBracket:
|
if t.kind == nkBracket:
|
||||||
t.sons[1].typ = t.typ
|
t.sons[1].typ = t.typ
|
||||||
genSeqConstr(p, t.sons[1], d)
|
genSeqConstr(p, t.sons[1], d)
|
||||||
|
|
@ -1442,7 +1405,7 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
|
||||||
if d.k == locNone:
|
if d.k == locNone:
|
||||||
getTemp(p, t.typ, d)
|
getTemp(p, t.typ, d)
|
||||||
# generate call to newSeq before adding the elements per hand:
|
# 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)
|
initLoc(newSeq, locExpr, t.typ, OnHeap)
|
||||||
newSeq.r = ropef("($1) newSeq($2, $3)", [getTypeDesc(p.module, t.typ),
|
newSeq.r = ropef("($1) newSeq($2, $3)", [getTypeDesc(p.module, t.typ),
|
||||||
genTypeInfo(p.module, t.typ), intLiteral(L)])
|
genTypeInfo(p.module, t.typ), intLiteral(L)])
|
||||||
|
|
@ -1456,12 +1419,32 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
|
||||||
arr.r = ropef("$1[$2]", [rdLoc(a), intLiteral(i)])
|
arr.r = ropef("$1[$2]", [rdLoc(a), intLiteral(i)])
|
||||||
genAssignment(p, elem, arr, {afDestIsNil, needToCopy})
|
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) =
|
proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
var line, filen: PRope
|
var line, filen: PRope
|
||||||
case op
|
case op
|
||||||
of mOr, mAnd: genAndOr(p, e, d, op)
|
of mOr, mAnd: genAndOr(p, e, d, op)
|
||||||
of mNot..mToBiggestInt: unaryArith(p, e, d, op)
|
of mNot..mToBiggestInt: unaryArith(p, e, d, op)
|
||||||
of mUnaryMinusI..mAbsI64: unaryArithOverflow(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 mShrI..mXor: binaryArith(p, e, d, op)
|
||||||
of mAddi..mModi64: binaryArithOverflow(p, e, d, op)
|
of mAddi..mModi64: binaryArithOverflow(p, e, d, op)
|
||||||
of mRepr: genRepr(p, e, d)
|
of mRepr: genRepr(p, e, d)
|
||||||
|
|
|
||||||
|
|
@ -327,7 +327,7 @@ proc libCandidates(s: string, dest: var TStringSeq) =
|
||||||
if le >= 0 and ri > le:
|
if le >= 0 and ri > le:
|
||||||
var prefix = copy(s, 0, le - 1)
|
var prefix = copy(s, 0, le - 1)
|
||||||
var suffix = copy(s, ri + 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)
|
libCandidates(prefix & middle & suffix, dest)
|
||||||
else:
|
else:
|
||||||
add(dest, s)
|
add(dest, s)
|
||||||
|
|
|
||||||
|
|
@ -47,18 +47,20 @@ Options:
|
||||||
-d, --define:SYMBOL define a conditional symbol
|
-d, --define:SYMBOL define a conditional symbol
|
||||||
-u, --undef:SYMBOL undefine a conditional symbol
|
-u, --undef:SYMBOL undefine a conditional symbol
|
||||||
-f, --forceBuild force rebuilding of all modules
|
-f, --forceBuild force rebuilding of all modules
|
||||||
--symbolFiles:on|off use symbol files to speed up compilation (buggy!)
|
--stackTrace:on|off turn stack tracing on|off
|
||||||
--stackTrace:on|off code generation for stack trace ON|OFF
|
--lineTrace:on|off turn line tracing on|off
|
||||||
--lineTrace:on|off code generation for line trace ON|OFF
|
--debugger:on|off turn Embedded Nimrod Debugger on|off
|
||||||
--debugger:on|off turn Embedded Nimrod Debugger ON|OFF
|
-x, --checks:on|off turn all runtime checks on|off
|
||||||
-x, --checks:on|off code generation for all runtime checks ON|OFF
|
--objChecks:on|off turn obj conversion checks on|off
|
||||||
--objChecks:on|off code generation for obj conversion checks ON|OFF
|
--fieldChecks:on|off turn case variant field checks on|off
|
||||||
--fieldChecks:on|off code generation for case variant fields ON|OFF
|
--rangeChecks:on|off turn range checks on|off
|
||||||
--rangeChecks:on|off code generation for range checks ON|OFF
|
--boundChecks:on|off turn bound checks on|off
|
||||||
--boundChecks:on|off code generation for bound checks ON|OFF
|
--overflowChecks:on|off turn int over-/underflow checks on|off
|
||||||
--overflowChecks:on|off code generation for over-/underflow checks ON|OFF
|
-a, --assertions:on|off turn assertions on|off
|
||||||
-a, --assertions:on|off code generation for assertions ON|OFF
|
--floatChecks:on|off turn all floating point (NaN/Inf) checks on|off
|
||||||
--deadCodeElim:on|off whole program dead code elimination 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
|
--opt:none|speed|size optimize not at all or for speed|size
|
||||||
--app:console|gui|lib generate a console|GUI application|dynamic library
|
--app:console|gui|lib generate a console|GUI application|dynamic library
|
||||||
-r, --run run the compiled program with given arguments
|
-r, --run run the compiled program with given arguments
|
||||||
|
|
@ -76,10 +78,10 @@ Advanced commands::
|
||||||
check checks the project for syntax and semantic
|
check checks the project for syntax and semantic
|
||||||
parse parses a single file (for debugging Nimrod)
|
parse parses a single file (for debugging Nimrod)
|
||||||
Advanced options:
|
Advanced options:
|
||||||
-w, --warnings:on|off warnings ON|OFF
|
-w, --warnings:on|off turn all warnings on|off
|
||||||
--warning[X]:on|off specific warning X ON|OFF
|
--warning[X]:on|off turn specific warning X on|off
|
||||||
--hints:on|off hints ON|OFF
|
--hints:on|off turn all hints on|off
|
||||||
--hint[X]:on|off specific hint X ON|OFF
|
--hint[X]:on|off turn specific hint X on|off
|
||||||
--lib:PATH set the system library path
|
--lib:PATH set the system library path
|
||||||
-c, --compileOnly compile only; do not assemble or link
|
-c, --compileOnly compile only; do not assemble or link
|
||||||
--noLinking compile but do not link
|
--noLinking compile but do not link
|
||||||
|
|
@ -93,8 +95,8 @@ Advanced options:
|
||||||
-l, --passl:OPTION pass an option to the linker
|
-l, --passl:OPTION pass an option to the linker
|
||||||
--genMapping generate a mapping file containing
|
--genMapping generate a mapping file containing
|
||||||
(Nimrod, mangled) identifier pairs
|
(Nimrod, mangled) identifier pairs
|
||||||
--lineDir:on|off generation of #line directive ON|OFF
|
--lineDir:on|off generation of #line directive on|off
|
||||||
--checkpoints:on|off turn on|off checkpoints; for debugging Nimrod
|
--checkpoints:on|off turn checkpoints on|off; for debugging Nimrod
|
||||||
--skipCfg do not read the general configuration file
|
--skipCfg do not read the general configuration file
|
||||||
--skipProjCfg do not read the project's configuration file
|
--skipProjCfg do not read the project's configuration file
|
||||||
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
|
--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,
|
proc splitSwitch(switch: string, cmd, arg: var string, pass: TCmdLinePass,
|
||||||
info: TLineInfo) =
|
info: TLineInfo) =
|
||||||
var i: int
|
|
||||||
cmd = ""
|
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)
|
||||||
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:
|
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,
|
proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass,
|
||||||
info: TLineInfo) =
|
info: TLineInfo) =
|
||||||
var
|
var id = "" # arg = "X]:on|off"
|
||||||
i, x: int
|
var i = 0
|
||||||
n: TNoteKind
|
var n = hintMin
|
||||||
id: string
|
|
||||||
id = "" # arg = "X]:on|off"
|
|
||||||
i = 0
|
|
||||||
n = hintMin
|
|
||||||
while (i < len(arg) + 0) and (arg[i] != ']'):
|
while (i < len(arg) + 0) and (arg[i] != ']'):
|
||||||
add(id, arg[i])
|
add(id, arg[i])
|
||||||
inc(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)
|
if (i < len(arg) + 0) and (arg[i] in {':', '='}): inc(i)
|
||||||
else: InvalidCmdLineOption(pass, arg, info)
|
else: InvalidCmdLineOption(pass, arg, info)
|
||||||
if state == wHint:
|
if state == wHint:
|
||||||
x = findStr(msgs.HintsToStr, id)
|
var x = findStr(msgs.HintsToStr, id)
|
||||||
if x >= 0: n = TNoteKind(x + ord(hintMin))
|
if x >= 0: n = TNoteKind(x + ord(hintMin))
|
||||||
else: InvalidCmdLineOption(pass, arg, info)
|
else: InvalidCmdLineOption(pass, arg, info)
|
||||||
else:
|
else:
|
||||||
x = findStr(msgs.WarningsToStr, id)
|
var x = findStr(msgs.WarningsToStr, id)
|
||||||
if x >= 0: n = TNoteKind(x + ord(warnMin))
|
if x >= 0: n = TNoteKind(x + ord(warnMin))
|
||||||
else: InvalidCmdLineOption(pass, arg, info)
|
else: InvalidCmdLineOption(pass, arg, info)
|
||||||
case whichKeyword(copy(arg, i))
|
case whichKeyword(copy(arg, i))
|
||||||
|
|
@ -297,6 +294,10 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||||
if optProfiler in gOptions: DefineSymbol("profiler")
|
if optProfiler in gOptions: DefineSymbol("profiler")
|
||||||
else: UndefSymbol("profiler")
|
else: UndefSymbol("profiler")
|
||||||
of wChecks, wX: ProcessOnOffSwitch(checksOptions, arg, pass, info)
|
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 wObjChecks: ProcessOnOffSwitch({optObjCheck}, arg, pass, info)
|
||||||
of wFieldChecks: ProcessOnOffSwitch({optFieldCheck}, arg, pass, info)
|
of wFieldChecks: ProcessOnOffSwitch({optFieldCheck}, arg, pass, info)
|
||||||
of wRangeChecks: ProcessOnOffSwitch({optRangeCheck}, arg, pass, info)
|
of wRangeChecks: ProcessOnOffSwitch({optRangeCheck}, arg, pass, info)
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ proc countDefinedSymbols(): int =
|
||||||
proc InitDefines() =
|
proc InitDefines() =
|
||||||
initStrTable(gSymbols)
|
initStrTable(gSymbols)
|
||||||
DefineSymbol("nimrod") # 'nimrod' is always defined
|
DefineSymbol("nimrod") # 'nimrod' is always defined
|
||||||
|
|
||||||
# add platform specific symbols:
|
# add platform specific symbols:
|
||||||
case targetCPU
|
case targetCPU
|
||||||
of cpuI386: DefineSymbol("x86")
|
of cpuI386: DefineSymbol("x86")
|
||||||
|
|
@ -103,7 +104,7 @@ proc InitDefines() =
|
||||||
DefineSymbol("posix")
|
DefineSymbol("posix")
|
||||||
else:
|
else:
|
||||||
nil
|
nil
|
||||||
DefineSymbol("cpu" & $(cpu[targetCPU].bit))
|
DefineSymbol("cpu" & $cpu[targetCPU].bit)
|
||||||
DefineSymbol(normalize(endianToStr[cpu[targetCPU].endian]))
|
DefineSymbol(normalize(endianToStr[cpu[targetCPU].endian]))
|
||||||
DefineSymbol(cpu[targetCPU].name)
|
DefineSymbol(cpu[targetCPU].name)
|
||||||
DefineSymbol(platform.os[targetOS].name)
|
DefineSymbol(platform.os[targetOS].name)
|
||||||
|
|
|
||||||
|
|
@ -536,7 +536,7 @@ proc renderRstToRst(d: PDoc, n: PRstNode): PRope =
|
||||||
result = ropef("$n$n$1.. index::$n$2", [ind, result])
|
result = ropef("$n$n$1.. index::$n$2", [ind, result])
|
||||||
of rnContents:
|
of rnContents:
|
||||||
result = ropef("$n$n$1.. contents::", [ind])
|
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 =
|
proc renderTocEntry(d: PDoc, e: TTocEntry): PRope =
|
||||||
result = dispF("<li><a class=\"reference\" id=\"$1_toc\" href=\"#$1\">$2</a></li>$n",
|
result = dispF("<li><a class=\"reference\" id=\"$1_toc\" href=\"#$1\">$2</a></li>$n",
|
||||||
|
|
@ -582,16 +582,12 @@ proc renderImage(d: PDoc, n: PRstNode): PRope =
|
||||||
if rsonsLen(n) >= 3: app(result, renderRstToOut(d, n.sons[2]))
|
if rsonsLen(n) >= 3: app(result, renderRstToOut(d, n.sons[2]))
|
||||||
|
|
||||||
proc renderCodeBlock(d: PDoc, n: PRstNode): PRope =
|
proc renderCodeBlock(d: PDoc, n: PRstNode): PRope =
|
||||||
var
|
|
||||||
m: PRstNode
|
|
||||||
g: TGeneralTokenizer
|
|
||||||
langstr: string
|
|
||||||
lang: TSourceLanguage
|
|
||||||
result = nil
|
result = nil
|
||||||
if n.sons[2] == nil: return
|
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")
|
if (m.kind != rnLeaf): InternalError("renderCodeBlock")
|
||||||
langstr = strip(getArgument(n))
|
var langstr = strip(getArgument(n))
|
||||||
|
var lang: TSourceLanguage
|
||||||
if langstr == "":
|
if langstr == "":
|
||||||
lang = langNimrod # default language
|
lang = langNimrod # default language
|
||||||
else:
|
else:
|
||||||
|
|
@ -600,12 +596,12 @@ proc renderCodeBlock(d: PDoc, n: PRstNode): PRope =
|
||||||
rawMessage(warnLanguageXNotSupported, langstr)
|
rawMessage(warnLanguageXNotSupported, langstr)
|
||||||
result = toRope(m.text)
|
result = toRope(m.text)
|
||||||
else:
|
else:
|
||||||
|
var g: TGeneralTokenizer
|
||||||
initGeneralTokenizer(g, m.text)
|
initGeneralTokenizer(g, m.text)
|
||||||
while true:
|
while true:
|
||||||
getNextToken(g, lang)
|
getNextToken(g, lang)
|
||||||
case g.kind
|
case g.kind
|
||||||
of gtEof:
|
of gtEof: break
|
||||||
break
|
|
||||||
of gtNone, gtWhitespace:
|
of gtNone, gtWhitespace:
|
||||||
app(result, copy(m.text, g.start + 0, g.length + g.start - 1 + 0))
|
app(result, copy(m.text, g.start + 0, g.length + g.start - 1 + 0))
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ proc initCompRes(r: var TCompRes) =
|
||||||
|
|
||||||
proc initProc(p: var TProc, globals: PGlobals, module: BModule, procDef: PNode,
|
proc initProc(p: var TProc, globals: PGlobals, module: BModule, procDef: PNode,
|
||||||
options: TOptions) =
|
options: TOptions) =
|
||||||
p.blocks = @ []
|
p.blocks = @[]
|
||||||
p.options = options
|
p.options = options
|
||||||
p.module = module
|
p.module = module
|
||||||
p.procDef = procDef
|
p.procDef = procDef
|
||||||
|
|
@ -87,8 +87,7 @@ const
|
||||||
tySet, tyVar, tyRef, tyPtr}
|
tySet, tyVar, tyRef, tyPtr}
|
||||||
|
|
||||||
proc mapType(typ: PType): TEcmasTypeKind =
|
proc mapType(typ: PType): TEcmasTypeKind =
|
||||||
var t: PType
|
var t = skipTypes(typ, abstractInst)
|
||||||
t = skipTypes(typ, abstractInst)
|
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyVar, tyRef, tyPtr:
|
of tyVar, tyRef, tyPtr:
|
||||||
if skipTypes(t.sons[0], abstractInst).kind in mappedToObject:
|
if skipTypes(t.sons[0], abstractInst).kind in mappedToObject:
|
||||||
|
|
@ -98,29 +97,20 @@ proc mapType(typ: PType): TEcmasTypeKind =
|
||||||
of tyPointer:
|
of tyPointer:
|
||||||
# treat a tyPointer like a typed pointer to an array of bytes
|
# treat a tyPointer like a typed pointer to an array of bytes
|
||||||
result = etyInt
|
result = etyInt
|
||||||
of tyRange, tyDistinct, tyOrdinal:
|
of tyRange, tyDistinct, tyOrdinal: result = mapType(t.sons[0])
|
||||||
result = mapType(t.sons[0])
|
of tyInt..tyInt64, tyEnum, tyChar: result = etyInt
|
||||||
of tyInt..tyInt64, tyEnum, tyChar:
|
of tyBool: result = etyBool
|
||||||
result = etyInt
|
of tyFloat..tyFloat128: result = etyFloat
|
||||||
of tyBool:
|
of tySet: result = etyObject # map a set to a table
|
||||||
result = etyBool
|
of tyString, tySequence: result = etyInt # little hack to get right semantics
|
||||||
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 tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray:
|
of tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray:
|
||||||
result = etyObject
|
result = etyObject
|
||||||
of tyNil:
|
of tyNil: result = etyNull
|
||||||
result = etyNull
|
|
||||||
of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, tyNone,
|
of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, tyNone,
|
||||||
tyForward, tyEmpty, tyExpr, tyStmt, tyTypeDesc:
|
tyForward, tyEmpty, tyExpr, tyStmt, tyTypeDesc:
|
||||||
result = etyNone
|
result = etyNone
|
||||||
of tyProc:
|
of tyProc: result = etyProc
|
||||||
result = etyProc
|
of tyCString: result = etyString
|
||||||
of tyCString:
|
|
||||||
result = etyString
|
|
||||||
|
|
||||||
proc mangle(name: string): string =
|
proc mangle(name: string): string =
|
||||||
result = ""
|
result = ""
|
||||||
|
|
@ -132,7 +122,7 @@ proc mangle(name: string): string =
|
||||||
nil
|
nil
|
||||||
of 'a'..'z', '0'..'9':
|
of 'a'..'z', '0'..'9':
|
||||||
add(result, name[i])
|
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 =
|
proc mangleName(s: PSym): PRope =
|
||||||
result = s.loc.r
|
result = s.loc.r
|
||||||
|
|
@ -199,8 +189,7 @@ proc genObjectFields(p: var TProc, typ: PType, n: PNode): PRope =
|
||||||
else: internalError(n.info, "genObjectFields")
|
else: internalError(n.info, "genObjectFields")
|
||||||
|
|
||||||
proc genObjectInfo(p: var TProc, typ: PType, name: PRope) =
|
proc genObjectInfo(p: var TProc, typ: PType, name: PRope) =
|
||||||
var s: PRope
|
var s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
|
||||||
s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
|
|
||||||
"finalizer: null};$n", [name, toRope(ord(typ.kind))])
|
"finalizer: null};$n", [name, toRope(ord(typ.kind))])
|
||||||
prepend(p.globals.typeInfo, s)
|
prepend(p.globals.typeInfo, s)
|
||||||
appf(p.globals.typeInfo, "var NNI$1 = $2;$n",
|
appf(p.globals.typeInfo, "var NNI$1 = $2;$n",
|
||||||
|
|
@ -302,8 +291,8 @@ type
|
||||||
TMagicFrmt = array[0..3, string]
|
TMagicFrmt = array[0..3, string]
|
||||||
|
|
||||||
const # magic checked op; magic unchecked op; checked op; unchecked op
|
const # magic checked op; magic unchecked op; checked op; unchecked op
|
||||||
ops: array[mAddi..mStrToStr, TMagicFrmt] = [["addInt", "", "addInt($1, $2)",
|
ops: array[mAddi..mStrToStr, TMagicFrmt] = [
|
||||||
"($1 + $2)"], # AddI
|
["addInt", "", "addInt($1, $2)", "($1 + $2)"], # AddI
|
||||||
["subInt", "", "subInt($1, $2)", "($1 - $2)"], # SubI
|
["subInt", "", "subInt($1, $2)", "($1 - $2)"], # SubI
|
||||||
["mulInt", "", "mulInt($1, $2)", "($1 * $2)"], # MulI
|
["mulInt", "", "mulInt($1, $2)", "($1 * $2)"], # MulI
|
||||||
["divInt", "", "divInt($1, $2)", "Math.floor($1 / $2)"], # DivI
|
["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
|
["mulInt64", "", "mulInt64($1, $2)", "($1 * $2)"], # MulI64
|
||||||
["divInt64", "", "divInt64($1, $2)", "Math.floor($1 / $2)"], # DivI64
|
["divInt64", "", "divInt64($1, $2)", "Math.floor($1 / $2)"], # DivI64
|
||||||
["modInt64", "", "modInt64($1, $2)", "Math.floor($1 % $2)"], # ModI64
|
["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)"], # ShrI
|
||||||
["", "", "($1 << $2)", "($1 << $2)"], # ShlI
|
["", "", "($1 << $2)", "($1 << $2)"], # ShlI
|
||||||
["", "", "($1 & $2)", "($1 & $2)"], # BitandI
|
["", "", "($1 & $2)", "($1 & $2)"], # BitandI
|
||||||
|
|
@ -327,10 +320,6 @@ const # magic checked op; magic unchecked op; checked op
|
||||||
["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI64
|
["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI64
|
||||||
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinI64
|
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinI64
|
||||||
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI64
|
["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
|
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64
|
||||||
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64
|
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64
|
||||||
["AddU", "AddU", "AddU($1, $2)", "AddU($1, $2)"], # AddU
|
["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)])
|
appf(r.com, "F.line = $1;$n", [toRope(line)])
|
||||||
|
|
||||||
proc finishTryStmt(p: var TProc, r: var TCompRes, howMany: int) =
|
proc finishTryStmt(p: var TProc, r: var TCompRes, howMany: int) =
|
||||||
for i in countup(1, howMany): app(r.com, "excHandler = excHandler.prev;" &
|
for i in countup(1, howMany):
|
||||||
tnl)
|
app(r.com, "excHandler = excHandler.prev;" & tnl)
|
||||||
|
|
||||||
proc genWhileStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
proc genWhileStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
var
|
var
|
||||||
|
|
|
||||||
23
rod/expand_importc.nim
Executable file
23
rod/expand_importc.nim
Executable file
|
|
@ -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 ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2008 Andreas Rumpf
|
# (c) Copyright 2009 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -37,15 +37,11 @@ proc getModuleFile(n: PNode): string =
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
proc rawImportSymbol(c: PContext, s: PSym) =
|
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
|
# This does not handle stubs, because otherwise loading on demand would be
|
||||||
# pointless in practice. So importing stubs is fine here!
|
# 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 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 (check != nil) and (check.id != copy.id):
|
||||||
if not (s.kind in OverloadableSyms):
|
if not (s.kind in OverloadableSyms):
|
||||||
# s and check need to be qualified:
|
# s and check need to be qualified:
|
||||||
|
|
@ -53,15 +49,16 @@ proc rawImportSymbol(c: PContext, s: PSym) =
|
||||||
IntSetIncl(c.AmbiguousSymbols, check.id)
|
IntSetIncl(c.AmbiguousSymbols, check.id)
|
||||||
StrTableAdd(c.tab.stack[importTablePos], copy)
|
StrTableAdd(c.tab.stack[importTablePos], copy)
|
||||||
if s.kind == skType:
|
if s.kind == skType:
|
||||||
etyp = s.typ
|
var etyp = s.typ
|
||||||
if etyp.kind in {tyBool, tyEnum}:
|
if etyp.kind in {tyBool, tyEnum}:
|
||||||
for j in countup(0, sonsLen(etyp.n) - 1):
|
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):
|
if (e.Kind != skEnumField):
|
||||||
InternalError(s.info, "rawImportSymbol")
|
InternalError(s.info, "rawImportSymbol")
|
||||||
# BUGFIX: because of aliases for enums the symbol may already
|
# BUGFIX: because of aliases for enums the symbol may already
|
||||||
# have been put into the symbol table
|
# have been put into the symbol table
|
||||||
# BUGFIX: but only iff they are the same symbols!
|
# BUGFIX: but only iff they are the same symbols!
|
||||||
|
var it: TIdentIter
|
||||||
check = InitIdentIter(it, c.tab.stack[importTablePos], e.name)
|
check = InitIdentIter(it, c.tab.stack[importTablePos], e.name)
|
||||||
while check != nil:
|
while check != nil:
|
||||||
if check.id == e.id:
|
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
|
addConverter(c, s) # rodgen assures that converters are no stubs
|
||||||
|
|
||||||
proc importSymbol(c: PContext, ident: PNode, fromMod: PSym) =
|
proc importSymbol(c: PContext, ident: PNode, fromMod: PSym) =
|
||||||
var
|
|
||||||
s, e: PSym
|
|
||||||
it: TIdentIter
|
|
||||||
if (ident.kind != nkIdent): InternalError(ident.info, "importSymbol")
|
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 == nil: liMessage(ident.info, errUndeclaredIdentifier, ident.ident.s)
|
||||||
if s.kind == skStub: loadStub(s)
|
if s.kind == skStub: loadStub(s)
|
||||||
if not (s.Kind in ExportableSymKinds):
|
if not (s.Kind in ExportableSymKinds):
|
||||||
|
|
@ -87,7 +81,8 @@ proc importSymbol(c: PContext, ident: PNode, fromMod: PSym) =
|
||||||
case s.Kind
|
case s.Kind
|
||||||
of skProc, skMethod, skIterator, skMacro, skTemplate, skConverter:
|
of skProc, skMethod, skIterator, skMacro, skTemplate, skConverter:
|
||||||
# for a overloadable syms add all overloaded routines
|
# 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:
|
while e != nil:
|
||||||
if (e.name.id != s.Name.id): InternalError(ident.info, "importSymbol: 3")
|
if (e.name.id != s.Name.id): InternalError(ident.info, "importSymbol: 3")
|
||||||
rawImportSymbol(c, e)
|
rawImportSymbol(c, e)
|
||||||
|
|
|
||||||
13
rod/main.nim
13
rod/main.nim
|
|
@ -31,8 +31,7 @@ var compMods: TFileModuleMap = @ []
|
||||||
|
|
||||||
proc registerModule(filename: string, module: PSym) =
|
proc registerModule(filename: string, module: PSym) =
|
||||||
# all compiled modules
|
# all compiled modules
|
||||||
var length: int
|
var length = len(compMods)
|
||||||
length = len(compMods)
|
|
||||||
setlen(compMods, length + 1)
|
setlen(compMods, length + 1)
|
||||||
compMods[length].filename = filename
|
compMods[length].filename = filename
|
||||||
compMods[length].module = module
|
compMods[length].module = module
|
||||||
|
|
@ -50,6 +49,9 @@ proc newModule(filename: string): PSym =
|
||||||
result.id = - 1 # for better error checking
|
result.id = - 1 # for better error checking
|
||||||
result.kind = skModule
|
result.kind = skModule
|
||||||
result.name = getIdent(splitFile(filename).name)
|
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.owner = result # a module belongs to itself
|
||||||
result.info = newLineInfo(filename, 1, 1)
|
result.info = newLineInfo(filename, 1, 1)
|
||||||
incl(result.flags, sfUsed)
|
incl(result.flags, sfUsed)
|
||||||
|
|
@ -68,11 +70,8 @@ proc importModule(filename: string): PSym =
|
||||||
liMessage(result.info, errAttemptToRedefine, result.Name.s)
|
liMessage(result.info, errAttemptToRedefine, result.Name.s)
|
||||||
|
|
||||||
proc CompileModule(filename: string, isMainFile, isSystemFile: bool): PSym =
|
proc CompileModule(filename: string, isMainFile, isSystemFile: bool): PSym =
|
||||||
var
|
var rd: PRodReader = nil
|
||||||
rd: PRodReader
|
var f = addFileExt(filename, nimExt)
|
||||||
f: string
|
|
||||||
rd = nil
|
|
||||||
f = addFileExt(filename, nimExt)
|
|
||||||
result = newModule(filename)
|
result = newModule(filename)
|
||||||
if isMainFile: incl(result.flags, sfMainModule)
|
if isMainFile: incl(result.flags, sfMainModule)
|
||||||
if isSystemFile: incl(result.flags, sfSystemModule)
|
if isSystemFile: incl(result.flags, sfSystemModule)
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,4 @@
|
||||||
@elif vcc:
|
@elif vcc:
|
||||||
# cgen.speed = ""
|
# cgen.speed = ""
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,7 @@ var
|
||||||
cmdLineInfo: TLineInfo
|
cmdLineInfo: TLineInfo
|
||||||
|
|
||||||
proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
|
proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
|
||||||
var
|
var p = parseopt.init()
|
||||||
p: TOptParser
|
|
||||||
bracketLe: int
|
|
||||||
key, val: string
|
|
||||||
p = parseopt.init()
|
|
||||||
while true:
|
while true:
|
||||||
parseopt.next(p)
|
parseopt.next(p)
|
||||||
case p.kind
|
case p.kind
|
||||||
|
|
@ -30,10 +26,10 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
|
||||||
of cmdLongOption, cmdShortOption:
|
of cmdLongOption, cmdShortOption:
|
||||||
# hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
|
# hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
|
||||||
# we fix this here
|
# we fix this here
|
||||||
bracketLe = strutils.find(p.key, '[')
|
var bracketLe = strutils.find(p.key, '[')
|
||||||
if bracketLe >= 0:
|
if bracketLe >= 0:
|
||||||
key = copy(p.key, 0, bracketLe - 1)
|
var key = copy(p.key, 0, bracketLe - 1)
|
||||||
val = copy(p.key, bracketLe + 1) & ':' & p.val
|
var val = copy(p.key, bracketLe + 1) & ':' & p.val
|
||||||
ProcessSwitch(key, val, pass, cmdLineInfo)
|
ProcessSwitch(key, val, pass, cmdLineInfo)
|
||||||
else:
|
else:
|
||||||
ProcessSwitch(p.key, p.val, pass, cmdLineInfo)
|
ProcessSwitch(p.key, p.val, pass, cmdLineInfo)
|
||||||
|
|
@ -49,16 +45,13 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
|
||||||
rawMessage(errArgsNeedRunOption)
|
rawMessage(errArgsNeedRunOption)
|
||||||
|
|
||||||
proc HandleCmdLine() =
|
proc HandleCmdLine() =
|
||||||
var
|
var start = getTime()
|
||||||
command, filename, prog: string
|
|
||||||
start: TTime
|
|
||||||
start = getTime()
|
|
||||||
if paramCount() == 0:
|
if paramCount() == 0:
|
||||||
writeCommandLineUsage()
|
writeCommandLineUsage()
|
||||||
else:
|
else:
|
||||||
# Process command line arguments:
|
# Process command line arguments:
|
||||||
command = ""
|
var command = ""
|
||||||
filename = ""
|
var filename = ""
|
||||||
ProcessCmdLine(passCmd1, command, filename)
|
ProcessCmdLine(passCmd1, command, filename)
|
||||||
if filename != "": options.projectPath = splitFile(filename).dir
|
if filename != "": options.projectPath = splitFile(filename).dir
|
||||||
nimconf.LoadConfig(filename) # load the right config file
|
nimconf.LoadConfig(filename) # load the right config file
|
||||||
|
|
@ -74,15 +67,11 @@ proc HandleCmdLine() =
|
||||||
rawMessage(hintSuccessX, [$(gLinesCompiled), $(getTime() - start)])
|
rawMessage(hintSuccessX, [$(gLinesCompiled), $(getTime() - start)])
|
||||||
if optRun in gGlobalOptions:
|
if optRun in gGlobalOptions:
|
||||||
when defined(unix):
|
when defined(unix):
|
||||||
prog = "./" & quoteIfContainsWhite(changeFileExt(filename, ""))
|
var prog = "./" & quoteIfContainsWhite(changeFileExt(filename, ""))
|
||||||
else:
|
else:
|
||||||
prog = quoteIfContainsWhite(changeFileExt(filename, ""))
|
var prog = quoteIfContainsWhite(changeFileExt(filename, ""))
|
||||||
execExternalProgram(prog & ' ' & arguments)
|
execExternalProgram(prog & ' ' & arguments)
|
||||||
|
|
||||||
#{@emit
|
|
||||||
# GC_disableMarkAndSweep();
|
|
||||||
#}
|
|
||||||
|
|
||||||
cmdLineInfo = newLineInfo("command line", - 1, - 1)
|
cmdLineInfo = newLineInfo("command line", - 1, - 1)
|
||||||
condsyms.InitDefines()
|
condsyms.InitDefines()
|
||||||
HandleCmdLine()
|
HandleCmdLine()
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,14 @@ type # please make sure we have under 32 options
|
||||||
# (improves code efficiency a lot!)
|
# (improves code efficiency a lot!)
|
||||||
TOption* = enum # **keep binary compatible**
|
TOption* = enum # **keep binary compatible**
|
||||||
optNone, optObjCheck, optFieldCheck, optRangeCheck, optBoundsCheck,
|
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
|
optOptimizeSpeed, optOptimizeSize, optStackTrace, # stack tracing support
|
||||||
optLineTrace, # line tracing support (includes stack tracing)
|
optLineTrace, # line tracing support (includes stack tracing)
|
||||||
optEndb, # embedded debugger
|
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)
|
optCheckpoints, # check for checkpoints (used for debugging)
|
||||||
optProfiler # profiler turned on
|
optProfiler # profiler turned on
|
||||||
TOptions* = set[TOption]
|
TOptions* = set[TOption]
|
||||||
|
|
@ -50,12 +53,7 @@ type # please make sure we have under 32 options
|
||||||
|
|
||||||
const
|
const
|
||||||
ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck,
|
ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck,
|
||||||
optOverflowCheck, optBoundsCheck, optAssert}
|
optOverflowCheck, optBoundsCheck, optAssert, optNaNCheck, optInfCheck}
|
||||||
optionToStr*: array[TOption, string] = ["optNone", "optObjCheck",
|
|
||||||
"optFieldCheck", "optRangeCheck", "optBoundsCheck", "optOverflowCheck",
|
|
||||||
"optNilCheck", "optAssert", "optLineDir", "optWarns", "optHints",
|
|
||||||
"optOptimizeSpeed", "optOptimizeSize", "optStackTrace", "optLineTrace",
|
|
||||||
"optEmdb", "optByRef", "optCheckpoints", "optProfiler"]
|
|
||||||
|
|
||||||
var
|
var
|
||||||
gOptions*: TOptions = {optObjCheck, optFieldCheck, optRangeCheck,
|
gOptions*: TOptions = {optObjCheck, optFieldCheck, optRangeCheck,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ const
|
||||||
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir,
|
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir,
|
||||||
wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal,
|
wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal,
|
||||||
wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop, wBreakpoint,
|
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,
|
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||||
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure, wDeprecated}
|
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure, wDeprecated}
|
||||||
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
|
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
|
||||||
|
|
@ -220,6 +221,9 @@ proc processOption(c: PContext, n: PNode) =
|
||||||
of wBoundchecks: OnOff(c, n, {optBoundsCheck})
|
of wBoundchecks: OnOff(c, n, {optBoundsCheck})
|
||||||
of wOverflowchecks: OnOff(c, n, {optOverflowCheck})
|
of wOverflowchecks: OnOff(c, n, {optOverflowCheck})
|
||||||
of wNilchecks: OnOff(c, n, {optNilCheck})
|
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 wAssertions: OnOff(c, n, {optAssert})
|
||||||
of wWarnings: OnOff(c, n, {optWarns})
|
of wWarnings: OnOff(c, n, {optWarns})
|
||||||
of wHints: OnOff(c, n, {optHints})
|
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,
|
of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks,
|
||||||
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
||||||
wLinedir, wStacktrace, wLinetrace, wOptimization, wByRef, wCallConv,
|
wLinedir, wStacktrace, wLinetrace, wOptimization, wByRef, wCallConv,
|
||||||
wDebugger, wProfiler:
|
wDebugger, wProfiler, wFloatChecks, wNanChecks, wInfChecks:
|
||||||
processOption(c, it) # calling conventions (boring...):
|
processOption(c, it) # calling conventions (boring...):
|
||||||
of firstCallConv..lastCallConv:
|
of firstCallConv..lastCallConv:
|
||||||
assert(sym != nil)
|
assert(sym != nil)
|
||||||
|
|
|
||||||
325
rod/rst.nim
325
rod/rst.nim
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# 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.
|
# subset is provided.
|
||||||
|
|
||||||
import
|
import
|
||||||
|
|
@ -33,25 +33,17 @@ type
|
||||||
rnFieldName, # consisting of a field name ...
|
rnFieldName, # consisting of a field name ...
|
||||||
rnFieldBody, # ... and a field body
|
rnFieldBody, # ... and a field body
|
||||||
rnOptionList, rnOptionListItem, rnOptionGroup, rnOption, rnOptionString,
|
rnOptionList, rnOptionListItem, rnOptionGroup, rnOption, rnOptionString,
|
||||||
rnOptionArgument, rnDescription, rnLiteralBlock, rnQuotedLiteralBlock, rnLineBlock, #
|
rnOptionArgument, rnDescription, rnLiteralBlock, rnQuotedLiteralBlock,
|
||||||
# the
|
rnLineBlock, # the | thingie
|
||||||
# |
|
|
||||||
# thingie
|
|
||||||
rnLineBlockItem, # sons of the | thing
|
rnLineBlockItem, # sons of the | thing
|
||||||
rnBlockQuote, # text just indented
|
rnBlockQuote, # text just indented
|
||||||
rnTable, rnGridTable, rnTableRow, rnTableHeaderCell, rnTableDataCell, rnLabel, #
|
rnTable, rnGridTable, rnTableRow, rnTableHeaderCell, rnTableDataCell,
|
||||||
# used
|
rnLabel, # used for footnotes and other things
|
||||||
# for
|
|
||||||
# footnotes
|
|
||||||
# and
|
|
||||||
# other
|
|
||||||
# things
|
|
||||||
rnFootnote, # a footnote
|
rnFootnote, # a footnote
|
||||||
rnCitation, # similar to footnote
|
rnCitation, # similar to footnote
|
||||||
rnStandaloneHyperlink, rnHyperlink, rnRef, rnDirective, # a directive
|
rnStandaloneHyperlink, rnHyperlink, rnRef, rnDirective, # a directive
|
||||||
rnDirArg, rnRaw, rnTitle, rnContents, rnImage, rnFigure, rnCodeBlock, rnContainer, #
|
rnDirArg, rnRaw, rnTitle, rnContents, rnImage, rnFigure, rnCodeBlock,
|
||||||
# ``container``
|
rnContainer, # ``container`` directive
|
||||||
# directive
|
|
||||||
rnIndex, # index directve:
|
rnIndex, # index directve:
|
||||||
# .. index::
|
# .. index::
|
||||||
# key
|
# key
|
||||||
|
|
@ -64,22 +56,8 @@ type
|
||||||
rnInterpretedText, # "`"
|
rnInterpretedText, # "`"
|
||||||
rnInlineLiteral, # "``"
|
rnInlineLiteral, # "``"
|
||||||
rnSubstitutionReferences, # "|"
|
rnSubstitutionReferences, # "|"
|
||||||
rnLeaf # a leaf; the node's text field contains the leaf val
|
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"]
|
|
||||||
|
|
||||||
type # the syntax tree of RST:
|
type # the syntax tree of RST:
|
||||||
PRSTNode* = ref TRstNode
|
PRSTNode* = ref TRstNode
|
||||||
|
|
@ -513,7 +491,6 @@ proc clearIndex(index: PRstNode, filename: string) =
|
||||||
|
|
||||||
proc setIndexPair(index, key, val: PRstNode) =
|
proc setIndexPair(index, key, val: PRstNode) =
|
||||||
var e, a, b: PRstNode
|
var e, a, b: PRstNode
|
||||||
# writeln(rstnodekindToStr[key.kind], ': ', rstnodekindToStr[val.kind]);
|
|
||||||
assert(index.kind == rnDefList)
|
assert(index.kind == rnDefList)
|
||||||
assert(key.kind != rnDefName)
|
assert(key.kind != rnDefName)
|
||||||
a = newRstNode(rnDefName)
|
a = newRstNode(rnDefName)
|
||||||
|
|
@ -590,7 +567,7 @@ proc isInlineMarkupEnd(p: TRstParser, markup: string): bool =
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc isInlineMarkupStart(p: TRstParser, markup: string): bool =
|
proc isInlineMarkupStart(p: TRstParser, markup: string): bool =
|
||||||
var c, d: Char
|
var d: Char
|
||||||
result = p.tok[p.idx].symbol == markup
|
result = p.tok[p.idx].symbol == markup
|
||||||
if not result:
|
if not result:
|
||||||
return # Rule 1:
|
return # Rule 1:
|
||||||
|
|
@ -606,7 +583,7 @@ proc isInlineMarkupStart(p: TRstParser, markup: string): bool =
|
||||||
if p.tok[p.idx - 1].symbol == "\\":
|
if p.tok[p.idx - 1].symbol == "\\":
|
||||||
result = false
|
result = false
|
||||||
else:
|
else:
|
||||||
c = p.tok[p.idx - 1].symbol[0]
|
var c = p.tok[p.idx - 1].symbol[0]
|
||||||
case c
|
case c
|
||||||
of '\'', '\"': d = c
|
of '\'', '\"': d = c
|
||||||
of '(': d = ')'
|
of '(': d = ')'
|
||||||
|
|
@ -641,30 +618,19 @@ proc match(p: TRstParser, start: int, expr: string): bool =
|
||||||
# 'T' always true
|
# 'T' always true
|
||||||
# 'E' whitespace, indent or eof
|
# 'E' whitespace, indent or eof
|
||||||
# 'e' tkWord or '#' (for enumeration lists)
|
# 'e' tkWord or '#' (for enumeration lists)
|
||||||
var
|
var i = 0
|
||||||
i, j, last, length: int
|
var j = start
|
||||||
c: char
|
var last = len(expr) + 0 - 1
|
||||||
i = 0
|
|
||||||
j = start
|
|
||||||
last = len(expr) + 0 - 1
|
|
||||||
while i <= last:
|
while i <= last:
|
||||||
case expr[i]
|
case expr[i]
|
||||||
of 'w':
|
of 'w': result = p.tok[j].kind == tkWord
|
||||||
result = p.tok[j].kind == tkWord
|
of ' ': result = p.tok[j].kind == tkWhite
|
||||||
of ' ':
|
of 'i': result = p.tok[j].kind == tkIndent
|
||||||
result = p.tok[j].kind == tkWhite
|
of 'p': result = p.tok[j].kind == tkPunct
|
||||||
of 'i':
|
of 'a': result = p.tok[j].kind == tkAdornment
|
||||||
result = p.tok[j].kind == tkIndent
|
of 'o': result = p.tok[j].kind == tkOther
|
||||||
of 'p':
|
of 'T': result = true
|
||||||
result = p.tok[j].kind == tkPunct
|
of 'E': result = p.tok[j].kind in {tkEof, tkWhite, tkIndent}
|
||||||
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':
|
of 'e':
|
||||||
result = (p.tok[j].kind == tkWord) or (p.tok[j].symbol == "#")
|
result = (p.tok[j].kind == tkWord) or (p.tok[j].symbol == "#")
|
||||||
if result:
|
if result:
|
||||||
|
|
@ -674,8 +640,8 @@ proc match(p: TRstParser, start: int, expr: string): bool =
|
||||||
else:
|
else:
|
||||||
nil
|
nil
|
||||||
else:
|
else:
|
||||||
c = expr[i]
|
var c = expr[i]
|
||||||
length = 0
|
var length = 0
|
||||||
while (i <= last) and (expr[i] == c):
|
while (i <= last) and (expr[i] == c):
|
||||||
inc(i)
|
inc(i)
|
||||||
inc(length)
|
inc(length)
|
||||||
|
|
@ -688,25 +654,22 @@ proc match(p: TRstParser, start: int, expr: string): bool =
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc fixupEmbeddedRef(n, a, b: PRstNode) =
|
proc fixupEmbeddedRef(n, a, b: PRstNode) =
|
||||||
var sep, incr: int
|
var sep = - 1
|
||||||
sep = - 1
|
|
||||||
for i in countdown(rsonsLen(n) - 2, 0):
|
for i in countdown(rsonsLen(n) - 2, 0):
|
||||||
if n.sons[i].text == "<":
|
if n.sons[i].text == "<":
|
||||||
sep = i
|
sep = i
|
||||||
break
|
break
|
||||||
if (sep > 0) and (n.sons[sep - 1].text[0] == ' '): incr = 2
|
var incr = if (sep > 0) and (n.sons[sep - 1].text[0] == ' '): 2 else: 1
|
||||||
else: incr = 1
|
|
||||||
for i in countup(0, sep - incr): addSon(a, n.sons[i])
|
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])
|
for i in countup(sep + 1, rsonsLen(n) - 2): addSon(b, n.sons[i])
|
||||||
|
|
||||||
proc parsePostfix(p: var TRstParser, n: PRstNode): PRstNode =
|
proc parsePostfix(p: var TRstParser, n: PRstNode): PRstNode =
|
||||||
var a, b: PRstNode
|
|
||||||
result = n
|
result = n
|
||||||
if isInlineMarkupEnd(p, "_"):
|
if isInlineMarkupEnd(p, "_"):
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
if (p.tok[p.idx - 2].symbol == "`") and (p.tok[p.idx - 3].symbol == ">"):
|
if (p.tok[p.idx - 2].symbol == "`") and (p.tok[p.idx - 3].symbol == ">"):
|
||||||
a = newRstNode(rnInner)
|
var a = newRstNode(rnInner)
|
||||||
b = newRstNode(rnInner)
|
var b = newRstNode(rnInner)
|
||||||
fixupEmbeddedRef(n, a, b)
|
fixupEmbeddedRef(n, a, b)
|
||||||
if rsonsLen(a) == 0:
|
if rsonsLen(a) == 0:
|
||||||
result = newRstNode(rnStandaloneHyperlink)
|
result = newRstNode(rnStandaloneHyperlink)
|
||||||
|
|
@ -799,33 +762,32 @@ proc parseUntil(p: var TRstParser, father: PRstNode, postfix: string,
|
||||||
else: rstMessage(p, errXExpected, postfix)
|
else: rstMessage(p, errXExpected, postfix)
|
||||||
|
|
||||||
proc parseInline(p: var TRstParser, father: PRstNode) =
|
proc parseInline(p: var TRstParser, father: PRstNode) =
|
||||||
var n: PRstNode
|
|
||||||
case p.tok[p.idx].kind
|
case p.tok[p.idx].kind
|
||||||
of tkPunct:
|
of tkPunct:
|
||||||
if isInlineMarkupStart(p, "**"):
|
if isInlineMarkupStart(p, "**"):
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
n = newRstNode(rnStrongEmphasis)
|
var n = newRstNode(rnStrongEmphasis)
|
||||||
parseUntil(p, n, "**", true)
|
parseUntil(p, n, "**", true)
|
||||||
addSon(father, n)
|
addSon(father, n)
|
||||||
elif isInlineMarkupStart(p, "*"):
|
elif isInlineMarkupStart(p, "*"):
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
n = newRstNode(rnEmphasis)
|
var n = newRstNode(rnEmphasis)
|
||||||
parseUntil(p, n, "*", true)
|
parseUntil(p, n, "*", true)
|
||||||
addSon(father, n)
|
addSon(father, n)
|
||||||
elif isInlineMarkupStart(p, "``"):
|
elif isInlineMarkupStart(p, "``"):
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
n = newRstNode(rnInlineLiteral)
|
var n = newRstNode(rnInlineLiteral)
|
||||||
parseUntil(p, n, "``", false)
|
parseUntil(p, n, "``", false)
|
||||||
addSon(father, n)
|
addSon(father, n)
|
||||||
elif isInlineMarkupStart(p, "`"):
|
elif isInlineMarkupStart(p, "`"):
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
n = newRstNode(rnInterpretedText)
|
var n = newRstNode(rnInterpretedText)
|
||||||
parseUntil(p, n, "`", true)
|
parseUntil(p, n, "`", true)
|
||||||
n = parsePostfix(p, n)
|
n = parsePostfix(p, n)
|
||||||
addSon(father, n)
|
addSon(father, n)
|
||||||
elif isInlineMarkupStart(p, "|"):
|
elif isInlineMarkupStart(p, "|"):
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
n = newRstNode(rnSubstitutionReferences)
|
var n = newRstNode(rnSubstitutionReferences)
|
||||||
parseUntil(p, n, "|", false)
|
parseUntil(p, n, "|", false)
|
||||||
addSon(father, n)
|
addSon(father, n)
|
||||||
else:
|
else:
|
||||||
|
|
@ -838,9 +800,8 @@ proc parseInline(p: var TRstParser, father: PRstNode) =
|
||||||
else: assert(false)
|
else: assert(false)
|
||||||
|
|
||||||
proc getDirective(p: var TRstParser): string =
|
proc getDirective(p: var TRstParser): string =
|
||||||
var j: int
|
|
||||||
if (p.tok[p.idx].kind == tkWhite) and (p.tok[p.idx + 1].kind == tkWord):
|
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)
|
inc(p.idx)
|
||||||
result = p.tok[p.idx].symbol
|
result = p.tok[p.idx].symbol
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
|
|
@ -859,13 +820,12 @@ proc getDirective(p: var TRstParser): string =
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
proc parseComment(p: var TRstParser): PRstNode =
|
proc parseComment(p: var TRstParser): PRstNode =
|
||||||
var indent: int
|
|
||||||
case p.tok[p.idx].kind
|
case p.tok[p.idx].kind
|
||||||
of tkIndent, tkEof:
|
of tkIndent, tkEof:
|
||||||
if p.tok[p.idx + 1].kind == tkIndent:
|
if p.tok[p.idx + 1].kind == tkIndent:
|
||||||
inc(p.idx) # empty comment
|
inc(p.idx) # empty comment
|
||||||
else:
|
else:
|
||||||
indent = p.tok[p.idx].ival
|
var indent = p.tok[p.idx].ival
|
||||||
while True:
|
while True:
|
||||||
case p.tok[p.idx].kind
|
case p.tok[p.idx].kind
|
||||||
of tkEof:
|
of tkEof:
|
||||||
|
|
@ -903,18 +863,15 @@ proc parseLine(p: var TRstParser, father: PRstNode) =
|
||||||
|
|
||||||
proc parseSection(p: var TRstParser, result: PRstNode)
|
proc parseSection(p: var TRstParser, result: PRstNode)
|
||||||
proc parseField(p: var TRstParser): PRstNode =
|
proc parseField(p: var TRstParser): PRstNode =
|
||||||
var
|
|
||||||
col, indent: int
|
|
||||||
fieldname, fieldbody: PRstNode
|
|
||||||
result = newRstNode(rnField)
|
result = newRstNode(rnField)
|
||||||
col = p.tok[p.idx].col
|
var col = p.tok[p.idx].col
|
||||||
inc(p.idx) # skip :
|
inc(p.idx) # skip :
|
||||||
fieldname = newRstNode(rnFieldname)
|
var fieldname = newRstNode(rnFieldname)
|
||||||
parseUntil(p, fieldname, ":", false)
|
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: parseLine(p, fieldbody)
|
||||||
if p.tok[p.idx].kind == tkIndent:
|
if p.tok[p.idx].kind == tkIndent:
|
||||||
indent = p.tok[p.idx].ival
|
var indent = p.tok[p.idx].ival
|
||||||
if indent > col:
|
if indent > col:
|
||||||
pushInd(p, indent)
|
pushInd(p, indent)
|
||||||
parseSection(p, fieldbody)
|
parseSection(p, fieldbody)
|
||||||
|
|
@ -923,10 +880,9 @@ proc parseField(p: var TRstParser): PRstNode =
|
||||||
addSon(result, fieldbody)
|
addSon(result, fieldbody)
|
||||||
|
|
||||||
proc parseFields(p: var TRstParser): PRstNode =
|
proc parseFields(p: var TRstParser): PRstNode =
|
||||||
var col: int
|
|
||||||
result = nil
|
result = nil
|
||||||
if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx + 1].symbol == ":"):
|
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)
|
result = newRstNode(rnFieldList)
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -938,17 +894,15 @@ proc parseFields(p: var TRstParser): PRstNode =
|
||||||
break
|
break
|
||||||
|
|
||||||
proc getFieldValue(n: PRstNode, fieldname: string): string =
|
proc getFieldValue(n: PRstNode, fieldname: string): string =
|
||||||
var f: PRstNode
|
|
||||||
result = ""
|
result = ""
|
||||||
if n.sons[1] == nil: return
|
if n.sons[1] == nil: return
|
||||||
if (n.sons[1].kind != rnFieldList):
|
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):
|
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:
|
if cmpIgnoreStyle(addNodes(f.sons[0]), fieldname) == 0:
|
||||||
result = addNodes(f.sons[1])
|
result = addNodes(f.sons[1])
|
||||||
if result == "":
|
if result == "": result = "\x01\x01" # indicates that the field exists
|
||||||
result = "\x01\x01" # indicates that the field exists
|
|
||||||
return
|
return
|
||||||
|
|
||||||
proc getArgument(n: PRstNode): string =
|
proc getArgument(n: PRstNode): string =
|
||||||
|
|
@ -957,13 +911,10 @@ proc getArgument(n: PRstNode): string =
|
||||||
|
|
||||||
proc parseDotDot(p: var TRstParser): PRstNode
|
proc parseDotDot(p: var TRstParser): PRstNode
|
||||||
proc parseLiteralBlock(p: var TRstParser): PRstNode =
|
proc parseLiteralBlock(p: var TRstParser): PRstNode =
|
||||||
var
|
|
||||||
indent: int
|
|
||||||
n: PRstNode
|
|
||||||
result = newRstNode(rnLiteralBlock)
|
result = newRstNode(rnLiteralBlock)
|
||||||
n = newRstNode(rnLeaf, "")
|
var n = newRstNode(rnLeaf, "")
|
||||||
if p.tok[p.idx].kind == tkIndent:
|
if p.tok[p.idx].kind == tkIndent:
|
||||||
indent = p.tok[p.idx].ival
|
var indent = p.tok[p.idx].ival
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
while True:
|
while True:
|
||||||
case p.tok[p.idx].kind
|
case p.tok[p.idx].kind
|
||||||
|
|
@ -1003,8 +954,7 @@ proc tokenAfterNewline(p: TRstParser): int =
|
||||||
else: inc(result)
|
else: inc(result)
|
||||||
|
|
||||||
proc isLineBlock(p: TRstParser): bool =
|
proc isLineBlock(p: TRstParser): bool =
|
||||||
var j: int
|
var j = tokenAfterNewline(p)
|
||||||
j = tokenAfterNewline(p)
|
|
||||||
result = (p.tok[p.idx].col == p.tok[j].col) and (p.tok[j].symbol == "|") or
|
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)
|
(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))
|
(p.tok[p.idx - 1].ival == currInd(p))
|
||||||
|
|
||||||
proc isDefList(p: TRstParser): bool =
|
proc isDefList(p: TRstParser): bool =
|
||||||
var j: int
|
var j = tokenAfterNewline(p)
|
||||||
j = tokenAfterNewline(p)
|
|
||||||
result = (p.tok[p.idx].col < p.tok[j].col) and
|
result = (p.tok[p.idx].col < p.tok[j].col) and
|
||||||
(p.tok[j].kind in {tkWord, tkOther, tkPunct}) and
|
(p.tok[j].kind in {tkWord, tkOther, tkPunct}) and
|
||||||
(p.tok[j - 2].symbol != "::")
|
(p.tok[j - 2].symbol != "::")
|
||||||
|
|
@ -1063,17 +1012,14 @@ proc whichSection(p: TRstParser): TRstNodeKind =
|
||||||
else: result = rnLeaf
|
else: result = rnLeaf
|
||||||
|
|
||||||
proc parseLineBlock(p: var TRstParser): PRstNode =
|
proc parseLineBlock(p: var TRstParser): PRstNode =
|
||||||
var
|
|
||||||
col: int
|
|
||||||
item: PRstNode
|
|
||||||
result = nil
|
result = nil
|
||||||
if p.tok[p.idx + 1].kind == tkWhite:
|
if p.tok[p.idx + 1].kind == tkWhite:
|
||||||
col = p.tok[p.idx].col
|
var col = p.tok[p.idx].col
|
||||||
result = newRstNode(rnLineBlock)
|
result = newRstNode(rnLineBlock)
|
||||||
pushInd(p, p.tok[p.idx + 2].col)
|
pushInd(p, p.tok[p.idx + 2].col)
|
||||||
inc(p.idx, 2)
|
inc(p.idx, 2)
|
||||||
while true:
|
while true:
|
||||||
item = newRstNode(rnLineBlockItem)
|
var item = newRstNode(rnLineBlockItem)
|
||||||
parseSection(p, item)
|
parseSection(p, item)
|
||||||
addSon(result, item)
|
addSon(result, item)
|
||||||
if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col) and
|
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)
|
parseParagraph(p, result)
|
||||||
|
|
||||||
proc parseHeadline(p: var TRstParser): PRstNode =
|
proc parseHeadline(p: var TRstParser): PRstNode =
|
||||||
var c: Char
|
|
||||||
result = newRstNode(rnHeadline)
|
result = newRstNode(rnHeadline)
|
||||||
parseLine(p, result)
|
parseLine(p, result)
|
||||||
assert(p.tok[p.idx].kind == tkIndent)
|
assert(p.tok[p.idx].kind == tkIndent)
|
||||||
assert(p.tok[p.idx + 1].kind == tkAdornment)
|
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)
|
inc(p.idx, 2)
|
||||||
result.level = getLevel(p.s.underlineToLevel, p.s.uLevel, c)
|
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
|
result = p.tok[p.idx].col + len(p.tok[p.idx].symbol) - 1
|
||||||
|
|
||||||
proc getColumns(p: var TRstParser, cols: var TIntSeq) =
|
proc getColumns(p: var TRstParser, cols: var TIntSeq) =
|
||||||
var L: int
|
var L = 0
|
||||||
L = 0
|
|
||||||
while true:
|
while true:
|
||||||
inc(L)
|
inc(L)
|
||||||
setlen(cols, L)
|
setlen(cols, L)
|
||||||
|
|
@ -1161,8 +1105,8 @@ proc parseSimpleTable(p: var TRstParser): PRstNode =
|
||||||
q: TRstParser
|
q: TRstParser
|
||||||
a, b: PRstNode
|
a, b: PRstNode
|
||||||
result = newRstNode(rnTable)
|
result = newRstNode(rnTable)
|
||||||
cols = @ []
|
cols = @[]
|
||||||
row = @ []
|
row = @[]
|
||||||
a = nil
|
a = nil
|
||||||
c = p.tok[p.idx].symbol[0]
|
c = p.tok[p.idx].symbol[0]
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -1177,8 +1121,8 @@ proc parseSimpleTable(p: var TRstParser): PRstNode =
|
||||||
if a != nil:
|
if a != nil:
|
||||||
for j in countup(0, rsonsLen(a) - 1): a.sons[j].kind = rnTableHeaderCell
|
for j in countup(0, rsonsLen(a) - 1): a.sons[j].kind = rnTableHeaderCell
|
||||||
if p.tok[p.idx].kind == tkEof: break
|
if p.tok[p.idx].kind == tkEof: break
|
||||||
for j in countup(0, high(row)):
|
for j in countup(0, high(row)): row[j] = ""
|
||||||
row[j] = "" # the following while loop iterates over the lines a single cell may span:
|
# the following while loop iterates over the lines a single cell may span:
|
||||||
line = p.tok[p.idx].line
|
line = p.tok[p.idx].line
|
||||||
while true:
|
while true:
|
||||||
i = 0
|
i = 0
|
||||||
|
|
@ -1212,8 +1156,7 @@ proc parseTransition(p: var TRstParser): PRstNode =
|
||||||
if p.tok[p.idx].kind == tkIndent: inc(p.idx)
|
if p.tok[p.idx].kind == tkIndent: inc(p.idx)
|
||||||
|
|
||||||
proc parseOverline(p: var TRstParser): PRstNode =
|
proc parseOverline(p: var TRstParser): PRstNode =
|
||||||
var c: char
|
var c = p.tok[p.idx].symbol[0]
|
||||||
c = p.tok[p.idx].symbol[0]
|
|
||||||
inc(p.idx, 2)
|
inc(p.idx, 2)
|
||||||
result = newRstNode(rnOverline)
|
result = newRstNode(rnOverline)
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -1232,19 +1175,15 @@ proc parseOverline(p: var TRstParser): PRstNode =
|
||||||
if p.tok[p.idx].kind == tkIndent: inc(p.idx)
|
if p.tok[p.idx].kind == tkIndent: inc(p.idx)
|
||||||
|
|
||||||
proc parseBulletList(p: var TRstParser): PRstNode =
|
proc parseBulletList(p: var TRstParser): PRstNode =
|
||||||
var
|
|
||||||
bullet: string
|
|
||||||
col: int
|
|
||||||
item: PRstNode
|
|
||||||
result = nil
|
result = nil
|
||||||
if p.tok[p.idx + 1].kind == tkWhite:
|
if p.tok[p.idx + 1].kind == tkWhite:
|
||||||
bullet = p.tok[p.idx].symbol
|
var bullet = p.tok[p.idx].symbol
|
||||||
col = p.tok[p.idx].col
|
var col = p.tok[p.idx].col
|
||||||
result = newRstNode(rnBulletList)
|
result = newRstNode(rnBulletList)
|
||||||
pushInd(p, p.tok[p.idx + 2].col)
|
pushInd(p, p.tok[p.idx + 2].col)
|
||||||
inc(p.idx, 2)
|
inc(p.idx, 2)
|
||||||
while true:
|
while true:
|
||||||
item = newRstNode(rnBulletItem)
|
var item = newRstNode(rnBulletItem)
|
||||||
parseSection(p, item)
|
parseSection(p, item)
|
||||||
addSon(result, item)
|
addSon(result, item)
|
||||||
if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col) and
|
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)
|
popInd(p)
|
||||||
|
|
||||||
proc parseOptionList(p: var TRstParser): PRstNode =
|
proc parseOptionList(p: var TRstParser): PRstNode =
|
||||||
var
|
|
||||||
a, b, c: PRstNode
|
|
||||||
j: int
|
|
||||||
result = newRstNode(rnOptionList)
|
result = newRstNode(rnOptionList)
|
||||||
while true:
|
while true:
|
||||||
if match(p, p.idx, "-w") or match(p, p.idx, "--w") or
|
if match(p, p.idx, "-w") or match(p, p.idx, "--w") or
|
||||||
match(p, p.idx, "/w"):
|
match(p, p.idx, "/w"):
|
||||||
a = newRstNode(rnOptionGroup)
|
var a = newRstNode(rnOptionGroup)
|
||||||
b = newRstNode(rnDescription)
|
var b = newRstNode(rnDescription)
|
||||||
c = newRstNode(rnOptionListItem)
|
var c = newRstNode(rnOptionListItem)
|
||||||
while not (p.tok[p.idx].kind in {tkIndent, tkEof}):
|
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):
|
if (p.tok[p.idx].kind == tkWhite) and (len(p.tok[p.idx].symbol) > 1):
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
break
|
break
|
||||||
addSon(a, newLeaf(p))
|
addSon(a, newLeaf(p))
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
j = tokenAfterNewline(p)
|
var j = tokenAfterNewline(p)
|
||||||
if (j > 0) and (p.tok[j - 1].kind == tkIndent) and
|
if (j > 0) and (p.tok[j - 1].kind == tkIndent) and
|
||||||
(p.tok[j - 1].ival > currInd(p)):
|
(p.tok[j - 1].ival > currInd(p)):
|
||||||
pushInd(p, p.tok[j - 1].ival)
|
pushInd(p, p.tok[j - 1].ival)
|
||||||
|
|
@ -1288,26 +1224,24 @@ proc parseOptionList(p: var TRstParser): PRstNode =
|
||||||
break
|
break
|
||||||
|
|
||||||
proc parseDefinitionList(p: var TRstParser): PRstNode =
|
proc parseDefinitionList(p: var TRstParser): PRstNode =
|
||||||
var
|
|
||||||
j, col: int
|
|
||||||
a, b, c: PRstNode
|
|
||||||
result = nil
|
result = nil
|
||||||
j = tokenAfterNewLine(p) - 1
|
var j = tokenAfterNewLine(p) - 1
|
||||||
if (j >= 1) and (p.tok[j].kind == tkIndent) and
|
if (j >= 1) and (p.tok[j].kind == tkIndent) and
|
||||||
(p.tok[j].ival > currInd(p)) and (p.tok[j - 1].symbol != "::"):
|
(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)
|
result = newRstNode(rnDefList)
|
||||||
while true:
|
while true:
|
||||||
j = p.idx
|
j = p.idx
|
||||||
a = newRstNode(rnDefName)
|
var a = newRstNode(rnDefName)
|
||||||
parseLine(p, a) #writeln('after def line: ', p.tok[p.idx].ival :1, ' ', col : 1);
|
parseLine(p, a)
|
||||||
if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival > currInd(p)) and
|
if (p.tok[p.idx].kind == tkIndent) and
|
||||||
|
(p.tok[p.idx].ival > currInd(p)) and
|
||||||
(p.tok[p.idx + 1].symbol != "::") and
|
(p.tok[p.idx + 1].symbol != "::") and
|
||||||
not (p.tok[p.idx + 1].kind in {tkIndent, tkEof}):
|
not (p.tok[p.idx + 1].kind in {tkIndent, tkEof}):
|
||||||
pushInd(p, p.tok[p.idx].ival)
|
pushInd(p, p.tok[p.idx].ival)
|
||||||
b = newRstNode(rnDefBody)
|
var b = newRstNode(rnDefBody)
|
||||||
parseSection(p, b)
|
parseSection(p, b)
|
||||||
c = newRstNode(rnDefItem)
|
var c = newRstNode(rnDefItem)
|
||||||
addSon(c, a)
|
addSon(c, a)
|
||||||
addSon(c, b)
|
addSon(c, b)
|
||||||
addSon(result, c)
|
addSon(result, c)
|
||||||
|
|
@ -1329,23 +1263,20 @@ proc parseEnumList(p: var TRstParser): PRstNode =
|
||||||
const
|
const
|
||||||
wildcards: array[0..2, string] = ["(e) ", "e) ", "e. "]
|
wildcards: array[0..2, string] = ["(e) ", "e) ", "e. "]
|
||||||
wildpos: array[0..2, int] = [1, 0, 0]
|
wildpos: array[0..2, int] = [1, 0, 0]
|
||||||
var
|
|
||||||
w, col, j: int
|
|
||||||
item: PRstNode
|
|
||||||
result = nil
|
result = nil
|
||||||
w = 0
|
var w = 0
|
||||||
while w <= 2:
|
while w <= 2:
|
||||||
if match(p, p.idx, wildcards[w]): break
|
if match(p, p.idx, wildcards[w]): break
|
||||||
inc(w)
|
inc(w)
|
||||||
if w <= 2:
|
if w <= 2:
|
||||||
col = p.tok[p.idx].col
|
var col = p.tok[p.idx].col
|
||||||
result = newRstNode(rnEnumList)
|
result = newRstNode(rnEnumList)
|
||||||
inc(p.idx, wildpos[w] + 3)
|
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]):
|
if (p.tok[j].col == p.tok[p.idx].col) or match(p, j, wildcards[w]):
|
||||||
pushInd(p, p.tok[p.idx].col)
|
pushInd(p, p.tok[p.idx].col)
|
||||||
while true:
|
while true:
|
||||||
item = newRstNode(rnEnumItem)
|
var item = newRstNode(rnEnumItem)
|
||||||
parseSection(p, item)
|
parseSection(p, item)
|
||||||
addSon(result, item)
|
addSon(result, item)
|
||||||
if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col) and
|
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
|
if i < rsonsLen(father): result = father.sons[i].kind
|
||||||
|
|
||||||
proc parseSection(p: var TRstParser, result: PRstNode) =
|
proc parseSection(p: var TRstParser, result: PRstNode) =
|
||||||
var
|
|
||||||
a: PRstNode
|
|
||||||
k: TRstNodeKind
|
|
||||||
leave: bool
|
|
||||||
while true:
|
while true:
|
||||||
leave = false
|
var leave = false
|
||||||
assert(p.idx >= 0)
|
assert(p.idx >= 0)
|
||||||
while p.tok[p.idx].kind == tkIndent:
|
while p.tok[p.idx].kind == tkIndent:
|
||||||
if currInd(p) == p.tok[p.idx].ival:
|
if currInd(p) == p.tok[p.idx].ival:
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
elif p.tok[p.idx].ival > currInd(p):
|
elif p.tok[p.idx].ival > currInd(p):
|
||||||
pushInd(p, p.tok[p.idx].ival)
|
pushInd(p, p.tok[p.idx].ival)
|
||||||
a = newRstNode(rnBlockQuote)
|
var a = newRstNode(rnBlockQuote)
|
||||||
parseSection(p, a)
|
parseSection(p, a)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
popInd(p)
|
popInd(p)
|
||||||
|
|
@ -1384,39 +1311,27 @@ proc parseSection(p: var TRstParser, result: PRstNode) =
|
||||||
break
|
break
|
||||||
if leave: break
|
if leave: break
|
||||||
if p.tok[p.idx].kind == tkEof: break
|
if p.tok[p.idx].kind == tkEof: break
|
||||||
a = nil
|
var a: PRstNode = nil
|
||||||
k = whichSection(p)
|
var k = whichSection(p)
|
||||||
case k
|
case k
|
||||||
of rnLiteralBlock:
|
of rnLiteralBlock:
|
||||||
inc(p.idx) # skip '::'
|
inc(p.idx) # skip '::'
|
||||||
a = parseLiteralBlock(p)
|
a = parseLiteralBlock(p)
|
||||||
of rnBulletList:
|
of rnBulletList: a = parseBulletList(p)
|
||||||
a = parseBulletList(p)
|
of rnLineblock: a = parseLineBlock(p)
|
||||||
of rnLineblock:
|
of rnDirective: a = parseDotDot(p)
|
||||||
a = parseLineBlock(p)
|
of rnEnumList: a = parseEnumList(p)
|
||||||
of rnDirective:
|
of rnLeaf: rstMessage(p, errNewSectionExpected)
|
||||||
a = parseDotDot(p)
|
of rnParagraph: nil
|
||||||
of rnEnumList:
|
of rnDefList: a = parseDefinitionList(p)
|
||||||
a = parseEnumList(p)
|
|
||||||
of rnLeaf:
|
|
||||||
rstMessage(p, errNewSectionExpected)
|
|
||||||
of rnParagraph:
|
|
||||||
nil
|
|
||||||
of rnDefList:
|
|
||||||
a = parseDefinitionList(p)
|
|
||||||
of rnFieldList:
|
of rnFieldList:
|
||||||
dec(p.idx)
|
dec(p.idx)
|
||||||
a = parseFields(p)
|
a = parseFields(p)
|
||||||
of rnTransition:
|
of rnTransition: a = parseTransition(p)
|
||||||
a = parseTransition(p)
|
of rnHeadline: a = parseHeadline(p)
|
||||||
of rnHeadline:
|
of rnOverline: a = parseOverline(p)
|
||||||
a = parseHeadline(p)
|
of rnTable: a = parseSimpleTable(p)
|
||||||
of rnOverline:
|
of rnOptionList: a = parseOptionList(p)
|
||||||
a = parseOverline(p)
|
|
||||||
of rnTable:
|
|
||||||
a = parseSimpleTable(p)
|
|
||||||
of rnOptionList:
|
|
||||||
a = parseOptionList(p)
|
|
||||||
else: InternalError("rst.parseSection()")
|
else: InternalError("rst.parseSection()")
|
||||||
if (a == nil) and (k != rnDirective):
|
if (a == nil) and (k != rnDirective):
|
||||||
a = newRstNode(rnParagraph)
|
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
|
# The text encoding of the external data file. Defaults to the document's
|
||||||
# encoding (if specified).
|
# encoding (if specified).
|
||||||
#
|
#
|
||||||
var
|
|
||||||
n: PRstNode
|
|
||||||
filename, path: string
|
|
||||||
q: TRstParser
|
|
||||||
result = nil
|
result = nil
|
||||||
n = parseDirective(p, {hasArg, argIsFile, hasOptions}, nil)
|
var n = parseDirective(p, {hasArg, argIsFile, hasOptions}, nil)
|
||||||
filename = strip(addNodes(n.sons[0]))
|
var filename = strip(addNodes(n.sons[0]))
|
||||||
path = findFile(filename)
|
var path = findFile(filename)
|
||||||
if path == "":
|
if path == "":
|
||||||
rstMessage(p, errCannotOpenFile, filename)
|
rstMessage(p, errCannotOpenFile, filename)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1507,6 +1418,7 @@ proc dirInclude(p: var TRstParser): PRstNode =
|
||||||
result = newRstNode(rnLiteralBlock)
|
result = newRstNode(rnLiteralBlock)
|
||||||
addSon(result, newRstNode(rnLeaf, readFile(path)))
|
addSon(result, newRstNode(rnLeaf, readFile(path)))
|
||||||
else:
|
else:
|
||||||
|
var q: TRstParser
|
||||||
initParser(q, p.s)
|
initParser(q, p.s)
|
||||||
q.filename = filename
|
q.filename = filename
|
||||||
getTokens(readFile(path), false, q.tok) # workaround a GCC bug:
|
getTokens(readFile(path), false, q.tok) # workaround a GCC bug:
|
||||||
|
|
@ -1515,15 +1427,12 @@ proc dirInclude(p: var TRstParser): PRstNode =
|
||||||
result = parseDoc(q)
|
result = parseDoc(q)
|
||||||
|
|
||||||
proc dirCodeBlock(p: var TRstParser): PRstNode =
|
proc dirCodeBlock(p: var TRstParser): PRstNode =
|
||||||
var
|
|
||||||
n: PRstNode
|
|
||||||
filename, path: string
|
|
||||||
result = parseDirective(p, {hasArg, hasOptions}, parseLiteralBlock)
|
result = parseDirective(p, {hasArg, hasOptions}, parseLiteralBlock)
|
||||||
filename = strip(getFieldValue(result, "file"))
|
var filename = strip(getFieldValue(result, "file"))
|
||||||
if filename != "":
|
if filename != "":
|
||||||
path = findFile(filename)
|
var path = findFile(filename)
|
||||||
if path == "": rstMessage(p, errCannotOpenFile, filename)
|
if path == "": rstMessage(p, errCannotOpenFile, filename)
|
||||||
n = newRstNode(rnLiteralBlock)
|
var n = newRstNode(rnLiteralBlock)
|
||||||
addSon(n, newRstNode(rnLeaf, readFile(path)))
|
addSon(n, newRstNode(rnLeaf, readFile(path)))
|
||||||
result.sons[2] = n
|
result.sons[2] = n
|
||||||
result.kind = rnCodeBlock
|
result.kind = rnCodeBlock
|
||||||
|
|
@ -1567,28 +1476,23 @@ proc dirRaw(p: var TRstParser): PRstNode =
|
||||||
# The text encoding of the external raw data (file or URL).
|
# The text encoding of the external raw data (file or URL).
|
||||||
# Defaults to the document's encoding (if specified).
|
# Defaults to the document's encoding (if specified).
|
||||||
#
|
#
|
||||||
var filename, path, f: string
|
|
||||||
result = parseDirective(p, {hasOptions}, parseSectionWrapper)
|
result = parseDirective(p, {hasOptions}, parseSectionWrapper)
|
||||||
result.kind = rnRaw
|
result.kind = rnRaw
|
||||||
filename = getFieldValue(result, "file")
|
var filename = getFieldValue(result, "file")
|
||||||
if filename != "":
|
if filename != "":
|
||||||
path = findFile(filename)
|
var path = findFile(filename)
|
||||||
if path == "":
|
if path == "":
|
||||||
rstMessage(p, errCannotOpenFile, filename)
|
rstMessage(p, errCannotOpenFile, filename)
|
||||||
else:
|
else:
|
||||||
f = readFile(path)
|
var f = readFile(path)
|
||||||
result = newRstNode(rnRaw)
|
result = newRstNode(rnRaw)
|
||||||
addSon(result, newRstNode(rnLeaf, f))
|
addSon(result, newRstNode(rnLeaf, f))
|
||||||
|
|
||||||
proc parseDotDot(p: var TRstParser): PRstNode =
|
proc parseDotDot(p: var TRstParser): PRstNode =
|
||||||
var
|
|
||||||
d: string
|
|
||||||
col: int
|
|
||||||
a, b: PRstNode
|
|
||||||
result = nil
|
result = nil
|
||||||
col = p.tok[p.idx].col
|
var col = p.tok[p.idx].col
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
d = getDirective(p)
|
var d = getDirective(p)
|
||||||
if d != "":
|
if d != "":
|
||||||
pushInd(p, col)
|
pushInd(p, col)
|
||||||
case getDirKind(d)
|
case getDirKind(d)
|
||||||
|
|
@ -1606,14 +1510,15 @@ proc parseDotDot(p: var TRstParser): PRstNode =
|
||||||
elif match(p, p.idx, " _"):
|
elif match(p, p.idx, " _"):
|
||||||
# hyperlink target:
|
# hyperlink target:
|
||||||
inc(p.idx, 2)
|
inc(p.idx, 2)
|
||||||
a = getReferenceName(p, ":")
|
var a = getReferenceName(p, ":")
|
||||||
if p.tok[p.idx].kind == tkWhite: inc(p.idx)
|
if p.tok[p.idx].kind == tkWhite: inc(p.idx)
|
||||||
b = untilEol(p)
|
var b = untilEol(p)
|
||||||
setRef(p, rstnodeToRefname(a), b)
|
setRef(p, rstnodeToRefname(a), b)
|
||||||
elif match(p, p.idx, " |"):
|
elif match(p, p.idx, " |"):
|
||||||
# substitution definitions:
|
# substitution definitions:
|
||||||
inc(p.idx, 2)
|
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 p.tok[p.idx].kind == tkWhite: inc(p.idx)
|
||||||
if cmpIgnoreStyle(p.tok[p.idx].symbol, "replace") == 0:
|
if cmpIgnoreStyle(p.tok[p.idx].symbol, "replace") == 0:
|
||||||
inc(p.idx)
|
inc(p.idx)
|
||||||
|
|
@ -1628,32 +1533,28 @@ proc parseDotDot(p: var TRstParser): PRstNode =
|
||||||
elif match(p, p.idx, " ["):
|
elif match(p, p.idx, " ["):
|
||||||
# footnotes, citations
|
# footnotes, citations
|
||||||
inc(p.idx, 2)
|
inc(p.idx, 2)
|
||||||
a = getReferenceName(p, "]")
|
var a = getReferenceName(p, "]")
|
||||||
if p.tok[p.idx].kind == tkWhite: inc(p.idx)
|
if p.tok[p.idx].kind == tkWhite: inc(p.idx)
|
||||||
b = untilEol(p)
|
var b = untilEol(p)
|
||||||
setRef(p, rstnodeToRefname(a), b)
|
setRef(p, rstnodeToRefname(a), b)
|
||||||
else:
|
else:
|
||||||
result = parseComment(p)
|
result = parseComment(p)
|
||||||
|
|
||||||
proc resolveSubs(p: var TRstParser, n: PRstNode): PRstNode =
|
proc resolveSubs(p: var TRstParser, n: PRstNode): PRstNode =
|
||||||
var
|
|
||||||
x: int
|
|
||||||
y: PRstNode
|
|
||||||
e, key: string
|
|
||||||
result = n
|
result = n
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
case n.kind
|
case n.kind
|
||||||
of rnSubstitutionReferences:
|
of rnSubstitutionReferences:
|
||||||
x = findSub(p, n)
|
var x = findSub(p, n)
|
||||||
if x >= 0:
|
if x >= 0:
|
||||||
result = p.s.subs[x].value
|
result = p.s.subs[x].value
|
||||||
else:
|
else:
|
||||||
key = addNodes(n)
|
var key = addNodes(n)
|
||||||
e = getEnv(key)
|
var e = getEnv(key)
|
||||||
if e != "": result = newRstNode(rnLeaf, e)
|
if e != "": result = newRstNode(rnLeaf, e)
|
||||||
else: rstMessage(p, warnUnknownSubstitutionX, key)
|
else: rstMessage(p, warnUnknownSubstitutionX, key)
|
||||||
of rnRef:
|
of rnRef:
|
||||||
y = findRef(p, rstnodeToRefname(n))
|
var y = findRef(p, rstnodeToRefname(n))
|
||||||
if y != nil:
|
if y != nil:
|
||||||
result = newRstNode(rnHyperlink)
|
result = newRstNode(rnHyperlink)
|
||||||
n.kind = rnInner
|
n.kind = rnInner
|
||||||
|
|
|
||||||
|
|
@ -139,18 +139,22 @@ proc fillToken*(L: var TToken)
|
||||||
proc isKeyword(kind: TTokType): bool =
|
proc isKeyword(kind: TTokType): bool =
|
||||||
result = (kind >= tokKeywordLow) and (kind <= tokKeywordHigh)
|
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) =
|
proc pushInd(L: var TLexer, indent: int) =
|
||||||
var length: int
|
var length = len(L.indentStack)
|
||||||
length = len(L.indentStack)
|
|
||||||
setlen(L.indentStack, length + 1)
|
setlen(L.indentStack, length + 1)
|
||||||
if (indent > L.indentStack[length - 1]):
|
if (indent > L.indentStack[length - 1]):
|
||||||
L.indentstack[length] = indent
|
L.indentstack[length] = indent
|
||||||
else:
|
else:
|
||||||
InternalError("pushInd") #writeln('push indent ', indent);
|
InternalError("pushInd")
|
||||||
|
|
||||||
proc popInd(L: var TLexer) =
|
proc popInd(L: var TLexer) =
|
||||||
var length: int
|
var length = len(L.indentStack)
|
||||||
length = len(L.indentStack)
|
|
||||||
setlen(L.indentStack, length - 1)
|
setlen(L.indentStack, length - 1)
|
||||||
|
|
||||||
proc findIdent(L: TLexer, indent: int): bool =
|
proc findIdent(L: TLexer, indent: int): bool =
|
||||||
|
|
@ -161,12 +165,9 @@ proc findIdent(L: TLexer, indent: int): bool =
|
||||||
|
|
||||||
proc tokToStr(tok: PToken): string =
|
proc tokToStr(tok: PToken): string =
|
||||||
case tok.tokType
|
case tok.tokType
|
||||||
of tkIntLit..tkInt64Lit:
|
of tkIntLit..tkInt64Lit: result = $tok.iNumber
|
||||||
result = $(tok.iNumber)
|
of tkFloatLit..tkFloat64Lit: result = $tok.fNumber
|
||||||
of tkFloatLit..tkFloat64Lit:
|
of tkInvalid, tkStrLit..tkCharLit, tkComment: result = tok.literal
|
||||||
result = $(tok.fNumber)
|
|
||||||
of tkInvalid, tkStrLit..tkCharLit, tkComment:
|
|
||||||
result = tok.literal
|
|
||||||
of tkParLe..tkColon, tkEof, tkInd, tkSad, tkDed, tkAccent:
|
of tkParLe..tkColon, tkEof, tkInd, tkSad, tkDed, tkAccent:
|
||||||
result = tokTypeToStr[tok.tokType]
|
result = tokTypeToStr[tok.tokType]
|
||||||
else:
|
else:
|
||||||
|
|
@ -194,7 +195,7 @@ proc fillToken(L: var TToken) =
|
||||||
|
|
||||||
proc openLexer(lex: var TLexer, filename: string, inputstream: PLLStream) =
|
proc openLexer(lex: var TLexer, filename: string, inputstream: PLLStream) =
|
||||||
openBaseLexer(lex, inputstream)
|
openBaseLexer(lex, inputstream)
|
||||||
lex.indentStack = @ [0]
|
lex.indentStack = @[0]
|
||||||
lex.filename = filename
|
lex.filename = filename
|
||||||
lex.indentAhead = - 1
|
lex.indentAhead = - 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,9 @@ type
|
||||||
wLinksys, wDeprecated, wVarargs, wByref, wCallconv, wBreakpoint, wDebugger,
|
wLinksys, wDeprecated, wVarargs, wByref, wCallconv, wBreakpoint, wDebugger,
|
||||||
wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline,
|
wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline,
|
||||||
wFastcall, wClosure, wNoconv, wOn, wOff, wChecks, wRangechecks,
|
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,
|
wHints, wOptimization, wSpeed, wSize, wNone, wPath, wP, wD, wU, wDebuginfo,
|
||||||
wCompileonly, wNolinking, wForcebuild, wF, wDeadCodeElim, wSafecode,
|
wCompileonly, wNolinking, wForcebuild, wF, wDeadCodeElim, wSafecode,
|
||||||
wCompileTime, wGc, wRefc, wBoehm, wA, wOpt, wO, wApp, wConsole, wGui,
|
wCompileTime, wGc, wRefc, wBoehm, wA, wOpt, wO, wApp, wConsole, wGui,
|
||||||
|
|
@ -100,7 +102,10 @@ const
|
||||||
"byref", "callconv", "breakpoint", "debugger", "nimcall", "stdcall",
|
"byref", "callconv", "breakpoint", "debugger", "nimcall", "stdcall",
|
||||||
"cdecl", "safecall", "syscall", "inline", "noinline", "fastcall", "closure",
|
"cdecl", "safecall", "syscall", "inline", "noinline", "fastcall", "closure",
|
||||||
"noconv", "on", "off", "checks", "rangechecks", "boundchecks",
|
"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",
|
"optimization", "speed", "size", "none", "path", "p", "d", "u", "debuginfo",
|
||||||
"compileonly", "nolinking", "forcebuild", "f", "deadcodeelim", "safecode",
|
"compileonly", "nolinking", "forcebuild", "f", "deadcodeelim", "safecode",
|
||||||
"compiletime", "gc", "refc", "boehm", "a", "opt", "o", "app", "console",
|
"compiletime", "gc", "refc", "boehm", "a", "opt", "o", "app", "console",
|
||||||
|
|
|
||||||
5
start.bat
Executable file
5
start.bat
Executable file
|
|
@ -0,0 +1,5 @@
|
||||||
|
@echo off
|
||||||
|
REM COLOR 0A
|
||||||
|
SET NIMRODPATH=.
|
||||||
|
SET PATH=%NIMRODPATH%\bin;%NIMRODPATH%\dist\mingw\bin;%PATH%
|
||||||
|
cmd
|
||||||
1
tests/99bottles.nim
Executable file
1
tests/99bottles.nim
Executable file
|
|
@ -0,0 +1 @@
|
||||||
|
# Test if the compiler detects invalid module names
|
||||||
8
tests/tfloat1.nim
Executable file
8
tests/tfloat1.nim
Executable file
|
|
@ -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]
|
||||||
8
tests/tfloat2.nim
Executable file
8
tests/tfloat2.nim
Executable file
|
|
@ -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]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue