diff options
author | Andreas Rumpf <andreas@andreas-desktop> | 2009-11-26 00:32:07 +0100 |
---|---|---|
committer | Andreas Rumpf <andreas@andreas-desktop> | 2009-11-26 00:32:07 +0100 |
commit | 196ef92c86d8b8971d4b316f7c18e404842c4b9b (patch) | |
tree | 03506a36422f8ae7543b492978067263beea8502 | |
parent | 3710309d39f65718ab5990d53a977acb241432a9 (diff) | |
download | Nim-196ef92c86d8b8971d4b316f7c18e404842c4b9b.tar.gz |
bug concerning constant evaluation fixed
-rwxr-xr-x | data/advopt.txt | 24 | ||||
-rwxr-xr-x | data/basicopt.txt | 22 | ||||
-rwxr-xr-x | doc/intern.txt | 7 | ||||
-rwxr-xr-x | doc/manual.txt | 8 | ||||
-rwxr-xr-x | doc/nimrodc.txt | 47 | ||||
-rwxr-xr-x | lib/impure/db_postgres.nim | 137 | ||||
-rwxr-xr-x | lib/impure/zipfiles.nim | 2 | ||||
-rwxr-xr-x | lib/pure/pegs.nim | 4 | ||||
-rwxr-xr-x | lib/pure/re.nim | 2 | ||||
-rwxr-xr-x | lib/system/profiler.nim | 8 | ||||
-rwxr-xr-x | lib/wrappers/postgres.nim | 2 | ||||
-rwxr-xr-x | nim/commands.pas | 49 | ||||
-rwxr-xr-x | nim/evals.pas | 228 | ||||
-rwxr-xr-x | rod/nimrod.ini | 1 |
14 files changed, 296 insertions, 245 deletions
diff --git a/data/advopt.txt b/data/advopt.txt index 975c09af8..1fe4e0e6e 100755 --- a/data/advopt.txt +++ b/data/advopt.txt @@ -1,9 +1,9 @@ Advanced commands:: pas convert a Pascal file to Nimrod syntax pretty pretty print the inputfile - gen_depend generate a DOT file containing the + genDepend generate a DOT file containing the 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 parse parses a single file (for debugging Nimrod) Advanced options: @@ -12,27 +12,27 @@ Advanced options: --hints:on|off hints ON|OFF --hint[X]:on|off specific hint X ON|OFF --lib:PATH set the system library path - -c, --compile_only compile only; do not assemble or link - --no_linking compile but do not link - --no_main do not generate a main procedure - --gen_script generate a compile script (in the 'nimcache' + -c, --compileOnly compile only; do not assemble or link + --noLinking compile but do not link + --noMain do not generate a main procedure + --genScript generate a compile script (in the 'nimcache' subdirectory named 'compile_$project$scriptext') --os:SYMBOL set the target operating system (cross-compilation) --cpu:SYMBOL set the target processor (cross-compilation) --debuginfo enables debug information -t, --passc:OPTION pass an option to the C compiler -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 - --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 - --skip_cfg do not read the general configuration file - --skip_proj_cfg do not read the project's configuration file + --skipCfg do not read the general configuration file + --skipProjCfg do not read the project's configuration file --gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC --index:FILE use FILE to generate a documenation index file --putenv:key=value set an environment variable - --list_cmd list the commands used to execute external programs - --parallel_build=0|1|... perform a parallel build + --listCmd list the commands used to execute external programs + --parallelBuild=0|1|... perform a parallel build value = number of processors (0 for auto-detect) --verbosity:0|1|2|3 set Nimrod's verbosity level (0 is default) -v, --version show detailed version information diff --git a/data/basicopt.txt b/data/basicopt.txt index af3f541ad..136c058c0 100755 --- a/data/basicopt.txt +++ b/data/basicopt.txt @@ -2,7 +2,7 @@ Usage:: nimrod command [options] inputfile [arguments] Command:: 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 rst2html converts a reStructuredText file to HTML rst2tex converts a reStructuredText file to TeX @@ -13,19 +13,19 @@ Options: -o, --out:FILE set the output filename -d, --define:SYMBOL define a conditional symbol -u, --undef:SYMBOL undefine a conditional symbol - -f, --force_build force rebuilding of all modules - --symbol_files:on|off use symbol files to speed up compilation (buggy!) - --stack_trace:on|off code generation for stack trace ON|OFF - --line_trace:on|off code generation for line trace ON|OFF + -f, --forceBuild force rebuilding of all modules + --symbolFiles:on|off use symbol files to speed up compilation (buggy!) + --stackTrace:on|off code generation for stack trace ON|OFF + --lineTrace:on|off code generation for line trace ON|OFF --debugger:on|off turn Embedded Nimrod Debugger ON|OFF -x, --checks:on|off code generation for all runtime checks ON|OFF - --obj_checks:on|off code generation for obj conversion checks ON|OFF - --field_checks:on|off code generation for case variant fields ON|OFF - --range_checks:on|off code generation for range checks ON|OFF - --bound_checks:on|off code generation for bound checks ON|OFF - --overflow_checks:on|off code generation for over-/underflow checks ON|OFF + --objChecks:on|off code generation for obj conversion checks ON|OFF + --fieldChecks:on|off code generation for case variant fields ON|OFF + --rangeChecks:on|off code generation for range checks ON|OFF + --boundChecks:on|off code generation for bound checks ON|OFF + --overflowChecks:on|off code generation for over-/underflow checks ON|OFF -a, --assertions:on|off code generation for assertions ON|OFF - --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 --app:console|gui|lib generate a console|GUI application|dynamic library -r, --run run the compiled program with given arguments diff --git a/doc/intern.txt b/doc/intern.txt index e62378e1d..dfdc33ae9 100755 --- a/doc/intern.txt +++ b/doc/intern.txt @@ -29,12 +29,11 @@ Path Purpose version ``data`` data files that are used for generating source code -``doc`` the documentation lives here; it is a bunch of +``doc`` the documentation; it is a bunch of reStructuredText files ``dist`` additional packages for the distribution ``config`` configuration files for Nimrod -``lib`` the Nimrod library lives here; ``rod`` depends - on it! +``lib`` the Nimrod library; ``rod`` depends on it! ``web`` website of Nimrod; generated by ``koch.py`` from the ``*.txt`` and ``*.tmpl`` 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. 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. Each cell has a header consisting of a RC and a pointer to its type diff --git a/doc/manual.txt b/doc/manual.txt index 647ce2774..5b04a3b52 100755 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -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 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 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 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. -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. -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. assertions on|off Turns the code generation for assertions on or off. diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt index 88ca52939..3720fc5cb 100755 --- a/doc/nimrodc.txt +++ b/doc/nimrodc.txt @@ -12,7 +12,7 @@ Introduction This document describes the usage of the *Nimrod compiler* 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 `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) 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 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 @@ -125,24 +125,24 @@ At runtime the dynamic library is searched for (in this order):: libtcl8.3.so.0 -No_decl Pragma -~~~~~~~~~~~~~~ -The `no_decl`:idx: pragma can be applied to almost any symbol (variable, proc, +NoDecl Pragma +~~~~~~~~~~~~~ +The `noDecl`:idx: pragma can be applied to almost any symbol (variable, proc, type, etc.) and is sometimes useful for interoperability with C: It tells Nimrod that it should not generate a declaration for the symbol in the C code. For example: .. code-block:: Nimrod var - EACCES {.importc, no_decl.}: cint # pretend EACCES was a variable, as - # Nimrod does not know its value + EACCES {.importc, noDecl.}: cint # pretend EACCES was a variable, as + # Nimrod does not know its value However, the ``header`` pragma is often the better alternative. 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 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 -Line_dir Option -~~~~~~~~~~~~~~~ -The `line_dir`:idx: option can be turned on or off. If on the generated C code -contains ``#line`` directives. This may be helpful for debugging with GDB. +LineDir Option +~~~~~~~~~~~~~~ +The `lineDir`:idx: option can be turned on or off. If turned on the +generated C code contains ``#line`` directives. This may be helpful for +debugging with GDB. -Stack_trace Option -~~~~~~~~~~~~~~~~~~ -If the `stack_trace`:idx: option is turned on, the generated C contains code to +StackTrace Option +~~~~~~~~~~~~~~~~~ +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 uncaught exception is raised. -Line_trace Option -~~~~~~~~~~~~~~~~~ -The `line_trace`:idx: option implies the ``stack_trace`` option. If turned on, +LineTrace Option +~~~~~~~~~~~~~~~~ +The `lineTrace`:idx: option implies the ``stackTrace`` option. If turned on, 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 is raised. @@ -239,21 +240,21 @@ information that this cannot happen to the GC. If the programmer uses the 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 pragma appers in. -The ``--dead_code_elim:on`` command line switch has the same effect as marking -every module with ``{.dead_code_elim:on}``. However, for some modules such as +The ``--deadCodeElim:on`` command line switch has the same effect as marking +every module with ``{.deadCodeElim:on}``. However, for some modules such as the GTK wrapper it makes sense to *always* turn on dead code elimination - no matter if it is globally active or not. Example: .. code-block:: nimrod - {.dead_code_elim: on.} + {.deadCodeElim: on.} Disabling certain messages diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index 197250d9c..b9d0b068f 100755 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -4,11 +4,20 @@ import strutils, postgres type - TDbHandle* = PGconn - TRow* = seq[string] - EDb* = object of EIO + TDbConn* = PPGconn ## encapsulates a database connection + TRow* = seq[string] ## a row of a dataset + 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. var e: ref EDb new(e) @@ -23,13 +32,13 @@ proc dbError*(msg: string) {.noreturn.} = raise e 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) if stmt == nil: dbError(db) if mysql_stmt_prepare(stmt, query, len(query)) != 0: dbError(db) var - bind: seq[MYSQL_BIND] + bindings: seq[MYSQL_BIND] discard mysql_stmt_close(stmt) proc dbQuote(s: string): string = @@ -39,91 +48,123 @@ proc dbQuote(s: string): string = else: add(result, c) add(result, '\'') -proc dbFormat(formatstr: string, args: openarray[string]): string = +proc dbFormat(formatstr: TSqlQuery, args: openarray[string]): string = result = "" var a = 0 - for c in items(formatstr): + for c in items(string(formatstr)): if c == '?': add(result, dbQuote(args[a])) inc(a) else: 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 res = PQExec(db, q) result = PQresultStatus(res) == PGRES_COMMAND_OK PQclear(res) -proc dbQuery*(db: TDbHandle, query: string, args: openarray[string]) = - var q = dbFormat(query, args) - var res = PQExec(db, q) - if PQresultStatus(res) != PGRES_COMMAND_OK: dbError(db) - 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 +proc dbQuery*(db: TDbConn, query: TSqlQuery, args: openarray[string]) = + ## executes the query and raises EDB if not successful. 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 = newSeq(result, L) for i in 0..L-1: result[i] = "" -iterator dbFastRows*(db: TDbHandle, query: string, - args: openarray[string]): TRow = +proc setupQuery(db: TDbConn, query: TSqlQuery, + args: openarray[string]): PPGresult = var q = dbFormat(query, args) - var res = PQExec(db, q) - if PQresultStatus(res) != PGRES_TUPLES_OK: dbError(db) + result = PQExec(db, q) + 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 result = newRow(L) for i in 0..PQntuples(res)-1: - for j in 0..L-1: - setLen(result[j], 0) - add(result[j], PQgetvalue(res, i, j)) + setRow(res, result, i, L) yield result PQclear(res) -proc dbGetAllRows*(db: TDbHandle, query: string, +proc dbGetAllRows*(db: TDbConn, query: TSqlQuery, args: openarray[string]): seq[TRow] = + ## executes the query and returns the whole result dataset. result = @[] for r in dbFastRows(db, query, args): result.add(r) -iterator dbRows*(db: TDbHandle, query: string, +iterator dbRows*(db: TDbConn, query: TSqlQuery, args: openarray[string]): TRow = + ## same as `dbFastRows`, but slower and safe. 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 = + ## 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 = "" for row in dbFastRows(db, query, args): result = row[0] break + +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: TDbHandle) = +proc dbClose*(db: TDbConn) = + ## closes the database connection. 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) - if PQStatus(result) != CONNECTION_OK: result = nil + if PQStatus(result) != CONNECTION_OK: dbError(result) # result = nil + diff --git a/lib/impure/zipfiles.nim b/lib/impure/zipfiles.nim index e48b0f08e..07fe41a04 100755 --- a/lib/impure/zipfiles.nim +++ b/lib/impure/zipfiles.nim @@ -43,7 +43,7 @@ proc close*(z: var TZipArchive) = zip_close(z.w) 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 ## ``"path1/path2/filename"`` it is not necessary ## to create the ``"path/path2"`` subdirectories - it will be done diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index 21205bdb2..488e42c7d 100755 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -148,7 +148,7 @@ proc sequence*(a: openArray[TPeg]): TPeg = multipleOp(pkSequence, addSequence) 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, pkGreedyRepSet}: # a* ? --> a* @@ -159,7 +159,7 @@ proc `?`*(a: TPeg): TPeg = result.sons = @[a] proc `*`*(a: TPeg): TPeg = - ## constructs a "greedy repetition" piece the PEG `a` + ## constructs a "greedy repetition" for the PEG `a` case a.kind of pkGreedyRep, pkGreedyRepChar, pkGreedyRepSet, pkGreedyAny, pkOption: assert false diff --git a/lib/pure/re.nim b/lib/pure/re.nim index f854c07e5..87fe79a04 100755 --- a/lib/pure/re.nim +++ b/lib/pure/re.nim @@ -224,7 +224,7 @@ proc replace*(s: string, sub: TRegEx, by: string): string = ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: ## ## .. 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: ## diff --git a/lib/system/profiler.nim b/lib/system/profiler.nim index 97c7dcfeb..b87b30d4a 100755 --- a/lib/system/profiler.nim +++ b/lib/system/profiler.nim @@ -41,10 +41,10 @@ proc writeProfile() {.noconv.} = var i = 0 var f: TFile var j = 1 - while openFile(f, filename & $j & ".txt"): - closeFile(f) + while open(f, filename & $j & ".txt"): + close(f) inc(j) - if openFile(f, filename & $j & ".txt", fmWrite): + if open(f, filename & $j & ".txt", fmWrite): var N = 0 # we have to compute the actual length of the array: while profileData[N].procname != nil: inc(N) @@ -56,6 +56,6 @@ proc writeProfile() {.noconv.} = write(f, ": ") writeln(f, profileData[i].total) inc(i) - closeFile(f) + close(f) addQuitProc(writeProfile) diff --git a/lib/wrappers/postgres.nim b/lib/wrappers/postgres.nim index d3c5e265b..26526b6c8 100755 --- a/lib/wrappers/postgres.nim +++ b/lib/wrappers/postgres.nim @@ -11,7 +11,7 @@ when defined(windows): elif defined(macosx): const dllName = "libpq.dylib" else: - const dllName = "libpq.so" + const dllName = "libpq.so(.5|)" type POid* = ptr Oid diff --git a/nim/commands.pas b/nim/commands.pas index e88fc6b8c..19f79fb4a 100755 --- a/nim/commands.pas +++ b/nim/commands.pas @@ -60,7 +60,7 @@ const +{&} ' nimrod command [options] inputfile [arguments]' +{&} nl +{&} 'Command::' +{&} 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 +{&} ' rst2html converts a reStructuredText file to HTML' +{&} nl +{&} ' rst2tex converts a reStructuredText file to TeX' +{&} nl @@ -71,19 +71,19 @@ const +{&} ' -o, --out:FILE set the output filename' +{&} nl +{&} ' -d, --define:SYMBOL define a conditional symbol' +{&} nl +{&} ' -u, --undef:SYMBOL undefine a conditional symbol' +{&} nl -+{&} ' -f, --force_build force rebuilding of all modules' +{&} nl -+{&} ' --symbol_files:on|off use symbol files to speed up compilation (buggy!)' +{&} nl -+{&} ' --stack_trace:on|off code generation for stack trace ON|OFF' +{&} nl -+{&} ' --line_trace:on|off code generation for line trace ON|OFF' +{&} nl ++{&} ' -f, --forceBuild force rebuilding of all modules' +{&} nl ++{&} ' --symbolFiles:on|off use symbol files to speed up compilation (buggy!)' +{&} nl ++{&} ' --stackTrace:on|off code generation for stack 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 +{&} ' -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 -+{&} ' --field_checks:on|off code generation for case variant fields ON|OFF' +{&} nl -+{&} ' --range_checks:on|off code generation for range checks ON|OFF' +{&} nl -+{&} ' --bound_checks:on|off code generation for bound checks ON|OFF' +{&} nl -+{&} ' --overflow_checks:on|off code generation for over-/underflow checks ON|OFF' +{&} nl ++{&} ' --objChecks:on|off code generation for obj conversion checks ON|OFF' +{&} nl ++{&} ' --fieldChecks:on|off code generation for case variant fields ON|OFF' +{&} nl ++{&} ' --rangeChecks:on|off code generation for range checks ON|OFF' +{&} nl ++{&} ' --boundChecks:on|off code generation for bound 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 -+{&} ' --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 +{&} ' --app:console|gui|lib generate a console|GUI application|dynamic library' +{&} nl +{&} ' -r, --run run the compiled program with given arguments' +{&} nl @@ -100,9 +100,9 @@ const +{&} 'Advanced commands::' +{&} nl +{&} ' pas convert a Pascal file to Nimrod syntax' +{&} 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 -+{&} ' 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 +{&} ' parse parses a single file (for debugging Nimrod)' +{&} nl +{&} 'Advanced options:' +{&} nl @@ -111,27 +111,27 @@ const +{&} ' --hints:on|off hints ON|OFF' +{&} nl +{&} ' --hint[X]:on|off specific hint X ON|OFF' +{&} nl +{&} ' --lib:PATH set the system library path' +{&} nl -+{&} ' -c, --compile_only compile only; do not assemble or link' +{&} nl -+{&} ' --no_linking compile but do not link' +{&} nl -+{&} ' --no_main do not generate a main procedure' +{&} nl -+{&} ' --gen_script generate a compile script (in the ''nimcache''' +{&} nl ++{&} ' -c, --compileOnly compile only; do not assemble or link' +{&} nl ++{&} ' --noLinking compile but do not link' +{&} nl ++{&} ' --noMain do not generate a main procedure' +{&} nl ++{&} ' --genScript generate a compile script (in the ''nimcache''' +{&} nl +{&} ' subdirectory named ''compile_$project$scriptext'')' +{&} nl +{&} ' --os:SYMBOL set the target operating system (cross-compilation)' +{&} nl +{&} ' --cpu:SYMBOL set the target processor (cross-compilation)' +{&} nl +{&} ' --debuginfo enables debug information' +{&} nl +{&} ' -t, --passc:OPTION pass an option to the C compiler' +{&} 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 -+{&} ' --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 -+{&} ' --skip_cfg do not read the general configuration file' +{&} nl -+{&} ' --skip_proj_cfg do not read the project''s configuration file' +{&} nl ++{&} ' --skipCfg do not read the general 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 +{&} ' --index:FILE use FILE to generate a documenation index file' +{&} nl +{&} ' --putenv:key=value set an environment variable' +{&} nl -+{&} ' --list_cmd list the commands used to execute external programs' +{&} nl -+{&} ' --parallel_build=0|1|... perform a parallel build' +{&} nl ++{&} ' --listCmd list the commands used to execute external programs' +{&} nl ++{&} ' --parallelBuild=0|1|... perform a parallel build' +{&} nl +{&} ' value = number of processors (0 for auto-detect)' +{&} nl +{&} ' --verbosity:0|1|2|3 set Nimrod''s verbosity level (0 is default)' +{&} nl +{&} ' -v, --version show detailed version information' +{&} nl @@ -180,7 +180,8 @@ begin helpWritten := true; messageOut(format(HelpMessage, [VersionAsString, platform.os[platform.hostOS].name, - cpu[platform.hostCPU].name])) + cpu[platform.hostCPU].name])); + halt(0); end end; diff --git a/nim/evals.pas b/nim/evals.pas index 43494f929..b9672ba37 100755 --- a/nim/evals.pas +++ b/nim/evals.pas @@ -117,6 +117,11 @@ begin liMessage(n.info, msg, arg); end; +function isSpecial(n: PNode): bool; +begin + result := (n.kind = nkExceptBranch) or (n.kind = nkEmpty) +end; + function evalIf(c: PEvalContext; n: PNode): PNode; var i, len: int; @@ -125,7 +130,7 @@ begin len := sonsLen(n); while (i < len) and (sonsLen(n.sons[i]) >= 2) do begin 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 result := evalAux(c, n.sons[i].sons[1]); exit @@ -144,7 +149,7 @@ var res: PNode; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; res := result; result := emptyNode; for i := 1 to sonsLen(n)-1 do begin @@ -173,7 +178,7 @@ function evalWhile(c: PEvalContext; n: PNode): PNode; begin while true do begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; if getOrdValue(result) = 0 then break; result := evalAux(c, n.sons[1]); case result.kind of @@ -183,7 +188,7 @@ begin break end end; - nkExceptBranch, nkReturnToken: break; + nkExceptBranch, nkReturnToken, nkEmpty: break; else begin end end; dec(gWhileCounter); @@ -314,7 +319,7 @@ begin v := a.sons[0].sym; if a.sons[2] <> nil then begin result := evalAux(c, a.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; end else result := getNullValue(a.sons[0].typ, a.sons[0].info); @@ -330,7 +335,7 @@ var i: int; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; prc := result; // bind the actual params to the local parameter // of a new binding @@ -344,13 +349,13 @@ begin setLength(d.params, sonsLen(n)); for i := 1 to sonsLen(n)-1 do begin result := evalAux(c, n.sons[i]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; d.params[i] := result; end; if n.typ <> nil then d.params[0] := getNullValue(n.typ, n.info); pushStackFrame(c, d); result := evalAux(c, prc); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; if n.typ <> nil then result := d.params[0]; popStackFrame(c); end; @@ -380,10 +385,10 @@ var idx: biggestInt; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; x := result; result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; idx := getOrdValue(result); result := emptyNode; case x.kind of @@ -416,7 +421,7 @@ var i: int; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; x := result; if x.kind <> nkPar then InternalError(n.info, 'evalFieldAccess'); field := n.sons[1].sym; @@ -437,10 +442,10 @@ var i: int; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; x := result; result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; x.kind := result.kind; x.typ := result.typ; case x.kind of @@ -469,10 +474,10 @@ var tmpn: PNode; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; x := result; result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; if (x.kind <> result.kind) then stackTrace(c, n, errCannotInterpretNodeX, nodeKindToStr[n.kind]) else begin @@ -527,10 +532,10 @@ var a, b: PNode; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; case a.kind of nkCharLit..nkInt64Lit: a.intval := a.intVal + sign * getOrdValue(b); @@ -553,7 +558,7 @@ var begin for i := 1 to sonsLen(n)-1 do begin result := evalAux(c, n.sons[i]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; Write(output, getStrValue(result)); end; writeln(output, ''); @@ -563,7 +568,7 @@ end; function evalExit(c: PEvalContext; n: PNode): PNode; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; liMessage(n.info, hintQuitCalled); halt(int(getOrdValue(result))); end; @@ -571,7 +576,7 @@ end; function evalOr(c: PEvalContext; n: PNode): PNode; begin 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.intVal = 0 then result := evalAux(c, n.sons[2]) end; @@ -579,7 +584,7 @@ end; function evalAnd(c: PEvalContext; n: PNode): PNode; begin 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.intVal <> 0 then result := evalAux(c, n.sons[2]) end; @@ -607,9 +612,8 @@ end; function evalDeref(c: PEvalContext; n: PNode): PNode; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; case result.kind of - nkExceptBranch: exit; nkNilLit: stackTrace(c, n, errNilAccess); nkRefTy: result := result.sons[0]; else InternalError(n.info, 'evalDeref ' + nodeKindToStr[result.kind]); @@ -622,7 +626,7 @@ var t: PType; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; t := newType(tyPtr, c.module); addSon(t, a.typ); @@ -647,7 +651,7 @@ var dest, src: PType; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; dest := skipTypes(n.typ, abstractPtrs); src := skipTypes(result.typ, abstractPtrs); if inheritanceDiff(src, dest) > 0 then @@ -659,13 +663,13 @@ var x, a, b: PNode; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; x := result; result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; if leValueConv(a, x) and leValueConv(x, b) then begin @@ -681,14 +685,14 @@ end; function evalConvStrToCStr(c: PEvalContext; n: PNode): PNode; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; result.typ := n.typ; end; function evalConvCStrToStr(c: PEvalContext; n: PNode): PNode; begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; result.typ := n.typ; end; @@ -698,7 +702,7 @@ var begin if n.sons[0] <> nil then begin result := evalAux(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := newNodeIT(nkExceptBranch, n.info, a.typ); addSon(result, a); @@ -717,7 +721,7 @@ function evalReturn(c: PEvalContext; n: PNode): PNode; begin if n.sons[0] <> nil then begin result := evalAsgn(c, n.sons[0]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; end; result := newNodeIT(nkReturnToken, n.info, nil); end; @@ -743,7 +747,7 @@ end; function evalHigh(c: PEvalContext; n: PNode): PNode; begin 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 tyOpenArray, tySequence: result := newIntNodeT(sonsLen(result), n); @@ -756,7 +760,7 @@ end; function evalIs(c: PEvalContext; n: PNode): PNode; begin 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) end; @@ -766,10 +770,10 @@ var oldLen, newLen: int; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; case a.kind of nkStrLit..nkTripleStrLit: begin @@ -793,10 +797,10 @@ var newLen, oldLen, i: int; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; if a.kind <> nkBracket then InternalError(n.info, 'evalSetLengthSeq'); newLen := int(getOrdValue(b)); @@ -814,10 +818,10 @@ var i: int; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; t := skipTypes(n.sons[1].typ, abstractVar); @@ -833,7 +837,7 @@ end; function evalAssert(c: PEvalContext; n: PNode): PNode; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; if getOrdValue(result) <> 0 then result := emptyNode else @@ -845,10 +849,10 @@ var a, b: PNode; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; if not inSet(a, b) then addSon(a, copyTree(b)); result := emptyNode; @@ -860,10 +864,10 @@ var i: int; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; 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); addSon(b, result); r := diffSets(a, b); @@ -877,10 +881,10 @@ var a, b: PNode; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; case a.kind of nkStrLit..nkTripleStrLit: addChar(a.strVal, chr(int(getOrdValue(b)))); @@ -896,11 +900,11 @@ var i: int; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; for i := 2 to sonsLen(n)-1 do begin result := evalAux(c, n.sons[i]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a.strVal := getStrValue(a) +{&} getStrValue(result); end; result := a; @@ -911,10 +915,10 @@ var a, b: PNode; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; case a.kind of nkStrLit..nkTripleStrLit: a.strVal := a.strVal +{&} getStrValue(b); @@ -928,10 +932,10 @@ var a, b: PNode; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; if a.kind = nkBracket then addSon(a, copyTree(b)) else InternalError(n.info, 'evalAppendSeqElem'); @@ -941,10 +945,15 @@ end; function evalRepr(c: PEvalContext; n: PNode): PNode; begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; result := newStrNodeT(renderTree(result, {@set}[renderNoComments]), n); end; +function isEmpty(n: PNode): bool; +begin + result := (n <> nil) and (n.kind = nkEmpty) +end; + function evalMagicOrCall(c: PEvalContext; n: PNode): PNode; var m: TMagic; @@ -979,7 +988,7 @@ begin mNLen: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := newNodeIT(nkIntLit, n.info, n.typ); case a.kind of @@ -989,10 +998,10 @@ begin end; mNChild: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; k := getOrdValue(result); if not (a.kind in [nkEmpty..nkNilLit]) and (k >= 0) and (k < sonsLen(a)) then begin @@ -1006,13 +1015,13 @@ begin end; mNSetChild: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; result := evalAux(c, n.sons[3]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; k := getOrdValue(b); if (k >= 0) and (k < sonsLen(a)) and not (a.kind in [nkEmpty..nkNilLit]) then begin @@ -1025,45 +1034,45 @@ begin end; mNAdd: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; addSon(a, result); result := emptyNode end; mNAddMultiple: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; 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]); result := emptyNode end; mNDel: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; 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 delSon(a, int(getOrdValue(b))); result := emptyNode; end; mNKind: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := newNodeIT(nkIntLit, n.info, n.typ); result.intVal := ord(a.kind); end; mNIntVal: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := newNodeIT(nkIntLit, n.info, n.typ); case a.kind of @@ -1073,7 +1082,7 @@ begin end; mNFloatVal: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := newNodeIT(nkFloatLit, n.info, n.typ); case a.kind of @@ -1083,18 +1092,18 @@ begin end; mNSymbol: begin 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') end; mNIdent: begin 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') end; mNGetType: result := evalAux(c, n.sons[1]); mNStrVal: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := newNodeIT(nkStrLit, n.info, n.typ); case a.kind of @@ -1104,64 +1113,64 @@ begin end; mNSetIntVal: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a.intVal := result.intVal; // XXX: exception handling? result := emptyNode end; mNSetFloatVal: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a.floatVal := result.floatVal; // XXX: exception handling? result := emptyNode end; mNSetSymbol: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a.sym := result.sym; // XXX: exception handling? result := emptyNode end; mNSetIdent: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a.ident := result.ident; // XXX: exception handling? result := emptyNode end; mNSetType: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a.typ := result.typ; // XXX: exception handling? result := emptyNode end; mNSetStrVal: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a.strVal := result.strVal; // XXX: exception handling? result := emptyNode end; mNNewNimNode: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; k := getOrdValue(result); result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; if (k < 0) or (k > ord(high(TNodeKind))) then internalError(n.info, 'request to create a NimNode with invalid kind'); @@ -1172,17 +1181,17 @@ begin end; mNCopyNimNode: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; result := copyNode(result); end; mNCopyNimTree: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; result := copyTree(result); end; mStrToIdent: begin 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 InternalError(n.info, 'no string node'); a := result; @@ -1191,7 +1200,7 @@ begin end; mIdentToStr: begin 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 ident node'); a := result; @@ -1200,10 +1209,10 @@ begin end; mEqIdent: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; result := newNodeIT(nkIntLit, n.info, n.typ); if (a.kind = nkIdent) and (b.kind = nkIdent) then @@ -1211,10 +1220,10 @@ begin end; mEqNimrodNode: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; result := newNodeIT(nkIntLit, n.info, n.typ); if (a = b) @@ -1224,19 +1233,19 @@ begin end; mNHint: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; liMessage(n.info, hintUser, getStrValue(result)); result := emptyNode end; mNWarning: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; liMessage(n.info, warnUser, getStrValue(result)); result := emptyNode end; mNError: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; stackTrace(c, n, errUser, getStrValue(result)); result := emptyNode end; @@ -1244,28 +1253,31 @@ begin mRepr: result := evalRepr(c, n); mNewString: begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; result := newNodeIT(nkStrLit, n.info, n.typ); result.strVal := newString(int(getOrdValue(a))); end; else begin result := evalAux(c, n.sons[1]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; a := result; b := nil; cc := nil; if sonsLen(n) > 2 then begin result := evalAux(c, n.sons[2]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; b := result; if sonsLen(n) > 3 then begin result := evalAux(c, n.sons[3]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; cc := result; 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; @@ -1290,7 +1302,7 @@ begin a := copyNode(n); for i := 0 to sonsLen(n)-1 do begin result := evalAux(c, n.sons[i]); - if result.kind = nkExceptBranch then exit; + if isSpecial(result) then exit; addSon(a, result); end; result := a @@ -1299,7 +1311,7 @@ begin a := copyTree(n); for i := 0 to sonsLen(n)-1 do begin 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; end; result := a @@ -1397,9 +1409,5 @@ begin end; initialization - new(emptyNode); -{@ignore} - fillChar(emptyNode^, sizeof(emptyNode^), 0); -{@emit} - emptyNode.kind := nkEmpty; + emptyNode := newNode(nkEmpty); end. diff --git a/rod/nimrod.ini b/rod/nimrod.ini index 78b736721..1046f400f 100755 --- a/rod/nimrod.ini +++ b/rod/nimrod.ini @@ -35,6 +35,7 @@ Files: "configure;makefile" Files: "*.html" Files: "*.py" Files: "*.ini" +Files: "*.nim" Files: "rod/readme.txt" Files: "rod/nimrod.ini" |