bug concerning constant evaluation fixed
This commit is contained in:
parent
3710309d39
commit
196ef92c86
14 changed files with 296 additions and 245 deletions
|
|
@ -1,9 +1,9 @@
|
||||||
Advanced commands::
|
Advanced commands::
|
||||||
pas convert a Pascal file to Nimrod syntax
|
pas convert a Pascal file to Nimrod syntax
|
||||||
pretty pretty print the inputfile
|
pretty pretty print the inputfile
|
||||||
gen_depend generate a DOT file containing the
|
genDepend generate a DOT file containing the
|
||||||
module dependency graph
|
module dependency graph
|
||||||
list_def list all defined conditionals and exit
|
listDef list all defined conditionals and exit
|
||||||
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:
|
||||||
|
|
@ -12,27 +12,27 @@ Advanced options:
|
||||||
--hints:on|off hints ON|OFF
|
--hints:on|off hints ON|OFF
|
||||||
--hint[X]:on|off specific hint X ON|OFF
|
--hint[X]:on|off specific hint X ON|OFF
|
||||||
--lib:PATH set the system library path
|
--lib:PATH set the system library path
|
||||||
-c, --compile_only compile only; do not assemble or link
|
-c, --compileOnly compile only; do not assemble or link
|
||||||
--no_linking compile but do not link
|
--noLinking compile but do not link
|
||||||
--no_main do not generate a main procedure
|
--noMain do not generate a main procedure
|
||||||
--gen_script generate a compile script (in the 'nimcache'
|
--genScript generate a compile script (in the 'nimcache'
|
||||||
subdirectory named 'compile_$project$scriptext')
|
subdirectory named 'compile_$project$scriptext')
|
||||||
--os:SYMBOL set the target operating system (cross-compilation)
|
--os:SYMBOL set the target operating system (cross-compilation)
|
||||||
--cpu:SYMBOL set the target processor (cross-compilation)
|
--cpu:SYMBOL set the target processor (cross-compilation)
|
||||||
--debuginfo enables debug information
|
--debuginfo enables debug information
|
||||||
-t, --passc:OPTION pass an option to the C compiler
|
-t, --passc:OPTION pass an option to the C compiler
|
||||||
-l, --passl:OPTION pass an option to the linker
|
-l, --passl:OPTION pass an option to the linker
|
||||||
--gen_mapping generate a mapping file containing
|
--genMapping generate a mapping file containing
|
||||||
(Nimrod, mangled) identifier pairs
|
(Nimrod, mangled) identifier pairs
|
||||||
--line_dir: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 on|off checkpoints; for debugging Nimrod
|
||||||
--skip_cfg do not read the general configuration file
|
--skipCfg do not read the general configuration file
|
||||||
--skip_proj_cfg 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
|
||||||
--index:FILE use FILE to generate a documenation index file
|
--index:FILE use FILE to generate a documenation index file
|
||||||
--putenv:key=value set an environment variable
|
--putenv:key=value set an environment variable
|
||||||
--list_cmd list the commands used to execute external programs
|
--listCmd list the commands used to execute external programs
|
||||||
--parallel_build=0|1|... perform a parallel build
|
--parallelBuild=0|1|... perform a parallel build
|
||||||
value = number of processors (0 for auto-detect)
|
value = number of processors (0 for auto-detect)
|
||||||
--verbosity:0|1|2|3 set Nimrod's verbosity level (0 is default)
|
--verbosity:0|1|2|3 set Nimrod's verbosity level (0 is default)
|
||||||
-v, --version show detailed version information
|
-v, --version show detailed version information
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ Usage::
|
||||||
nimrod command [options] inputfile [arguments]
|
nimrod command [options] inputfile [arguments]
|
||||||
Command::
|
Command::
|
||||||
compile, c compile project with default code generator (C)
|
compile, c compile project with default code generator (C)
|
||||||
compile_to_c, cc compile project with C code generator
|
compileToC, cc compile project with C code generator
|
||||||
doc generate the documentation for inputfile
|
doc generate the documentation for inputfile
|
||||||
rst2html converts a reStructuredText file to HTML
|
rst2html converts a reStructuredText file to HTML
|
||||||
rst2tex converts a reStructuredText file to TeX
|
rst2tex converts a reStructuredText file to TeX
|
||||||
|
|
@ -13,19 +13,19 @@ Options:
|
||||||
-o, --out:FILE set the output filename
|
-o, --out:FILE set the output filename
|
||||||
-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, --force_build force rebuilding of all modules
|
-f, --forceBuild force rebuilding of all modules
|
||||||
--symbol_files:on|off use symbol files to speed up compilation (buggy!)
|
--symbolFiles:on|off use symbol files to speed up compilation (buggy!)
|
||||||
--stack_trace:on|off code generation for stack trace ON|OFF
|
--stackTrace:on|off code generation for stack trace ON|OFF
|
||||||
--line_trace:on|off code generation for line trace 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 code generation for all runtime checks ON|OFF
|
-x, --checks:on|off code generation for all runtime checks ON|OFF
|
||||||
--obj_checks:on|off code generation for obj conversion checks ON|OFF
|
--objChecks:on|off code generation for obj conversion checks ON|OFF
|
||||||
--field_checks:on|off code generation for case variant fields ON|OFF
|
--fieldChecks:on|off code generation for case variant fields ON|OFF
|
||||||
--range_checks:on|off code generation for range checks ON|OFF
|
--rangeChecks:on|off code generation for range checks ON|OFF
|
||||||
--bound_checks:on|off code generation for bound checks ON|OFF
|
--boundChecks:on|off code generation for bound checks ON|OFF
|
||||||
--overflow_checks:on|off code generation for over-/underflow checks ON|OFF
|
--overflowChecks:on|off code generation for over-/underflow checks ON|OFF
|
||||||
-a, --assertions:on|off code generation for assertions ON|OFF
|
-a, --assertions:on|off code generation for assertions ON|OFF
|
||||||
--dead_code_elim:on|off whole program dead code elimination 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
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,11 @@ Path Purpose
|
||||||
version
|
version
|
||||||
``data`` data files that are used for generating source
|
``data`` data files that are used for generating source
|
||||||
code
|
code
|
||||||
``doc`` the documentation lives here; it is a bunch of
|
``doc`` the documentation; it is a bunch of
|
||||||
reStructuredText files
|
reStructuredText files
|
||||||
``dist`` additional packages for the distribution
|
``dist`` additional packages for the distribution
|
||||||
``config`` configuration files for Nimrod
|
``config`` configuration files for Nimrod
|
||||||
``lib`` the Nimrod library lives here; ``rod`` depends
|
``lib`` the Nimrod library; ``rod`` depends on it!
|
||||||
on it!
|
|
||||||
``web`` website of Nimrod; generated by ``koch.py``
|
``web`` website of Nimrod; generated by ``koch.py``
|
||||||
from the ``*.txt`` and ``*.tmpl`` files
|
from the ``*.txt`` and ``*.tmpl`` files
|
||||||
``obj`` generated ``*.obj`` files
|
``obj`` generated ``*.obj`` files
|
||||||
|
|
@ -183,7 +182,7 @@ I use the term *cell* here to refer to everything that is traced
|
||||||
This section describes how the new GC works.
|
This section describes how the new GC works.
|
||||||
|
|
||||||
The basic algorithm is *Deferrent Reference Counting* with cycle detection.
|
The basic algorithm is *Deferrent Reference Counting* with cycle detection.
|
||||||
References in the stack are not counted for better performance and easier C
|
References on the stack are not counted for better performance and easier C
|
||||||
code generation.
|
code generation.
|
||||||
|
|
||||||
Each cell has a header consisting of a RC and a pointer to its type
|
Each cell has a header consisting of a RC and a pointer to its type
|
||||||
|
|
|
||||||
|
|
@ -666,7 +666,7 @@ The notation ``x[i]`` can be used to access the i-th element of ``x``.
|
||||||
|
|
||||||
Arrays are always bounds checked (at compile-time or at runtime). These
|
Arrays are always bounds checked (at compile-time or at runtime). These
|
||||||
checks can be disabled via pragmas or invoking the compiler with the
|
checks can be disabled via pragmas or invoking the compiler with the
|
||||||
``--bound_checks:off`` command line switch.
|
``--boundChecks:off`` command line switch.
|
||||||
|
|
||||||
An open array is also a means to implement passing a variable number of
|
An open array is also a means to implement passing a variable number of
|
||||||
arguments to a procedure. The compiler converts the list of arguments
|
arguments to a procedure. The compiler converts the list of arguments
|
||||||
|
|
@ -2450,11 +2450,11 @@ pragma allowed values description
|
||||||
=============== =============== ============================================
|
=============== =============== ============================================
|
||||||
checks on|off Turns the code generation for all runtime
|
checks on|off Turns the code generation for all runtime
|
||||||
checks on or off.
|
checks on or off.
|
||||||
bound_checks on|off Turns the code generation for array bound
|
boundChecks on|off Turns the code generation for array bound
|
||||||
checks on or off.
|
checks on or off.
|
||||||
overflow_checks on|off Turns the code generation for over- or
|
overflowChecks on|off Turns the code generation for over- or
|
||||||
underflow checks on or off.
|
underflow checks on or off.
|
||||||
nil_checks on|off Turns the code generation for nil pointer
|
nilChecks on|off Turns the code generation for nil pointer
|
||||||
checks on or off.
|
checks on or off.
|
||||||
assertions on|off Turns the code generation for assertions
|
assertions on|off Turns the code generation for assertions
|
||||||
on or off.
|
on or off.
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ Introduction
|
||||||
|
|
||||||
This document describes the usage of the *Nimrod compiler*
|
This document describes the usage of the *Nimrod compiler*
|
||||||
on the different supported platforms. It is not a definition of the Nimrod
|
on the different supported platforms. It is not a definition of the Nimrod
|
||||||
programming language (therefore is the manual).
|
programming language (therefore is the `manual <manual>`_).
|
||||||
|
|
||||||
Nimrod is free software; it is licensed under the
|
Nimrod is free software; it is licensed under the
|
||||||
`GNU General Public License <gpl.html>`_.
|
`GNU General Public License <gpl.html>`_.
|
||||||
|
|
@ -42,7 +42,7 @@ looks for it in the following directories (in this order):
|
||||||
3. ``/etc/nimrod.cfg`` (UNIX)
|
3. ``/etc/nimrod.cfg`` (UNIX)
|
||||||
|
|
||||||
The search stops as soon as a configuration file has been found. The reading
|
The search stops as soon as a configuration file has been found. The reading
|
||||||
of ``nimrod.cfg`` can be suppressed by the ``--skip_cfg`` command line option.
|
of ``nimrod.cfg`` can be suppressed by the ``--skipCfg`` command line option.
|
||||||
Configuration settings can be overwritten in a project specific
|
Configuration settings can be overwritten in a project specific
|
||||||
configuration file that is read automatically. This specific file has to
|
configuration file that is read automatically. This specific file has to
|
||||||
be in the same directory as the project and be of the same name, except
|
be in the same directory as the project and be of the same name, except
|
||||||
|
|
@ -125,24 +125,24 @@ At runtime the dynamic library is searched for (in this order)::
|
||||||
libtcl8.3.so.0
|
libtcl8.3.so.0
|
||||||
|
|
||||||
|
|
||||||
No_decl Pragma
|
NoDecl Pragma
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
The `no_decl`:idx: pragma can be applied to almost any symbol (variable, proc,
|
The `noDecl`:idx: pragma can be applied to almost any symbol (variable, proc,
|
||||||
type, etc.) and is sometimes useful for interoperability with C:
|
type, etc.) and is sometimes useful for interoperability with C:
|
||||||
It tells Nimrod that it should not generate a declaration for the symbol in
|
It tells Nimrod that it should not generate a declaration for the symbol in
|
||||||
the C code. For example:
|
the C code. For example:
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
var
|
var
|
||||||
EACCES {.importc, no_decl.}: cint # pretend EACCES was a variable, as
|
EACCES {.importc, noDecl.}: cint # pretend EACCES was a variable, as
|
||||||
# Nimrod does not know its value
|
# Nimrod does not know its value
|
||||||
|
|
||||||
However, the ``header`` pragma is often the better alternative.
|
However, the ``header`` pragma is often the better alternative.
|
||||||
|
|
||||||
|
|
||||||
Header Pragma
|
Header Pragma
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
The `header`:idx: pragma is very similar to the ``no_decl`` pragma: It can be
|
The `header`:idx: pragma is very similar to the ``noDecl`` pragma: It can be
|
||||||
applied to almost any symbol and specifies that it should not be declared
|
applied to almost any symbol and specifies that it should not be declared
|
||||||
and instead the generated code should contain an ``#include``:
|
and instead the generated code should contain an ``#include``:
|
||||||
|
|
||||||
|
|
@ -170,22 +170,23 @@ strings automatically:
|
||||||
printf("hallo %s", "world") # "world" will be passed as C string
|
printf("hallo %s", "world") # "world" will be passed as C string
|
||||||
|
|
||||||
|
|
||||||
Line_dir Option
|
LineDir Option
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
The `line_dir`:idx: option can be turned on or off. If on the generated C code
|
The `lineDir`:idx: option can be turned on or off. If turned on the
|
||||||
contains ``#line`` directives. This may be helpful for debugging with GDB.
|
generated C code contains ``#line`` directives. This may be helpful for
|
||||||
|
debugging with GDB.
|
||||||
|
|
||||||
|
|
||||||
Stack_trace Option
|
StackTrace Option
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
If the `stack_trace`:idx: option is turned on, the generated C contains code to
|
If the `stackTrace`:idx: option is turned on, the generated C contains code to
|
||||||
ensure that proper stack traces are given if the program crashes or an
|
ensure that proper stack traces are given if the program crashes or an
|
||||||
uncaught exception is raised.
|
uncaught exception is raised.
|
||||||
|
|
||||||
|
|
||||||
Line_trace Option
|
LineTrace Option
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
The `line_trace`:idx: option implies the ``stack_trace`` option. If turned on,
|
The `lineTrace`:idx: option implies the ``stackTrace`` option. If turned on,
|
||||||
the generated C contains code to ensure that proper stack traces with line
|
the generated C contains code to ensure that proper stack traces with line
|
||||||
number information are given if the program crashes or an uncaught exception
|
number information are given if the program crashes or an uncaught exception
|
||||||
is raised.
|
is raised.
|
||||||
|
|
@ -239,21 +240,21 @@ information that this cannot happen to the GC. If the programmer uses the
|
||||||
memory, but nothing worse happens.
|
memory, but nothing worse happens.
|
||||||
|
|
||||||
|
|
||||||
Dead_code_elim Pragma
|
DeadCodeElim Pragma
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
The `dead_code_elim`: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.
|
||||||
|
|
||||||
The ``--dead_code_elim:on`` command line switch has the same effect as marking
|
The ``--deadCodeElim:on`` command line switch has the same effect as marking
|
||||||
every module with ``{.dead_code_elim:on}``. However, for some modules such as
|
every module with ``{.deadCodeElim:on}``. However, for some modules such as
|
||||||
the GTK wrapper it makes sense to *always* turn on dead code elimination -
|
the GTK wrapper it makes sense to *always* turn on dead code elimination -
|
||||||
no matter if it is globally active or not.
|
no matter if it is globally active or not.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
{.dead_code_elim: on.}
|
{.deadCodeElim: on.}
|
||||||
|
|
||||||
|
|
||||||
Disabling certain messages
|
Disabling certain messages
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,20 @@
|
||||||
import strutils, postgres
|
import strutils, postgres
|
||||||
|
|
||||||
type
|
type
|
||||||
TDbHandle* = PGconn
|
TDbConn* = PPGconn ## encapsulates a database connection
|
||||||
TRow* = seq[string]
|
TRow* = seq[string] ## a row of a dataset
|
||||||
EDb* = object of EIO
|
EDb* = object of EIO ## exception that is raised if a database error occurs
|
||||||
|
|
||||||
proc dbError(db: TDbHandle) {.noreturn.} =
|
TSqlQuery* = distinct string ## an SQL query string
|
||||||
|
|
||||||
|
proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} =
|
||||||
|
## constructs a TSqlQuery from the string `query`: If assertions are turned
|
||||||
|
## off, it does nothing. If assertions are turned on, the string is checked
|
||||||
|
## for SQL security holes. This is supposed to be used as a
|
||||||
|
## raw-string-literal modifier: ``sql"update user set counter = counter + 1"``
|
||||||
|
result = TSqlQuery(query)
|
||||||
|
|
||||||
|
proc dbError(db: TDbConn) {.noreturn.} =
|
||||||
## raises an EDb exception.
|
## raises an EDb exception.
|
||||||
var e: ref EDb
|
var e: ref EDb
|
||||||
new(e)
|
new(e)
|
||||||
|
|
@ -23,13 +32,13 @@ proc dbError*(msg: string) {.noreturn.} =
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
proc dbQueryOpt*(db: TDbHandle, query: string, args: openarray[string]) =
|
proc dbQueryOpt*(db: TDbConn, query: string, args: openarray[string]) =
|
||||||
var stmt = mysql_stmt_init(db)
|
var stmt = mysql_stmt_init(db)
|
||||||
if stmt == nil: dbError(db)
|
if stmt == nil: dbError(db)
|
||||||
if mysql_stmt_prepare(stmt, query, len(query)) != 0:
|
if mysql_stmt_prepare(stmt, query, len(query)) != 0:
|
||||||
dbError(db)
|
dbError(db)
|
||||||
var
|
var
|
||||||
bind: seq[MYSQL_BIND]
|
bindings: seq[MYSQL_BIND]
|
||||||
discard mysql_stmt_close(stmt)
|
discard mysql_stmt_close(stmt)
|
||||||
|
|
||||||
proc dbQuote(s: string): string =
|
proc dbQuote(s: string): string =
|
||||||
|
|
@ -39,91 +48,123 @@ proc dbQuote(s: string): string =
|
||||||
else: add(result, c)
|
else: add(result, c)
|
||||||
add(result, '\'')
|
add(result, '\'')
|
||||||
|
|
||||||
proc dbFormat(formatstr: string, args: openarray[string]): string =
|
proc dbFormat(formatstr: TSqlQuery, args: openarray[string]): string =
|
||||||
result = ""
|
result = ""
|
||||||
var a = 0
|
var a = 0
|
||||||
for c in items(formatstr):
|
for c in items(string(formatstr)):
|
||||||
if c == '?':
|
if c == '?':
|
||||||
add(result, dbQuote(args[a]))
|
add(result, dbQuote(args[a]))
|
||||||
inc(a)
|
inc(a)
|
||||||
else:
|
else:
|
||||||
add(result, c)
|
add(result, c)
|
||||||
|
|
||||||
proc dbTryQuery*(db: TDbHandle, query: string, args: openarray[string]): bool =
|
proc dbTryQuery*(db: TDbConn, query: TSqlQuery,
|
||||||
|
args: openarray[string]): bool =
|
||||||
|
## tries to execute the query and returns true if successful, false otherwise.
|
||||||
var q = dbFormat(query, args)
|
var q = dbFormat(query, args)
|
||||||
var res = PQExec(db, q)
|
var res = PQExec(db, q)
|
||||||
result = PQresultStatus(res) == PGRES_COMMAND_OK
|
result = PQresultStatus(res) == PGRES_COMMAND_OK
|
||||||
PQclear(res)
|
PQclear(res)
|
||||||
|
|
||||||
proc dbQuery*(db: TDbHandle, query: string, args: openarray[string]) =
|
proc dbQuery*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
|
||||||
|
## executes the query and raises EDB if not successful.
|
||||||
var q = dbFormat(query, args)
|
var q = dbFormat(query, args)
|
||||||
var res = PQExec(db, q)
|
var res = PQExec(db, q)
|
||||||
if PQresultStatus(res) != PGRES_COMMAND_OK: dbError(db)
|
if PQresultStatus(res) != PGRES_COMMAND_OK: dbError(db)
|
||||||
PQclear(res)
|
PQclear(res)
|
||||||
|
|
||||||
proc dbTryInsertID*(db: TDbHandle, query: string,
|
|
||||||
args: openarray[string]): int64 =
|
|
||||||
var q = dbFormat(query, args)
|
|
||||||
|
|
||||||
|
|
||||||
if mysqlRealQuery(db, q, q.len) != 0'i32:
|
|
||||||
result = -1'i64
|
|
||||||
else:
|
|
||||||
result = mysql_insert_id(db)
|
|
||||||
LAST_INSERT_ID()
|
|
||||||
|
|
||||||
proc dbInsertID*(db: TDbHandle, query: string, args: openArray[string]): int64 =
|
|
||||||
result = dbTryInsertID(db, query, args)
|
|
||||||
if result < 0: dbError(db)
|
|
||||||
|
|
||||||
proc dbQueryAffectedRows*(db: TDbHandle, query: string,
|
|
||||||
args: openArray[string]): int64 =
|
|
||||||
## runs the query (typically "UPDATE") and returns the
|
|
||||||
## number of affected rows
|
|
||||||
var q = dbFormat(query, args)
|
|
||||||
var res = PQExec(db, q)
|
|
||||||
if PQresultStatus(res) != PGRES_COMMAND_OK: dbError(db)
|
|
||||||
result = parseBiggestInt($PQcmdTuples(res))
|
|
||||||
PQclear(res)
|
|
||||||
|
|
||||||
proc newRow(L: int): TRow =
|
proc newRow(L: int): TRow =
|
||||||
newSeq(result, L)
|
newSeq(result, L)
|
||||||
for i in 0..L-1: result[i] = ""
|
for i in 0..L-1: result[i] = ""
|
||||||
|
|
||||||
iterator dbFastRows*(db: TDbHandle, query: string,
|
proc setupQuery(db: TDbConn, query: TSqlQuery,
|
||||||
args: openarray[string]): TRow =
|
args: openarray[string]): PPGresult =
|
||||||
var q = dbFormat(query, args)
|
var q = dbFormat(query, args)
|
||||||
var res = PQExec(db, q)
|
result = PQExec(db, q)
|
||||||
if PQresultStatus(res) != PGRES_TUPLES_OK: dbError(db)
|
if PQresultStatus(result) != PGRES_TUPLES_OK: dbError(db)
|
||||||
|
|
||||||
|
proc setRow(res: PPGresult, r: var TRow, line, cols: int) =
|
||||||
|
for col in 0..cols-1:
|
||||||
|
setLen(r[col], 0)
|
||||||
|
add(r[col], PQgetvalue(res, line, cols))
|
||||||
|
|
||||||
|
iterator dbFastRows*(db: TDbConn, query: TSqlQuery,
|
||||||
|
args: openarray[string]): TRow =
|
||||||
|
## executes the query and iterates over the result dataset. This is very
|
||||||
|
## fast, but potenially dangerous: If the for-loop-body executes another
|
||||||
|
## query, the results can be undefined. For Postgres it is safe though.
|
||||||
|
var res = setupQuery(db, query, args)
|
||||||
var L = int(PQnfields(res))
|
var L = int(PQnfields(res))
|
||||||
var result = newRow(L)
|
var result = newRow(L)
|
||||||
for i in 0..PQntuples(res)-1:
|
for i in 0..PQntuples(res)-1:
|
||||||
for j in 0..L-1:
|
setRow(res, result, i, L)
|
||||||
setLen(result[j], 0)
|
|
||||||
add(result[j], PQgetvalue(res, i, j))
|
|
||||||
yield result
|
yield result
|
||||||
PQclear(res)
|
PQclear(res)
|
||||||
|
|
||||||
proc dbGetAllRows*(db: TDbHandle, query: string,
|
proc dbGetAllRows*(db: TDbConn, query: TSqlQuery,
|
||||||
args: openarray[string]): seq[TRow] =
|
args: openarray[string]): seq[TRow] =
|
||||||
|
## executes the query and returns the whole result dataset.
|
||||||
result = @[]
|
result = @[]
|
||||||
for r in dbFastRows(db, query, args):
|
for r in dbFastRows(db, query, args):
|
||||||
result.add(r)
|
result.add(r)
|
||||||
|
|
||||||
iterator dbRows*(db: TDbHandle, query: string,
|
iterator dbRows*(db: TDbConn, query: TSqlQuery,
|
||||||
args: openarray[string]): TRow =
|
args: openarray[string]): TRow =
|
||||||
|
## same as `dbFastRows`, but slower and safe.
|
||||||
for r in items(dbGetAllRows(db, query, args)): yield r
|
for r in items(dbGetAllRows(db, query, args)): yield r
|
||||||
|
|
||||||
proc dbGetValue*(db: TDbHandle, query: string,
|
proc dbGetValue*(db: TDbConn, query: TSqlQuery,
|
||||||
args: openarray[string]): string =
|
args: openarray[string]): string =
|
||||||
|
## executes the query and returns the result dataset's the first column
|
||||||
|
## of the first row. Returns "" if the dataset contains no rows. This uses
|
||||||
|
## `dbFastRows`, so it inherits its fragile behaviour.
|
||||||
result = ""
|
result = ""
|
||||||
for row in dbFastRows(db, query, args):
|
for row in dbFastRows(db, query, args):
|
||||||
result = row[0]
|
result = row[0]
|
||||||
break
|
break
|
||||||
|
|
||||||
proc dbClose*(db: TDbHandle) =
|
proc dbTryInsertID*(db: TDbConn, query: TSqlQuery,
|
||||||
|
args: openarray[string]): int64 =
|
||||||
|
## executes the query (typically "INSERT") and returns the
|
||||||
|
## generated ID for the row or -1 in case of an error. For Postgre this adds
|
||||||
|
## ``RETURNING id`` to the query, so it only works if your primary key is
|
||||||
|
## named ``id``.
|
||||||
|
var val = dbGetValue(db, TSqlQuery(string(query) & " RETURNING id"), args)
|
||||||
|
if val.len > 0:
|
||||||
|
result = ParseBiggestInt(val)
|
||||||
|
else:
|
||||||
|
result = -1
|
||||||
|
#if mysqlRealQuery(db, q, q.len) != 0'i32:
|
||||||
|
# result = -1'i64
|
||||||
|
#else:
|
||||||
|
# result = mysql_insert_id(db)
|
||||||
|
#LAST_INSERT_ID()
|
||||||
|
|
||||||
|
proc dbInsertID*(db: TDbConn, query: TSqlQuery,
|
||||||
|
args: openArray[string]): int64 =
|
||||||
|
## executes the query (typically "INSERT") and returns the
|
||||||
|
## generated ID for the row. For Postgre this adds
|
||||||
|
## ``RETURNING id`` to the query, so it only works if your primary key is
|
||||||
|
## named ``id``.
|
||||||
|
result = dbTryInsertID(db, query, args)
|
||||||
|
if result < 0: dbError(db)
|
||||||
|
|
||||||
|
proc dbQueryAffectedRows*(db: TDbConn, query: TSqlQuery,
|
||||||
|
args: openArray[string]): int64 =
|
||||||
|
## executes the query (typically "UPDATE") and returns the
|
||||||
|
## number of affected rows.
|
||||||
|
var q = dbFormat(query, args)
|
||||||
|
var res = PQExec(db, q)
|
||||||
|
if PQresultStatus(res) != PGRES_COMMAND_OK: dbError(db)
|
||||||
|
result = parseBiggestInt($PQcmdTuples(res))
|
||||||
|
PQclear(res)
|
||||||
|
|
||||||
|
proc dbClose*(db: TDbConn) =
|
||||||
|
## closes the database connection.
|
||||||
if db != nil: PQfinish(db)
|
if db != nil: PQfinish(db)
|
||||||
|
|
||||||
proc dbOpen*(connection, user, password, database: string): TDbHandle =
|
proc dbOpen*(connection, user, password, database: string): TDbConn =
|
||||||
|
## opens a database connection. Returns nil in case of an error.
|
||||||
result = PQsetdbLogin(nil, nil, nil, nil, database, user, password)
|
result = PQsetdbLogin(nil, nil, nil, nil, database, user, password)
|
||||||
if PQStatus(result) != CONNECTION_OK: result = nil
|
if PQStatus(result) != CONNECTION_OK: dbError(result) # result = nil
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ proc close*(z: var TZipArchive) =
|
||||||
zip_close(z.w)
|
zip_close(z.w)
|
||||||
|
|
||||||
proc createDir*(z: var TZipArchive, dir: string) =
|
proc createDir*(z: var TZipArchive, dir: string) =
|
||||||
## Creates a directory within the `z` archive. This does not fails if the
|
## Creates a directory within the `z` archive. This does not fail if the
|
||||||
## directory already exists. Note that for adding a file like
|
## directory already exists. Note that for adding a file like
|
||||||
## ``"path1/path2/filename"`` it is not necessary
|
## ``"path1/path2/filename"`` it is not necessary
|
||||||
## to create the ``"path/path2"`` subdirectories - it will be done
|
## to create the ``"path/path2"`` subdirectories - it will be done
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ proc sequence*(a: openArray[TPeg]): TPeg =
|
||||||
multipleOp(pkSequence, addSequence)
|
multipleOp(pkSequence, addSequence)
|
||||||
|
|
||||||
proc `?`*(a: TPeg): TPeg =
|
proc `?`*(a: TPeg): TPeg =
|
||||||
## constructs an optional piece with the PEG `a`
|
## constructs an optional for the PEG `a`
|
||||||
if a.kind in {pkOption, pkGreedyRep, pkGreedyAny, pkGreedyRepChar,
|
if a.kind in {pkOption, pkGreedyRep, pkGreedyAny, pkGreedyRepChar,
|
||||||
pkGreedyRepSet}:
|
pkGreedyRepSet}:
|
||||||
# a* ? --> a*
|
# a* ? --> a*
|
||||||
|
|
@ -159,7 +159,7 @@ proc `?`*(a: TPeg): TPeg =
|
||||||
result.sons = @[a]
|
result.sons = @[a]
|
||||||
|
|
||||||
proc `*`*(a: TPeg): TPeg =
|
proc `*`*(a: TPeg): TPeg =
|
||||||
## constructs a "greedy repetition" piece the PEG `a`
|
## constructs a "greedy repetition" for the PEG `a`
|
||||||
case a.kind
|
case a.kind
|
||||||
of pkGreedyRep, pkGreedyRepChar, pkGreedyRepSet, pkGreedyAny, pkOption:
|
of pkGreedyRep, pkGreedyRepChar, pkGreedyRepSet, pkGreedyAny, pkOption:
|
||||||
assert false
|
assert false
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ proc replace*(s: string, sub: TRegEx, by: string): string =
|
||||||
## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples:
|
## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples:
|
||||||
##
|
##
|
||||||
## .. code-block:: nimrod
|
## .. code-block:: nimrod
|
||||||
## "var1=key; var2=key2".replace(p"{\ident}'='{\ident}", "$1<-$2$2")
|
## "var1=key; var2=key2".replace(re"{\ident}'='{\ident}", "$1<-$2$2")
|
||||||
##
|
##
|
||||||
## Results in:
|
## Results in:
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,10 @@ proc writeProfile() {.noconv.} =
|
||||||
var i = 0
|
var i = 0
|
||||||
var f: TFile
|
var f: TFile
|
||||||
var j = 1
|
var j = 1
|
||||||
while openFile(f, filename & $j & ".txt"):
|
while open(f, filename & $j & ".txt"):
|
||||||
closeFile(f)
|
close(f)
|
||||||
inc(j)
|
inc(j)
|
||||||
if openFile(f, filename & $j & ".txt", fmWrite):
|
if open(f, filename & $j & ".txt", fmWrite):
|
||||||
var N = 0
|
var N = 0
|
||||||
# we have to compute the actual length of the array:
|
# we have to compute the actual length of the array:
|
||||||
while profileData[N].procname != nil: inc(N)
|
while profileData[N].procname != nil: inc(N)
|
||||||
|
|
@ -56,6 +56,6 @@ proc writeProfile() {.noconv.} =
|
||||||
write(f, ": ")
|
write(f, ": ")
|
||||||
writeln(f, profileData[i].total)
|
writeln(f, profileData[i].total)
|
||||||
inc(i)
|
inc(i)
|
||||||
closeFile(f)
|
close(f)
|
||||||
|
|
||||||
addQuitProc(writeProfile)
|
addQuitProc(writeProfile)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ when defined(windows):
|
||||||
elif defined(macosx):
|
elif defined(macosx):
|
||||||
const dllName = "libpq.dylib"
|
const dllName = "libpq.dylib"
|
||||||
else:
|
else:
|
||||||
const dllName = "libpq.so"
|
const dllName = "libpq.so(.5|)"
|
||||||
|
|
||||||
type
|
type
|
||||||
POid* = ptr Oid
|
POid* = ptr Oid
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ const
|
||||||
+{&} ' nimrod command [options] inputfile [arguments]' +{&} nl
|
+{&} ' nimrod command [options] inputfile [arguments]' +{&} nl
|
||||||
+{&} 'Command::' +{&} nl
|
+{&} 'Command::' +{&} nl
|
||||||
+{&} ' compile, c compile project with default code generator (C)' +{&} nl
|
+{&} ' compile, c compile project with default code generator (C)' +{&} nl
|
||||||
+{&} ' compile_to_c, cc compile project with C code generator' +{&} nl
|
+{&} ' compileToC, cc compile project with C code generator' +{&} nl
|
||||||
+{&} ' doc generate the documentation for inputfile' +{&} nl
|
+{&} ' doc generate the documentation for inputfile' +{&} nl
|
||||||
+{&} ' rst2html converts a reStructuredText file to HTML' +{&} nl
|
+{&} ' rst2html converts a reStructuredText file to HTML' +{&} nl
|
||||||
+{&} ' rst2tex converts a reStructuredText file to TeX' +{&} nl
|
+{&} ' rst2tex converts a reStructuredText file to TeX' +{&} nl
|
||||||
|
|
@ -71,19 +71,19 @@ const
|
||||||
+{&} ' -o, --out:FILE set the output filename' +{&} nl
|
+{&} ' -o, --out:FILE set the output filename' +{&} nl
|
||||||
+{&} ' -d, --define:SYMBOL define a conditional symbol' +{&} nl
|
+{&} ' -d, --define:SYMBOL define a conditional symbol' +{&} nl
|
||||||
+{&} ' -u, --undef:SYMBOL undefine a conditional symbol' +{&} nl
|
+{&} ' -u, --undef:SYMBOL undefine a conditional symbol' +{&} nl
|
||||||
+{&} ' -f, --force_build force rebuilding of all modules' +{&} nl
|
+{&} ' -f, --forceBuild force rebuilding of all modules' +{&} nl
|
||||||
+{&} ' --symbol_files:on|off use symbol files to speed up compilation (buggy!)' +{&} nl
|
+{&} ' --symbolFiles:on|off use symbol files to speed up compilation (buggy!)' +{&} nl
|
||||||
+{&} ' --stack_trace:on|off code generation for stack trace ON|OFF' +{&} nl
|
+{&} ' --stackTrace:on|off code generation for stack trace ON|OFF' +{&} nl
|
||||||
+{&} ' --line_trace:on|off code generation for line trace ON|OFF' +{&} nl
|
+{&} ' --lineTrace:on|off code generation for line trace ON|OFF' +{&} nl
|
||||||
+{&} ' --debugger:on|off turn Embedded Nimrod Debugger ON|OFF' +{&} nl
|
+{&} ' --debugger:on|off turn Embedded Nimrod Debugger ON|OFF' +{&} nl
|
||||||
+{&} ' -x, --checks:on|off code generation for all runtime checks ON|OFF' +{&} nl
|
+{&} ' -x, --checks:on|off code generation for all runtime checks ON|OFF' +{&} nl
|
||||||
+{&} ' --obj_checks:on|off code generation for obj conversion checks ON|OFF' +{&} nl
|
+{&} ' --objChecks:on|off code generation for obj conversion checks ON|OFF' +{&} nl
|
||||||
+{&} ' --field_checks:on|off code generation for case variant fields ON|OFF' +{&} nl
|
+{&} ' --fieldChecks:on|off code generation for case variant fields ON|OFF' +{&} nl
|
||||||
+{&} ' --range_checks:on|off code generation for range checks ON|OFF' +{&} nl
|
+{&} ' --rangeChecks:on|off code generation for range checks ON|OFF' +{&} nl
|
||||||
+{&} ' --bound_checks:on|off code generation for bound checks ON|OFF' +{&} nl
|
+{&} ' --boundChecks:on|off code generation for bound checks ON|OFF' +{&} nl
|
||||||
+{&} ' --overflow_checks:on|off code generation for over-/underflow checks ON|OFF' +{&} nl
|
+{&} ' --overflowChecks:on|off code generation for over-/underflow checks ON|OFF' +{&} nl
|
||||||
+{&} ' -a, --assertions:on|off code generation for assertions ON|OFF' +{&} nl
|
+{&} ' -a, --assertions:on|off code generation for assertions ON|OFF' +{&} nl
|
||||||
+{&} ' --dead_code_elim:on|off whole program dead code elimination ON|OFF' +{&} nl
|
+{&} ' --deadCodeElim:on|off whole program dead code elimination ON|OFF' +{&} nl
|
||||||
+{&} ' --opt:none|speed|size optimize not at all or for speed|size' +{&} nl
|
+{&} ' --opt:none|speed|size optimize not at all or for speed|size' +{&} nl
|
||||||
+{&} ' --app:console|gui|lib generate a console|GUI application|dynamic library' +{&} nl
|
+{&} ' --app:console|gui|lib generate a console|GUI application|dynamic library' +{&} nl
|
||||||
+{&} ' -r, --run run the compiled program with given arguments' +{&} nl
|
+{&} ' -r, --run run the compiled program with given arguments' +{&} nl
|
||||||
|
|
@ -100,9 +100,9 @@ const
|
||||||
+{&} 'Advanced commands::' +{&} nl
|
+{&} 'Advanced commands::' +{&} nl
|
||||||
+{&} ' pas convert a Pascal file to Nimrod syntax' +{&} nl
|
+{&} ' pas convert a Pascal file to Nimrod syntax' +{&} nl
|
||||||
+{&} ' pretty pretty print the inputfile' +{&} nl
|
+{&} ' pretty pretty print the inputfile' +{&} nl
|
||||||
+{&} ' gen_depend generate a DOT file containing the' +{&} nl
|
+{&} ' genDepend generate a DOT file containing the' +{&} nl
|
||||||
+{&} ' module dependency graph' +{&} nl
|
+{&} ' module dependency graph' +{&} nl
|
||||||
+{&} ' list_def list all defined conditionals and exit' +{&} nl
|
+{&} ' listDef list all defined conditionals and exit' +{&} nl
|
||||||
+{&} ' check checks the project for syntax and semantic' +{&} nl
|
+{&} ' check checks the project for syntax and semantic' +{&} nl
|
||||||
+{&} ' parse parses a single file (for debugging Nimrod)' +{&} nl
|
+{&} ' parse parses a single file (for debugging Nimrod)' +{&} nl
|
||||||
+{&} 'Advanced options:' +{&} nl
|
+{&} 'Advanced options:' +{&} nl
|
||||||
|
|
@ -111,27 +111,27 @@ const
|
||||||
+{&} ' --hints:on|off hints ON|OFF' +{&} nl
|
+{&} ' --hints:on|off hints ON|OFF' +{&} nl
|
||||||
+{&} ' --hint[X]:on|off specific hint X ON|OFF' +{&} nl
|
+{&} ' --hint[X]:on|off specific hint X ON|OFF' +{&} nl
|
||||||
+{&} ' --lib:PATH set the system library path' +{&} nl
|
+{&} ' --lib:PATH set the system library path' +{&} nl
|
||||||
+{&} ' -c, --compile_only compile only; do not assemble or link' +{&} nl
|
+{&} ' -c, --compileOnly compile only; do not assemble or link' +{&} nl
|
||||||
+{&} ' --no_linking compile but do not link' +{&} nl
|
+{&} ' --noLinking compile but do not link' +{&} nl
|
||||||
+{&} ' --no_main do not generate a main procedure' +{&} nl
|
+{&} ' --noMain do not generate a main procedure' +{&} nl
|
||||||
+{&} ' --gen_script generate a compile script (in the ''nimcache''' +{&} nl
|
+{&} ' --genScript generate a compile script (in the ''nimcache''' +{&} nl
|
||||||
+{&} ' subdirectory named ''compile_$project$scriptext'')' +{&} nl
|
+{&} ' subdirectory named ''compile_$project$scriptext'')' +{&} nl
|
||||||
+{&} ' --os:SYMBOL set the target operating system (cross-compilation)' +{&} nl
|
+{&} ' --os:SYMBOL set the target operating system (cross-compilation)' +{&} nl
|
||||||
+{&} ' --cpu:SYMBOL set the target processor (cross-compilation)' +{&} nl
|
+{&} ' --cpu:SYMBOL set the target processor (cross-compilation)' +{&} nl
|
||||||
+{&} ' --debuginfo enables debug information' +{&} nl
|
+{&} ' --debuginfo enables debug information' +{&} nl
|
||||||
+{&} ' -t, --passc:OPTION pass an option to the C compiler' +{&} nl
|
+{&} ' -t, --passc:OPTION pass an option to the C compiler' +{&} nl
|
||||||
+{&} ' -l, --passl:OPTION pass an option to the linker' +{&} nl
|
+{&} ' -l, --passl:OPTION pass an option to the linker' +{&} nl
|
||||||
+{&} ' --gen_mapping generate a mapping file containing' +{&} nl
|
+{&} ' --genMapping generate a mapping file containing' +{&} nl
|
||||||
+{&} ' (Nimrod, mangled) identifier pairs' +{&} nl
|
+{&} ' (Nimrod, mangled) identifier pairs' +{&} nl
|
||||||
+{&} ' --line_dir:on|off generation of #line directive ON|OFF' +{&} nl
|
+{&} ' --lineDir:on|off generation of #line directive ON|OFF' +{&} nl
|
||||||
+{&} ' --checkpoints:on|off turn on|off checkpoints; for debugging Nimrod' +{&} nl
|
+{&} ' --checkpoints:on|off turn on|off checkpoints; for debugging Nimrod' +{&} nl
|
||||||
+{&} ' --skip_cfg do not read the general configuration file' +{&} nl
|
+{&} ' --skipCfg do not read the general configuration file' +{&} nl
|
||||||
+{&} ' --skip_proj_cfg do not read the project''s configuration file' +{&} nl
|
+{&} ' --skipProjCfg do not read the project''s configuration file' +{&} nl
|
||||||
+{&} ' --gc:refc|boehm|none use Nimrod''s native GC|Boehm GC|no GC' +{&} nl
|
+{&} ' --gc:refc|boehm|none use Nimrod''s native GC|Boehm GC|no GC' +{&} nl
|
||||||
+{&} ' --index:FILE use FILE to generate a documenation index file' +{&} nl
|
+{&} ' --index:FILE use FILE to generate a documenation index file' +{&} nl
|
||||||
+{&} ' --putenv:key=value set an environment variable' +{&} nl
|
+{&} ' --putenv:key=value set an environment variable' +{&} nl
|
||||||
+{&} ' --list_cmd list the commands used to execute external programs' +{&} nl
|
+{&} ' --listCmd list the commands used to execute external programs' +{&} nl
|
||||||
+{&} ' --parallel_build=0|1|... perform a parallel build' +{&} nl
|
+{&} ' --parallelBuild=0|1|... perform a parallel build' +{&} nl
|
||||||
+{&} ' value = number of processors (0 for auto-detect)' +{&} nl
|
+{&} ' value = number of processors (0 for auto-detect)' +{&} nl
|
||||||
+{&} ' --verbosity:0|1|2|3 set Nimrod''s verbosity level (0 is default)' +{&} nl
|
+{&} ' --verbosity:0|1|2|3 set Nimrod''s verbosity level (0 is default)' +{&} nl
|
||||||
+{&} ' -v, --version show detailed version information' +{&} nl
|
+{&} ' -v, --version show detailed version information' +{&} nl
|
||||||
|
|
@ -180,7 +180,8 @@ begin
|
||||||
helpWritten := true;
|
helpWritten := true;
|
||||||
messageOut(format(HelpMessage, [VersionAsString,
|
messageOut(format(HelpMessage, [VersionAsString,
|
||||||
platform.os[platform.hostOS].name,
|
platform.os[platform.hostOS].name,
|
||||||
cpu[platform.hostCPU].name]))
|
cpu[platform.hostCPU].name]));
|
||||||
|
halt(0);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
||||||
228
nim/evals.pas
228
nim/evals.pas
|
|
@ -117,6 +117,11 @@ begin
|
||||||
liMessage(n.info, msg, arg);
|
liMessage(n.info, msg, arg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function isSpecial(n: PNode): bool;
|
||||||
|
begin
|
||||||
|
result := (n.kind = nkExceptBranch) or (n.kind = nkEmpty)
|
||||||
|
end;
|
||||||
|
|
||||||
function evalIf(c: PEvalContext; n: PNode): PNode;
|
function evalIf(c: PEvalContext; n: PNode): PNode;
|
||||||
var
|
var
|
||||||
i, len: int;
|
i, len: int;
|
||||||
|
|
@ -125,7 +130,7 @@ begin
|
||||||
len := sonsLen(n);
|
len := sonsLen(n);
|
||||||
while (i < len) and (sonsLen(n.sons[i]) >= 2) do begin
|
while (i < len) and (sonsLen(n.sons[i]) >= 2) do begin
|
||||||
result := evalAux(c, n.sons[i].sons[0]);
|
result := evalAux(c, n.sons[i].sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if (result.kind = nkIntLit) and (result.intVal <> 0) then begin
|
if (result.kind = nkIntLit) and (result.intVal <> 0) then begin
|
||||||
result := evalAux(c, n.sons[i].sons[1]);
|
result := evalAux(c, n.sons[i].sons[1]);
|
||||||
exit
|
exit
|
||||||
|
|
@ -144,7 +149,7 @@ var
|
||||||
res: PNode;
|
res: PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
res := result;
|
res := result;
|
||||||
result := emptyNode;
|
result := emptyNode;
|
||||||
for i := 1 to sonsLen(n)-1 do begin
|
for i := 1 to sonsLen(n)-1 do begin
|
||||||
|
|
@ -173,7 +178,7 @@ function evalWhile(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
while true do begin
|
while true do begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if getOrdValue(result) = 0 then break;
|
if getOrdValue(result) = 0 then break;
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
case result.kind of
|
case result.kind of
|
||||||
|
|
@ -183,7 +188,7 @@ begin
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
nkExceptBranch, nkReturnToken: break;
|
nkExceptBranch, nkReturnToken, nkEmpty: break;
|
||||||
else begin end
|
else begin end
|
||||||
end;
|
end;
|
||||||
dec(gWhileCounter);
|
dec(gWhileCounter);
|
||||||
|
|
@ -314,7 +319,7 @@ begin
|
||||||
v := a.sons[0].sym;
|
v := a.sons[0].sym;
|
||||||
if a.sons[2] <> nil then begin
|
if a.sons[2] <> nil then begin
|
||||||
result := evalAux(c, a.sons[2]);
|
result := evalAux(c, a.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
result := getNullValue(a.sons[0].typ, a.sons[0].info);
|
result := getNullValue(a.sons[0].typ, a.sons[0].info);
|
||||||
|
|
@ -330,7 +335,7 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
prc := result;
|
prc := result;
|
||||||
// bind the actual params to the local parameter
|
// bind the actual params to the local parameter
|
||||||
// of a new binding
|
// of a new binding
|
||||||
|
|
@ -344,13 +349,13 @@ begin
|
||||||
setLength(d.params, sonsLen(n));
|
setLength(d.params, sonsLen(n));
|
||||||
for i := 1 to sonsLen(n)-1 do begin
|
for i := 1 to sonsLen(n)-1 do begin
|
||||||
result := evalAux(c, n.sons[i]);
|
result := evalAux(c, n.sons[i]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
d.params[i] := result;
|
d.params[i] := result;
|
||||||
end;
|
end;
|
||||||
if n.typ <> nil then d.params[0] := getNullValue(n.typ, n.info);
|
if n.typ <> nil then d.params[0] := getNullValue(n.typ, n.info);
|
||||||
pushStackFrame(c, d);
|
pushStackFrame(c, d);
|
||||||
result := evalAux(c, prc);
|
result := evalAux(c, prc);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if n.typ <> nil then result := d.params[0];
|
if n.typ <> nil then result := d.params[0];
|
||||||
popStackFrame(c);
|
popStackFrame(c);
|
||||||
end;
|
end;
|
||||||
|
|
@ -380,10 +385,10 @@ var
|
||||||
idx: biggestInt;
|
idx: biggestInt;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
x := result;
|
x := result;
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
idx := getOrdValue(result);
|
idx := getOrdValue(result);
|
||||||
result := emptyNode;
|
result := emptyNode;
|
||||||
case x.kind of
|
case x.kind of
|
||||||
|
|
@ -416,7 +421,7 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
x := result;
|
x := result;
|
||||||
if x.kind <> nkPar then InternalError(n.info, 'evalFieldAccess');
|
if x.kind <> nkPar then InternalError(n.info, 'evalFieldAccess');
|
||||||
field := n.sons[1].sym;
|
field := n.sons[1].sym;
|
||||||
|
|
@ -437,10 +442,10 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
x := result;
|
x := result;
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
x.kind := result.kind;
|
x.kind := result.kind;
|
||||||
x.typ := result.typ;
|
x.typ := result.typ;
|
||||||
case x.kind of
|
case x.kind of
|
||||||
|
|
@ -469,10 +474,10 @@ var
|
||||||
tmpn: PNode;
|
tmpn: PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
x := result;
|
x := result;
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if (x.kind <> result.kind) then
|
if (x.kind <> result.kind) then
|
||||||
stackTrace(c, n, errCannotInterpretNodeX, nodeKindToStr[n.kind])
|
stackTrace(c, n, errCannotInterpretNodeX, nodeKindToStr[n.kind])
|
||||||
else begin
|
else begin
|
||||||
|
|
@ -527,10 +532,10 @@ var
|
||||||
a, b: PNode;
|
a, b: PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
case a.kind of
|
case a.kind of
|
||||||
nkCharLit..nkInt64Lit: a.intval := a.intVal + sign * getOrdValue(b);
|
nkCharLit..nkInt64Lit: a.intval := a.intVal + sign * getOrdValue(b);
|
||||||
|
|
@ -553,7 +558,7 @@ var
|
||||||
begin
|
begin
|
||||||
for i := 1 to sonsLen(n)-1 do begin
|
for i := 1 to sonsLen(n)-1 do begin
|
||||||
result := evalAux(c, n.sons[i]);
|
result := evalAux(c, n.sons[i]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
Write(output, getStrValue(result));
|
Write(output, getStrValue(result));
|
||||||
end;
|
end;
|
||||||
writeln(output, '');
|
writeln(output, '');
|
||||||
|
|
@ -563,7 +568,7 @@ end;
|
||||||
function evalExit(c: PEvalContext; n: PNode): PNode;
|
function evalExit(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
liMessage(n.info, hintQuitCalled);
|
liMessage(n.info, hintQuitCalled);
|
||||||
halt(int(getOrdValue(result)));
|
halt(int(getOrdValue(result)));
|
||||||
end;
|
end;
|
||||||
|
|
@ -571,7 +576,7 @@ end;
|
||||||
function evalOr(c: PEvalContext; n: PNode): PNode;
|
function evalOr(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if result.kind <> nkIntLit then InternalError(n.info, 'evalOr');
|
if result.kind <> nkIntLit then InternalError(n.info, 'evalOr');
|
||||||
if result.intVal = 0 then result := evalAux(c, n.sons[2])
|
if result.intVal = 0 then result := evalAux(c, n.sons[2])
|
||||||
end;
|
end;
|
||||||
|
|
@ -579,7 +584,7 @@ end;
|
||||||
function evalAnd(c: PEvalContext; n: PNode): PNode;
|
function evalAnd(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if result.kind <> nkIntLit then InternalError(n.info, 'evalAnd');
|
if result.kind <> nkIntLit then InternalError(n.info, 'evalAnd');
|
||||||
if result.intVal <> 0 then result := evalAux(c, n.sons[2])
|
if result.intVal <> 0 then result := evalAux(c, n.sons[2])
|
||||||
end;
|
end;
|
||||||
|
|
@ -607,9 +612,8 @@ end;
|
||||||
function evalDeref(c: PEvalContext; n: PNode): PNode;
|
function evalDeref(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
case result.kind of
|
case result.kind of
|
||||||
nkExceptBranch: exit;
|
|
||||||
nkNilLit: stackTrace(c, n, errNilAccess);
|
nkNilLit: stackTrace(c, n, errNilAccess);
|
||||||
nkRefTy: result := result.sons[0];
|
nkRefTy: result := result.sons[0];
|
||||||
else InternalError(n.info, 'evalDeref ' + nodeKindToStr[result.kind]);
|
else InternalError(n.info, 'evalDeref ' + nodeKindToStr[result.kind]);
|
||||||
|
|
@ -622,7 +626,7 @@ var
|
||||||
t: PType;
|
t: PType;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
t := newType(tyPtr, c.module);
|
t := newType(tyPtr, c.module);
|
||||||
addSon(t, a.typ);
|
addSon(t, a.typ);
|
||||||
|
|
@ -647,7 +651,7 @@ var
|
||||||
dest, src: PType;
|
dest, src: PType;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
dest := skipTypes(n.typ, abstractPtrs);
|
dest := skipTypes(n.typ, abstractPtrs);
|
||||||
src := skipTypes(result.typ, abstractPtrs);
|
src := skipTypes(result.typ, abstractPtrs);
|
||||||
if inheritanceDiff(src, dest) > 0 then
|
if inheritanceDiff(src, dest) > 0 then
|
||||||
|
|
@ -659,13 +663,13 @@ var
|
||||||
x, a, b: PNode;
|
x, a, b: PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
x := result;
|
x := result;
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
|
|
||||||
if leValueConv(a, x) and leValueConv(x, b) then begin
|
if leValueConv(a, x) and leValueConv(x, b) then begin
|
||||||
|
|
@ -681,14 +685,14 @@ end;
|
||||||
function evalConvStrToCStr(c: PEvalContext; n: PNode): PNode;
|
function evalConvStrToCStr(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
result.typ := n.typ;
|
result.typ := n.typ;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function evalConvCStrToStr(c: PEvalContext; n: PNode): PNode;
|
function evalConvCStrToStr(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
result.typ := n.typ;
|
result.typ := n.typ;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -698,7 +702,7 @@ var
|
||||||
begin
|
begin
|
||||||
if n.sons[0] <> nil then begin
|
if n.sons[0] <> nil then begin
|
||||||
result := evalAux(c, n.sons[0]);
|
result := evalAux(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := newNodeIT(nkExceptBranch, n.info, a.typ);
|
result := newNodeIT(nkExceptBranch, n.info, a.typ);
|
||||||
addSon(result, a);
|
addSon(result, a);
|
||||||
|
|
@ -717,7 +721,7 @@ function evalReturn(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
if n.sons[0] <> nil then begin
|
if n.sons[0] <> nil then begin
|
||||||
result := evalAsgn(c, n.sons[0]);
|
result := evalAsgn(c, n.sons[0]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
end;
|
end;
|
||||||
result := newNodeIT(nkReturnToken, n.info, nil);
|
result := newNodeIT(nkReturnToken, n.info, nil);
|
||||||
end;
|
end;
|
||||||
|
|
@ -743,7 +747,7 @@ end;
|
||||||
function evalHigh(c: PEvalContext; n: PNode): PNode;
|
function evalHigh(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
case skipTypes(n.sons[1].typ, abstractVar).kind of
|
case skipTypes(n.sons[1].typ, abstractVar).kind of
|
||||||
tyOpenArray, tySequence:
|
tyOpenArray, tySequence:
|
||||||
result := newIntNodeT(sonsLen(result), n);
|
result := newIntNodeT(sonsLen(result), n);
|
||||||
|
|
@ -756,7 +760,7 @@ end;
|
||||||
function evalIs(c: PEvalContext; n: PNode): PNode;
|
function evalIs(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
result := newIntNodeT(ord(inheritanceDiff(result.typ, n.sons[2].typ) >= 0), n)
|
result := newIntNodeT(ord(inheritanceDiff(result.typ, n.sons[2].typ) >= 0), n)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -766,10 +770,10 @@ var
|
||||||
oldLen, newLen: int;
|
oldLen, newLen: int;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
case a.kind of
|
case a.kind of
|
||||||
nkStrLit..nkTripleStrLit: begin
|
nkStrLit..nkTripleStrLit: begin
|
||||||
|
|
@ -793,10 +797,10 @@ var
|
||||||
newLen, oldLen, i: int;
|
newLen, oldLen, i: int;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
if a.kind <> nkBracket then InternalError(n.info, 'evalSetLengthSeq');
|
if a.kind <> nkBracket then InternalError(n.info, 'evalSetLengthSeq');
|
||||||
newLen := int(getOrdValue(b));
|
newLen := int(getOrdValue(b));
|
||||||
|
|
@ -814,10 +818,10 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
|
|
||||||
t := skipTypes(n.sons[1].typ, abstractVar);
|
t := skipTypes(n.sons[1].typ, abstractVar);
|
||||||
|
|
@ -833,7 +837,7 @@ end;
|
||||||
function evalAssert(c: PEvalContext; n: PNode): PNode;
|
function evalAssert(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if getOrdValue(result) <> 0 then
|
if getOrdValue(result) <> 0 then
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
else
|
else
|
||||||
|
|
@ -845,10 +849,10 @@ var
|
||||||
a, b: PNode;
|
a, b: PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
if not inSet(a, b) then addSon(a, copyTree(b));
|
if not inSet(a, b) then addSon(a, copyTree(b));
|
||||||
result := emptyNode;
|
result := emptyNode;
|
||||||
|
|
@ -860,10 +864,10 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := newNodeIT(nkCurly, n.info, n.sons[1].typ);
|
b := newNodeIT(nkCurly, n.info, n.sons[1].typ);
|
||||||
addSon(b, result);
|
addSon(b, result);
|
||||||
r := diffSets(a, b);
|
r := diffSets(a, b);
|
||||||
|
|
@ -877,10 +881,10 @@ var
|
||||||
a, b: PNode;
|
a, b: PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
case a.kind of
|
case a.kind of
|
||||||
nkStrLit..nkTripleStrLit: addChar(a.strVal, chr(int(getOrdValue(b))));
|
nkStrLit..nkTripleStrLit: addChar(a.strVal, chr(int(getOrdValue(b))));
|
||||||
|
|
@ -896,11 +900,11 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
for i := 2 to sonsLen(n)-1 do begin
|
for i := 2 to sonsLen(n)-1 do begin
|
||||||
result := evalAux(c, n.sons[i]);
|
result := evalAux(c, n.sons[i]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a.strVal := getStrValue(a) +{&} getStrValue(result);
|
a.strVal := getStrValue(a) +{&} getStrValue(result);
|
||||||
end;
|
end;
|
||||||
result := a;
|
result := a;
|
||||||
|
|
@ -911,10 +915,10 @@ var
|
||||||
a, b: PNode;
|
a, b: PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
case a.kind of
|
case a.kind of
|
||||||
nkStrLit..nkTripleStrLit: a.strVal := a.strVal +{&} getStrValue(b);
|
nkStrLit..nkTripleStrLit: a.strVal := a.strVal +{&} getStrValue(b);
|
||||||
|
|
@ -928,10 +932,10 @@ var
|
||||||
a, b: PNode;
|
a, b: PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
if a.kind = nkBracket then addSon(a, copyTree(b))
|
if a.kind = nkBracket then addSon(a, copyTree(b))
|
||||||
else InternalError(n.info, 'evalAppendSeqElem');
|
else InternalError(n.info, 'evalAppendSeqElem');
|
||||||
|
|
@ -941,10 +945,15 @@ end;
|
||||||
function evalRepr(c: PEvalContext; n: PNode): PNode;
|
function evalRepr(c: PEvalContext; n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
result := newStrNodeT(renderTree(result, {@set}[renderNoComments]), n);
|
result := newStrNodeT(renderTree(result, {@set}[renderNoComments]), n);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function isEmpty(n: PNode): bool;
|
||||||
|
begin
|
||||||
|
result := (n <> nil) and (n.kind = nkEmpty)
|
||||||
|
end;
|
||||||
|
|
||||||
function evalMagicOrCall(c: PEvalContext; n: PNode): PNode;
|
function evalMagicOrCall(c: PEvalContext; n: PNode): PNode;
|
||||||
var
|
var
|
||||||
m: TMagic;
|
m: TMagic;
|
||||||
|
|
@ -979,7 +988,7 @@ begin
|
||||||
|
|
||||||
mNLen: begin
|
mNLen: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := newNodeIT(nkIntLit, n.info, n.typ);
|
result := newNodeIT(nkIntLit, n.info, n.typ);
|
||||||
case a.kind of
|
case a.kind of
|
||||||
|
|
@ -989,10 +998,10 @@ begin
|
||||||
end;
|
end;
|
||||||
mNChild: begin
|
mNChild: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
k := getOrdValue(result);
|
k := getOrdValue(result);
|
||||||
if not (a.kind in [nkEmpty..nkNilLit]) and (k >= 0)
|
if not (a.kind in [nkEmpty..nkNilLit]) and (k >= 0)
|
||||||
and (k < sonsLen(a)) then begin
|
and (k < sonsLen(a)) then begin
|
||||||
|
|
@ -1006,13 +1015,13 @@ begin
|
||||||
end;
|
end;
|
||||||
mNSetChild: begin
|
mNSetChild: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
result := evalAux(c, n.sons[3]);
|
result := evalAux(c, n.sons[3]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
k := getOrdValue(b);
|
k := getOrdValue(b);
|
||||||
if (k >= 0) and (k < sonsLen(a))
|
if (k >= 0) and (k < sonsLen(a))
|
||||||
and not (a.kind in [nkEmpty..nkNilLit]) then begin
|
and not (a.kind in [nkEmpty..nkNilLit]) then begin
|
||||||
|
|
@ -1025,45 +1034,45 @@ begin
|
||||||
end;
|
end;
|
||||||
mNAdd: begin
|
mNAdd: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
addSon(a, result);
|
addSon(a, result);
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
mNAddMultiple: begin
|
mNAddMultiple: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
for i := 0 to sonsLen(result)-1 do addSon(a, result.sons[i]);
|
for i := 0 to sonsLen(result)-1 do addSon(a, result.sons[i]);
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
mNDel: begin
|
mNDel: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
result := evalAux(c, n.sons[3]);
|
result := evalAux(c, n.sons[3]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
for i := 0 to int(getOrdValue(result))-1 do
|
for i := 0 to int(getOrdValue(result))-1 do
|
||||||
delSon(a, int(getOrdValue(b)));
|
delSon(a, int(getOrdValue(b)));
|
||||||
result := emptyNode;
|
result := emptyNode;
|
||||||
end;
|
end;
|
||||||
mNKind: begin
|
mNKind: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := newNodeIT(nkIntLit, n.info, n.typ);
|
result := newNodeIT(nkIntLit, n.info, n.typ);
|
||||||
result.intVal := ord(a.kind);
|
result.intVal := ord(a.kind);
|
||||||
end;
|
end;
|
||||||
mNIntVal: begin
|
mNIntVal: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := newNodeIT(nkIntLit, n.info, n.typ);
|
result := newNodeIT(nkIntLit, n.info, n.typ);
|
||||||
case a.kind of
|
case a.kind of
|
||||||
|
|
@ -1073,7 +1082,7 @@ begin
|
||||||
end;
|
end;
|
||||||
mNFloatVal: begin
|
mNFloatVal: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := newNodeIT(nkFloatLit, n.info, n.typ);
|
result := newNodeIT(nkFloatLit, n.info, n.typ);
|
||||||
case a.kind of
|
case a.kind of
|
||||||
|
|
@ -1083,18 +1092,18 @@ begin
|
||||||
end;
|
end;
|
||||||
mNSymbol: begin
|
mNSymbol: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if result.kind <> nkSym then InternalError(n.info, 'no symbol')
|
if result.kind <> nkSym then InternalError(n.info, 'no symbol')
|
||||||
end;
|
end;
|
||||||
mNIdent: begin
|
mNIdent: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if result.kind <> nkIdent then InternalError(n.info, 'no symbol')
|
if result.kind <> nkIdent then InternalError(n.info, 'no symbol')
|
||||||
end;
|
end;
|
||||||
mNGetType: result := evalAux(c, n.sons[1]);
|
mNGetType: result := evalAux(c, n.sons[1]);
|
||||||
mNStrVal: begin
|
mNStrVal: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := newNodeIT(nkStrLit, n.info, n.typ);
|
result := newNodeIT(nkStrLit, n.info, n.typ);
|
||||||
case a.kind of
|
case a.kind of
|
||||||
|
|
@ -1104,64 +1113,64 @@ begin
|
||||||
end;
|
end;
|
||||||
mNSetIntVal: begin
|
mNSetIntVal: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a.intVal := result.intVal; // XXX: exception handling?
|
a.intVal := result.intVal; // XXX: exception handling?
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
mNSetFloatVal: begin
|
mNSetFloatVal: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a.floatVal := result.floatVal; // XXX: exception handling?
|
a.floatVal := result.floatVal; // XXX: exception handling?
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
mNSetSymbol: begin
|
mNSetSymbol: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a.sym := result.sym; // XXX: exception handling?
|
a.sym := result.sym; // XXX: exception handling?
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
mNSetIdent: begin
|
mNSetIdent: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a.ident := result.ident; // XXX: exception handling?
|
a.ident := result.ident; // XXX: exception handling?
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
mNSetType: begin
|
mNSetType: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a.typ := result.typ; // XXX: exception handling?
|
a.typ := result.typ; // XXX: exception handling?
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
mNSetStrVal: begin
|
mNSetStrVal: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a.strVal := result.strVal; // XXX: exception handling?
|
a.strVal := result.strVal; // XXX: exception handling?
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
mNNewNimNode: begin
|
mNNewNimNode: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
k := getOrdValue(result);
|
k := getOrdValue(result);
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
if (k < 0) or (k > ord(high(TNodeKind))) then
|
if (k < 0) or (k > ord(high(TNodeKind))) then
|
||||||
internalError(n.info, 'request to create a NimNode with invalid kind');
|
internalError(n.info, 'request to create a NimNode with invalid kind');
|
||||||
|
|
@ -1172,17 +1181,17 @@ begin
|
||||||
end;
|
end;
|
||||||
mNCopyNimNode: begin
|
mNCopyNimNode: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
result := copyNode(result);
|
result := copyNode(result);
|
||||||
end;
|
end;
|
||||||
mNCopyNimTree: begin
|
mNCopyNimTree: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
result := copyTree(result);
|
result := copyTree(result);
|
||||||
end;
|
end;
|
||||||
mStrToIdent: begin
|
mStrToIdent: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if not (result.kind in [nkStrLit..nkTripleStrLit]) then
|
if not (result.kind in [nkStrLit..nkTripleStrLit]) then
|
||||||
InternalError(n.info, 'no string node');
|
InternalError(n.info, 'no string node');
|
||||||
a := result;
|
a := result;
|
||||||
|
|
@ -1191,7 +1200,7 @@ begin
|
||||||
end;
|
end;
|
||||||
mIdentToStr: begin
|
mIdentToStr: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
if result.kind <> nkIdent then
|
if result.kind <> nkIdent then
|
||||||
InternalError(n.info, 'no ident node');
|
InternalError(n.info, 'no ident node');
|
||||||
a := result;
|
a := result;
|
||||||
|
|
@ -1200,10 +1209,10 @@ begin
|
||||||
end;
|
end;
|
||||||
mEqIdent: begin
|
mEqIdent: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
result := newNodeIT(nkIntLit, n.info, n.typ);
|
result := newNodeIT(nkIntLit, n.info, n.typ);
|
||||||
if (a.kind = nkIdent) and (b.kind = nkIdent) then
|
if (a.kind = nkIdent) and (b.kind = nkIdent) then
|
||||||
|
|
@ -1211,10 +1220,10 @@ begin
|
||||||
end;
|
end;
|
||||||
mEqNimrodNode: begin
|
mEqNimrodNode: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
result := newNodeIT(nkIntLit, n.info, n.typ);
|
result := newNodeIT(nkIntLit, n.info, n.typ);
|
||||||
if (a = b)
|
if (a = b)
|
||||||
|
|
@ -1224,19 +1233,19 @@ begin
|
||||||
end;
|
end;
|
||||||
mNHint: begin
|
mNHint: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
liMessage(n.info, hintUser, getStrValue(result));
|
liMessage(n.info, hintUser, getStrValue(result));
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
mNWarning: begin
|
mNWarning: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
liMessage(n.info, warnUser, getStrValue(result));
|
liMessage(n.info, warnUser, getStrValue(result));
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
mNError: begin
|
mNError: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
stackTrace(c, n, errUser, getStrValue(result));
|
stackTrace(c, n, errUser, getStrValue(result));
|
||||||
result := emptyNode
|
result := emptyNode
|
||||||
end;
|
end;
|
||||||
|
|
@ -1244,28 +1253,31 @@ begin
|
||||||
mRepr: result := evalRepr(c, n);
|
mRepr: result := evalRepr(c, n);
|
||||||
mNewString: begin
|
mNewString: begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
result := newNodeIT(nkStrLit, n.info, n.typ);
|
result := newNodeIT(nkStrLit, n.info, n.typ);
|
||||||
result.strVal := newString(int(getOrdValue(a)));
|
result.strVal := newString(int(getOrdValue(a)));
|
||||||
end;
|
end;
|
||||||
else begin
|
else begin
|
||||||
result := evalAux(c, n.sons[1]);
|
result := evalAux(c, n.sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a := result;
|
a := result;
|
||||||
b := nil;
|
b := nil;
|
||||||
cc := nil;
|
cc := nil;
|
||||||
if sonsLen(n) > 2 then begin
|
if sonsLen(n) > 2 then begin
|
||||||
result := evalAux(c, n.sons[2]);
|
result := evalAux(c, n.sons[2]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
b := result;
|
b := result;
|
||||||
if sonsLen(n) > 3 then begin
|
if sonsLen(n) > 3 then begin
|
||||||
result := evalAux(c, n.sons[3]);
|
result := evalAux(c, n.sons[3]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
cc := result;
|
cc := result;
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
result := evalOp(m, n, a, b, cc);
|
if isEmpty(a) or isEmpty(b) or isEmpty(cc) then
|
||||||
|
result := emptyNode
|
||||||
|
else
|
||||||
|
result := evalOp(m, n, a, b, cc);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -1290,7 +1302,7 @@ begin
|
||||||
a := copyNode(n);
|
a := copyNode(n);
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
result := evalAux(c, n.sons[i]);
|
result := evalAux(c, n.sons[i]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
addSon(a, result);
|
addSon(a, result);
|
||||||
end;
|
end;
|
||||||
result := a
|
result := a
|
||||||
|
|
@ -1299,7 +1311,7 @@ begin
|
||||||
a := copyTree(n);
|
a := copyTree(n);
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
result := evalAux(c, n.sons[i].sons[1]);
|
result := evalAux(c, n.sons[i].sons[1]);
|
||||||
if result.kind = nkExceptBranch then exit;
|
if isSpecial(result) then exit;
|
||||||
a.sons[i].sons[1] := result;
|
a.sons[i].sons[1] := result;
|
||||||
end;
|
end;
|
||||||
result := a
|
result := a
|
||||||
|
|
@ -1397,9 +1409,5 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
new(emptyNode);
|
emptyNode := newNode(nkEmpty);
|
||||||
{@ignore}
|
|
||||||
fillChar(emptyNode^, sizeof(emptyNode^), 0);
|
|
||||||
{@emit}
|
|
||||||
emptyNode.kind := nkEmpty;
|
|
||||||
end.
|
end.
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ Files: "configure;makefile"
|
||||||
Files: "*.html"
|
Files: "*.html"
|
||||||
Files: "*.py"
|
Files: "*.py"
|
||||||
Files: "*.ini"
|
Files: "*.ini"
|
||||||
|
Files: "*.nim"
|
||||||
|
|
||||||
Files: "rod/readme.txt"
|
Files: "rod/readme.txt"
|
||||||
Files: "rod/nimrod.ini"
|
Files: "rod/nimrod.ini"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue